redis学习笔记-事务、键空间的维护与性能

痛苦之源
• 阅读 4302

redis事务

事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制。
并且在事务执行期间,服务器不会中断事务而改去执行其他客户端的命令请求,它会将事务中的所有命令都执行完毕,然后才去处理其他客户端的命令请求。

事务特性

  1. 满足事务一致性和隔离性

  2. 非原子性
    在redis事务中如果有某一条命令执行失败,其后的命令仍然会被继续执行,并不会回滚。

  3. 非持久性
    在 RDB 模式下,服务器可能在事务执行之后、RDB文件更新之前的这段时间失败,所以RDB模式下的Redis事务也是不持久的;在AOF的”总是SYNC“模式下,事务的每条命令在执行成功之后,都会立即调用fsync或fdatasync将事务数据写入到AOF文件。但是,这种保存是由后台线程进行的,主线程不会阻塞直到保存成功。所以从命令执行成功到数据保存到硬盘之间,还是有一段非常小的间隔,所以这种模式下的事务也是不持久的。

缺点

  1. 遇到有查询的情况穿插在事务中间,不会返回结果:设置事务开始标志后,所有的命令都是queued,即使是查询指令。 如果后续的更新操作需要依赖于前面的查询指令,那redis事务就无法有效的完成任务。

  2. 事实上,事务中的每条命令都与redis服务器进行了一次网络交互。

  3. 小优化:
    对于所有的get/set操作,可使用现有的mget/mset指令;对于各种不同类型的更新操作,可使用lua脚本将命令打包后,发送到服务器端一次执行。

事务执行命令

multi -> 启动一个事务
incr t1 -> 添加该命令到队列中
incr t2 -> 添加该命令到队列中
discard -> 事务回滚
exec -> 执行

watch命令(基于CAS的乐观锁)

在multi命令执行之前,可以指定待监控的Keys,然而在执行exec时,如果被监控的Keys发生修改,exec将放弃执行该事务队列中的所有命令。

多客户端并发执行情况下出现竞态争用,伪代码如下:

val = get mykey
val = val + 1
set mykey $val

客户端A和B都在同一时刻读取了mykey的原有值,假设该值为10,此后两个客户端又均将该值加1后set回Redis服务器,这样就会导致mykey的结果为11,而不是我们认为的12。

watch命令可用于提供基于CAS的乐观锁,伪代码如下:

watch mykey
val = get mykey
val = val + 1
multi
set mykey $val
exec

如果当前连接获取的mykey的值被其它连接的客户端修改,那么当前连接的exec命令将执行失败。

读写键空间时的维护操作

  1. 在读取一个键之后(读操作和写操作都要对键进行读取),服务器会根据键是否存在来更新服务器的键空间命中(hit) 次数或键空间不命中(miss)次数,这两个值可以在INFO stats 命令的keyspace_hits属性和keyspace_misses属性中查看。

  2. 在读取一个键之后,服务器会更新键的LRU(最后一次使用)时间,这个值可以用于计算键的闲置时间,使用Object idletime <key> 命令可以查看键key的闲置时间。

  3. 如果服务器在读取一个键时发现该键已经过期,那么服务器会先删除这个过期键,然后才执行余下的其他操作。

  4. 服务器每次修改一个键之后,都会对脏( dirty ) 键计数器的值增1 ,这个计数器会触发服务器的持久化操作。

  5. 如果服务器开启了数据库通知功能,那么在对键进行修改之后,服务器将按配置发送相应的数据库通知。

键删除策略

redis使用惰性删除定期删除两种策略来删除过期的键:惰性删除策略只在碰到过期键时才进行删除操作,定期删除策略则每隔一段时间主动查找并删除过期键。通过配合使用这两种策略,服务器可以很好地在合理使用CPU时间和避免浪费内存空间之间取得平衡。

数据库通知

可以让客户端通过订阅通知的方式,来获知数据库中键的变化,以及数据库中命令的执行情况。通知有两种类型:

  • 键空间通知(关注某个键执行了什么命令)

    subscribe __keyspace@0__:aaa //客户端订阅键空间通知,0指0号数据库

  • 键事件通知(关注某个命令被什么键执行了)

    subscirbe __keyevent@0__:set //客户端订阅键事件通知

服务器配置的notify-keyspace-events选项决定了服务器所发送通知的类型:

  • 想让服务器发送所有类型的键空间通知和键事件通知,可以将选项的值设置为AKE。

  • 想让服务器发送所有类型的键空间通知,可以将选项的值设置为AK。

  • 想让服务器发送所有类型的键事件通知,可以将选项的值设置为AE。

  • 想让服务器只发送和字符串键有关的键空间通知,可以将选项的值设置为K$。

  • 想让服务器只发送和列表键有关的键事件通知,可以将选项的值设置为El。

redis性能

设置key回收策略

redis默认配置不会回收key,当redis内存使用率超过可用内存的95%时,会触发内存交换(严重影响性能);通过设置maxmemory为系统可用内存的45%或95%和设置maxmemory-policy可以比较准确的限制redis最大内存使用率,在绝大多数场景下可确保redis不会进行内存交换。

若是启用了rdb持久化功能,应该设置maxmemory值为系统可使用内存的45%。因为rdb需要一倍的内存来复制整个数据集,也就是说如果当前已使用45%,在持久化期间会变成95%(45%+45%+5%),其中5%是预留给其他的开销。 如果没开启rdb持久化功能,maxmemory最高能设置为系统可用内存的95%。

当used_memory达到最大阈值maxmemory时,会触发数据淘汰,即回收key。
info evicted_keys可以看到淘汰的key数量。淘汰策略取决于maxmemory-policy:

volatile-lru: //使用LRU算法从已设置过期时间的数据集合中淘汰数据
volatile-ttl: //从已设置过期时间的数据集合中挑选即将过期的数据淘汰
volatile-random: //从已设置过期时间的数据集合中随机挑选数据淘汰
allkeys-lru: //使用LRU算法从所有数据集合中淘汰数据
allkeys-random: //从数据集合中任意选择数据淘汰
noenviction: //禁止淘汰数据

命令响应时延

监控

redis学习笔记-事务、键空间的维护与性能

处理方法

redis学习笔记-事务、键空间的维护与性能

点赞
收藏
评论区
推荐文章
Stella981 Stella981
3年前
Redis事务,持久化,哨兵机制
1Redis事务基本事务指令Redis提供了一定的事务支持,可以保证一组操作原子执行不被打断,但是如果执行中出现错误,事务不能回滚,Redis未提供回滚支持。multi 开启事务exec 执行事务127.0.0.1:6379multiOK127.0.0.
Easter79 Easter79
3年前
TiDB 性能竞赛 11.16
TiDB实现了快照隔离级别的分布式事务,支持悲观锁、乐观锁,同时也解决了大事务的难点。事务是数据库的基础,提供高效的、支持完整ACID的分布式事务更是分布式数据库的立足之本。事务是数据库执行的最小单元,允许用户将多个读写操作组合为一个逻辑单元。事务需要满足原子性、一致性、隔离性和持久性,也就是ACID。数据库有多种并发控制方法,乐观并发控制(
Easter79 Easter79
3年前
Spring事务(二):Spring事务的特点
事务特性实现事务必须满足以下四大特性:Atomicity(原子性):构成事务的的所有操作必须是一个逻辑单元,要么全部执行,要么全部不执行。Consistency(一致性):数据库在事务执行前后,完整性没有被破坏。(转账前后,钱的总数不变)Durability(持久性):事务执行成功后必须全部写入磁盘。
Stella981 Stella981
3年前
Redis笔记总结
四、事务  Redis中的事务是一组命令的集合。事务同命令一样都是Redis的最小执行单位,一个事务的命令要么全部执行,要么全部不执行。  事务的原理是先将一个事务的命令发给Redis,然后再让Redis依次执行这些命令。  需要注意的是Redis并没有提过像关系型数据库那样的回滚功能!不过由于Redis不支持回滚,这也使得Redis在事
Stella981 Stella981
3年前
Redis pipeline(12)
常规的连接客户端一般有3种请求方式:1.Client2.Pipeline3.事务三中模式的区别Client模式:就是客户端发送一个命令,阻塞等待服务端执行,然后读取返回结果。Pipeline模式:是一次性发送多个命令,最后一次取回所有的返回结果,这种模式通过减少网络的往返时间和io读写次数,大幅度提高通信性能。事
Stella981 Stella981
3年前
Redis 事务(8)
为什么要用事务Redis的单个命令是原子性的(比如getsetmgetmset),如果涉及到多个命令的时候,需要把多个命令作为一个不可分割的处理序列,就需要用到事务。例如我们之前说的用setnx实现分布式锁,我们先set,然后设置对key设置expire,防止del发生异常的时候锁不会被释放,业务处理完了以后再del,这三个动作我们就
Stella981 Stella981
3年前
Redis高级特性
redis的事务(transaction)转载:https://blog.csdn.net/fmwind/article/details/78065236redis中的事务是一组命令的集合。事务同命令一样都是redis的最小执行单元。一组事务中的命令要么都执行,要么都不执行。(例如:转账)原理:先
Wesley13 Wesley13
3年前
MySQL 事务的四大特性ACID介绍
事务的四大特性(ACID)1、原子性(Atomicity)事务是一个不可分割的单位,事务中的所有SQL等操作要么都发生,要么都不发生。2、一致性(Consistency)事务发生前和发生后,数据的完整性必须保持一致。3、隔离性(Isolation)当并发访问数据库时,一个正在执行的事务在执行完毕前,对应其他的会话是不可见的,多个并发事
Stella981 Stella981
3年前
Redis 事务
Redis事务一、理论1.是什么:    可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不许加塞。2.作用:    一个队列中,一次性、顺序性、排他性地执行一系列命令3.常用命令:    通过MUL
Wesley13 Wesley13
3年前
MySQL常见问题
事务四大特性原子性:不可分割的操作单元,事务中所有操作,要么全部成功;要么撤回到执行事务之前的状态一致性:如果在执行事务之前数据库是一致的,那么在执行事务之后数据库也还是一致的;隔离性:事务操作之间彼此独立和透明互不影响。事务独立运行。这通常使用锁来实现。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。
3A网络 3A网络
2年前
Lua 脚本在 Redis 事务中的应用实践
Lua脚本在Redis事务中的应用实践使用过Redis事务的应该清楚,Redis事务实现是通过打包多条命令,单独的隔离操作,事务中的所有命令都会按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。事务中的命令要