MySQLとRedisのキャッシュ同期スキーム

  • この記事では、MySQLとRedisのキャッシュを同期するための2つのソリューションを紹介します

    • 解決策1:MySQL、MySQLトリガー+ UDF関数の実装を通じてRedisを自動的に更新する

    • 解決策2:MySQLのbinlog実装を分析し、データベース内のデータをRedisに同期します

1.スキーム1(UDF)

  • シナリオ分析:  MySQLデータベースでデータ操作を実行するときに、対応するデータをRedisに同時に同期します。Redisに同期した後、クエリ操作はRedisから検索されます。

  • プロセスはおおまかに次のとおりです。

    • MySQLで操作するデータのトリガートリガーを設定し、操作を監視します

    • クライアント(NodeServer)がMySQLにデータを書き込むと、トリガーがトリガーされます。トリガーの後、MySQLUDF関数が呼び出されます。

    • UDF関数は、同期の効果を実現するために、Redisにデータを書き込むことができます

画像

  • ケース分析:

    • このスキームは、読み取りが多く書き込みが少なく、同時書き込みがないシナリオに適しています。

    • MySQLトリガー自体が効率の低下を引き起こすため、テーブルが頻繁に操作される場合、このソリューションはそれが不適切であることを示しています

デモケース

  • 以下はMySQLテーブルです

画像

  • 以下はUDFの解析コードです

画像

  • 対応するトリガーを定義する

画像

画像

画像

2、プラン2(binlogの分析)

  • オプション2を導入する前に、次の図に示すように、まずMySQLレプリケーションの原則を紹介しましょう。

    • メインサーバーはデータを操作し、データをビンログに書き込みます

    • サーバーからI / Oスレッドを呼び出して、メインサーバーのBinログを読み取り、それを独自のリレーログに書き込みます。次に、SQLスレッドを呼び出して、リレーログからデータを解析し、独自のデータベースに同期します。

画像

  • オプション2は次のとおりです。

    • 上記のMySQLのレプリケーションプロセス全体は、1つの文に要約できます。つまり、サーバーからメインサーバーのビンログのデータを読み取り、それを独自のデータベースに同期します。

    • 同じことがソリューション2にも当てはまります。これは、概念的にマスターサーバーをMySQLに、スレーブサーバーをRedisに変更することです(下の図を参照)。MySQLに書き込むデータがある場合は、MySQLBinログを解析します。次に、同期の効果を実現するために、解析されたデータがRedisに書き込まれます。

画像

  • たとえば、以下はクラウドデータベースインスタンスの分析です。

    • クラウドデータベースは、ローカルデータベースとマスタースレーブ関係にあります。クラウドデータベースは書き込み用のメインデータベースとして機能し、ローカルデータベースはメインデータベースからデータを読み取るためのスレーブデータベースとして機能します。

    • ローカルデータベースがデータを読み取った後、Binログを解析し、データをRedisに書き込んで書き込み、クライアントがRedisからデータを読み取ります。

画像

  • この技術的ソリューションの難しさは、  MySQLビンログを解析する方法にありますただし、これにはbinlogファイルとMySQLを非常に深く理解する必要があります。同時に、binlogには複数の形式のStatement / Row / Mixedlevelがあるため、同期を実現するためにbinlogを分析するワークロードは非常に大きくなります。

Canalオープンソーステクノロジー

  • Canalは、純粋なJavaで開発されたAlibabaのオープンソースプロジェクトです。データベースの増分ログ分析に基づいて、増分データのサブスクリプションと消費を提供します。現在、主にMySQLをサポートしています(mariaDBもサポートしています)。

  • オープンソースの参照アドレスは次のとおりです:https://github.com/liukelin/canal_mysql_nosql_sync

  • 動作原理(MySQLレプリケーションを模倣):

    • Canalは、mysqlスレーブの対話型プロトコルをシミュレートし、mysqlスレーブのふりをして、ダンププロトコルをmysqlマスターに送信します。

    • mysqlマスターはダンプ要求を受信し、バイナリログをスレーブ(つまり、運河)にプッシュし始めます。

    • Canalはバイナリログオブジェクト(元のバイトストリーム)を解析します

画像

  • 建築:

    • eventParser(データソースアクセス、シミュレートされたスレーブプロトコルとマスターの相互作用、プロトコル分析)

    • eventSink(パーサーおよびストアリンカー、データフィルタリング、処理、および配布作業)

    • eventStore(データストレージ)

    • metaManager(インクリメンタルサブスクリプションおよびコンシューマーインフォメーションマネージャー)

    • サーバーは、jvmに対応する運河の実行中のインスタンスを表します

    • インスタンスはデータキューに対応します(1つのサーバーは1..nインスタンスに対応します)

    • インスタンスモジュール:

画像

  • 一般的な分析プロセスは次のとおりです。

    • parseはMySQLBinログを解析し、データをシンクに入れます

    • シンクフィルター、処理、およびデータの配布

    • ストアは、解析されたデータをシンクから読み取り、保存します

    • 次に、デザインコードを使用して、ストア内のデータをRedisに同期的に書き込みます。

    • その中で、解析/シンクはフレームワークによってカプセル化されています。私たちが行うのは、ストアデータを読み取るステップです。

画像

  • Canclの詳細はBaiduで検索できます

  • 以下は、実行中のトポロジ図です。

画像

  • MySQLテーブルの同期は、Chain of Responsibilityモードを採用し、各テーブルはFilterに対応します 。たとえば、zvsyncで使用されるクラスは次のように設計されています。

画像

  • 以下は、マテリアライズドzvsyncで使用されるクラスです 。テーブルが追加または削除されるたびに、直接追加および削除するだけです。

画像

3、追加

  • この記事の上記のすべては、MySQLからキャッシュに同期されます。

    しかし、実際の開発では、誰かが次のスキームを使用する可能性があります。

    • クライアントがデータを取得したら、最初にそれをRedisに保存してから、MySQLに同期します

    • このスキーム自体も安全ではない/信頼性が低いため、Redisに短期間のダウンタイムや障害が発生すると、データが失われます

画像

おすすめ

転載: blog.csdn.net/weixin_42073629/article/details/115038573