1. ホーム
  2. データベース
  3. レディス

インタビューFAQです。Redisキャッシュとデータベース間のデータ整合性を確保する方法

2022-01-15 19:28:45

まず、どのような一貫性のシナリオがあるのかを見てみましょう。

I. 一貫性

1. 強い一貫性

キャッシュに対するプロジェクトの要件が強く一貫している場合は、キャッシュを使用しないでください。このレベルの一貫性は、ユーザーにとって最も直感的なものです。システムが書き込んだものが読み出されることを必要とし、これは良いユーザー体験ですが、しばしば実装時にシステムに大きなパフォーマンスの影響を及ぼします。

2. 弱い整合性

この整合性レベルは、書き込みが成功した直後に書き込んだ値を読み出すことを約束することや、データが整合性を持つようになるまでの時間を制約するもので、ある時間レベル(例えば第二レベル)後にデータが整合性を持つ状態になることを保証しようとするものである。

3. 最終的な整合性

最終的な一貫性とは、弱い一貫性の特殊なケースで、システムが時間の経過とともにデータの一貫した状態を達成することが保証されていることです。最終的な一貫性は、弱い一貫性のモデルとして高く評価されており、大規模な分散システムにおけるデータの一貫性に関して、業界で尊敬されるようになったため、ここで特別に取り上げました。一般に、高可用性は最終的な一貫性のみを保証し、強い一貫性は保証しません。

強い一貫性では、読み取り要求と書き込み要求をシリアライズしてメモリキューに連ねることで、システムの処理効率を大幅に向上させ、スループットを大幅に低下させることができます。

II. redisキャッシュとmysqlデータベースのデータ一貫性ソリューション

これは、ほとんどの人がキャッシュのために多くのビジネスオペレーションをベースにしている図です。しかし、一度二重書きするように設計したり
データベースとキャッシュの更新のような操作では、データの一貫性に問題が生じやすくなります。先にデータベースに書き込んでキャッシュを削除しても、先にキャッシュを削除してデータベースに書き込んでも、データの一貫性に問題が生じます。ここに二つの小さな例があります。

1. redisキャッシュを先に削除したが、何らかの理由でまだデータベースに書き込まれていない、別のスレッドが来てそれを読み、キャッシュが空であることがわかり、データベースに行って前のデータを読み、キャッシュに書き込み、キャッシュが汚れている。

2. データベースを先に書き込んだが、キャッシュを削除する前にデータベースへの書き込みを行ったスレッドが何らかの理由で中断し、キャッシュが削除されなかった場合にも、不整合なデータが発生します。

まとめると、書き込みと読み出しはほとんどの場合同時進行であり、順序の絶対的な保証はないため、キャッシュとデータベースのデータに不整合が生じやすいということです。

1. オプション 1: 遅延型ダブル削除戦略を使用する

基本的な考え方 ライブラリを書き込む前と後にキャッシュを削除し、適度なタイムアウトを設定する。
基本的な手順 まずキャッシュを削除し、再度データベースを書き込み、しばらくスリープさせ、再度キャッシュを削除する。
注:ハイバネーション時間は、プロジェクトの時間のかかる読み取りデータのビジネスロジックに応じて決定されます。この主な理由は、読み取り要求が書き込み要求の前に終了し、書き込み要求が読み取り要求によって引き起こされたキャッシュ内のダーティデータを削除できることを確認するためです。

このソリューションの欠点:設定された二重削除ポリシー+キャッシュタイムアウトポリシーにより、最悪の場合、タイムアウト中にデータの不整合が発生し、その結果、書き込みリクエストにかかる時間が長くなってしまうことです。

2. オプション2:ワンステップキャッシュ更新(Binlogサブスクリプションに基づく同期化メカニズム)

基本的な考え方:mysql Binlog 拡張サブスクリプション消費 + メッセージキュー + redis への増分データ更新 - redis を読む:ホットデータは基本的に redis にある - mysql を書く:追加、削除、変更は操作 mysql - redis データの更新 mysql データ操作 Binlog, to update redis

もう一度、詳細な処理を見てみましょう

1. Redisアップデート

1)、Data操作は大きく2つのブロックに分かれる。
一つは、すべてのデータをredisに書き込むフル量、もう一つは、リアルタイムで更新するインクリメンタル量(update, insert, delete)です。

2) binlogを読み込んで解析し、メッセージキューを利用して各局のredisキャッシュデータをプッシュして更新する。
このメカニズムは、実はMySQLのマスター・スレーブバックアップのメカニズムと非常によく似ており、MySQLのマスターバックアップもbinlogを通じてデータの一貫性を実現しているのである。

ここでは、MySQLのbinlogを購読できるcanal(Aliのオープンソースフレームワーク)を組み合わせて使用し、canalがmysqlのスレーブデータベースのバックアップ要求を模倣して、Redisのデータ更新を同じ効果を達成させることが可能です。

もちろん、Redisに更新をプッシュするために使用できるサードパーティのメッセージングツールは他にもあります:kafka、rabbitMQなどです。

コメントでの議論を歓迎します。

<リンク これは、面接官がよく質問することです:Redisキャッシュとデータベース間のデータの一貫性を確保する方法、Redisキャッシュとデータベースのデータの一貫性に関する詳細については、スクリプトハウスの他の関連記事に注意してください!。