SPDYをRTBに応用してみた

かなり冷え込んできましたね。

先週末に長野戦のラリーにコ・ドライバーで出場するために木曽まで行ってきました。
日中は暖かく絶好のラリー日よりで快適でしたが、朝夜は氷点下で日陰では前日に降った雪が薄っすら残っていました。

現地でいろいろな方に話を伺いましたが、御岳の報道をマスコミがこぞって木曽で行った結果、風評被害により木曽温泉をはじめとした観光産業が壊滅寸前とのことです。
ウィンタースポーツを楽しむ人には雪質もよくて人も少なくてお勧めかも?
微力ながら今後も継続して応援したいと思います。

さて、今回はあまり手の込んでないWAN高速化の話です。
自社のSSPは特徴であるところの複数のDSPと接続してRTBを行っています。

DSPからのレスポンスのタイムアウトは150msに設定してあります。

すべてのDSPからのレスポンスを待ってからピカチュウ、君に決めたも当然ありですが、利益機会を追求しすぎてRTBのタイムアウトを長くした結果、広告表示の遅延に繋がりメディア運営者や閲覧者からクレームが来ることは避けなければいけません。
自社ではぎりぎりの足きりが150msという数値の設定です。

また、唯一絶対神株主様の意向で限られたインフラリソースでやり取りしているため、タイムアウトを長くすることにより、口をあけて待っている開きっぱなしのソケットが増えることはリソースの浪費になるため好ましくありません。

このような背景がある中で、今までは国内に拠点を持ったDSP事業者との接続がメインでしたが、海外に拠点をもったDSPとRTB接続をする要件があがりました。

海外とのRTBで一番の問題になるのはレイテンシーです。

今回の相手側のロケーションは香港ですが、IIJの良質のバックボーンを使ってもpingで50msちょっとかかります。
一般ユーザが意識せずに使うには十分なパフォーマンスですが、TCPの3ウェイハンドシェイクを考慮すると最低でも通信に要する時間が100msとなり、DSP側は50ms以内にレスポンスを返さないとRTBでの取引が成立しないことになります。

3way hand shakeチャキチャキなDSPは”50ms or die”とおっしゃってくださっているのですが、、、残念ながら実際はでかく見せておいてあまりがんばってなさそうな方々が大多数です。
これではレスポンスを送る側も受ける側もタイムアウトの足きりによって、お互いに機会損失とリソースの無駄があるという社内での議論や、そもそもWANの高速化なんて誰でもやってんだからその気になればやりゃできるだろ、という単純な自分の思考から改善に取り組み始めました。

単純な答えはTCPの3ウェイハンドシェイクを省略すれば2倍の速度で通信することができます。
問題は実装です。

いくつか方法を考えましたが、開発コストや現実不可能なためすべて却下しました。

・独自プロトコルを実装する
・UDPを使う
・SIPのヘッダとかに無理やりのせる
・DSPと調整してHTTP Keepaliveを有効にできる環境を作る
・TCP Fast Openでなんとかする
・低軌道衛星使いたい
・採算度外視で香港に東京とほぼリアルタイムで同期しながら動く拠点を作る
・VPNでごにょごにょ

etc・・・

開発コストをかけないためにできるだけインフラ側で吸収するために現行の枠のまま通信速度を2倍にするという無理難題に対して、数々のアイデアを出してはボツにしました。
そんな中でフワっと注目したのが、SPDYでした。
SPDYをProxyとして利用して、東京と香港にSPDY Proxyサーバを用意すれば一番時間のかかる海を渡る拠点間の通信が無理やりKeepaliveできるのではなかろうかと思いました。

そこからはあっという間で一週間くらいですべて検証できました。

同じこと考える人間が絶対いるはずだからSPDY Proxyとか普通にあるだろーとか調べていたらspdylayというライブラリにshrpxというSPDY Reverse Forward Proxy デーモンが含まれており、まずこれを利用してSPDYでHTTP通信が海外拠点と高速化できることを実証しました。

しかしshrpxはバックエンドのサーバをIPで直接指定する機能しかないため、実運用上のハードルはかなり高いと思いました。

そこで、shrpx のバックエンドにローカルホストでsquidを立てて、そこを参照するようにしました。

rtb2これにより、アプリケーション側は特にSPDY環境を意識することなく、香港宛の通信を高速化したいときはPOSTしているcurlのオプションにproxyサーバのオプションを一個追加するだけで利用することができます。

SPDY Proxyありとなしの差の結果は以下の通りです。

$ time curl --proxy [LVS-VIP]:3000 http://[香港ホストのURL]
{"result":"0"}
real 0m0.070s
user 0m0.008s
sys 0m0.000s

$ time curl http://[香港ホストのURL]
{"result":"0"}
real 0m0.158s
user 0m0.004s
sys 0m0.004s

香港側はVPSを利用しましたが、AWSなどメジャーどころがなく怪しいところばかりでいろいろ探した結果、Rackspaceを利用しました。
アクティベーションがちょっと面倒だったものの、幸いにも今回の香港接続先ととても近く2~3msで通信できました。

この話をN社の方にしたら普通はTCPでそこまでしないとありがたい言葉をいただきましたが、WANのアクセラレーションは身近な技術で安価に実施できますので、ぜひ機会があれば試してみてください。