http://company.myshopify.com/blogs/technology/14909841-kafka-producer-pipeline-for-ruby-on-rails
1 comment | 0 points | by WazanovaNews 約5時間前 edited
オンラインストア & リアルショップ向けのアプリを提供しているShopifyがブログでKafkaの導入について紹介しています。
Kafkaに限らず、Google / Facebook / Twitter / LinkedInなど大手がオープンソースで取組んできたApache系の大規模分散システム向けのソリューションを、他のネット企業もサービスが成長してきたら導入するという話しが続いていますが、このShopifyのように、「魅力的なソリューションに見えるけど、LinkedInみたいに社員をフルタイムでこのオープンソースの開発にあてて、十分な運営経験を積んでいるわけではないので、うまくつかいこなせるのかな?」という不安はあるんでしょうね。
導入に至る前のShopify側の課題としては、
- イベントデータを収集してデータウェアハウスに送信する信頼度の高いソリューションが欲しかった。
- SOA(Service-oriented architecture)化を検討していたので、コンポーネント間のメーッセージ受渡しの標準化が必要であった。
- Dockerの導入を考えていたので、コンテナからログを収集できる方法が必要であった。
そこで、Kafkaの採用を考えたが、JVM前提(Kafkaのメイン開発をしているLinkedInがJVMベース)であったため、Ruby + GoのShopifyにおいては導入に工夫が必要であった。
RubyとKafkaをダイレクトにつなぐことは避けた
Shopifyのサービスからダイレクトにイベントを送り、キューにバッファーして、スレッドで処理をするというストレートな方法をLinkedInはとっているが、ShopifyはKafkaの運用経験がまったくなかったし、プロセスメモリにキューが溜まっている状態でKafkaを落として、データを消失させずにデプロイするようなチャレンジをしたくなかった。このあたりをうまくやってくれるRubyのライブラリは見当たらず、既にGoでKafka用のSaramaライブラリを書いていたので、それを利用することにした。
ShopifyのRailsアプリからGoのproducerにイベントを確実に送る仕組みが課題。データを消失せずに、システムを落とすことができる仕組みが必要。最終的には、懐かしのSysV メッセージキューを採用することにした。(システム構成図)
SysVメッセージキューによって、Kernelがコントロールするシステムレベルでのバッファーが使えるようになった。キューをいつでも再起動できるので、デプロイのロジックがかなりシンプルにできる。GoとRuby向けのラッパーを用意することで、Kafkaがダウンすることがあっても最大2時間分のキューを溜めておくことができる。
Docker導入への対応
数ヶ月後にDockerを導入。コンテナはIPCにおいてネームスペースをデフォルトで隔離する。つまり、コンテナとホストはSysVキューを共有できないので、全てのコンテナでproducerが実行されることになる。
コンテナをできるだけコンパクトに、つまり、完全なバーチャルマシンではなく、ひとつのプロセスのための強力な隔離レイヤとしたかったので、起動と停止を繰返す数千のコンテナの中でKafkaを動かすようなオペレーションの負荷は避けたかった。コンテナをシャットダウンするときは常にキューを空にしたいが、Kafkaがダウンしたり、プレッシャーの中デプロイするには無理。また数千のコネクションをKafkaと接続しなくてはならず、それはもしかしたら大丈夫なのかもしれないが、とにかくKafkaの運用経験がなかったので避けたかった。
既に利用しているStatsDの方式に倣い、サービスをホストで実行し、TCPでやりとりをした。SysVメッセージキュープロキシへの簡単なTCPを用意し、Kafka producerとあわせて実行し、同程度の信頼度を確保しつつ、コンテナからネットワークにメッセージを送れるようになった。もし今同じことが必要であれば、イベントシャトルのようなものを使うのがよいかとも思う。
次のステップ
毎秒数千のイベントが処理ができるようになった。このプロジェクトを開始した時点では、Rubyのlibrdkafkaが自分たちが必要なKafkaのバージョンをサポートしてなかったが、本番でKafkaを運用した経験もできたので、キューとワーカースレッドでlibrdkafkaをラップしたバージョンに挑戦してみたい。
#shopify #kafka #rails #ruby #go #docker