- 普段Elixir(GenServer) を使用している
- Go(goroutine+channel) で遊んだこともある
- Rubyの並行・並列はどうなっているか知りたかった
- 分離ヒープ+メッセージ送受信の仕組み
- 真の並列実行が可能(GVLの制約を超える)
- 多くは非共有。データはコピーまたはムーブで受け渡し
- スレッド: I/Oは強いが、Ruby計算はGVLで並列にならない
- ファイバ+スケジューラ: 大量I/Oに強い(軽量・低メモリ)
- プロセス: 強い隔離と確実な並列
- Ractor: プロセスより軽く、言語内で並列(ただし制約多め)
- シンプルな並列デモを参考に開始(Zenn: jnchito)
- 結果: Ractorのほうが遅いケースが目立つ
GVL(グローバルVMロック)を完全に廃止せず、Ractor単位でロック・メッセージ送受信を使うことで、インプロセス並列を実現しようとしている。
単純なCPU計算(例:Fib計算など)では並列効果が見えるが、実アプリケーション規模では事情が異なり、期待通りのスケールアップは難しい。
現時点で「Ractorは実験的」警告が出る。セグフォやデッドロック等の未解決バグも多く、本番運用の基盤にはリスクが高い。
Ractor間でも依然として全体を止めるロック(例:interned stringテーブルなど)が残っており、例えば JSON.parse をRactorで並列実行しても逆に遅くなるケースが再現されている。
多くのC拡張オブジェクトはmove不可(例:Time オブジェクトすら移動不可)。DBクライアント等は専用Ractorに隔離してカプセル化する必要があり、実装コストや設計が煩雑になりがち。
Ractor::Queue や Ractor::ConcurrentMap のような共有可能な標準データ構造や、C拡張のmove対応といったエコシステム強化が求められている。
現状Ractorは本番システムのメイン並列プリミティブとしては推奨できない。使う場合はライブラリ内部の限定的な並列処理や、検証用途に留めるのが現実的。
まずはファイバ(またはスレッド)を選択。I/O待ちを効率よく捌きたい場合に最適。
原則としてプロセスによる並列化が安全かつ確実。Ractorは「十分に重いタスク」を限定して使い、必ず実際に効果を計測・検証してから採用を検討。
現時点ではRactor前提の設計は避けるのが無難。ライブラリやバッチ処理など、限定的な用途で検証的に使うにとどめる。
- Ruby公式: Ractor ドキュメント
- 解説記事(Zenn / jnchito)
- 2025年の動向まとめ(TechRacho: byroot記事の翻訳)
Uh oh!
There was an error while loading. Please reload this page.