pitchfork
当初はunicornのパッチとして始まったが、unicorn本体が古いRubyをサポートするのでメンテナンスが難しく、forkして実装されることになった ohbarye.icon pitchforkによって解決される問題はとても狭いのでよほどの理由がなければ移行は避けた方がよさそう
refork
pitchfork最大の特徴
しかしRuby プロセスでは一般に遅延初期化されるメモリ領域が大量にある
workerプロセスを起動直後にforkすると、これらのコードパスが実行される前なのでメモリ共有のメリットは時間経過で失われていく pitchforkはウォームアップされてキャッシュが十分に効いているプロセスを昇格させ、fork元として使う 新しいfork元 (mold) が昇格したら、moldから新しいプロセスをforkして古いworkerをロールアウトで置き換えていく
子プロセスがメモリに書き込むとき、カーネルはプロセスを停止してメモリページをコピーする必要があり、これは非常にコストのかかる操作 つまり、reforkの利用はメモリ使用量とレイテンシのトレードオフになる
用途
すべてのアプリケーションに適しているわけではない
CPU/メモリ/ディスクを大量に使用し、外部リソース (データベース サーバーや外部 API など) の待機時間がほとんどないアプリケーション向けに最適化されている First and foremost, if you don't have any specific problem with your current server, then don't.
Pitchfork isn't a silver bullet, it's a very opinionated software that focus on very specific tradeoffs, that are different from other servers.
unicornの持つデーモン化、pid ファイル管理、ホット リロードなどの多くの機能を削除している コンテナ化された世界で意味のある機能のみを残している
Shopifyでの効果
スタディサプリでの効果
reforkを無限に繰り返してもメモリ使用量の削減にはあまり意味がないことをメトリクスから理解し、4世代、計6000リクエストほど処理した段階でreforkを止めるように設定した
トレードオフの関係を理解し、メトリクスを見たうえで最適な設定ができていてすごい
pocke
:pocke: 1:05 PM
Puma の refork と近い発想かなと思ったので「非常にユニークな概念」というのに若干違和感があったのですが、pumaのそれとは結構違う発想なんですかね?
ざっと見た感じ大筋は同じことをやりたそうに見えるけど、違いがあるなら興味あります :eyes:
k0kubun
1:46 PM
同じだと思います。pumaにも既にあるという意味ではCRuby環境での唯一性はないけど、多くの処理系では普通はマルチスレッドで解決されるべき問題なので、アプリケーションサーバー全般の文脈で言うとreforkingという概念自体は比較的ユニークなものだと思います。僕はそれよりもpumaを各プロセス1スレッドで使うという発想に誰もならない(のでスレッドアンセーフなアプリにpumaを使わない)ことの方が引っかかる
k0kubun
1:52 PM
gRPCの例にもあるように、フォークアンセーフなライブラリというのはあって、それでクラッシュした時に直すパワーは必要なので、そういう (スレッドセーフティを保証するのとどっちが簡単かすらわからない) 難しさからあんまり流行らないと思うんですよね。うちが本番モノリスにいれたからにはそこで使ってるようなgemだけ使ってれば動くとは思いますが
k0kubun
2:00 PM
Railsアプリとかだとワーカー起動前にアプリのプリロードが走らせられる分、その後GC.compactやってからフォークすればreforkingとかしなくても比較的CoWフレンドリになるから、pumaに入った当時も (fork safetyを保証する苦労の割に) そんなにインパクトなくてあまり使われなかったのだと思うけど、YJITをいれるとJITで使うメモリがほとんどフォーク後に作られるので、reforkingした時のメモリ使用量のインパクトが大きくなり、pumaに入った時と違って重要性が高まっているのだと思われる