-
Notifications
You must be signed in to change notification settings - Fork 406
Demo Stack
This page will walk you through the steps needed to launch an RTB stack. Of course, this is not meant to be a full production deployment of any kind but a presentation to showcase how the different components interact with each other.
One word before we begin: Depending on your setup, this could be spending real money. So, beware and use wisely.
#Preparation
First, make sure that you have a working build of RTBkit and that all tests are passing. The process is described here.
To be able to find each other, RTBkit components use a central naming service implemented with ZooKeeper. Therefore, you need a running instance of ZooKeeper. For this demo, we will use a very basic configuration for a local standalone server.
Simply run:
cp sample.zookeeper.conf ~/local/bin/zookeeper/conf/zoo.cfg
~/local/bin/zookeeper/bin/zkServer.sh start
If you already have an instance running, you will be able to specify it later.
Next on the list is our persistence backend. This is used by the banker to safely backup the tree of accounts that are needed for doing distributed accounting.
From the rtbkit folder, simply run:
redis-server ./sample.redis.conf
If you already have an instance running, you will be able to specify it later.
This step is optional but recommended. RTBkit components use Graphite to report various metrics and events that are happening within the system in real-time. Without a tool like this, the system is pretty opaque and it's really hard to tell what is going on.
Graphite requires:
pip install pycairo mod_python django python-ldap python-memcached python-sqlite2 bitmap bitmap-fonts
The first step is to install the required components:
pip install carbon
pip install whisper
pip install graphite-web
Now, to start the Carbon service that RTBkit components communicate with, you can use the example configuration files directly:
cd /opt/graphite/conf
for i in `ls *`; do sudo cp $i `echo $i | sed "s/\.example//g"`; done
and run :
/opt/graphite/bin/carbon-cache.py start
If you have an error while executing that script, run:
sudo pip install 'Twisted<12.0'
because newer versions of Twisted don't run very well with graphite.
Now, to setup Graphite itself, follow the installation instructions on the web site and configure your web server accordingly.
Then, don't forget to edit the file sample.bootstrap.json
and add the location of your carbon service accordingly e.g. localhost:2003
. This will enable all services to start logging metrics to the Carbon database. More information about this can be found here.
Notice that when configuring wsgi file in graphite (/opt/graphite/conf/graphite.wsgi) , You should replace this:
sys.path.append('/opt/graphite/webapp')
with this:
sys.path.insert(1,'/opt/graphite/webapp')
This will make sure you are using the right graphite web folder as it will put this folder as first option on system PATH.
#Mock Exchange
In RTBkit, we have added a simple mock exchange to validate the stack before going into production. We'll be using that to begin with and we will make sure that the whole thing works before pointing to a real exchange. The mock exchange simply generates a number of synthetic bid requests and randomly returns wins.
To start it, simply run:
./build/x86_64/bin/mock_exchange_runner
By default, this will send bid requests on port 12339 and wins notification on port 12340.
#RTBkit
With the preparation out of the way, let's focus on RTBkit components. To be able to run, we need:
- the request router to receive bid requests
- at least one agent that will perform the actual bidding
- the banker to manage accounts
- an optional augmenter to add content to a bid request
- some interface to an ad server to process wins
- the post auction loop service to process results from the ad server
- a data logger to store events on disk
- the agent configuration service
- and the monitor to track the sanity of the whole stack
That's quite a few processes. For this demo, you will use the fixed price bidding agent and the frequency cap augmenter that are available as examples in RTBkit.
To make things simpler, we have created a launcher application that starts those process along with a launch script.
Simply run:
./build/x86_64/bin/launcher --node localhost --script ./launch.sh rtbkit/sample.launch.json
./launch.sh
This should start a tmux
session that looks like the following:
By pressing Ctrl-B and 7
, you can see the router processing bids. Right now, all bids are performed by the agent but they get rejected because there's no budget. Thus, with Ctrl-B and 8
, you can't win any bids so nothing is happening in the post auction loop.
So let's add some budget.
The agent currently is tied to a budget account named hello:world
. Since the banker has a REST API, you can take a look in your browser or by doing this:
curl http://localhost:9985/v1/accounts
To add budget, simply do a POST request like so:
curl http://localhost:9985/v1/accounts/hello/budget -d '{ "USD/1M": 123456789 }'
Note that this notation specifies that the amount is in micro dollars. Thus, this is about 125$. When the budget gets added, you should start to see wins coming back to the exchange if you installed graphite and carbon:
And hit Ctrl-B and 2
for the monitor that should now report that everything is OK:
rtbAgentConfiguration:
agentConfigurationService OK 2013-08-28 22:01:36 Alive
rtbBanker:
masterBanker OK 2013-08-28 22:01:36 Banker persistence: OK
rtbDataLogger:
data_logger OK 2013-08-28 22:01:37 Alive
rtbPostAuctionService:
postAuction ERR 2013-08-28 22:01:36 WinLoss pipe: ERROR, CampaignEvent pipe: ERROR
rtbRequestRouter:
router OK 2013-08-28 22:01:36 Connection to PAL: OK
rtbAgentConfiguration:
agentConfigurationService OK 2013-08-28 22:01:46 Alive
rtbBanker:
masterBanker OK 2013-08-28 22:01:46 Banker persistence: OK
rtbDataLogger:
data_logger OK 2013-08-28 22:01:47 Alive
rtbPostAuctionService:
postAuction OK 2013-08-28 22:01:46 WinLoss pipe: OK, CampaignEvent pipe: OK
rtbRequestRouter:
router OK 2013-08-28 22:01:46 Connection to PAL: OK
To stop the whole stack, simply hit Ctrl-C
on pane 0 to close it. Note that all the other panes are simply showing logs. Those can be found in ./logs
#Live Exchange
Connecting to a real live exchange is possible with a setup like this. To do so, there is at least 2 things that need to be done.
First, specify what kind of exchange connector will be used to connect to the exchange. By default, the launch sequence starts the router_runner
with the configuration file located at examples/router-config.json
. Thus, either edit that configuration file or supply another. You'll notice that it currently uses the mock exchange.
So, set the name of the exchange connector based on the Exchange-Connectors page. Note that the parameters are specific for each type of exchange connector.
The second thing that needs to be done is setup win notifications. Just like the exchange connector, it needs to match the protocol used by your ad server. If this is not done, the stack monitor will detect that no wins are getting in and will simply raise a flag saying that this is an abnormal situation. The router will then enter what we call slow mode and will engage in an austerity strategy and only bid a few amount of money per second. This is a protection mechanism to avoid losing track of how much money was actually spent.
So, either supply your own ad server and add it to the launch sequence or use the one supplied with RTBkit documented here: Standard-Ad-Server-Protocol.
#Scaling
When done, jump to How to scale the demo stack for more information about increasing the capacity of the demo stack.
- Getting Started
- Pull Request Guidelines
- Coding Standards
- Demo Stack
- How to compile static filters test
- RTBkit Binary Package
- Architecture
- Bid Request Lifecycle
- ZooKeeper Nodes
- Load Shedding
- Banker
- Post Auction Loop State Machine
- Post-Auction Loop Sharding
- ZMQ Endpoints