Redis 트랜잭션은 ACID를 지원하나요? 다음 문서에서는 Redis 트랜잭션을 이해하고 Redis가 트랜잭션을 구현하는 방법을 소개하며 Redis 트랜잭션이 ACID를 지원하는지 여부에 대해 설명합니다. 도움이 되기를 바랍니다.
Tencent 면접관: "Redis의 트랜잭션을 이해하십니까? 해당 트랜잭션 메커니즘이 ACID 속성을 실현할 수 있습니까?"
Cheng Xuyuan: "고민합니다... Lua 스크립트가 트랜잭션을 실현할 수 있다는 것을 알고 있습니다. ..."
텐센트 면접관: "좋아요, 돌아가서 알림을 기다리세요."
엄마 형님, 제의는 많이 받았는데, 결국 질문에서 지는 줄은 몰랐어요. "Redis는 트랜잭션을 어떻게 구현합니까?"
단계별로 분석해 보겠습니다.
트랜잭션 ACID란 무엇인가요?
Redis는 트랜잭션을 어떻게 구현하나요?
Redis 트랜잭션은 어떤 속성을 달성할 수 있나요?
Lua 스크립트 구현.
등불을 부는 귀신의 『운남 벌레 계곡』에서 모진 선장은 "함께 살고, 나눠서 죽는다"라는 말을 합니다. 셋이 일을 나눠서 명확하게 하고 함께 전진하고 후퇴해야 성공할 수 있습니다.
트랜잭션은 일련의 작업으로 구성된 동시성 제어 단위입니다. 이러한 작업이 모두 실행되거나 아무것도 실행되지 않습니다. [관련 추천 : Redis 영상 튜토리얼]
"분할할 수 없는 작업 단위입니다."
트랜잭션이 실행되면 다음과 같은 특별한 속성 보장이 제공됩니다.
원자성: 트랜잭션의 여러 작업이 완료되어야 하거나 어느 작업도 완료되어서는 안 됩니다(ps: MySQL은 어떻게 원자성을 달성합니까? 메시지 영역)
Consistency(일관성): 트랜잭션 실행이 완료된 후 데이터베이스의 무결성 제약 조건이 파괴되지 않으며, 트랜잭션 실행 순서는 합법적인 데이터 상태입니다.
데이터베이스의 무결성 제약 조건에는 다음이 포함되지만 이에 국한되지는 않습니다.
격리: 트랜잭션 내의 작업은 다른 트랜잭션과 격리되며 동시에 실행되는 트랜잭션은 서로 간섭할 수 없습니다.
서로 다른 트랜잭션 간의 상호 작용에 중점을 둡니다. 엄격한 격리는 격리 수준에서 직렬화 가능(Serialize)에 해당합니다.
내구성: 트랜잭션이 제출되면 모든 수정 사항이 데이터베이스에 영구적으로 저장되며 시스템이 충돌하고 다시 시작되더라도 데이터가 손실되지 않습니다.
Ma 형제님, ACID의 특정 요구 사항을 이해한 후 Redis는 어떻게 트랜잭션 메커니즘을 구현합니까?
MULTI, EXEC, DISCARD 및 WATCH 명령은 Redis가 트랜잭션을 구현하는 기초입니다.
Redis 트랜잭션 실행 프로세스는 다음 세 단계로 구성됩니다.
트랜잭션 열기
명령을 대기열에 넣습니다.
트랜잭션을 실행하거나
시작하다 transaction
클라이언트는 MULTI
명령을 통해 명시적으로 트랜잭션을 시작하며, 후속 명령은 대기열에 저장되고 실제로 실행되지 않습니다.
Command enqueue
클라이언트는 트랜잭션에서 실행될 일련의 명령을 서버로 보냅니다.
명령이 서버로 전송되더라도 Redis 인스턴스는 이 일련의 명령을 명령 대기열에 일시적으로 저장만 하고 즉시 실행하지는 않는다는 점에 유의해야 합니다.
트랜잭션 실행 또는 폐기
클라이언트는 트랜잭션을 서버에 커밋하거나 폐기하는 명령을 보내 Redis가 두 번째 단계에서 보낸 특정 명령을 실행하거나 대기열 명령을 지우고 실행을 포기할 수 있도록 합니다. .
Redis는 EXEC 를 호출할 때 간단히 대기열 명령 실행을 예약할 수 있습니다.
또한 DISCARD를 사용하여 두 번째 단계에서 대기열에 저장된 명령을 삭제할 수도 있습니다.
Redis 거래 사례
온라인 디버깅 웹사이트를 통해 샘플 코드를 실행하세요: try.redis.io
정상 실행
MULTI
및 EXEC
를 통해 트랜잭션 프로세스 실행: 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"
码哥,Redis 的事务能保证 ACID 特性么?
这个问题问得好,我们一起来分析下。
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
批量指令在执行 EXEC 命令之前会放入队列暂存;
收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行;
事务执行过程中,其他客户端提交的命令不会插入到当前命令执行的序列中。
原子性
码哥,如果事务执行过程中发生错误了,原子性能保证么?
在事务期间,可能遇到两种命令错误:
EXEC
命令前,发送的指令本身就错误。如下:maxmemory
指令配置内存限制)。EXEC
命令后,命令可能会失败。例如,命令和操作的数据类型不匹配(对 String 类型 的 value 执行了 List 列表操作);EXEC
命令时。 Redis 实例发生了故障导致事务执行失败。EXEC 执行前报错
在命令入队时,Redis 就会报错并且记录下这个错误。
此时,我们还能继续提交命令操作。
等到执行了 EXEC
#开启事务 > 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.각 읽기 및 쓰기 명령 실행 후 반환 결과가
QUEUED
인 것을 볼 수 있습니다. 이는 감사 작업이 명령 대기열에 일시적으로 저장되었으며 실제로 실행되지 않았음을 의미합니다.
EXEC
명령이 실행되면 각 명령의 구체적인 응답 데이터를 볼 수 있습니다. Abandon transaction
Discard queue 명령을 통한MULTI
및 DISCARD
: rrreeeMa 형제님, Redis 트랜잭션이 ACID 특성을 보장할 수 있나요?
좋은 질문입니다. 함께 분석해 보겠습니다.Redis 트랜잭션은 한 번에 여러 명령을 실행할 수 있으며 다음과 같은 세 가지 중요한 보장이 제공됩니다.
배치 명령은 실행 중에 실행됩니다. EXEC 명령은
EXEC 명령을 받은 후 트랜잭션 실행을 시작하기 전에 대기열에 저장됩니다. 트랜잭션의 명령이 실행되지 않으면 나머지 명령은
실행됩니다. 트랜잭션 실행 프로세스, 다른 클라이언트가 제출합니다. 명령은 현재 명령 실행 순서에 삽입되지 않습니다.
Atomicity
Brother 코드, 트랜잭션 실행 중 오류가 발생하면 원자 성능이 보장됩니까?
EXEC
명령을 실행하기 전에 명령 자체가 잘못되었습니다. 다음과 같습니다. 명령 이름이 잘못되었으며 존재하지 않는 명령이 사용되었습니다. 메모리가 부족합니다(Redis 인스턴스는 maxmemory
지시어를 사용하여 구성). 메모리 제한).
EXEC
명령을 실행한 후 명령이 실패할 수 있습니다. 예를 들어 명령과 작업의 데이터 유형이 일치하지 않습니다(문자열 유형의 값에 대해 목록 목록 작업이 수행됨). 트랜잭션의 EXEC
명령을 실행할 때. Redis 인스턴스에서 오류가 발생하여 트랜잭션 실행이 실패했습니다.
명령이 대기열에 추가되면 Redis는
오류를 보고하고 오류를 기록합니다.
현재 계속해서 명령 작업을 제출할 수 있습니다.
EXEC
명령을 실행한 후 Redis는
RDB 또는 AOF를 활성화하지 않으면 인스턴스가 실패하고 다시 시작된 후 데이터가 사라지고 데이터베이스의 일관성이 유지됩니다.
RDB 스냅샷을 사용한다면 트랜잭션이 실행될 때 RDB 스냅샷이 실행되지 않기 때문입니다.
따라서 트랜잭션 명령 작업의 결과는 RDB 스냅샷에 저장되지 않습니다. RDB 스냅샷을 복구에 사용하면 데이터베이스의 데이터도 일관성을 유지하게 됩니다.
AOF 로그를 사용하고 트랜잭션 작업이 AOF 로그에 기록되기 전에 인스턴스가 실패하는 경우 AOF 로그를 사용하여 복원된 데이터베이스 데이터는 일관성이 있습니다.
AOF 로그에 일부 작업만 기록된 경우 redis-check-aof를 사용하여 트랜잭션에서 완료된 작업을 지울 수 있으며 복구 후에도 데이터베이스의 일관성이 유지됩니다.
Isolation
트랜잭션 실행은 명령 대기열 추가(EXEC 명령 실행 전)와 명령 실제 실행(EXEC 명령 실행 후)의 두 단계로 나눌 수 있습니다.
따라서 동시 실행 중에 우리는 두 가지 상황에서 이 두 단계를 분석합니다.
동시 작업은 EXEC
명령 전에 실행되고 격리는 WATCH
메커니즘을 통과해야 합니다. 보장; EXEC
命令前执行,隔离性需要通过 WATCH
机制保证;
并发操作在 EXEC
命令之后,隔离性可以保证。
码哥,什么是 WATCH 机制?
我们重点来看第一种情况:一个事务的 EXEC 命令还没有执行时,事务的命令操作是暂存在命令队列中的。
此时,如果有其它的并发操作,同样的 key 被修改,需要看事务是否使用了 WATCH
EXEC
명령 이후의 동시 작업, 격리가 보장됩니다.
마 형제님, WATCH 메커니즘이 무엇인가요?첫 번째 상황에 집중해 보겠습니다. 트랜잭션의 EXEC 명령이 실행되지 않은 경우 트랜잭션의 명령 작업이 일시적으로 명령 대기열에 저장됩니다.
이때, 다른 동시 작업이 있고 동일한 키가 수정된 경우 해당 트랜잭션이 WATCH
메커니즘을 사용하는지 확인해야 합니다.
WATCH 메커니즘의 기능은 트랜잭션이 실행되기 전에 하나 이상의 키 값 변경을 모니터링하는 것입니다. 트랜잭션이 실행을 위해 EXEC 명령을 호출하면 WATCH 메커니즘은 먼저 모니터링되는 키가 다른 키에 의해 수정되었는지 확인합니다. 클라이언트.
수정된 경우 트랜잭션 격리가 파기되는 것을 방지하기 위해 트랜잭션 실행을 포기합니다.동시에 클라이언트는 트랜잭션을 다시 실행할 수 있으며, 이때 트랜잭션 데이터를 수정하는 동시 작업이 없으면 트랜잭션이 정상적으로 실행될 수 있으며 격리도 보장됩니다.
WATCH 없음
WATCH 메커니즘이 없으면 동시 작업은 EXEC 명령이 실행되기 전에 데이터를 읽고 씁니다.
EXEC가 실행되면 트랜잭션 내에서 운용될 데이터가 변경되며 Redis는 트랜잭션을 격리하지 않습니다.
동시 작업은 EXEC 이후에 수신되고 실행됩니다. 두 번째 경우는 Redis가 단일 스레드를 사용하여 명령을 실행하기 때문에 EXEC 명령이 실행된 후 Redis는 명령의 모든 명령이 queue가 먼저 실행된 후 다음 지침을 실행합니다.
따라서 이 경우 동시 작업은 트랜잭션의 격리를 깨지 않습니다.
PersistenceRedis가 RDB 또는 AOF를 사용하지 않으면 트랜잭션의 지속성 속성이 확실히 보장되지 않습니다.
Redis가 RDB 모드를 사용하는 경우 트랜잭션이 실행된 후 다음 RDB 스냅샷이 실행되기 전에 인스턴스 충돌이 발생하고 데이터가 손실되면 이 경우 트랜잭션에 의해 수정된 데이터의 지속성을 보장할 수 없습니다. Redis가 AOF 모드를 채택하면 AOF 모드의 세 가지 구성 옵션인 no, Everysec 및 Always로 인해 데이터가 손실됩니다.
따라서 거래의 내구성 속성은 아직 보장되지 않습니다.Redis는 어느 정도 원자성을 갖고 있지만 롤백을 지원하지 않습니다.
Redis에는 ACID에 일관성 개념이 없습니다. (아니면 Redis가 디자인할 때 이것을 무시했을 수도 있습니다.)
Redis는 격리되어 있습니다. Redis는 내구성을 보장하지 않습니다.
Redis의 트랜잭션 메커니즘은 일관성과 격리성을 보장할 수 있지만 내구성은 보장할 수 없습니다.
🎜🎜그러나 Redis 자체는 메모리 내 데이터베이스이기 때문에 지속성은 필수 속성이 아닙니다. 원자성, 일관성 및 격리라는 세 가지 속성에 더 관심이 있습니다. 🎜🎜원자성의 상황은 더 복잡합니다. 🎜트랜잭션에 사용된 명령 구문이 잘못된 경우 원자성이 보장되지 않습니다🎜. 다른 경우에는 트랜잭션이 원자적으로 실행될 수 있습니다. 🎜🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 소개🎜를 방문하세요! ! 🎜위 내용은 거래 ACID란 무엇입니까? Redis 트랜잭션에서 ACID를 구현할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!