Erlang: WhatsAppを支える技術 (その1)

http://vimeo.com/44312354#at=0

2 comments | 3 points | by Jshiike 約4年前


Jshiike 約4年前 | ▲upvoteする | link

[Slide] http://www.erlang-factory.com/upload/presentations/558/efsf2012-whatsapp-scaling.pdf


WhatsAppは日本でいうところのLineにあたるサービスでしょうか。このニュースによると、WhatsApp: 月間UU3億、WeChat: 月間UU2.3億、Skype: 月間UU2.8億、Line: 登録2億 (UUは発表しないんですね。。) ということですから、相当でかいですね。


昨年になりますが、Rick Reed (WhatsApp <- Yahoo! <- SGI)が、同サービスを支える、数百万ユーザの同時接続システムについて、SanFranciscoのErlangのカンファレンスで語ってます。



メッセージのトラフィックは、メキシコの地震、スペインのサッカーなどの事象で大きくはねる。当初のコネクション想定は、20万。どこまでトラフィックが伸びるか予想が難しく、障害/過負荷に対してクラスタは脆弱。


Yahoo!のトラフィックは世界Top10の巨大さで、そのスケールアップを担当した経験はあったが、均質なアクセスを大量のサーバでさばくかたちだったので、WatsAppのようなサーバあたり百万コネクションを実現するというのはまったく別次元だった。しかも、ソフトウェア障害、ハードウェア障害(サーバ、ネットワーク機器)、世界で突発的におきる大きなニュースなどに対応できる仕組みにする必要があった。


標準サーバ設定: Dual Westmere Hex-core (24個のロジカルCPU)、100GB RAM / SSD、Dual NIC (対ユーザ側、バックエンドとディストリビューションはプライベートネットワーク)、FreeBSD 8.3、OTP R14B03


モニタリングツールを導入。(詳細スライド8-10を参照)最初は1分単位のスナップショットだったが、現在は1秒単位でとっている。


最初は人工的に負荷をつくろうとしたが、本番環境のトラフィックは、クライアント端末 / 国ごとの違いなどを考慮して再現はできないので、チューニングには役立たない。


次に本番トラフィックの一部をパイプして別システムに出力してシミュレーションした。これだと、teeでinputするだけで、outputには対応できないが、チューニングには多いに役立った。


最終的には、IPFWで本番トラフィックの一部をサーバからサーバへフォワードして、正確にほしいコネクションをシミュレーションできたが、カーネルパニックは多少起きた。


最初のボトルネックは、42.5万コネクション辺り。CPU使用率35%-40%でもスケジューラ95%で競合が発生していた。これを対応(詳細は後半)することで、100万コネクション達成。翌月には200万コネクション。


次に、アプリのコードの最適化に着手。コネクション当たり2プロセスだったのをシングルプロセスにしたのが効いた。ピークは、280万コネクション。その時点で、57.1万パケット(in & out)/ 秒、20万+ メッセージ / 秒。次は300万コネクションに挑戦したい。


ErlangはSMPのスケーラビリティがすごい。24個のロジカルCPUで使用率85%超。FreeBSDとの相性もいい。CPU使用率とコネクション数の増加がリニアにあがっていく。


200万コネクションまでは競合が問題。BEAMについては、Erlangのコード修正が必要なもの、BEAMのパッチが必要なもの両方あった。アプリ側で、トラフィックがプロセスをまたがないようにパーティションをしっかりやる。


FreeBSDについては、TSCベースのカーネルタイムカウンターを戻した。gettimeofday (2)コールのほうが手軽で、早い。igbネットワークドライバも戻した。複数のインタラクティブなキューでカードをロックして問題があった。当たり前のsysctlのチューニング。ファイル、ソケットの数増やすとか。tcpハッシュサイズ広げる。


BEAMの統計については、プロセス実行時間 / システム実行時間に対する使用率、wait/sleepの回数を測るためにスケジューラを導入。message_queues統計はErlangでやるより早く測れる。enq/deq/sendの回数と率を1秒/10秒/100秒で計測するprocess_info。message_que_statsをまとめた統計。fprof cpuタイムスタンプがなかったのを直した。大きな非同期スレッドを数えるためにlock-countingがワークするようにした。erts_debug:lock_counterにいくつかオプションを設定。アウトバウンド distバイトの計測を直した。


BEAMのチューニングは、スケジューラ waikupスレッドを低くした。msegをマックスにしてmallocでなくmsegが選ばれるように。スケジューラごとのallocator instance。2M mallocを自動的に最大superpageに。リアルタイムスケジューラ優先で実行。スケジューラが無駄にスピンするのを修正。


BEAMの競合については、timeofday deliveryのロックが全体のスケジューラを止めるので最適化。timer wheelも最適化。check_ioテーブルのアロケーションを調整。prim_file:write_fileはポート再利用。


OTPスループットについては、messageキューが長くかかるときにgcスロット追加調整。デフォルトでdistが受けられるバッファーを増やして、設定可能とした。mnesia_tmを修正し、テーブルごとに並列処理できるようにした。


Slide 29 & 30のErlang usageのところは、時間がなったようで、Videoでは、ほぼ説明省略。)



その2はこちら



ワザノバ TOP100 アクセスランキング [8/25-10/12]



#erlang #whatsapp

WazanovaNews 3年以上前 edited | ▲upvoteする | link

WhatsAppのMUUはこの半年で2.3億から4.5億にほぼ倍増したということですね。

Back