>  기사  >  데이터 베이스  >  거래 ACID란 무엇입니까? Redis 트랜잭션에서 ACID를 구현할 수 있나요?

거래 ACID란 무엇입니까? Redis 트랜잭션에서 ACID를 구현할 수 있나요?

青灯夜游
青灯夜游앞으로
2022-01-22 09:26:462346검색

Redis 트랜잭션은 ACID를 지원하나요? 다음 문서에서는 Redis 트랜잭션을 이해하고 Redis가 트랜잭션을 구현하는 방법을 소개하며 Redis 트랜잭션이 ACID를 지원하는지 여부에 대해 설명합니다. 도움이 되기를 바랍니다.

거래 ACID란 무엇입니까? Redis 트랜잭션에서 ACID를 구현할 수 있나요?

Tencent 면접관: "Redis의 트랜잭션을 이해하십니까? 해당 트랜잭션 메커니즘이 ACID 속성을 실현할 수 있습니까?"

Cheng Xuyuan: "고민합니다... Lua 스크립트가 트랜잭션을 실현할 수 있다는 것을 알고 있습니다. ..."

텐센트 면접관: "좋아요, 돌아가서 알림을 기다리세요."


엄마 형님, 제의는 많이 받았는데, 결국 질문에서 지는 줄은 몰랐어요. "Redis는 트랜잭션을 어떻게 구현합니까?"

단계별로 분석해 보겠습니다.

  • 트랜잭션 ACID란 무엇인가요?

  • Redis는 트랜잭션을 어떻게 구현하나요?

  • Redis 트랜잭션은 어떤 속성을 달성할 수 있나요?

  • Lua 스크립트 구현.

사사의 ACID는 무엇입니까

등불을 부는 귀신의 『운남 벌레 계곡』에서 모진 선장은 "함께 살고, 나눠서 죽는다"라는 말을 합니다. 셋이 일을 나눠서 명확하게 하고 함께 전진하고 후퇴해야 성공할 수 있습니다.

트랜잭션은 일련의 작업으로 구성된 동시성 제어 단위입니다. 이러한 작업이 모두 실행되거나 아무것도 실행되지 않습니다. [관련 추천 : Redis 영상 튜토리얼]

"분할할 수 없는 작업 단위입니다."

트랜잭션이 실행되면 다음과 같은 특별한 속성 보장이 제공됩니다.

  • 원자성: 트랜잭션의 여러 작업이 완료되어야 하거나 어느 작업도 완료되어서는 안 됩니다(ps: MySQL은 어떻게 원자성을 달성합니까? 메시지 영역)

  • Consistency(일관성): 트랜잭션 실행이 완료된 후 데이터베이스의 무결성 제약 조건이 파괴되지 않으며, 트랜잭션 실행 순서는 합법적인 데이터 상태입니다.

    데이터베이스의 무결성 제약 조건에는 다음이 포함되지만 이에 국한되지는 않습니다.

    • 엔티티 무결성(예: 행의 기본 키가 존재하고 고유함)
    • 열 무결성(예: 항목의 유형, 크기 및 길이) 필드는 요구 사항을 충족해야 함)
    • 외래 키 제약 조건;
    • 사용자 정의 무결성(예: 두 계정의 잔액 합계는 이체 전후에 변경되지 않고 유지되어야 함)
  • 격리: 트랜잭션 내의 작업은 다른 트랜잭션과 격리되며 동시에 실행되는 트랜잭션은 서로 간섭할 수 없습니다.

    서로 다른 트랜잭션 간의 상호 작용에 중점을 둡니다. 엄격한 격리는 격리 수준에서 직렬화 가능(Serialize)에 해당합니다.

  • 내구성: 트랜잭션이 제출되면 모든 수정 사항이 데이터베이스에 영구적으로 저장되며 시스템이 충돌하고 다시 시작되더라도 데이터가 손실되지 않습니다.

Ma 형제님, ACID의 특정 요구 사항을 이해한 후 Redis는 어떻게 트랜잭션 메커니즘을 구현합니까?

Redis가 트랜잭션을 구현하는 방법

MULTI, EXEC, DISCARD WATCH 명령은 Redis가 트랜잭션을 구현하는 기초입니다.

Redis 트랜잭션 실행 프로세스는 다음 세 단계로 구성됩니다.

  • 트랜잭션 열기

  • 명령을 대기열에 넣습니다.

  • 트랜잭션을 실행하거나

시작하다 transaction

클라이언트는 MULTI 명령을 통해 명시적으로 트랜잭션을 시작하며, 후속 명령은 대기열에 저장되고 실제로 실행되지 않습니다.

Command enqueue

클라이언트는 트랜잭션에서 실행될 일련의 명령을 서버로 보냅니다.

명령이 서버로 전송되더라도 Redis 인스턴스는 이 일련의 명령을 명령 대기열에 일시적으로 저장만 하고 즉시 실행하지는 않는다는 점에 유의해야 합니다.

트랜잭션 실행 또는 폐기

클라이언트는 트랜잭션을 서버에 커밋하거나 폐기하는 명령을 보내 Redis가 두 번째 단계에서 보낸 특정 명령을 실행하거나 대기열 명령을 지우고 실행을 포기할 수 있도록 합니다. .

Redis는 EXEC 를 호출할 때 간단히 대기열 명령 실행을 예약할 수 있습니다.

또한 DISCARD를 사용하여 두 번째 단계에서 대기열에 저장된 명령을 삭제할 수도 있습니다.

Redis 거래 사례

온라인 디버깅 웹사이트를 통해 샘플 코드를 실행하세요: try.redis.io

정상 실행

MULTIEXEC를 통해 트랜잭션 프로세스 실행: MULTIEXEC 执行一个事务过程:

# 开启事务
> 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 命令,就可以看到具体每个指令的响应数据。

放弃事务

通过 MULTIDISCARD丢弃队列命令:

# 初始化订单数
> SET "order:mobile" 100
OK
# 开启事务
> MULTI
OK
# 订单 - 1
> DECR "order:mobile"
QUEUED
# 丢弃丢列命令
> DISCARD
OK
# 数据没有被修改
> GET "order:mobile"
"100"

码哥,Redis 的事务能保证 ACID 特性么?

这个问题问得好,我们一起来分析下。

Redis 事务满足 ACID?

Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:

  • 批量指令在执行 EXEC 命令之前会放入队列暂存;

  • 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行;

  • 事务执行过程中,其他客户端提交的命令不会插入到当前命令执行的序列中。

原子性

码哥,如果事务执行过程中发生错误了,原子性能保证么?

在事务期间,可能遇到两种命令错误:

  • 在执行 EXEC 命令前,发送的指令本身就错误。如下:
    • 参数数量错误;
    • 命令名称错误,使用了不存在的命令;
    • 内存不足(Redis 实例使用 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 명령을 통한 MULTIDISCARD:

rrreeeMa 형제님, Redis 트랜잭션이 ACID 특성을 보장할 수 있나요?

좋은 질문입니다. 함께 분석해 보겠습니다.

Redis 트랜잭션은 ACID를 충족하나요?

Redis 트랜잭션은 한 번에 여러 명령을 실행할 수 있으며 다음과 같은 세 가지 중요한 보장이 제공됩니다.

    배치 명령은 실행 중에 실행됩니다. EXEC 명령은

EXEC 명령을 받은 후 트랜잭션 실행을 시작하기 전에 대기열에 저장됩니다. 트랜잭션의 명령이 실행되지 않으면 나머지 명령은

실행됩니다. 트랜잭션 실행 프로세스, 다른 클라이언트가 제출합니다. 명령은 현재 명령 실행 순서에 삽입되지 않습니다.

Atomicity

Brother 코드, 트랜잭션 실행 중 오류가 발생하면 원자 성능이 보장됩니까?
  • 트랜잭션 중에 두 가지 종류의 명령 오류가 발생할 수 있습니다.
  • EXEC 명령을 실행하기 전에 명령 자체가 잘못되었습니다. 다음과 같습니다.
매개변수 개수가 잘못되었습니다.

명령 이름이 잘못되었으며 존재하지 않는 명령이 사용되었습니다. 메모리가 부족합니다(Redis 인스턴스는 maxmemory 지시어를 사용하여 구성). 메모리 제한).

EXEC 명령을 실행한 후 명령이 실패할 수 있습니다. 예를 들어 명령과 작업의 데이터 유형이 일치하지 않습니다(문자열 유형의 값에 대해 목록 목록 작업이 수행됨).

트랜잭션의 EXEC 명령을 실행할 때. Redis 인스턴스에서 오류가 발생하여 트랜잭션 실행이 실패했습니다.

EXEC는 실행 전에 오류를 보고합니다

명령이 대기열에 추가되면 Redis는

오류를 보고하고 오류를 기록합니다

.

현재 계속해서 명령 작업을 제출할 수 있습니다.

EXEC 명령을 실행한 후 Redis는

제출된 모든 명령 작업 실행을 거부하고 트랜잭션 실패 결과를 반환합니다 🎜. 🎜🎜이런 방식으로 🎜트랜잭션의 모든 명령이 더 이상 실행되지 않아 원자성이 보장됩니다. 🎜🎜🎜다음은 명령이 대기열에 포함될 때 오류가 발생하여 트랜잭션이 실패하는 예입니다. 🎜rrreee🎜🎜EXEC는 실행 후 오류를 보고합니다.🎜🎜🎜트랜잭션 작업이 대기열에 포함될 때 명령의 데이터 유형과 작업이 일치하지 않지만 Redis 인스턴스가 오류를 감지하지 못합니다. 🎜🎜그러나 EXEC 명령을 실행한 후 Redis는 실제로 이러한 명령을 실행할 때 오류를 보고합니다. 🎜🎜🎜칠판을 두드리세요. Redis가 잘못된 지시에 대해 오류를 보고하더라도 트랜잭션은 여전히 ​​올바른 명령을 실행합니다. 이때 트랜잭션의 원자성은 보장될 수 없습니다. 🎜🎜🎜🎜엄마 형제님, 왜 Redis는 롤백을 지원하지 않나요? 🎜🎜🎜사실 Redis는 롤백 메커니즘을 제공하지 않습니다. Redis는 DISCARD 명령을 제공하지만. 🎜🎜그러나 이 명령은 트랜잭션 실행을 적극적으로 포기하고 임시 명령 대기열을 지우는 데에만 사용할 수 있습니다. 롤백 효과는 없습니다. 🎜🎜🎜EXEC 실행 시 오류가 발생했습니다🎜🎜🎜Redis가 AOF 로그를 활성화하면 트랜잭션 작업 중 일부만 AOF 로그에 기록됩니다. 🎜🎜 AOF 로그 파일을 확인하려면 redis-check-aof 도구를 사용해야 합니다. 이 도구는 AOF 파일에서 완료되지 않은 트랜잭션 작업을 제거할 수 있습니다. 🎜🎜이런 방식으로 AOF를 사용하여 인스턴스를 복원한 후에는 트랜잭션 작업이 더 이상 실행되지 않으므로 원자성이 보장됩니다. 🎜🎜🎜간단한 요약🎜: 🎜🎜🎜 명령이 대기열에 추가되면 오류가 보고되고 원자성을 보장하기 위해 트랜잭션 실행이 중단됩니다. 🎜🎜 명령이 대기열에 추가되면 오류가 보고되지 않습니다. 그러나 실제로 실행되면 오류가 보고되며 원자성은 보장되지 않습니다. 🎜🎜EXEC 명령 실행 인스턴스 실패 시 AOF 로그가 켜져 있으면 원자성을 보장할 수 있습니다. 🎜🎜🎜🎜🎜Consistency🎜🎜🎜🎜명령 오류와 인스턴스 실패의 두 가지 차원의 타이밍에 따라 일관성은 세 가지 상황으로 분석될 수 있습니다. 🎜🎜🎜EXEC 실행 전 오류가 보고되면 🎜🎜🎜 거래가 중단되므로 일관성이 보장됩니다. 🎜🎜🎜EXEC가 실행된 후에는 실제 실행 중에 오류가 보고됩니다. 🎜🎜🎜오류가 발생하면 정상적으로 명령이 실행될 수 있으며 일관성이 보장됩니다. 🎜🎜🎜EXEC가 실행되면 인스턴스 실패 후 🎜🎜🎜가 다시 시작됩니다. 이는 인스턴스에 RDB 또는 AOF가 활성화되어 있는지 여부에 따라 설명됩니다. 🎜

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 명령이 실행되지 않은 경우 트랜잭션의 명령 작업이 일시적으로 명령 대기열에 저장됩니다.

거래 ACID란 무엇입니까? Redis 트랜잭션에서 ACID를 구현할 수 있나요?이때, 다른 동시 작업이 있고 동일한 키가 수정된 경우 해당 트랜잭션이 WATCH 메커니즘을 사용하는지 확인해야 합니다.

WATCH 메커니즘의 기능은 트랜잭션이 실행되기 전에 하나 이상의 키 값 변경을 모니터링하는 것입니다. 트랜잭션이 실행을 위해 EXEC 명령을 호출하면 WATCH 메커니즘은 먼저 모니터링되는 키가 다른 키에 의해 수정되었는지 확인합니다. 클라이언트.

수정된 경우 트랜잭션 격리가 파기되는 것을 방지하기 위해 트랜잭션 실행을 포기합니다.

동시에 클라이언트는 트랜잭션을 다시 실행할 수 있으며, 이때 트랜잭션 데이터를 수정하는 동시 작업이 없으면 트랜잭션이 정상적으로 실행될 수 있으며 격리도 보장됩니다.

거래 ACID란 무엇입니까? Redis 트랜잭션에서 ACID를 구현할 수 있나요?

WATCH 없음

WATCH 메커니즘이 없으면 동시 작업은 EXEC 명령이 실행되기 전에 데이터를 읽고 씁니다.

EXEC가 실행되면 트랜잭션 내에서 운용될 데이터가 변경되며 Redis는 트랜잭션을 격리하지 않습니다.

거래 ACID란 무엇입니까? Redis 트랜잭션에서 ACID를 구현할 수 있나요?

동시 작업은 EXEC 이후에 수신되고 실행됩니다. 두 번째 경우는 Redis가 단일 스레드를 사용하여 명령을 실행하기 때문에 EXEC 명령이 실행된 후 Redis는 명령의 모든 명령이 queue가 먼저 실행된 후 다음 지침을 실행합니다.

따라서 이 경우 동시 작업은 트랜잭션의 격리를 깨지 않습니다.

Persistence

Redis가 RDB 또는 AOF를 사용하지 않으면 트랜잭션의 지속성 속성이 확실히 보장되지 않습니다.

Redis가 RDB 모드를 사용하는 경우 트랜잭션이 실행된 후 다음 RDB 스냅샷이 실행되기 전에 인스턴스 충돌이 발생하고 데이터가 손실되면 이 경우 트랜잭션에 의해 수정된 데이터의 지속성을 보장할 수 없습니다. Redis가 AOF 모드를 채택하면 AOF 모드의 세 가지 구성 옵션인 no, Everysec 및 Always로 인해 데이터가 손실됩니다.

따라서 거래의 내구성 속성은 아직 보장되지 않습니다.
  • Redis가 어떤 지속성 모드를 채택하더라도 트랜잭션의 내구성 속성은 보장되지 않습니다.
  • 요약

Redis는 어느 정도 원자성을 갖고 있지만 롤백을 지원하지 않습니다.

Redis에는 ACID에 일관성 개념이 없습니다. (아니면 Redis가 디자인할 때 이것을 무시했을 수도 있습니다.)

Redis는 격리되어 있습니다. Redis는 내구성을 보장하지 않습니다.

Redis의 트랜잭션 메커니즘은 일관성과 격리성을 보장할 수 있지만 내구성은 보장할 수 없습니다.

🎜🎜그러나 Redis 자체는 메모리 내 데이터베이스이기 때문에 지속성은 필수 속성이 아닙니다. 원자성, 일관성 및 격리라는 세 가지 속성에 더 관심이 있습니다. 🎜🎜원자성의 상황은 더 복잡합니다. 🎜트랜잭션에 사용된 명령 구문이 잘못된 경우 원자성이 보장되지 않습니다🎜. 다른 경우에는 트랜잭션이 원자적으로 실행될 수 있습니다. 🎜🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 소개🎜를 방문하세요! ! 🎜

위 내용은 거래 ACID란 무엇입니까? Redis 트랜잭션에서 ACID를 구현할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제