pitchforkのメモリ使用量が多すぎませんか?

他の人もこれを見ている人はいますか? サイズやトラフィックの規模としては、かなり控えめなフォーラムです。pitchforkのワーカープロセスが4つあり、そのうち1つが受信リクエストの大部分を処理しており、他のプロセスよりも多くのメモリを使用しているように見えます。スワップが大量に使用されており、pitchforkを意図的に再起動すると、これがかなり減少します。したがって、pitchforkのプロセスには現在スワップアウトされているコールドページがたくさんあると結論づけています。

これは稼働20日目、RAM 4GB、スワップ4GBのマシンでのことです。

スワップを使い果たすのは良くありません。pitchforkが最終的にガベージコレクションを実行した際に、スワップに退避されたデータがすべてページインされる可能性があるため、それを見せられるのも良くありません。

他の人も同様の現象を見ている人はいますか? マシンの構成を共有してください。

# ps aux | sort -n -k 4 | egrep pitchf\|MEM |tail
root     2167652  0.0  0.0   5912  1792 pts/0    S+   20:07   0:00 grep -E --color=auto pitchf|MEM
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
1000       15094  0.0  0.2 497544 10988 ?        Sl   Jul28   0:17 pitchfork monitor - 
1000       15704  0.0  2.5 6799124 97836 ?       Sl   Jul28   1:00 pitchfork (gen:0) service - ready
1000       15097  0.0  4.8 6791252 189724 ?      Sl   Jul28   5:26 pitchfork (gen:0) mold - ready
1000       15959  0.0  8.1 6815508 319708 ?      Sl   Jul28  12:05 pitchfork (gen:0) worker[3] - requests: 6684, waiting
1000       15900  0.0  9.2 6864596 360696 ?      Sl   Jul28  17:43 pitchfork (gen:0) worker[2] - requests: 14756, waiting
1000       15795  0.1 10.3 6884756 405420 ?      Sl   Jul28  48:36 pitchfork (gen:0) worker[1] - requests: 97007, waiting
1000       15734  2.1 12.8 11299708 500120 ?     Sl   Jul28 637:50 pitchfork (gen:0) worker[0] - requests: 2229848, waiting

# free
               total        used        free      shared  buff/cache   available
Mem:         3904968     1874636       98840      678812     1931492     1160916
Swap:        4194288     1226600     2967688


# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0 1226600 115820  65288 1866284    1    1    20    38    0    3  3  1 97  0  0
 0  0 1226600 113208  65296 1866296    0    0     0    14  411  478  1  1 98  0  0
 0  0 1226600 112956  65304 1866336    0    0     1    23  438  528  2  1 97  0  0
 0  0 1226600 112704  65308 1866360    0    0     1    31  518  603  5  1 94  0  0
 0  0 1226600 112704  65308 1866364    0    0     0    11  347  387  1  1 98  0  0

vmstatの出力には、現在メモリ圧力がないことが示されています - ページングアクティビティはありません。私の懸念は、現在のインストールがうまく機能していないことではなく、危険が潜んでいる可能性があるということです。

cpu0

もう少し真面目な話ですが、ほとんどの作業をしているワーカーのRSSは平均値より100MBしか上回っていませんね?私には正常に見えますが、何か見落としはありますか?

より活発なフォーラムの統計データが見てみたいと思います。累積リクエスト数が重要であるように見えますが、私の環境は決して活発とは言えません。

はい、RSSの差は比較的 modest ですが、300Mから500Mの範囲内でも、割合としてはかなり大きな差があります。

より顕著なのはスワップ使用量です。回収(リサイクル)を始める前に、

# free
               total        used        free      shared  buff/cache   available
Mem:         3904968     1888140       77308      679004     1939520     1147220
Swap:        4194288     1226344     2967944

回収後には、

# free
               total        used        free      shared  buff/cache   available
Mem:         3904968     1486412     1422380      640744      996176     1587908
Swap:        4194288      309892     3884396

私には、回収によって約1300M解放されたように見えます(usedとswapの差)。

unicornを使用していた時には、これほど多くのスワップが必要だったとは記憶していません。それがタイトルの由来です。

繰り返しますが、他のインスタンスの数値を見てみたいと思います。

1つのpitchforkプロセスが負荷の大部分を担うのは正常なことです。他のプロセスは、最初のプロセスがビジー状態の場合にのみ選択されます。メモリが時間の経過とともに増加することもあります。キャッシュやruby-JITなどがウォームアップされると、最終的には安定した状態に達するはずです。

これは、1つの本番クラスタの7日間にわたるグラフです。ここでは、メモリ使用量が最も多い単一のプロセスを追跡しています。緑色の点線はデプロイ(つまりpitchforkの新しい起動)を示しています:

ご覧のとおり、初期起動後に増加しますが、その後約1.4GBで落ち着いています。このクラスタは数百のサイトを処理しているため、数値の比較としては最適ではないかもしれませんが、成長の可視化は役立つと思います。

プロセスごとのRSSの数値だけでは、全容がわかりません。Pitchforkは「フォーク型Webサーバー」です。つまり、まず「モールド」プロセスを起動し、その後、すべてのワーカーがコピーオンライトメモリパターンでそこからフォークされます。したがって、worker[0]のRSSが500MBを示していても、そのうち約200MBはモールドおよび他のすべてのワーカーと共有されています。

近いうちに、Pitchforkの"reforking"機能を有効にできるようにしたいと考えています。これは定期的にワーカーを殺し、すでにウォームアップされたワーカーから再フォークすることで、時間の経過とともに可能な限り多くのメモリを共有できるようにするものです。ただし、すべてのコードがこの種のパターンと互換性があることを確認するためには、いくつかの作業が必要です :crossed_fingers:

有用な可視化、ありがとう。それが完全に落ち着いたとは言えないが、成長率は以前ほど高くない。

周期的なリフォークは、それを導入する価値がある素晴らしい機能に思える。もし可能であれば、実装された際にここにメモを残してもらえると助かる。

緑のラインについて何か言えることはあるか? ピッチフォークがゴミ回収(garbage collect)を行うタイミング(それがもしあるなら)、その原因、そして実行中の影響について知りたい。

緑の線はアップデートをデプロイしたタイミングを示しています。つまり、./launcher rebuild app を実行しているということです。

Ruby(およびRubyプロセス内でMiniRacer/v8を通じて実行しているJS)は、実行中に常にガベージコレクションを行い、オペレーティングシステムからのシグナルにも反応します。そのため、手動で何かを行うことで大きな利得が得られるとは思いません。

ありがとうございます。長期的にどうなるのか見てみたいのですが、比較的多く更新されるサーバーでは、それは分かりにくいでしょう。私の場合は、20日経ったところで、pitchforkを使って再起動する選択をしました。それは何かを教えてくれましたが、同時に時計もリセットされました。