10億レベルのトラフィックスパイクシステムを作成するためのJavaパフォーマンスの最適化:4。クエリパフォーマンスの最適化:マルチマシンキャッシング

4.クエリパフォーマンスの最適化:マルチマシンキャッシング

1.学習目標:

前のセクションでは、サーバーを水平方向に拡張することで、アプリケーションを複数のマシンにデプロイしてリクエストを処理することでTPSが大幅に向上しましたが、これらの複数のデータベースは引き続き同じマシンのデータベースを使用します。
次に、いくつかのクエリ最適化手法を使用して、製品の詳細ページのクエリ最適化ソリューションを完成させます。

  • マルチレベルキャッシュの定義を把握する
  • マスターredisキャッシュ、ローカルキャッシュ
  • ホットnginxluxキャッシュをマスターする

2.キャッシュ設計の原則の概要

  • 高速アクセス機器、メモリを使用するためのキャッシュ
  • ネットワークの遅延を減らすために、ユーザーに最も近い場所にキャッシュをプッシュします
  • ダーティキャッシュのクリーニング:データベースが変更された後、キャッシュ内の古いデータは、脏缓存クリーンアップの方法とクリーニング戦略です。

**マルチレベルキャッシュ**

  • redisキャッシュ
  • ホットデータ、ローカルメモリキャッシュ
  • nginxプロキシキャッシュキャッシュ
  • nginxluaキャッシュ

3つ目は、Redisの集中型キャッシュの導入です

インストール、原則、セッション管理、およびトークン管理については、上記を参照してください。
Key-Value形式のデータベース。
memorycatchは完全なメモリデータベースです。
Redisはデータをディスクにフラッシュできるため、ある程度の損失が発生する可能性があります。一般に、揮発性ストレージと見なされます。

なぜ集中キャッシュ?

アプリケーションサーバーが水平方向に拡張された後、同じRedisサーバーに接続されます。
image.png

1.スタンドアロンバージョン

障害のボトルネック、容量の上限
image.png

2.センチナルセンチネルモード

ここに画像の説明を挿入

redis2はredis1のスレーブバックアップredisであり、redisでの変更はバックアップのためにredis2に同期されます。
ただし、パーティredis1がハングした場合、アプリケーションサーバーはredis2にサービスを自動的に要求する必要がありますが、並行環境が複雑すぎるため、アプリケーションサーバーがredis2がダウンしていることを認識できません。したがって、歩哨モード。

初めて使用する場合、アプリケーションサーバーは最初にセンチネルにどのredisを使用するかを尋ね、センチネルは応答して通知し、アプリケーションサーバーはredisを要求します。
センチネルツールは、redisを使用してハートビートメカニズムを確立します。ハートビートが切断される原因となる状況では、センチネルはそれをredis1の失敗と見なします。redis2をマスターに、redis1をスレーブに変更するコマンドを送信し、アプリケーションサーバーに変更を通知します(次の図を参照)。

image.png

3.クラスタークラスターモード

センチネルモードの欠点も明らかですが、同時に、1つのredisだけが外の世界にサービスを提供します。
クラスター化の前に、フラグメンテーションと読み取り/書き込み分離を使用します。
ここに画像の説明を挿入

ただし、redis5を追加すると、さまざまな複雑なデータ移行が必要になります。スケーラビリティはまだ不十分です。
したがって、クラスターモードが
表示されました。2回の読み取りと2回の書き込みをredisします。そして、自動的にマスターとスレーブを選択します。そして、すべてのredisはすべての関係を知っています。そして、このリレーショナルルーティングテーブルをアプリケーションサーバーに送信すると、アプリケーションサーバーはフラグメンテーション情報を独自のメモリに保持します。
redis3が失敗すると、パーカーメカニズムを介してステータスが自動的に再配布され、ハッシュフラグメントが自動的に再調整されます。
ただし、アプリケーションサーバーにはまだ誤ったフラグメントルーティングリストがあります。アプリケーションサーバーがエラーリストに従ってredis2によって要求されたデータを検出すると、redis2は調整後にサーバーによって要求されたキーが管理カテゴリに属していないことを検出し、サーバーに再プルを許可するために要求をサーバーに返します。最新のフラグメントルーティングテーブル。
ここに画像の説明を挿入
image.png
これら3つのモデルがjedis実現されました。

第4に、Redisの集中キャッシュ製品の詳細ページ

コントローラ層では、詳細情報がキャッシュされ、ダウンストリームのサービス呼び出しは行われません。データベースへの依存を減らします。
image.png

しかし、redis自体によってシリアル化された後の文字化けしたコード
ここに画像の説明を挿入

デフォルトのキー値のシリアル化方法が変更され、読みやすくなりました。
image.png

5つのローカルホットスポットキャッシュ

つまり、JVMサーバーのローカル

  • ホットデータ
  • ダーティ読み取りは非常に影響を受けません。データベースが変更されると、ダーティキャッシュデータの多くが知らないうちに読み取られます。

MQを介して更新できますが、利益は損失を上回ります。

  • 記憶は制御可能で貴重です

インスタントアクセスとしてのみであるため、キャッシュの有効時間は非常に短くなります。

同時読み取りと書き込みをサポートする必要があります。単純なハッシュマップは満足できません。LRUなどの戦略によっても排除でき、KEYは時間に応じて自動的に無効になります。

成し遂げる:

Guavaキャッシュ

  • サイズとタイムアウトのみを制御可能
  • 構成可能なlru戦略
  • スレッドセーフ

image.png

@Service
public class CacheServiceImpl implements CacheService {
    
    

    private Cache<String,Object> commonCache = null;

    @PostConstruct
    public void init(){
    
    
        commonCache = CacheBuilder.newBuilder()
                //设置缓存容器的初始容量为10
                .initialCapacity(10)
                //设置缓存中最大可以存储100个KEY,超过100个之后会按照LRU的策略移除缓存项
                .maximumSize(100)
                //设置写缓存后多少秒过期
                .expireAfterWrite(60, TimeUnit.SECONDS).build();
    }

    @Override
    public void setCommonCache(String key, Object value) {
    
    
            commonCache.put(key,value);
    }

    @Override
    public Object getFromCommonCache(String key) {
    
    
        return commonCache.getIfPresent(key);
    }
}

1000TPSを増やします。

六、Nginxプロキシキャッチ

  • プロキシキャッチは、nginxリバースプロキシが事前に有効になっている場合にのみ使用できます
  • キャッシュ操作を完了するには、ファイルシステムのインデックスレベルのファイルに依存します
  • ファイルアドレスをキャッシュするためにメモリに依存する

ただし、キャッシュはメモリではなくローカルディスクシステムに格納されるため、QPSは大幅に改善されておらず、jvmローカルキャッシュのパフォーマンスよりもさらに低くなっています。平均遅延は長くなります。

セブン、NginxLuaの原則

  • Luaコルーチンメカニズム

スレッド宇宙ステーションでは、ユーザーシミュレーションによると、スレッドに依存しています

  • Nginxコルーチンメカニズム

非同期プログラミングモデルを考慮する必要はありません

  • nginxluaプラグインポイント
  • OpenResty

1.コルーチンメカニズム

  • スレッドメモリモデルに依存し、スイッチングオーバーヘッドが低い
  • 閉塞の場合、実行権が時間内に返され、コードが同期されます
  • ロックする必要はありません

image.png

2.Nginxコルーチン

  • nginxの各ワーカープロセスは、epollまたはkqueueのイベントモデルの上にあるコルーチンにカプセル化されます。

いつ

  • すべてのリクエストはコルーチンによって処理されます
  • ngx_luaがluaを実行している場合でも、cに比べて一定のオーバーヘッドがありますが、それでも高い同時実行性を保証できます。

3.Nginxコルーチンメカニズム

  • nginxの各ワーカープロセスは、lua仮想マシンを作成します。luaファイルの実行に使用
  • ワーカープロセスのすべてのコルーチンは同じVMを共有します
  • 各外部リクエストはluaコルーチンによって処理され、それらの間でデータが分離されます
  • luaコードがioなどの非同期インターフェースを呼び出すと、コルーチンは一時停止され、コンテキストデータは変更されません。
  • 作業プロセスをブロックすることなく、自動的に保存します
  • io非同期操作が完了すると、コルーチンコンテキストが復元され、コードが実行され続けます。つまり、コードは同期プログラミングであり、比較的単純です。

つまり、HTTPリクエストを受信した後、それを処理するためにLuaコルーチンが割り当てられますが、たとえば、リバースプロキシがバックエンドサーバーがデータを返すのを待つ必要がある場合、ソケットハンドルをepollリスニングキューに入れ、ハングアップします。他のコルーチンの実行を続行し、バックエンドサーバーが戻るまで待ちます。epollがリッスンすると、コルーチンがウェイクアップして後続の応答操作を処理します。
このため、各コルーチン間のデータは分離されています。
Nginxはワーカーであり、スレッドであり、その下には多くのコルーチンがあります。シリアル処理は完全にコルーチンに基づいています。
Javaサーブレットがhttpリクエストを処理する場合、それはリクエストであり、それを処理するためにスレッドが割り当てられます。

4.Nginx処理段階

ここに画像の説明を挿入

5. Nginxluaマウントポイント

ここに画像の説明を挿入

ここに画像の説明を挿入

6.OpenResty

  • Nginxのイベント駆動型モデルとノンブロッキングIOの助けを借りて、高性能のWebアプリケーションを実現できます。
  • Mysql、redis、memcacheなどの多数のコンポーネントが提供されており、nginxでのWebアプリケーションの開発が容易になっています。

(1)Hello World

image.png
つまり、helloworldにアクセスすると、/ item / get?id = 6にアクセスした結果が返されます。

(2)共有DIC

すべてのワーカープロセスに表示される共有メモリディクショナリ

guaua catchに似たメモリ辞書で、lru除去をサポートします

ただし、メモリの制限があります。
など

(3)Openrestyredisのサポート

Nginxは、共有DICからの読み取りよりもredisからの読み取りが確実に遅くなります。
ここに画像の説明を挿入

更新メカニズムはnginxで省略されているため、ダウンストリームアプリケーションサーバーを更新できます。nginxは読み取り専用であり、書き込みは行いません。
Nginxは、redisでデータをリアルタイムで認識し、不正な読み取りを回避できます。
ここに画像の説明を挿入

したがって、nginxはホットデータを独自のメモリキャッシュにのみ保存でき、非ホットデータはredisスレーブを読み取ります。

8.まとめ

アップストリームに近いほど、キャッシュが占めるシステムリソースのコストが高くなり、対応する更新メカニズムが難しくなり、パフォーマンスが向上します。
したがって、統一された一般的なキャッシュスキームはなく、実際のビジネスシナリオ、ダーティリードの許容度、およびホットデータの程度に応じて、動的リクエストのキャッシュスキームを決定する必要があります。

おすすめ

転載: blog.csdn.net/xiaohaigary/article/details/108010966