システムのスループットを改善するために、私たちはしばしば、ビジネスアーキテクチャにバッファ層を導入します。
- キャッシュの浸透
- キャッシングのコレクション
- ホットデータキャッシュ
- 使用して、高い一貫性を確保するために、ロック
- 楽観的な戦略
- リネーム
- 一時的なキーを生成
- SortedSet
- 遅延キューイング
- スライディングウィンドウ
- いくつかの常識
キャッシュの浸透
無効なデータがキャッシュを占有しないようにするために、我々は通常、空のオブジェクトがキャッシュに格納されていないが、この戦略が質問に貫通キャッシュになります。
照会するには、データが、その後、もちろん、これはキャッシュからのデータで見つけることができない、データベースへの論理アクセスでキャッシュの無効化を存在しない、存在しないすべてのデータは、クエリのデータベースは、キャッシュの浸透として知られている現象に到着します。
無意味なデータベースへのアクセスを減らすために、我々はデータをキャッシュすることができますプレースホルダの存在を示すものではありません。
存在しなかったデータへのアクセスは、削除データを、データを削除したため、キャッシュ表現に置かれるべきであるとのアクセスのより高い確率と比較すると、プレースホルダが削除されています。
キャッシングのコレクション
Redisのは、私たちが、キャッシングのコレクションを呼び出しますリスト、ハッシュ、設定およびにSortedSetや他のデータ構造を、提供しています。
組み立てキャッシュは、典型的には、より複雑なロジックを更新している(または困難な一貫性を確保するために)再構成ロジックは単純ですが、キャッシュデータベースにも多くの圧力をもたらす可能性があり再構築します。
カウンタ更新ロジックはまた、キャッシングコンプレックスを持っていますが、単純なキャッシュデータベース圧特性を再構築するために再構築し、著者はまた、キャッシングのコレクションとして分類されます。目的は、ユーザーの数をカウントし、物品の総数として、特に複雑なステートマシンを、あるカウンタの複雑さは、物品を開示しています。
レビュー論文のリストでは、例えば、Redisのは空であるリストを確認キャッシュする場合、2つの理由が考えられます
- キャッシュの無効化
- コメントはありません
キャッシュを更新しようと、我々は検討する必要があるときにキャッシュがコメントした後、コメントの一覧で見つからない場合、キャッシュミスや、元はコメントしなかったです。コメントを挿入し、直接LPUSHまたはZADD命令を使用しないでください。
キャッシュ内の要素の組み立ては、不変オブジェクトまたはIDのオブジェクトでなければなりません。それでもストレージが一覧にSortedSetに直接コメントやオブジェクトをシリアライズ場合たとえば、あなたがコメントだけを見つけるために、完全なフィールドオブジェクトを知って、リストを確認します。コメントを変更した後、我々は高い位置を取得したり、元のコメントの難易度の内容を変更することはできません。コメントはキャッシング複数のセットに存在する場合は、複数を変更する必要があります。
また、完全なオブジェクトを使用すると、大量のメモリを節約することができ、複数のストレージを必要とするときIDを使用して、バイトのコメントIDの数よりもはるかに大きいです。
ホットデータキャッシュ
実際のビジネスでは、私たちはしばしばホットスポットデータキャッシュの無効化の問題に対処する必要があります。データの同時読み取りホットスポット量が大きい場合には、障害が発生しているスレッドのキャッシュ多数のデータベースにアクセスしたら、それも応答データベースのダウンタイムやその他の重大な結果が遅くなる場合があり起こります。
ホット頻繁に書き込まれたデータは、いくつかのシナリオの下で発生する可能性があり、更新されたキャッシュポリシーを使用すると、通常は問題ではありません。我々はホットデータの更新は非常に迅速に削除キャッシュにつながるので、更新する期限切れのキャッシュ戦略を削除することを選択した場合、頻繁にキャッシュの無効化、さらにエラーを大量に生産します。後の戦略更新にデータベースを使用すると、最初のキャッシュを削除した場合、読み取り要求の数が多い可能性が非常に高いライトキャッシュ同時実行エラーが古いデータになります。
そのようなキャッシュの設定またはにSortedSetセットとしてホットスポットデータならば、我々は再構築操作を完了するためのアトミック命令を使用することができるので、再構成プロセスのスレッドの安全性を確保するために考慮される必要がないかもしれません。
どのようにホットデータの一貫性の要件に応じて、我々は政策の二組を持っています。
使用して、高い一貫性を確保するために、ロック
高コンシステンシー要件のシーンのために我々は、分散ロック・サービスを使用することができます。読み取り要求の後にデータにアクセスするには、読み取りロックを取得する書き込みロックの後に取得すべきデータを更新するための要求を記述する必要があります。
キャッシュミスの場合が発生した場合、分散ロック・サービスは1と取得書き込みロックと読み取りキャッシュ行わ復興作業に一つだけのスレッドがあることを保証するキャッシュが再構築が完了するまで、ブロックされているため、ロックを取得できないことに、他のスレッドを読んでください。この方法は、多数のスレッドが仕事のプレッシャーを再構築キャッシュデータベースの結果を繰り返して回避しますが、遅い応答を回避することはできません。
同時に複数のスレッドでSingletonパターンでのgetInstance()メソッドを呼び出すと、重複したオブジェクトは、同様の問題があるキャッシュロック再建を使用して作成することがあります。スレッドがキャッシュミスを発見したので、書き込みロックの復興作業、スレッドBは、書き込みロックを取得するためにBの試みを通す、その後、キャッシュの無効化が依然として発生する再構築キャッシュにアクセスする前に完了します。書き込みロックがスレッドAによって保持されているので、再構築書き込みロックを取得するために完了するまで、スレッドBがブロックされています。キャッシュが再構築されているため、スレッドBが再構築し続けた場合、キャッシュはオーバーヘッド無意味になります。
Singletonパターン我々はこの問題を解決するためのチェック・ロック・チェック・戦略に精通しています:
try {
读取缓存
加读锁
} finally {
释放读锁
}
if (缓存失效) {
try {
加写锁
读取缓存
if (缓存失效) {
重建缓存
}
} finally {
释放写锁
}
}
書き込み保護ロックスレッドの安全性の問題なので、私たちはキャッシュの再構築を心配する必要がある場合。
楽観的な戦略
ときにキャッシュホット・データ障害、我々は最初のプレースホルダプレースホルダ、その後、キャッシュされた再構成を使用することができます。他のスレッドはキャッシュプレースホルダが発生することがあり、データベースにアクセスせずに空の結果を返しますが、また、スレッドブロックの多数の悪影響を避けるために読んでください。
プレースホルダデータベースにアクセスするために、その一つだけのスレッドを保証するものではありません。プレースホルダ書かれた場合は、スレッドA、スレッドBは、再構成プロセスにキャッシュミスを発生した可能性があります。
私たちは、原子再構成プロセスを保証することはできません場合は、その後、すべてのスレッド原子正式に公開鍵を交換するために名前の変更]コマンドを使用して、一時的なキーに復元操作を完了することができます。
リネーム
が、Redisのコマンドはアトミックですが、私たちは、多くの場合、単一のコマンドに遭遇保証スレッドセーフ複雑なプロセスに分散ロックを使用することに加えて、操作を完了することはできませんが、いくつかのシナリオでは、我々は、オーバーヘッド削減にrenameコマンドを使用することができます。
典型的なシナリオでは、我々は、操作は現在のスレッドが再構築またはアトミック操作を更新し、すべてのスレッドに、原子正式に公開鍵を交換するために名前の変更]コマンドを使用してキャッシュの一時的な秘密鍵で行うことができます保証することはできません、上記れます。
もう1つの一般的なシナリオは、SSCANまたはHSCANコマンドの使用は非同期に更新され、設定またはハッシュにダーティなデータです。SSCANコマンドは、プロセス全体トラバーサルキーの終わりに開始することが保証されて、新しいデータを追加し、同じ時間を横断する反復または行方不明の場合に生じる可能性があれば、データセット内に存在は、少なくとも一回返されますされています。
プライベート汚れたデータセットを横断することは、他のスレッドがまだダーティ・データ・セットの行にデータを追加することができますしながら、私たちは、ダーティデータ・セットは、一時的な秘密鍵の非同期スレッド、非同期スレッドの名前を変更することができます。
一時的なキーを生成
クラスタ環境では、それだけで同じスロットでRENAMEコマンドとRENAMENXをサポートすることができます。したがって、我々は一時鍵と同じスロットに元のキーを確保するためのハッシュキーのメカニズムを使用することができます。
元の鍵は、我々は、一時キーは「{オリジナル} -1」のみ括弧内のサブストリングによってブレースを示すが決定ハッシュスロットであり、「{オリジナル} -1」と意志」で生成することができる「オリジナル」である場合同じスロットにオリジナル」。
一時鍵の目的はそう、並行性の問題は、シングルスレッドで動作避けるキーを一時的に他のスレッドによって占有されているかどうかをチェックするために必ずすることです。
2つの一時鍵生成方法があります。
- オリジナルキーと、ランダム値:「{オリジナル} -kGi3X1」は、この方法の利点は、ランダムキー違反の確率が低いが、一時鍵データベースを走査することは困難です
- オリジナルキーとカウンタ:「{オリジナル} -1」、「{オリジナル} -2」、この方法の利点は、スキャンライブラリ一時鍵が、より高い衝突確率が容易です。
一時キーを使用して検出が安全ではありません後、スレッドAが一時鍵、それは一時的なキーで利用可能になったときに検出します他のスレッドを使用して、実際に使用可能な一時的なキーの間で検出された存在していません。
一時的なキーの競合を避けるために、我々は最初のプレースホルダを使用する前に設定してみてください。例えば、「{原稿を} -1」成功すれば「-1ロックをSETNX {原}」最初の実行前に「{原稿を} -1」を用いて、または安全に使用することができます。これは実際には単純な分散ロックを追加することです。
使用に加えて、ランダムな値が再構築や紛争を最小限にするためにキャッシュを更新する必要があります。汚い方法を通過する必要があり、プラスカウンタを使用して、我々は中断されたプロセスを横断継続するカウンターの下でリリースされていない一時的なキーを検索することができます。
SortedSet
たSortedSet Redisのは、データ構造としてソートすることができ、いくつかは、より柔軟なアプリケーションの範囲を見出すことができます。
遅延キューイング
シーンでの一貫性は遅延キュー、メンバー、UNIXタイムスタンプスコアとして所定の実行時間など、メッセージの内容として高い要求にSortedSet行為することなく使用することができます。
ポーリング呼び出しZRANGEBYSCORE所定の実行時間の方法は、メッセージの現在の時刻よりも前であるとメッセージコンシューマー・プロセスを送信します。
127.0.0.1:6379> ZADD DelayQueue 155472822 msg
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE DelayQueue 0 1554728933 WITHSCORES
1) "msg"
2) "1554728822"
Redisの永続化機構に、我々はRedisのキューに基づいて、サービスのいずれか高い一貫性を提供することはできません。
使用しないでくださいRedisのは、ビジネスシーンの高い一貫性の要件でメッセージキューを行います。
スライディングウィンドウ
ホット検索や制限などのビジネス・シナリオでは、我々はすぐに過去1時間に最も検索されたキーワードを見つける必要があります。
同様に、UNIXタイムスタンプをスコアとして遅延キュー、メンバーにSortedSetとしてキーワードです。
タイムイベントの一定期間を照会するために使用ZRANGEBYSCOREコマンドが発生し、ZREMRANGEBYSCOREコマンドは、古くなったデータを削除します。
いくつかの常識
この記事の読者を読む読者の時間を無駄にしないようにするRedisのキャッシュを持ついくつかの経験なので、最後にいくつかの基本的な知識を持っている必要があります。
- IOのかかる操作は限りIO時間を短縮するために、バッチコマンドなどMGETパイプラインメカニズムを使用して可能な限り、読み取りと書き込みのサイクルIO操作のRedisはありません、一般的にCPUの計算よりもはるかに高いです
- Redisのモデルアトミックと直列性を保証するために、シングルスレッドモードを多重化カーネルIO、コマンド実行を使用。(Redisの4.0バージョンへの書き込みがまだそうである場合には、マルチスレッドカーネルを導入することが可能です)
- RDBとAOFのRedisのは、私たちは、そのデータはRedisの崩壊後に失われていない保証することはできません、永続的な非同期モードです。だから、ビジネスシーンの高い一貫性の要件のためではないのRedisを行います。