2025/06/19 09:58 Rewriting Kafka in Rust

やっほー、ロボ子!StoneMQっていう面白いプロジェクトがあるのじゃ。

StoneMQですか?初めて聞きました。どんなものなんですか?

KafkaとかPulsarみたいなメッセージングキューを、もっと低いレベルの言語で作り直して、性能と安定性を上げようっていう試みらしいぞ。

なるほど。それで、どんな言語を使っているんですか?

Rustを使ってるんだって!C/C++じゃなくてRustを選んだのは、メモリ安全とかパフォーマンスでRustが有利だかららしいぞ。賢明な判断じゃな。

確かに、Rustは最近注目されていますよね。StoneMQの開発で得られた教訓が7つあるみたいですが、どんな内容なんでしょう?

まず「非同期関数(async fn)の過剰な使用を避ける」ことじゃな。同期的にできることは同期関数でやるべき、と。

非同期処理は必要な箇所に限定する、ということですね。たしかに、闇雲にasyncを使うとパフォーマンスが悪化することがありますからね。

それから、「Tokioタスクの数を最小限に抑える」のも大事らしいぞ。タスクが増えすぎると、CPUキャッシュの効率が落ちたり、スケジューラに負荷がかかったりするからの。

タスクの統合ですか。StoneMQでは、コネクションごとにタスクを割り当てつつ、リクエストは中央のチャネルに集約して、固定サイズのワーカープールで処理する方式を採用しているんですね。

そうそう。あと「ロックフリーなアーキテクチャを優先」して、「Tokioの非同期ロックの使用を最小限に抑える」のも重要みたいじゃ。ロックはできるだけ避けて、メッセージパッシングとかタスクの所有権を活用するんじゃ。

ロックを使う場合は、短い時間だけ同期ロックを使用し、async/.awaitを跨がないようにするんですね。ロック競合を避けるための工夫ですね。

「パフォーマンスが重要な箇所でのみunsafeコードを慎重に使用する」のもポイントじゃな。unsafeコードは、メモリマップドファイルへのアクセスとか、どうしても性能を上げたい場合に限定的に使うんじゃ。

unsafeは最終手段、という感じですね。使う場合は、厳格なテストとコードレビューが必須ですね。

「可変データと不変データを分離し、ロックの粒度を最適化する」のも大事じゃ。ロックするのは可変データだけにすれば、ロックの範囲を狭められるからの。

なるほど。不変データはロックなしで共有できるんですね。効率的な設計ですね。

さらに、「非同期データ操作と同期データ操作を分離し、ロックの使用を最適化する」のも重要じゃ。非同期コードの中で同期ロックを使うとブロッキングが発生するから、データを分けるんじゃ。

非同期と同期でデータを分離することで、ロックによるブロッキングを防ぐんですね。理にかなっていますね。

最後に、「パフォーマンスが重要な箇所では、可能な限り静的ディスパッチを使用する」んじゃ。プロトコル層の実装で、動的ポリモーフィズムじゃなくてenumを使うことで、実行時のオーバーヘッドを減らすんじゃ。

静的ディスパッチはコンパイル時に型が解決されるから、実行時のパフォーマンスが良いんですよね。enumを使うのは良いアイデアですね。

これらの設計原則のおかげで、StoneMQは高性能で安全で、しかも保守しやすいシステムになったらしいぞ。素晴らしいのじゃ!

確かに、これらの原則はRustに限らず、他の言語でも応用できそうですね。勉強になりました!

そうじゃろ、そうじゃろ。しかし、ロボ子よ、これだけ高性能だと、石でできたメッセージキューでも爆速になるかの?

博士、石でメッセージキューを作ったら、遅延が大きすぎて誰も使わないと思いますよ…
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。