1

Redis に基づく、Rails アプリ用の効率的な SystemSettings モジュールを実装しようとしています。

ほとんどすべてのリクエストで SystemSettings モジュールを使用しているため、これは可能な限り高速である必要があります。したがって、このモジュールを呼び出すことで生じるオーバーヘッドを最小限に抑えようとしています。

モジュールには、値を追加/削除/更新するための対応する Web UI も含まれます。

最も単純な実装は明らかに各操作で Redis サーバーを呼び出すことですが、Redis サービスは Web サーバーとは別のサーバーにあるため、これは明らかにすべての操作でネットワーク オーバーヘッドを作成します。 .

一定期間値をキャッシュする方法を探しています。その間、Redis サービスを呼び出す代わりに、キャッシュされた結果を返すだけです。

私たちが思いついた唯一の良い解決策はActionDispatch::Callbacks、設定キャッシュを更新する時が来たかどうかを判断するために使用することでした. 問題は、ランダムなユーザー要求に基づいてキャッシュの更新を行うのは間違っているように思われることです。

また、キャッシュの更新を開始するアクションを「トリガー」する特定の URL を呼び出す、約 5 分ごとに実行される小さなスクリプトを作成することも考えていました。このソリューションの問題点は、すべての Passenger プロセスではなく、Passenger プロセスの 1 つ (リクエストを処理したプロセス) のキャッシュ リフレッシュのみが行われることです。

何か案は?

4

1 に答える 1

0

問題は、ランダムなユーザー要求に基づいてキャッシュの更新を行うのは間違っているように思われることです。

全くない。リクエストを処理しない限り、キャッシュをクリアする必要はありません。どのようなキャッシュ設定でも、ローカライズされたデータが原因でパフォーマンスが犠牲になり、一貫性に関する潜在的な問題が生じることに注意してください。キャッシュの無効化はそのような問題です。

あなたの場合、私が最初に行うことは、ローカライズされたインプロセス キャッシュが必要かどうかを実際に測定することです。Redis は非常に高速で、複数の小さなリクエストを送信することは、実際にはこのサーバーの適切な使用パターンです。ネットワーク オーバーヘッドが実際には問題ではないことに気付くかもしれません。このオーバーヘッドは、応答時間全体のほんの一部にすぎないことが判明する可能性があります (ユーザー エクスペリエンスに大きく影響するブラウザーでのレンダリングとアセット時間は言うまでもありません)。

さらに、実際に測定しない場合、状況がどの程度改善されたかをどのように知ることができますか? たぶん、50 行の余分なコードと追加された複雑さは、リクエストごとに 20 ミリ秒の高速化に値しないでしょうか? 確かなデータがなければ、ここで十分な情報に基づいた決定を下すことはできません。

そうは言っても、あなたが本当にそれを必要としていると仮定すると、キャッシュの読み取りコードとともにキャッシュの無効化を実装します。書き込み時に各エントリの有効期限を保存し、読み取り時に時間が過去かどうかを確認します。そうである場合は、キャッシュを更新します。

Railsでは、次のようMemoryStoreexpires_inオプションを使用できます。

cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
cache.fetch('configuration_key') do
  # your redis contacting code
end
于 2013-03-11T09:53:28.150 に答える