Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Sidekiqクラスタースクリプトの紹介

Honeybadgerでは、処理パイプラインをSidekiqに大きく依存しています。私たちが行うほとんどすべては、ある時点でキューを通過します。結果として、Sidekiqが正常に実行されていることを確認したいと思います。最近のEC2への移行により、長寿命のサーバーの安定したセットから、ジョブを実行するインスタンスの絶え間なく変化するセットに変更されました。これにより、起動時にSidekiqを起動する方法を再検討するようになりました。これは、以前よりもはるかに重要になっているためです。

以前は、すべてのワーカープロセスをスピンアップすることを神に依存していました。これは、ワーカープロセスを監視し、メモリを使いすぎたプロセスを終了するためです。私たちの神の構成は、それらのワーカーを実行するためにデプロイしたサーバー用に手動で調整されました。残念ながら、systemdを使用して新しいインスタンスで古い神の構成を起動すると、指定した構成よりも多くのワーカーが実行されることがありました。これはインスタンスのメモリプレッシャーにつながりますが、これは悪いニュースでした。しばらくそれをいじって、その機能の多くを使用していないことに気付いた後、私はプロセスを管理するために神を使用するのをやめる時が来たと判断しました。

複数のSidekiqプロセスを実行するための1つの簡単なコマンド

私が本当に欲しかったのは、コアごとに1つのSidekiqプロセスを生成し、メモリを大量に消費したプロセスを再起動するsystemdサービスとして実行できるスクリプトでした。さまざまなインスタンスサイズを試してワークロードに最適なものを確認したため、コアの数とRAMの量が異なる可能性があるため、スクリプトはさまざまなサイズのEC2インスタンスで動作できる必要がありました。それを正確に実行するスクリプトが見つからなかったので、次のように記述しました。

もちろん、そのスクリプトには少し借用したコードがあります。 :) process_countのコード メソッドはおそらくStackOverflow(ユニコーン構成で何年も使用しています)とfork_childから来ています メソッドは基本的にsidekiq sidekiq宝石からのビン。

このスクリプトは、存在するCPUコアの数に基づいて多数の子プロセスを生成します。各子プロセスは、sidekiqを実行した場合と同じです。 直接コマンド。その結果、このスクリプトに渡すコマンドラインオプションはすべて、Sidekiq CLIコードに渡されます(そして解析されます)。つまり、sidekiqに渡すことができる任意のオプションをこのスクリプトに渡すことができます。 直接実行する場合、一部のオプション(pidファイルオプションなど)は使用しても意味がありません。各子プロセスのメモリ使用量を定期的にチェックするためのスレッドも生成されます。子プロセスが使用量のしきい値を超えると、そのプロセスは強制終了され、新しいプロセスが生成されて置き換えられます。

クラスターの操作

プロセスの数はデフォルトでコアの数になりますが(インスタンスをSidekiqプロセスの実行専用にする場合)、スクリプトを実行する前にSK_PROCESS_COUNT環境変数を設定することでこれをオーバーライドできます。同様に、メモリしきい値はインスタンスの合計RAMのパーセンテージとして設定されます(58行目のprocess_count値に1を追加することでRAMをいくらか残します)が、SK_MEMORY_PCT_LIMIT環境変数を使用して任意のパーセンテージを設定できます。これらの2つの変数を使用して、UIを強化するRailsアプリを実行しているインスタンスのSidekiqプロセスの数とメモリ使用量を制限します。

追加のボーナスとして、このスクリプトはSidekiqプロセスを管理するために通常使用されるシグナルをキャッチし、それらのシグナルを子プロセスに渡します。これにより、pkill -f -USR1 skclusterを使用できるようになります 子プロセスが新しい作業の受け入れを停止するようにし(これはデプロイメントスクリプトの初期のタスクです)、pkill -f skclusterを使用できます。 すべてを終了します。

systemdの構成

systemdサービスの定義は簡単です:

すべてのインスタンスでpgbouncerを使用して、postgresへの接続をプロキシするため、sidekiqプロセスが起動する前にpgbouncerサービスが実行されていることを確認します。同じインスタンスでredisを実行している場合は、requires行とAfter行にredis-server.serviceも追加します。 EnvironmentFileは、ファイル名の接頭辞-を使用して、ファイルが存在しなくても問題がないことをsystemdに通知します。これにより、デフォルトのプロセス数とメモリ制限を使用する場合に、そのファイルを省略できます。 --requireを使用します Railsアプリケーションの構成と初期化子をロードする場所をSidekiqに知らせるオプション。 skclusterスクリプトはSIGTERMをキャッチするため、systemctl restart skcluster.serviceを使用できます。 すべてのワーカーを再起動します(これはデプロイメントスクリプトの後半のタスクです)。

このスクリプトはしばらく使用していて、チャンピオンのように機能しています。起動時に生成されるプロセスが多すぎるという問題はもうありません。モニタリングからのメモリ使用量の警告もありません。また、必要な任意のタイプのEC2インスタンスを起動できます。手間のかからない操作は、私が最も好きな種類の操作です。 :)


  1. ObjectRocketでのメトリックダッシュボードの紹介

    元々は2019年9月9日にObjectRocket.com/blogで公開されました Rackspace ObjectRocketでの私たちの使命は、お客様のデータベースを自動操縦に置くことです。そのため、データについて心配する必要がなく、優れたアプリの構築に集中できます。ただし、データベースが自動操縦になっている場合でも、システムの可観測性を維持することは重要な目標です。 データストアで何が起こっているのか、最新のアプリケーションの変更がデータベースのパフォーマンスにどのような影響を与えているのかを正確に把握することは非常に重要です。 そのため、新しいプラットフォームのCockro

  2. Railsでワンタイムスクリプトを書く

    CSVファイルからアプリに大量のデータをインポートしたいと思ったことはありませんか?または、カスタマーレビューの一部で正しくエンコードされていない文字を修正する必要があるかもしれません。または、Redisにデータを保存する方法について考えを変え、すべてを古い形式から新しい形式に移動する必要がありました。 Avvoでは、これらを「アドホックタスク」と呼んでいました。のように、おそらく一度だけ実行する必要があります。 では、Railsでアドホックタスクを処理するための最良の方法は何ですか? データベース移行を作成する データベース内のデータの構造を変更する必要がある場合は、移行が適切に機能し