Redis能保证ACID的哪些特性?

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis能保证ACID的哪些特性?

Redis能保证ACID的哪些特性?

文章目录

Redis事务ACID分析

总结:

原子性

  • 命令入队时就报错,会放弃事务执行,保证原子性;
  • 命令入队时没报错,实际执行时报错,不保证原子性;
  • EXEC 命令执行时实例故障,如果开启了 AOF 日志,可以保证原子性。

一致性:能保证一致性

隔离性:能保证隔离性

持久性:不能保证持久性

原子性(A)分析

如果命令正常运行,事务中的原子性是可以得到保证的。

那么在执行命令的过程中如果有命令失败了呢?

过程中执行命令失败很可以不会保证原子性操作,因为这是要分情况的。

1、命令入队就报错

比如执行一个不存在的命令,或者命令的写错了

例如下面代码:

127.0.0.1:6379> set test-mult-key 100
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECR test-mult-key
QUEUED
# DECR 命令拼写错了
127.0.0.1:6379> DECRR test-mult-key
(error) ERR unknown command `DECRR`, with args beginning with: `test-mult-key`,
127.0.0.1:6379> DECR test-mult-key
QUEUED
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.

可以看到事务中 DECR 的命令拼写错了,写成了 DECRR。这时候事务是不能执行的,在执行 EXEC 的时候,Redis 抛出了错误,整个事务的执行被丢弃了。

对于这种情况,在命令入队时,Redis就会报错并且记录下这个错误。此时,我们还能继续提交命令操作。等到执行了EXEC命令之后,Redis就会拒绝执行所有提交的命令操作,返回事务失败的结果。这样一来,事务中的所有命令都不会再被执行了,保证了原子性。

2、命令执行的时候报错

这种情况,就是我们操作 Redis 命令时候,命令的类型不匹配。

栗如:我们对一个 value 为 string 类型的 key,执行 DECR 操作。

127.0.0.1:6379> set test-mult-key 100
OK
127.0.0.1:6379> set test-mult-key-string 's100'
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECR test-mult-key
QUEUED
127.0.0.1:6379> DECR test-mult-key
QUEUED
# 对 value 为 string 的,执行 DECR 操作,结果会报错
# 模拟错误的命令
127.0.0.1:6379> DECR test-mult-key-string
QUEUED
127.0.0.1:6379> DECR test-mult-key
QUEUED
127.0.0.1:6379> EXEC
1) (integer) 99
2) (integer) 98
3) (error) ERR value is not an integer or out of range
4) (integer) 97

这种情况下,虽然错误的命令会报错,但是还是会把正确的命令执行完成。

这种情况下,命令的原子性就无法得到保证了。Redis 中没有提供事务的回滚机制。

3、EXEC命令执行时实例发生故障

如果 Redis 开启了 AOF 日志,那么,只会有部分的事务操作被记录到 AOF 日志中。

机器实例恢复后,我们可以使用 redis-check-aof 工具检查 AOF 日志文件,这个工具可以把已完成的事务操作从 AOF 文件中去除。这样一来,我们使用 AOF 恢复实例后,事务操作不会再被执行,从而保证了原子性。

总结

所以关于 Redis 中事务原子性的总结,就是下面几点

  • 命令入队时就报错,会放弃事务执行,保证原子性;
  • 命令入队时没报错,实际执行时报错,不保证原子性;
  • EXEC 命令执行时实例故障,如果开启了 AOF 日志,可以保证原子性。

一致性(C)分析

关于一致性的分析还是从上面三个点来展开

1、命令入队时就报错

事务本身就不会执行,一致性可以得到保证

2、命令执行的时候报错

有错误的命令不会被执行,正确的命令可以正常执行,也不会改变数据库的一致性。

3、EXEC命令执行时实例发生故障

如果没有开启持久化,那么实例故障重启后,数据都没有了,数据库是一致的。

如果使用 RDB 快照,因为 RDB 快照不会在事务执行时执行,所以事务执行的结果不会保存到 RDB 快照中,使用 RDB 快照进行恢复时,数据库中的数据也是一致性的。

如果我们使用了 AOF 日志,而事务操作还没有被记录到 AOF 日志时,实例就发生了故障,那么,使用 AOF 日志恢复的数据库数据是一致的。如果只有部分操作被记录到了 AOF 日志,我们可以使用 redis-check-aof 清除事务中已经完成的操作,数据库恢复后也是一致的。

总结:Redis 中对于数据一致性属性还是有保证的。

隔离性(I)分析

事务的隔离性要求每个读写事务的对象对其他事务的操作对象相互分离,即该事务提交前对其他事务都不可见。

这里分析下 Redis 中事务的隔离性,Redis 中事务的隔离性将从下面两个方面进行分析

1、如果在命令入队,EXEC执行之前,有并发操作

因为 Redis 在事务提交之前只是把命令,放入到了队列中,所以如果在命令入队,EXEC执行之前,有并发操作,这种情况下,事务是没有隔离性的。

这种情况下,可以借助于 watch 实现:

1、客户端 1 首先,使用 watch 监听一个 key,然后开始一个事务,在事务中写入一些命令;

127.0.0.1:6379> set test-mult-key 100
OK
127.0.0.1:6379> watch test-mult-key
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECR test-mult-key
QUEUED
127.0.0.1:6379> DECR test-mult-key
QUEUED

2、客户端 2 在客户端 1 事务提交之前,操作修改该键值;

127.0.0.1:6379> DECR test-mult-key
(integer) 99

3、客户端 1 提交事务;

127.0.0.1:6379> EXEC
(nil)

从上面的结果可以看到如果使用 watch 之后,如果当前键值,在事务之外有了修改,那么当前事务就会放弃本次事务的执行。这样就实现了事务的隔离性。

1、如果在事务提交之后,有并发操作

这种情况下是没有问题的,Redis 会先把事务中的命令执行完成,然后再去执行后续的命令,因为 Redis 对于命令的执行是单线程的,这种情况下,可以保证事务的隔离性。

总结:事务的隔离性可以保证。

持久性(D)分析

Redis 是会存在丢数据的情况的,如果在数据持久化之前,数据库宕机,那么就会有一部分数据没有及时持久化,而丢失。

虽然他有RDB和AOF日志,但是要保证性能,所以不能保证真正的保存,所以可能存在一部分数据一部分数据没有及时持久化的情况

所以,Redis 中不能保证事务的持久性

Redis 为什么不支持回滚?源码分析

Redis 中为什么没有提供事务的回滚,有下面两个方面的考量

1、Redis是单线程的,支持回滚会对 Redis 的简单性和性能有很大的影响;

2、Redis 中只有在 语法错误者键值的类型操作错误 中才会出错,这些问题应该在开发中解决,不应该出现在生产中。

基于上面两点的考虑,目前 Redis 中不支持事务的回滚。


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
9月前
|
NoSQL 安全 Redis
Redis6.0新特性——ACL(权限控制列表)实现限制用户可执行命令和KEY
Redis6.0新特性——ACL(权限控制列表)实现限制用户可执行命令和KEY
139 0
|
3月前
|
缓存 监控 NoSQL
腾讯二面:Redis 事务支持 ACID 么?
腾讯二面:Redis 事务支持 ACID 么?
71 0
|
3月前
|
缓存 NoSQL 安全
Redis 新特性篇:多线程模型解读
Redis 新特性篇:多线程模型解读
50 5
|
3月前
|
存储 NoSQL 关系型数据库
Redis协议与异步方式(redis网络层、pipeline、事务、lua脚本、ACID特性、发布订阅、hiredis实现同步连接与异步连接)
Redis协议与异步方式(redis网络层、pipeline、事务、lua脚本、ACID特性、发布订阅、hiredis实现同步连接与异步连接)
71 0
|
4月前
|
消息中间件 存储 缓存
Redis之初识特性
Redis之初识特性
27 0
|
5月前
|
存储 缓存 NoSQL
深入挖掘Redis的特性和用途
当谈到高性能缓存和内存数据库时,Redis通常是首选。它有很多独特的功能和用途,比如数据类型、Pub/Sub、Lua脚本等。在这篇博客中,我们将深入挖掘 Redis 的特性和用途,并分享一些实际应用场景。
41 0
|
5月前
|
存储 NoSQL 关系型数据库
redis协议与异步方式(redis网络层、pipeline、事务、lua脚本、ACID特性、发布订阅、hiredis实现同步连接与异步连接)
redis协议与异步方式(redis网络层、pipeline、事务、lua脚本、ACID特性、发布订阅、hiredis实现同步连接与异步连接)
90 0
|
6月前
|
存储 移动开发 NoSQL
Redis到底是什么?都有哪些特性?看完这一篇就都会了
Redis到底是什么?都有哪些特性?看完这一篇就都会了
158 1
|
6月前
|
NoSQL 关系型数据库 MySQL
21Redis - 多数据库特性
21Redis - 多数据库特性
23 0
|
9月前
|
存储 NoSQL Linux
【Redis 系列】redis 学习二,redis 的特性,安装方式,及为什么 redis 会这么快
【Redis 系列】redis 学习二,redis 的特性,安装方式,及为什么 redis 会这么快

热门文章

最新文章