ホームページ >データベース >Redis >トランザクションACIDとは何ですか? Redis トランザクションは ACID を実装できますか?

トランザクションACIDとは何ですか? Redis トランザクションは ACID を実装できますか?

青灯夜游
青灯夜游転載
2022-01-22 09:26:462400ブラウズ

Redis トランザクションは ACID をサポートしていますか?次の記事では、Redis トランザクションを理解し、Redis がトランザクションを実装する方法を紹介し、Redis トランザクションが ACID をサポートしているかどうかについて説明します。

トランザクションACIDとは何ですか? Redis トランザクションは ACID を実装できますか?

Tencent インタビュアー:「Redis のトランザクションを理解していますか?そのトランザクション メカニズムは ACID プロパティを実装できますか?」

Cheng Xuyuan : 「頭をかきむしります、これは...Lua スクリプトでトランザクションを実装できることは知っています...」

Tencent 面接官:「わかりました。戻って通知を待ちます。」


Code Brother さん、たくさんのオファーをいただきましたが、「Redis はトランザクションをどのように実装するのか?」という質問で最終的に負けるとは予想していませんでした。

ステップごとに分析してみましょう:

  • トランザクション ACID とは何ですか?

  • Redis はトランザクションをどのように実装しますか?

  • Redis トランザクションはどのようなプロパティを実現できますか?

  • Lua スクリプトの実装。

事態のACIDとは何ですか

ゴースト・ブローイング・ザ・ランプの「雲南ワーム・バレー」のキャプテン・モジンには、「ルール」という言葉があります。 「生、分断、死。」 ムーヘンビーズを見つけるために、三人は明確な役割分担を持ち、力を合わせて前進と後退を成功させた。

トランザクションは同時実行制御の単位であり、一連の操作で構成され、これらの操作がすべて実行されるか、まったく実行されません。 [関連する推奨事項:

Redis ビデオ チュートリアル ]

「これは分割できない作業単位です。」

トランザクションが実行されると、特別な属性保証が提供されます:

  • アトミック性: トランザクションの複数の操作が完了するか、どれも完了しない必要があります ( ps: MySQL はどのようにして原子性を実現しますか? メッセージ領域へのコメントは歓迎です);

  • 一貫性 (一貫性): トランザクションの実行が完了した後、データベースの整合性制約はまだ解除されていません。破棄され、トランザクションの実行前後の順序はすべて正当なデータ状態になります。

    データベースの整合性制約には次のものが含まれますが、これらに限定されません:

      エンティティの整合性 (行の主キーが存在し、一意であるなど);
    • 列の整合性 (フィールドなど、タイプ、サイズ、長さが要件を満たしている必要があります)
    • 外部キー制約;
    • ユーザー定義の整合性 (たとえば、2 つのバランスの合計など)アカウントは転送の前後で変更されない必要があります)。
  • #分離: トランザクション内の操作は他のトランザクションから分離されており、同時に実行されるトランザクションは相互に干渉できません。

    は異なるトランザクション間の相互作用に焦点を当てており、厳密な分離は分離レベルのシリアライズ可能 (Serializable) に相当します。

  • 耐久性: トランザクションがコミットされると、すべての変更はデータベースに永続的に保存され、システムがクラッシュして再起動されてもデータは失われません。

# Ma 兄弟、ACID の特定の要件を理解した後、Redis はトランザクション メカニズムをどのように実装しますか?

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 トランザクションは ACID を満たしていますか?

Redis トランザクションは一度に複数のコマンドを実行でき、次の 3 つの重要な保証があります:

  • バッチ コマンドが実行されるEXEC コマンドは一時記憶域のキューに入れられます。

  • EXEC コマンドを受信した後、トランザクションの実行に入ります。トランザクション内のいずれかのコマンドが実行に失敗した場合、残りのコマンドは実行されません。

  • トランザクションの実行中、他のクライアントによって送信されたコマンドは、現在のコマンド実行シーケンスに挿入されません。

Atomicity

コード兄弟、トランザクション実行中にエラーが発生した場合、アトミックなパフォーマンスが保証されます?

トランザクション中に、2 種類のコマンド エラーが発生する可能性があります。

  • EXEC コマンドを実行する前に、コマンド自体が正しくありません。次のように:
    • パラメータの数が間違っています;
    • コマンド名が間違っており、存在しないコマンドが使用されています;
    • メモリ不足 (Redis インスタンスが構成されています) 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 を使用してインスタンスを復元すると、トランザクション操作は実行されなくなり、アトミック性が確保されます。

簡単な概要:

    コマンドがキューに入れられるとエラーが報告され、アトミック性を確保するためにトランザクションの実行は中止されます。
  • コマンドがキューに入れられたとき エラーは報告されませんが、実際の実行中にエラーが報告され、アトミック性は保証されません;
  • EXEC コマンドの実行時にインスタンスが失敗します。AOF ログがオンになっている場合、アトミック性が保証できる。

一貫性

一貫性は、不正なコマンドやインスタンス障害のタイミングによって影響を受けます。コマンド エラーによると、ディメンションの発生タイミングは 3 つの状況で分析できます。

EXEC の実行前、キューに入った後にエラーが報告された場合、トランザクションは破棄されるため、整合性は保証されます。

EXEC 実行後、実際の実行時にエラーが報告されます。

エラーのある実行は実行されません。正しい命令は正常に実行され、一貫性を保証できます。

EXEC を実行すると、インスタンスが失敗します。

インスタンスが失敗すると、インスタンスが再起動されます。これはデータの回復方法に関係します。オープン RDB または AOF については、ケースバイケースで検討されます。

RDB または AOF を有効にしない場合、インスタンスが失敗して再起動した後、データは失われ、データベースの整合性は保たれます。

RDB スナップショットを使用する場合、トランザクション実行時に RDB スナップショットは実行されないためです。

したがって、トランザクション コマンド操作の結果は、RDB スナップショットには保存されません。RDB スナップショットを使用してリカバリすると、データベース内のデータは一貫したものになります。

AOF ログを使用し、トランザクション操作が AOF ログに記録される前にインスタンスが失敗した場合、AOF ログを使用して復元されたデータベース データには一貫性があります。

一部の操作のみが AOF ログに記録されている場合、redis-check-aof を使用してトランザクション内の完了した操作をクリアでき、回復後のデータベースの整合性が保たれます。

#分離

トランザクションの実行は、コマンドのキューイング (EXEC コマンドの実行前) とコマンドの実際の実行 (EXEC コマンドの実行後) に分けることができます。が実行されます) 2 段階。

したがって、同時実行中に、これら 2 つのステージを 2 つの状況で分析します。

  • 同時操作は

    EXEC コマンドの前に実行されます。分離には次のことが必要です。 WATCH メカニズムを通じて保証されます;

  • EXEC コマンドの後で同時操作が保証されます。

マー兄弟、WATCH メカニズムとは何ですか?

最初の状況に注目してみましょう。トランザクションの EXEC コマンドが実行されていないとき、トランザクションのコマンド操作はコマンド キューに一時的に保存されます。

現時点で、他の同時操作があり、同じキーが変更されている場合は、トランザクションが

WATCH メカニズムを使用しているかどうかを確認する必要があります。

WATCH メカニズムの機能は、トランザクションが実行される前に 1 つ以上のキーの値の変更を監視することです。トランザクションが実行するために EXEC コマンドを呼び出すと、WATCH メカニズムはまず監視対象のキーが変更されているかどうかを確認します。他のクライアントによって変更されました。

変更された場合、トランザクションの分離が破壊されるのを防ぐために、トランザクションの実行は中止されます。

同時に、クライアントはトランザクションを再度実行できます。このとき、トランザクション データを変更する同時操作がなければ、トランザクションは正常に実行でき、分離性も保証されます。 。

トランザクションACIDとは何ですか? Redis トランザクションは ACID を実装できますか?

WATCH なし

WATCH メカニズムがない場合、同時操作は EXEC コマンドが実行される前にデータの読み取りと書き込みを行います。

EXECを実行すると、トランザクション内で操作するデータが変更されており、Redisではトランザクション間の分離が実現していません。

トランザクションACIDとは何ですか? Redis トランザクションは ACID を実装できますか?

同時操作は受信され、EXEC 後に実行されます。

2 番目のケースについては、Redis は単一のスレッドを使用してコマンドを実行するためです。 、および 、EXEC コマンドが実行された後、Redis は後続の命令を実行する前に、コマンド キュー内のすべてのコマンドが実行されることを確認します。

したがって、この場合、同時操作によってトランザクションの分離が破壊されることはありません。

トランザクションACIDとは何ですか? Redis トランザクションは ACID を実装できますか?

永続性

Redis が RDB または AOF を使用しない場合、トランザクションの永続性属性保証はありません。

Redis が RDB モードを使用している場合、トランザクションの実行後、次の RDB スナップショットが実行される前にインスタンスがクラッシュしてデータが失われた場合、この場合、トランザクションの変更データも保証されません。耐久性があること。

Redis が AOF モードを採用する場合、AOF モードの 3 つの構成オプション (いいえ、毎秒、常時) によりデータ損失が発生します。

したがって、トランザクションの耐久性特性はまだ保証されていません。

Redis がどの永続モードを採用しても、トランザクションの耐久性特性は保証されません。

概要

    Redis はある程度のアトミック性を備えていますが、ロールバックはサポートしていません。
  • Redis には、ACID に一貫性という概念がありません。 (または、Redis は設計時にこれを無視しました)
  • Redis は分離されています。
  • Redis は耐久性を保証しません。

Redis のトランザクション メカニズムは一貫性と分離性を保証できますが、耐久性は保証できません。

ただし、Redis 自体はインメモリ データベースであるため、永続性は必須の属性ではなく、アトミック性、一貫性、分離性の 3 つの属性の方が重要です。

アトミック性の状況はさらに複雑です。

トランザクションで使用されるコマンド構文が間違っている場合、アトミック性は保証されません。それ以外の場合、トランザクションはアトミックに実行できます。

プログラミング関連の知識について詳しくは、

プログラミング入門をご覧ください。 !

以上がトランザクションACIDとは何ですか? Redis トランザクションは ACID を実装できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。