《Redis设计与实现》学习笔记-发布与订阅、事务、慢查询日志

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
日志服务 SLS,月写入数据量 50GB 1个月
简介:

发布与订阅

Redis通过发布订阅提供一对多甚至是多对多的节点消息通信,发布订阅由PUBLISH、SUBSCRIBE、PSUBSCRIBE、PUBSUB等命令组成。

  • SUBSCRIBE命令:订阅某频道,在redisServer结构中通过pubsub_channels字典属性保存当前服务器所有频道的订阅关系,字典键时频道名称,字典值是一个链表,记录了所有订阅这个频道的客户端。
  • UNSUBSCRIBE命令:退订频道,调用该命令之后,会把订阅关系从pubsub_channels中删掉,如果键对应的链表为空了,则把键从字典中删除。
  • PSUBSCRIBE命令:订阅模式,服务器将所有的模式订阅关系保存在redisServer结构的pubsub_patterns属性中,该属性是一个链表,每个链表节点包含一个pubsubPattern结构,该结构记录了被订阅的模式和订阅该模式的客户端。
  • PUNSUBSCRIBE命令:退订模式,调用该命令之后,服务器会遍历pubsub_patterns链表,把客户端和模式都匹配的那个节点删除。
  • PUBLISH命令:发送订阅消息,服务器接收到该命令之后,先遍历pubsub_channels找出频道订阅者,把消息发送给所有频道订阅者,然后遍历pubsub_patterns找出与channel匹配的模式,并将消息发送给订阅了这些模式的客户端。
  • PUBSUB命令,查看订阅信息包含下面三个子命令:
  • PUBSUB CHANNLES [pattern]:返回当前服务器被订阅的频道,如指定pattern,则返回与模式匹配的频道
  • PUBSUB NUMSUB [channel-1 ... channel-n]:返回指定频道的订阅者数量
  • PUBSUB NUMPAT:返回服务器当前被订阅模式的数量

事务

Redis通过MULTI、EXEC、WATCH等命令来实现事务功能,实现将多个命令打包然后一次性顺序执行。事务以MULTI命令开始,EXEC命令结束。在执行MULTI命令之后执行的命令不立刻执行,而是向客户端返回一个QUEUED,等执行EXEC命令之后再执行。

事务的实现

事务开始

执行MULTI命令之后,服务器把客户端从非事务态切换到事务态,通过设置redisClient的flags标识,把REDIS_MULTI标识打开。

命令入队

客户端处于非事务态时,客户端发送的命令立刻执行,当处于事务态时:

如果客户端发送的命令为EXEC、DISCARD、WATCH、MULTI其中的一个时,服务器立即执行。
如果客户端发送的命令是其它的命令,服务器不会立刻执行这个命令,而是把命令放到事务队列中,然后向客户端返回QUEUED。
redisClient中有个multiState结构的属性mstate记录客户端的事务状态,在multiState结构中有个commands列表属性,它记录了调用MULTI之后该客户端入队的命令,count属性记录入队命令的数量。multiCmd结构记录命令实现函数指针,命令的参数,已经参数的数量。事务队列以FIFO的方式保存入队命令,先入队的命令先执行。
执行事务
执行EXEC命令提交事务,服务器接收该命令之后:

  1. 遍历client.mstate.commands,获取已入队的命令并且挨个执行,把命令的返回值添加到回复队列尾部。
  2. 清空客户端的事务状态,包括清零入队命令计数器,释放事务队列。
  3. 把执行结果返回给客户端。

WATCH命令实现

WATCH命令是一个乐观锁,在执行EXEC之前监视制定的数据库键,在执行EXEC命令执行时检查被监视的键是否至少有一个已经被修改过,如果是的话,服务器拒绝执行命令,并向客户端返回代表事务执行失败的空回复。
Redis数据库的redisDb结构保存了一个watched_keys字典,字典的键时某个被WATCH命令监视的键,值是一个链表,链表中记录了所有监视相应数据库键的客户端。
在执行对数据库修改的命令时,执行之后会调用multi.c/touchWatchKey函数对watched_keys字典进行检查,查看是否有客户端正在监视刚刚被命令修改过的数据库键,如果有的话,touchWatchKey函数将监视被修改键的客户端的REDIS_DIRTY_CAS标识打开,表示该客户端的事务安全性已经被破坏。当服务器接收到一个客户端发来的EXEC命令时,服务器根据这个客户端是否打开了REDIS_DIRTY_CAS标识来决定是否执行事务。

事务的ACID

原子性:对Redis事务来说,事务中的多个命令被当做一个整体,事务队列中的命令要么全部被执行,要么都不执行,Redis事务时具有原子性的,但是Redis事务部支持回滚,即使队列中某个命令执行出现了错误也不影响后面的命令,整个事务会继续执行。
一致性:在命令入队错误、执行错误、服务器停机时都不会影响数据库的一致性。ps:当入队错误时对2.6.5之前的版本事务会继续执行,2.6.5之后事务会被拒绝执行
隔离性:Redis事务执行期间不会被其它命令中断,以串行的方式运行,Redis事务是具有隔离性的
持久性:

  • 当服务器运行在无持久化的内存模式下时,事务不具有持久性:一旦服务器停机,所有数据都会丢失
  • 当服务器运行在RDB持久化模式下时,当服务器停机时会有一段时间的数据会丢失,事务不具有持久性
  • 当服务器运行在AOF持久化模式下,并且appendsync选项值为always时,数据会被及时保存到硬盘中,此时事务具有持久性(前提是没有打开no-appendfsync-on-rewrite选项,打开该选项之后,为了尽可能的减少IO操作,当服务器执行BGSAVE或BGREWRITEAOF时,会停止AOF文件同步,所以此时事务也不具有持久性)
  • 当服务器运行在AOF持久化模式下,并且appendsync选项值为everysec时,可能会丢失1秒的数据,此时事务不具有持久性
  • 当服务器运行在AOF持久化模式下,并且appendsync选项值为no,服务器停机时数据会丢失,此时事务不具有持久性

慢查询日志

Redis 的慢查询日志功能用于记录执行时间超过给定时长的命令请求, 用户可以通过这个功能产生的日志来监视和优化查询速度。

服务器配置有两个和慢查询日志相关的选项:

  • slowlog-log-slower-than 选项指定执行时间超过多少微秒(1 秒等于 1,000,000 微秒)的命令请求会被记录到日志上。

    举个例子, 如果这个选项的值为 100 , 那么执行时间超过 100 微秒的命令就会被记录到慢查询日志; 如果这个选项的值为 500 , 那么执行时间超过 500 微秒的命令就会被记录到慢查询日志; 诸如此类。

  • slowlog-max-len 选项指定服务器最多保存多少条慢查询日志。

    服务器使用先进先出的方式保存多条慢查询日志: 当服务器储存的慢查询日志数量等于 slowlog-max-len 选项的值时, 服务器在添加一条新的慢查询日志之前, 会先将最旧的一条慢查询日志删除。

    举个例子, 如果服务器 slowlog-max-len 的值为 100 , 并且假设服务器已经储存了 100 条慢查询日志, 那么如果服务器打算添加一条新日志的话, 它就必须先删除目前保存的最旧的那条日志, 然后再添加新日志。

原文链接:[http://wely.iteye.com/blog/2361639 ]
相关实践学习
基于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
目录
打赏
0
0
0
0
16429
分享
相关文章
|
6月前
|
Redis 事务
10月更文挑战第18天
64 1
【赵渝强老师】Redis的慢查询日志
Redis慢查询日志用于记录执行时间超过预设阈值的命令,帮助开发和运维人员定位性能问题。每条慢查询日志包含标识ID、发生时间戳、命令耗时及详细信息。配置参数包括`slowlog-max-len`(默认128)和`slowlog-log-slower-than`(默认10000微秒)。实战中可通过`slowlog get`获取日志、`slowlog len`查看长度、`slowlog reset`重置日志。建议线上环境将`slowlog-max-len`设为1000以上,并根据并发量调整`slowlog-log-slower-than`。需要注意的是,慢查询只记录命令执行时间。
188 5
|
4月前
|
Redis事务长什么样?一文带你全面了解
Redis事务是一组命令的有序队列,通过MULTI、EXEC、WATCH和DISCARD等命令实现原子性操作。事务中的命令在EXEC执行前不会实际运行,而是先进入队列,确保所有命令要么全部成功,要么全部失败。此外,Redis还支持Lua脚本实现类似事务的操作,通常更简单高效。事务适用于购物车结算、秒杀活动、排行榜更新等需要保证数据一致性的场景。
63 0
Pytorch学习笔记(七):F.softmax()和F.log_softmax函数详解
本文介绍了PyTorch中的F.softmax()和F.log_softmax()函数的语法、参数和使用示例,解释了它们在进行归一化处理时的作用和区别。
700 1
Pytorch学习笔记(七):F.softmax()和F.log_softmax函数详解
redis学习四、可视化操作工具链接 centos redis,付费Redis Desktop Manager和免费Another Redis DeskTop Manager下载、安装
本文介绍了Redis的两个可视化管理工具:付费的Redis Desktop Manager和免费的Another Redis DeskTop Manager,包括它们的下载、安装和使用方法,以及在使用Another Redis DeskTop Manager连接Redis时可能遇到的问题和解决方案。
231 1
redis学习四、可视化操作工具链接 centos redis,付费Redis Desktop Manager和免费Another Redis DeskTop Manager下载、安装
Docker学习二(Centos):Docker安装并运行redis(成功运行)
这篇文章介绍了在CentOS系统上使用Docker安装并运行Redis数据库的详细步骤,包括拉取Redis镜像、创建挂载目录、下载配置文件、修改配置以及使用Docker命令运行Redis容器,并检查运行状态和使用Navicat连接Redis。
663 3
【赵渝强老师】Redis的消息发布与订阅
本文介绍了Redis实现消息队列的两种场景:发布者订阅者模式和生产者消费者模式。其中,发布者订阅者模式通过channel频道进行解耦,订阅者监听特定channel的消息,当发布者向该channel发送消息时,所有订阅者都能接收到消息。文章还提供了相关操作命令及示例代码,展示了如何使用Redis实现消息的发布与订阅。
177 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
103 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
77 3
Tensorboard可视化学习笔记(一):如何可视化通过网页查看log日志
关于如何使用TensorBoard进行数据可视化的教程,包括TensorBoard的安装、配置环境变量、将数据写入TensorBoard、启动TensorBoard以及如何通过网页查看日志文件。
502 0

热门文章

最新文章