[高並行性]高並行性環境でアプリケーションレベルのキャッシュを構築するにはどうすればよいですか?

前に書く

システムの負荷がますます高くなると、システムのパフォーマンスが低下します。現時点では、キャッシュを使用してデータの読み取りと書き込みのパフォーマンスが低下する問題を解決することは当然考えられます。しかし、上級アーキテクトになると決心した場合、同時実行性の高い環境でアプリケーションレベルのキャッシュを合理的かつ効率的に構築できますか?

キャッシュヒット率

キャッシュヒット率は、キャッシュからのデータ読み取り数と読み取りの総数の比率であり、ヒット率が高いほど優れています。キャッシュヒット率=キャッシュからの読み取り数/(読み取りの総数(キャッシュからの読み取り数+低速デバイスからの読み取り数))。これは非常に重要な監視インジケータです。キャッシュを行う場合は、このインジケータを監視して、キャッシュが適切に機能しているかどうかを確認する必要があります。

キャッシュリサイクル戦略

1.スペースベース

スペースベースとは、キャッシュに10MBなどのストレージスペースが設定されていることを意味します。ストレージスペースの制限に達すると、特定の戦略に従ってデータが削除されます。

2.容量に基づく

容量に基づいて、キャッシュの最大サイズが設定され、キャッシュエントリが最大サイズを超えると、古いデータは特定の戦略に従って削除されます。

3.時間ベース

TTL(存続時間):存続期間、つまりキャッシュデータが作成されてから期限切れになるまでの期間(この期間内にアクセスされたかどうかに関係なく、キャッシュデータは期限切れになります)。
TTI(Time To Idle):アイドル期間、つまりキャッシュが削除される前に、キャッシュされたデータにアクセスされなかった時間。

4.オブジェクト参照に基づく

ソフトリファレンス:オブジェクトがソフトリファレンスの場合、JVMヒープメモリが不足すると、ガベージコレクターはこれらのオブジェクトを再利用できます。ソフトリファレンスはキャッシングに適しているため、JVMヒープメモリが不十分な場合、これらのオブジェクトを再利用して強力なリファレンスオブジェクト用のスペースを確保し、OOMを回避できます。
弱い参照:ガベージコレクターがメモリを再利用するときに、弱い参照が見つかった場合、すぐに再利用されます。ソフトリファレンスと比較して、弱いリファレンスはライフサイクルが短くなります。

注:他の強い参照オブジェクトが弱い参照/ソフト参照オブジェクトを参照していない場合のみ、参照はガベージコレクション中に収集されます。つまり、オブジェクト(弱参照/ソフト参照オブジェクトではない)が弱参照/ソフト参照オブジェクトを参照する場合、ガベージコレクション中に弱参照/ソフト参照オブジェクトは収集されません。

5.リサイクルアルゴリズム

スペースベースおよび容量ベースのキャッシュの使用は、特定の戦略を使用して古いデータを削除します。一般的なものは次のとおりです。

  • FIFO(先入れ先出し):先入れ先出しアルゴリズム、つまり、最初にキャッシュに入れられたものが最初に削除されます。
  • LRU(最も最近使用されていない):最も長く使用されていないアルゴリズムで、時間と時間が最も長いアルゴリズムが削除されます。
  • LFU(Least Frequently Used):最も一般的に使用されていないアルゴリズムで、一定期間内に使用回数(頻度)が最も少ないアルゴリズムが削除されます。

実際のアプリケーションでは、ほとんどのLRUベースのキャッシュが使用されます。

キャッシュタイプ

ヒープメモリ: Javaヒープメモリを使用してオブジェクトを格納します。ヒープキャッシュを使用する利点は、シリアル化/逆シリアル化がなく、最も高速なキャッシュであることです。キャッシュされたデータの量が多いと、GC(ガベージコレクション)の一時停止時間が長くなり、ストレージ容量はヒープスペースのサイズによって制限されます。キャッシュオブジェクトは通常、ソフト参照/弱参照を介して保存されます。つまり、ヒープメモリが不足している場合、メモリのこの部分を強制的に再利用して、ヒープメモリ空間を解放できます。ヒープキャッシュは通常、ホットデータを格納するために使用されます。Guava Cache、Ehcache 3.x、MapDBを使用して実現できます。

オフヒープメモリ:つまり、キャッシュされたデータはオフヒープメモリに保存されます。これにより、GCの一時停止時間を短縮でき(ヒープオブジェクトがヒープから転送され、GCスキャンと移動オブジェクトが少なくなります)、より多くのキャッシュスペースをサポートできます(マシンメモリのサイズによってのみ影響を受けます)制限。ヒープ領域の影響を受けません)。ただし、データの読み取り時にはシリアル化/非シリアル化が必要です。したがって、ヒープキャッシュよりもはるかに遅くなります。Ehcache 3.x、MapDBを使用して実現できます。

ディスクキャッシュ:つまり、キャッシュされたデータはディスクに保存され、JVMの再起動時にもデータは存在します。ヒープ/オフヒープキャッシュデータは失われ、再ロードする必要があります。Ehcache 3.x、MapDBを使用できます。

分散キャッシュ:分散キャッシュは、ehcache-clustered(Terracottaサーバーを使用)を使用して、Javaプロセス間の分散キャッシュを実現できます。MemcachedとRedisを使用することもできます。

キャッシュモード

スタンドアロンモード:最もホットなデータをヒープキャッシュに、比較的ホットなデータをオフヒープキャッシュに、ホットでないデータをディスクキャッシュに保存します。
クラスターモード:最もホットなデータをヒープキャッシュに格納し、比較的ホットなデータを外部キャッシュに格納し、データの全量を分散キャッシュに格納します。

最後に書く

この記事が役に立った場合は、WeChatで「Binghe Technology」のWeChatアカウントを検索してフォローし、Bingheで同時実行プログラミングのテクニックを学んでください。

最後に、コンカレントプログラミングで習得する必要があるコアスキルナレッジマップを添付します。
ここに画像の説明を挿入

1356件のオリジナル記事が公開されました 2387件の賞賛 544万回の閲覧

おすすめ

転載: blog.csdn.net/l1028386804/article/details/105546816