Redis トランザクションは ACID をサポートしていますか?次の記事では、Redis トランザクションを理解し、Redis がトランザクションを実装する方法を紹介し、Redis トランザクションが ACID をサポートしているかどうかについて説明します。
Tencent インタビュアー:「Redis のトランザクションを理解していますか?そのトランザクション メカニズムは ACID プロパティを実装できますか?」
Cheng Xuyuan : 「頭をかきむしります、これは...Lua スクリプトでトランザクションを実装できることは知っています...」
Tencent 面接官:「わかりました。戻って通知を待ちます。」
Code Brother さん、たくさんのオファーをいただきましたが、「Redis はトランザクションをどのように実装するのか?」という質問で最終的に負けるとは予想していませんでした。
ステップごとに分析してみましょう:
トランザクション ACID とは何ですか?
Redis はトランザクションをどのように実装しますか?
Redis トランザクションはどのようなプロパティを実現できますか?
Lua スクリプトの実装。
ゴースト・ブローイング・ザ・ランプの「雲南ワーム・バレー」のキャプテン・モジンには、「ルール」という言葉があります。 「生、分断、死。」 ムーヘンビーズを見つけるために、三人は明確な役割分担を持ち、力を合わせて前進と後退を成功させた。
トランザクションは同時実行制御の単位であり、一連の操作で構成され、これらの操作がすべて実行されるか、まったく実行されません。 [関連する推奨事項:Redis ビデオ チュートリアル ]
「これは分割できない作業単位です。」 トランザクションが実行されると、特別な属性保証が提供されます:# Ma 兄弟、ACID の特定の要件を理解した後、Redis はトランザクション メカニズムをどのように実装しますか?
MULTI,EXEC,DISCARD andWATCH このコマンドは、Redis がトランザクションを実装するための基礎となります。
Redis トランザクションの実行プロセスは 3 つのステップで構成されます:
トランザクションを明示的に開始する
顧客最後は、MULTI コマンドを通じてトランザクションを開くことを明示的に示しており、後続のコマンドはキューに入れられてキャッシュされ、実際には実行されません。
コマンドのキューイング
クライアントは、トランザクションで実行される一連の命令をサーバーに送信します。 命令はサーバーに送信されますが、Redis インスタンスはこの一連の命令をコマンド キューに一時的に保存するだけで、すぐには実行されないことに注意してください。トランザクションの実行または破棄
クライアントは、トランザクションを送信または破棄するコマンドをサーバーに送信し、送信されたコマンドを Redis に実行させます。 2 番目のステップでは、特定の命令またはキューのクリア コマンドによって実行が中止されます。 Redis は、EXEC を呼び出すときにキュー コマンドの実行をスケジュールするだけで済みます。
DISCARD を使用して、2 番目のステップでキューに保存されたコマンドを破棄することもできます。
Redis トランザクションのケース
オンライン デバッグ Web サイトを通じてサンプル コードを実行します: try.redis.io
通常の実行
Through MULTI
と EXEC
はトランザクション プロセスを実行します:
# 开启事务 > MULTI OK # 开始定义一些列指令 > SET “公众号:码哥字节” "粉丝 100 万" QUEUED > SET "order" "30" QUEUED > SET "文章数" 666 QUEUED > GET "文章数" QUEUED # 实际执行事务 > EXEC 1) OK 2) OK 3) OK 4) "666"
各読み取りおよび書き込み命令の実行後の戻り結果は QUEUED
であることがわかります。これはありがとうを意味します。この操作はコマンド キューに一時的に保存され、実際には実行されません。
EXEC
コマンドを実行すると、各コマンドの具体的な応答データを確認できます。
トランザクションの破棄
MULTI
および DISCARD
によるキュー コマンドの破棄:
# 初始化订单数 > SET "order:mobile" 100 OK # 开启事务 > MULTI OK # 订单 - 1 > DECR "order:mobile" QUEUED # 丢弃丢列命令 > DISCARD OK # 数据没有被修改 > GET "order:mobile" "100"
Brother Code、Redis トランザクションは ACID プロパティを保証できますか?
これは良い質問です。一緒に分析しましょう。
Redis トランザクションは一度に複数のコマンドを実行でき、次の 3 つの重要な保証があります:
バッチ コマンドが実行されるEXEC コマンドは一時記憶域のキューに入れられます。
EXEC コマンドを受信した後、トランザクションの実行に入ります。トランザクション内のいずれかのコマンドが実行に失敗した場合、残りのコマンドは実行されません。
トランザクションの実行中、他のクライアントによって送信されたコマンドは、現在のコマンド実行シーケンスに挿入されません。
Atomicity
コード兄弟、トランザクション実行中にエラーが発生した場合、アトミックなパフォーマンスが保証されます?
トランザクション中に、2 種類のコマンド エラーが発生する可能性があります。
EXEC
コマンドを実行する前に、コマンド自体が正しくありません。次のように: maxmemory
ディレクティブのメモリ制限を使用します)。 EXEC
コマンドの実行後、コマンドが失敗する場合があります。たとえば、コマンドと操作のデータ型が一致しません (List リスト操作は String 型の値に対して実行されます);EXEC
コマンドを実行するとき。 Redis インスタンスで障害が発生し、トランザクションの実行が失敗しました。 EXEC は実行前にエラーを報告します
コマンドがキューに入れられると、Redis は エラーを報告し、エラーを記録します。
現時点では、 は引き続きコマンド操作を送信できます。
EXEC
コマンドが実行されると、Redis は 送信されたすべてのコマンド操作の実行を拒否し、トランザクション失敗の結果を返します。
このようにして、トランザクション内のすべてのコマンドは実行されなくなり、アトミック性が確保されます。
#次は、コマンドのキューイングでエラーが発生し、トランザクションが失敗する例です。#开启事务 > MULTI OK #发送事务中的第一个操作,但是Redis不支持该命令,返回报错信息 127.0.0.1:6379> PUT order 6 (error) ERR unknown command `PUT`, with args beginning with: `order`, `6`, #发送事务中的第二个操作,这个操作是正确的命令,Redis把该命令入队 > DECR b:stock QUEUED #实际执行事务,但是之前命令有错误,所以Redis拒绝执行 > EXEC (error) EXECABORT Transaction discarded because of previous errors.
EXEC が実行後にエラーを報告します
Transaction オペレーションがキューに登録されている コマンドとオペレーションのデータ型が一致しない場合、Redis インスタンスはエラーを検出しません。 ただし、EXEC コマンドの実行後、これらの命令を実際に実行すると、Redis はエラーを報告します。黒板をノックする: Redis は間違った命令のエラーを報告しますが、トランザクションは依然として正しいコマンドを実行します。現時点では、トランザクションのアトミック性は保証できません。
Ma 兄弟、なぜ Redis はロールバックをサポートしないのですか?実際、Redis にはロールバック メカニズムが提供されていません。 Redis は DISCARD コマンドを提供しますが。 ただし、このコマンドはトランザクションの実行を積極的に放棄し、一時コマンド キューをクリアするためにのみ使用でき、ロールバックの効果はありません。
EXEC を実行するとエラーが発生します
Redis が AOF ログをオンにすると、トランザクション操作の一部のみが AOF ログに記録されます。 AOF ログ ファイルを確認するには、redis-check-aof ツールを使用する必要があります。このツールは、AOF ファイルから未完了のトランザクション操作を削除できます。 このように、AOF を使用してインスタンスを復元すると、トランザクション操作は実行されなくなり、アトミック性が確保されます。簡単な概要:
一貫性
一貫性は、不正なコマンドやインスタンス障害のタイミングによって影響を受けます。コマンド エラーによると、ディメンションの発生タイミングは 3 つの状況で分析できます。EXEC の実行前、キューに入った後にエラーが報告された場合、トランザクションは破棄されるため、整合性は保証されます。
EXEC 実行後、実際の実行時にエラーが報告されます。エラーのある実行は実行されません。正しい命令は正常に実行され、一貫性を保証できます。
EXEC を実行すると、インスタンスが失敗します。 インスタンスが失敗すると、インスタンスが再起動されます。これはデータの回復方法に関係します。オープン RDB または AOF については、ケースバイケースで検討されます。 RDB または AOF を有効にしない場合、インスタンスが失敗して再起動した後、データは失われ、データベースの整合性は保たれます。 RDB スナップショットを使用する場合、トランザクション実行時に RDB スナップショットは実行されないためです。 したがって、トランザクション コマンド操作の結果は、RDB スナップショットには保存されません。RDB スナップショットを使用してリカバリすると、データベース内のデータは一貫したものになります。 AOF ログを使用し、トランザクション操作が AOF ログに記録される前にインスタンスが失敗した場合、AOF ログを使用して復元されたデータベース データには一貫性があります。 一部の操作のみが AOF ログに記録されている場合、redis-check-aof を使用してトランザクション内の完了した操作をクリアでき、回復後のデータベースの整合性が保たれます。 #分離 EXEC EXEC WATCH 変更された場合、トランザクションの分離が破壊されるのを防ぐために、トランザクションの実行は中止されます。 WATCH なし 同時操作は受信され、EXEC 後に実行されます。 永続性 Redis がどの永続モードを採用しても、トランザクションの耐久性特性は保証されません。 概要 Redis のトランザクション メカニズムは一貫性と分離性を保証できますが、耐久性は保証できません。 トランザクションで使用されるコマンド構文が間違っている場合、アトミック性は保証されません。それ以外の場合、トランザクションはアトミックに実行できます。 プログラミング入門をご覧ください。 !
コマンドの前に実行されます。分離には次のことが必要です。
WATCH メカニズムを通じて保証されます;
コマンドの後で同時操作が保証されます。
マー兄弟、WATCH メカニズムとは何ですか?
最初の状況に注目してみましょう。トランザクションの EXEC コマンドが実行されていないとき、トランザクションのコマンド操作はコマンド キューに一時的に保存されます。 現時点で、他の同時操作があり、同じキーが変更されている場合は、トランザクションが メカニズムを使用しているかどうかを確認する必要があります。
Redis はある程度のアトミック性を備えていますが、ロールバックはサポートしていません。
以上がトランザクションACIDとは何ですか? Redis トランザクションは ACID を実装できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。