こんにちは!Wantedly でプロジェクトマネージャ兼バックエンドエンジニアをしている鴛海です。
今回は、日本最大の Ruby に関するカンファレンスである RubyKaigi に Wantedly がスポンサードし、Wantedly のエンジニアも参加しています。また、Wantedly はスポンサーブースを設けていて、Twitterをフォローしてくださった方には技術書や開発に役立つ Engineering Handbook をプレゼントしているので参加されている方はぜひお立ち寄りください!
久しぶりのオフライン開催の RubyKaigi は他社の Rubyist と話せてとても充実した 1日目でした!
この記事では鴛海とバックエンドエンジニアの江草から 1日目の「Making *MaNy* threads on Ruby」について紹介させていただきます。
Making *MaNy* threads on Ruby
このセッションは Ruby で 100K 以上のスレッドを扱うことができるようにする MaNy Project の発表でした。
いままでの Ruby のスレッド実装
まずは Ruby のスレッド実装は現在までで1度大きな変更が加えられているようでした。
Ruby 1.8 以前は1つの Native thread (kernel thread) に対して複数の Ruby thread を立てることでスレッド処理を実現していました。これを 1:N モデルと言います。1:N は Ruby 上で完全に制御でき、軽量であるというメリットはありますが、並列処理ができなかったりブロッキング処理が難しいという問題がありました。
そこで Ruby 1.9 からは 1つの Native thread に対して 1つの Ruby thread に制限し、 Native thread を複数立てるようになりました。これを 1:1 モデルと言います。1:1 ではシステムがブロッキング処理を行ってくれるためシンプルで扱いやすくなりました。しかし、Native thread に頼ることで 1:N よりオーバーヘッドが多くなってしまったり、Ruby 上で完全に扱えていた 1:N と比べてコントロールしにくくなってしまいました。
これからの Ruby のスレッド処理 - M:N threads
そこで Go 言語や Erlang などのように M:N threads 、つまり複数の Native thread に対して複数の Ractor を実行する試みが MaNy Project です。M:N は 1:N と 1:1 を混ぜたような特徴を持っていて、コントロールしやすく軽量であり並行処理が可能であるが、ブロッキング処理が難しくなっています。また複雑性も増しています。
Fiber scheduler との違い
多数のネットワークコネクションを扱いたいというモチベーションは、 MaNy と同じです。Fiber scheduler では、ユーザーが自分で scheduler を実装することができるので、特定のアプリケーションに特化してチューニングすることができます。一方 MaNy では、ユーザーが scheduler のことを気にする必要がなく、より良いパフォーマンスを出すことができます。また、MaNy では Ractor を使って実装されているため並列して処理ができます。
Chat Server の例
最後に server と client との間で多数の connetion を貼る Chat server を使ってパフォーマンスを評価した例が紹介されていました。スレッドを使わずに IO.select を使った実装、MaNy、現在の 1:1 モデル(master の実装)を使った実装の順で、パフォーマンスが良いという結果でした。なお、IO.select を使った実装は「人間にはできないくらい難しい」らしいです。この Chat server の例では、アプリケーションの実装を変えずに MaNy によって2倍前後高速化できているので、良い結果なのではないかと思いました。
感想
Ruby のスレッドについてあまり詳しくなかったのですが、今回の発表で過去の仕様から未来の構想まで知ることができて理解を深めることができました。Chat Server の例であったように Web サーバも Ruby レイヤで並列して処理をすることで高速化する未来がくるのかもしれないなと思い、これからの Ruby への期待が高まりました。
明日以降も発表紹介レポートを上げていくのでよろしくお願いします!
#6 次のブログへ👇