RustConfからTwitterがキャッシュサーバーをRustで書き直したセッションを紹介
高速でセキュアなプログラミング言語であるRustのオンラインカンファレンスRustConf 2021が、2021年9月に開催された。今回は、TwitterのエンジニアがMemcachedをRustで書き換えた事例を紹介するセッションの解説を行いたい。
RustConf公式サイト:https://rustconf.com/
Rustは言語の仕様としてメモリーセーフで、C言語などで可能な制約のないポインターの利用などとは正反対に言語の仕様としてメモリーアクセス関連のバグが起こらないようになっている。またCargoという公式のビルドツールによって、エコシステムが整理されているのが特徴だ。
なお2020年には、RustConfはオンラインカンファレンスとして開催されている。レポートについては以下の記事を参考にして欲しい。
RustConf 2020:RustConfで見えてきたRustプロジェクトが最も大事にする価値とは?
今回のトピックの中心であるキャッシュサーバーについて、Martin氏は「非常に高い性能(スループット、低レイテンシー)」そして「高速なキーバリューストア」を要求されるソフトウェアであることを紹介し、その実装例としてRedisとMemcachedがあることを紹介した。
動画へのリンク:RustConf 2021 - Whoops! I Rewrote It in Rust by Brian Martin
そしてTwitterの中で利用されているキャッシュサーバーのためのフレームワークであるPelikanを紹介。ここからMemcachedをRustで書き換える道のりを解説する流れとなった。
PelikanはTwitterが開発したキャッシュサーバーのためのフレームワークであると説明されているが、Memcachedとコンパチブルなプロトコルをサポートしており、シングルコードベースであるというところから、C言語で書かれたMemcachedを含んだ内容になっているようだ。
GitHubのリポジトリーに書かれている記述を参考にすると、Twemcacheがmemcachedと同等、SlimcacheはMemcachedと同じ機能ながらメモリーに関するオーバーヘッドをRedis/Memcachedに比べて90%程度まで削減した高速のキャッシュサーバーということになる。
2018年にRustで書かれたストレージのためのライブラリーを開発し、この時にTwitterとして初めてPelikanの中でRustによるコミットが行われたということである。
サーバーのコードにRustを使うというのは、C言語で書かれた機能を再度、実装するということになるため、いわゆる「車輪の再発明」になってしまうのではないかという危惧もあったという。TwemcacheをCからRustに書き直す際にポイントとなるのは、膨大なリクエストを捌くスループットとレイテンシーであるということで、キャッシュサーバーと同じような動作をするPingserverを実験台としてコードの開発と測定を行ったというのが2019年辺りの経緯であるようだ。
ここではMemcachedとコンパチブルであること、Rustの非同期通信のライブラリーTokioを使ったこと、キャッシュデータには従来のC言語のストレージライブラリーを使ったことが説明されている。
このベンチマークでは、Rustで書かれたTwemcacheはC言語版に比べて明らかに遅く、特に高スループット時においてはその違いが明確である。そのため、どの部分が遅いのか? を明らかにするために、Pingserverを使ってC版とRust版の性能テストを行っている。その際には、ビジネスサイドからの要望であったTLSのサポートも含まれているという。ちなみにこのPingserverは、今もPelikanのGitHubリポジトリーに存在しており、単なるテストのためのアプリという扱いではないことがわかる。
Pingserverのv2では、TLSの部分にGoogleがOpenSSLからフォークしたBoringsslを使って実装している。
そして行われた性能テストでは、Rustで書かれたPingserverがCで書かれたものと遜色ない性能を出していることを確認できたという。
この結果を受けて、本来の目的であるキャッシュサーバーをRustで書き直すというプロジェクトのプロトタイピングが開始された。
しかしストレージについてはC言語のライブラリーを使っていたということだが、Cのソ-スコードをmakeしたくない、メトリクスがその部分だけ違ってしまうなどのマイナスポイントを解消するために、ストレージについてもRustで書き直すことを決めた。
その背景にはSegcacheという新しいキャッシュデータに関するTwitterとカーネギーメロン大学による共同研究の成果があるようだ。これは非常に小さなキャッシュデータの消去に関する効果的な方法と、メタデータを極限まで小さくするための新しい方法が組み込まれている。詳細は以下のTwitterのブログを参照されたい。この新しいテクノロジーでは、期限切れとなったキャッシュデータを効率的に消去する方法を提供し、キャッシュデータのメタデータが肥大化している問題を解決するものであることが解説されている。
Segcache:Segcache: a memory-efficient, scalable cache for small objects with TTL
この新しいキャッシュデータの保存方法を実装することで、TwitterのキャッシュサーバーはRustを使って実装されることになったという。これがタイトルにある「Whoops! I rewrote it in Rust」の意味に繋がる。
今のところシングルスレッドでのみ動作しているということで、ある意味、イージーモードを選択したと説明されている。
そしてこの書き直しに費やした期間2か月かかったと語った。また現状では、機能面ですべて同等とは言えないことも解説した。
最終的なMemcachedとRustで書かれたSegcache RSの比較を表したのがこのグラフである。
このグラフでは途中までほぼ同等という性能だが、スループットが12万/秒を超えた辺りで、Memcachedの性能が急激に悪化していることが見てとれる。
この新しいキャッシュサーバーを本番運用するためには、機能面でMemcachedと同じレベルにすること、より厳しいテストなどが必要であるという。そして今後の開発計画については、マルチスレッドでのパフォーマンス検証、最適化、Redisのリプレースなどを挙げた。
これを受けて書き直しの利点と欠点をまとめている。
予定日程をオーバーしたり書き直すための工数がかかったりすることもあったが、すべてがRustによるコードベースになったことで開発が簡単になったこと、C言語をmakeしなくても良くなったことなどを挙げた。
またRustのエコシステムには良質なツールが存在していることを紹介して、セッションを終えた。
この書き直しのプロジェクトから学べることは、すべてを書き直すために、デザインがよく似たシステムを最初に作って目的を達成できるかどうかを検証するという姿勢だろう。Pingserverを使って新たにTLSを実装した上で性能がC言語と同じかどうかを検証し、同時にメトリクスについても必要なデータが取得できるかどうかを確かめるやり方は参考になるだろう。
参考:Pelikanの公式サイト:https://github.com/twitter/pelikan
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Rustと非同期ライブラリーTokioで作成した簡易版Redisを紹介
- RustConfで見えてきたRustプロジェクトが最も大事にする価値とは?
- MySQL5.6- さらなる機能追加とNoSQL
- 分散KVS「okuyama」の活用ノウハウ
- ownCloudのパフォーマンスチューニング
- DB、クラウド-実例から学ぶmixiアプリ運用ノウハウ
- MySQL 5.6での機能強化点(その2)- NoSQL APIとパフォーマンス・スキーマ
- IoTに適したNoSQL・分散Key-Valueストア
- キーバリュー型データベースの概要とその例
- IBMがRustを使ってNode.jsのプロジェクトを書き換え。その背景とは?