インメモリ辞書によるキャッシング。私たちはそれをすべて間違っていますか?


8

このアプローチは、私たちの会社で何かをするために受け入れられている方法です。簡単な例:顧客のデータの一部がサービスから要求された場合、その顧客のすべてのデータ(サービスに関連する部分)をフェッチし、それをメモリ内辞書に保存して、次の要求でそこから提供します(シングルトンサービスを実行します)。更新はすべてDBに送信され、次にメモリ内辞書が更新されます。それはすべて単純で無害に思えますが、より複雑なビジネスルールを実装すると、キャッシュが同期しなくなり、見つけにくいバグに対処する必要があります。時々、データベースへの書き込みを延期し、それまで新しいデータをキャッシュに保持します。テーブルには他のテーブルとの関係が多く、集計データをすばやく表示する必要があるため、数百万の行をメモリに格納する場合があります。

このすべてのキャッシュ処理はコードベースの大きな部分を占めており、これは正しい方法ではないように思います。このすべてのジャグリングはコードに過度のノイズを追加し、実際のビジネスロジックを理解することを困難にします。ただし、毎回データベースにアクセスする必要がある場合、妥当な時間内にデータを提供できるとは思いません。

私は現在の状況に不満を持っていますが、これ以上の選択肢はありません。私の唯一の解決策は、NHibernateの2番目のレベルのキャッシュを使用することですが、これに関する経験はほとんどありません。多くのキャンパニーがパフォーマンスを上げるためにRedisまたはMemCachedを頻繁に使用していることを知っていますが、どのように私たちのシステムに統合するかわかりません。また、メモリ内のデータ構造やクエリよりもパフォーマンスが良いかどうかもわかりません。

検討すべき代替のアプローチはありますか?

回答:


9

最初の最後の質問:なぜRedis / memcachedですか?

いいえ、それらは(通常)単純なインプロセス辞書よりも高速ではありません。複数のワーカープロセス、または多くのアプリレイヤーマシンがある場合に利点があります。その場合、各プロセスが独自の小さなキャッシュを持つ代わりに、それらすべてが単一の大きな(分散)キャッシュを共有します。キャッシュが大きいほど、ヒット率が向上します。

ご覧のとおり、キャッシュレイヤーはデータベースとよく似た共有リソースになりますが、(うまくいけば)高速になります。

さて、大部分について:混乱を避ける方法は?

あなたの問題は、キャッシュをデータベースから切り離すと同時にキャッシュの一貫性を保つことです。そこには3つの問題点があります。

  1. キャッシュの無効化。これは難しいです。場合によっては、最も簡単な解決策は、すべてのレコードに世代IDを追加し、それをキャッシュキーの一部として使用することです。データが更新されると、新しい世代IDが取得され、次のキャッシュクエリがヒットしないため、データベースに移動してキャッシュを更新します。もちろん、(現在は未使用の)エントリは、最終的にはキャッシュから削除されるように、適切な有効期限が必要です。

  2. 返事を書く。キャッシュを操作して、後でデータベースを更新するとします。これは危険です。ほとんどのアーキテクチャはその考えを避けています。正しい方向への一歩は、キャッシュ内のすべての新しいエントリまたは変更されたエントリを「ダーティ」としてマークすることです。これにより、分離されたプロセスによってデータベースにフラッシュできます。メッセージキューが変更されるとすぐにメッセージキューに追加して、データベースへの書き込みを効果的に「インラインだが非同期」にすることをお勧めします。最後に、これはキャッシュの有効な使用法ではないことを理解する必要があります。これは「ステージング領域」であり、キャッシュレイヤーとは異なるアーキテクチャで処理する必要があります。

  3. プロセス間同期:インプロセスキャッシュは各プロセスに対してプライベートであるため、変更はデータベースにフラッシュされるまで他のプロセスに反映されません。これはアプリの設計では正しいかもしれませんが(貧弱な人のトランザクション分離のようなものです)、意図しない結果になる可能性があります。より管理しやすいアーキテクチャは、データベースと同じ共有プロパティを持ち、データベースと同じように「信頼できる」データベースの高速APIであるキャッシュレイヤーです。そのためには、memcachedやRedisなどのアウトプロセスキャッシュが必要です。


8
コンピュータサイエンスには、キャッシュの無効化と名前付けという2つの難しいことしかありません。
Michael Borgwardt

12
コンピュータサイエンスには、キャッシュの無効化、名前の付け方、オフバイワンエラーの2つだけ難しい問題があります。
マシューキング

2
@MatthewKingコンピュータサイエンスで難しいのは3つだけです。2つずれたエラーです。
Jimmy Hoffa

@MatthewKing、私はユーモアが大好きです。:)
アンソニーガトリン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.