redis学习_Redis学习笔记归纳(第四部分:Redis高级)

9db5af384f3f4798f77a33e55cfbdd44.png

写在开头:

本章是Redis学习归纳第四部分,着重于归纳redis发布与订阅,事务,Lua脚本,慢查询日志和监视器的笔记。

文章内容输出来源:拉勾教育大数据高薪训练营。

Redis高级部分是整个redis中较为重要的部分,在学习时经常会遇到概念不清和配置错误的问题,这里感谢导师Bob的帮助。

发布与订阅

Redis提供了发布订阅功能,可以用于消息的传输,Redis的发布订阅机制包括三个部分,publisher,subscriber和Channel 。

c4c5c83b4f83bb363f73c4eb81be9e6b.png

发布者和订阅者都是Redis客户端,Channel则为Redis服务器端。

发布者将消息发送到某个的频道,订阅了这个频道的订阅者就能接收到这条消息。

频道/模式的订阅与退订

subscribe:订阅 subscribe channel1 channel2 ..

Redis客户端1订阅频道1和频道2

28fc16b3990ba659f241395591aa30b9.png

publish:发布消息 publish channel message

Redis客户端2将消息发布在频道1和频道2上

e545007c031414184736f2f534a8a70a.png

Redis客户端1接收到频道1和频道2的消息

6178f8268723f5be745defbbd23b349c.png

unsubscribe:退订 channel

Redis客户端1退订频道1

e162d6e0379c21c1417360f2eab83f3a.png

psubscribe :模式匹配 psubscribe +模式

Redis客户端1订阅所有以ch开头的频道

056b2346225286dca0bfaffd14d6e5ce.png

Redis客户端2发布信息在频道5上

177a48971c2077559476965974ab3928.png

Redis客户端1收到频道5的信息

782f0e880d68fdb070e40d142d7e365f.png

punsubscribe 退订模式

punsubscribe ch*

0c9e932a5f83437339d3991f60e0aeef.png

发布订阅的机制

订阅某个频道或模式:

客户端(client):

属性为pubsub_channels,该属性表明了该客户端订阅的所有频道

属性为pubsub_patterns,该属性表示该客户端订阅的所有模式

服务器端(RedisServer):

属性为pubsub_channels,该服务器端中的所有频道以及订阅了这个频道的客户端

属性为pubsub_patterns,该服务器端中的所有模式和订阅了这些模式的客户端

d57a2a5b6f3941ad19b378ff8f5c2c37.png

当客户端向某个频道发送消息时,Redis首先在redisServer中的pubsub_channels中找出键为该频道的结点,遍历该结点的值,即遍历订阅了该频道的所有客户端,将消息发送给这些客户端。

然后,遍历结构体redisServer中的pubsub_patterns,找出包含该频道的模式的结点,将消息发送给订阅了该模式的客户端。

使用场景:哨兵模式,Redisson框架使用

在Redis哨兵模式中,哨兵通过发布与订阅的方式与Redis主服务器和Redis从服务器进行通信。这个我们将在后面的章节中详细讲解。

Redisson是一个分布式锁框架,在Redisson分布式锁释放的时候,是使用发布与订阅的方式通知的,这个我们将在后面的章节中详细讲解。

事务

所谓事务(Transaction) ,是指作为单个逻辑工作单元执行的一系列操作。

ACID回顾

  1. Atomicity(原子性):构成事务的的所有操作必须是一个逻辑单元,要么全部执行,要么全部不执行。 Redis:一个队列中的命令 执行或不执行
  2. Consistency(一致性):数据库在事务执行前后状态都必须是稳定的或者是一致的。 Redis: 集群中不能保证时时的一致性,只能是最终一致性
  3. Isolation(隔离性):事务之间不会相互影响。 Redis: 命令是顺序执行的,在一个事务中,有可能被执行其他客户端的命令的
  4. Durability(持久性):事务执行成功后必须全部写入磁盘。 Redis有持久化但不保证 数据的完整性

Redis事务

  • Redis的事务是通过multi、exec、discard和watch这四个命令来完成的。
  • Redis的单个命令都是原子性的,所以这里需要确保事务性的对象是命令集合。
  • Redis将命令集合序列化并确保处于同一事务的命令集合连续且不被打断的执行
  • Redis不支持回滚操作

事务命令

multi:用于标记事务块的开始,Redis会将后续的命令逐个放入队列中,然后使用exec原子化地执行这个命令队列

exec:执行命令队列

discard:清除命令队列

watch:监视key

unwatch:清除监视key

9e67d043e30e78fdcc64e8d6399dbefa.png

命令书写:

1。开始一个事务,写两个命令,然后执行

c7b1bada3cfe81ae3a34fa3c3229768e.png

2。使用discard命令清楚队列,这时调用exec就会报错。

f7449e6959a41e0f864ee32576dc7335.png

3。使用watch命令监视一个key,在执行exec之前,用另一个客户端修改s1的值,然后就监视到了s1的变化,那么这里就会修改失败。

80e37445fe6e155f11d69834af37972e.png

事务机制

事务的执行

1. 事务开始

在RedisClient中,有属性flags,用来表示是否在事务中

flags=REDIS_MULTI

2. 命令入队

RedisClient将命令存放在事务队列中 (EXEC,DISCARD,WATCH,MULTI除外)

3. 事务队列

multiCmd *commands 用于存放命令

4. 执行事务

RedisClient向服务器端发送exec命令,RedisServer会遍历事务队列,执行队列中的命令,最后将执行的结果一次性返回给客户端。

如果某条命令在入队过程中发生错误,redisClient将flags置为REDIS_DIRTY_EXEC,EXEC命令将会失败返回。

cf36f638fab22336470a827fd67a4579.png

6598a95edf3f08759cef0e7337e6422f.png

Watch的执行

使用WATCH命令监视数据库键

redisDb有一个watched_keys字典,key是某个被监视的数据的key,值是一个链表.记录了所有监视这个数据的客户端。

监视机制的触发

当修改数据后,监视这个数据的客户端的flags置为REDIS_DIRTY_CAS

事务执行

RedisClient向服务器端发送exec命令,服务器判断RedisClient的flags,如果为REDIS_DIRTY_CAS,则清空事务队列。

208214e73b805c05b181e7f910beb509.png

8ac82f09a0e247c64953d9da37feda9e.png

Redis的弱事务性

1。Redis语法错误

整个事务的命令在队列里都清除

0bc431e37e55322c85c9162669fec5d2.png

flags=REDIS_DIRTY_EXEC

2。运行错误

在队列里正确的命令可以执行 (弱事务性)

弱事务性 :

1、在队列里正确的命令可以执行 (非原子操作)

2、不支持回滚

596027aa32abe7a8c783e80ef9b303d2.png

3。Redis不支持事务回滚(为什么呢)

1、大多数事务失败是因为语法错误或者类型错误,这两种错误,在开发阶段都是可以预见的

2、Redis为了性能方面就忽略了事务回滚。 (回滚记录历史版本)

Lua脚本

lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

Lua应用场景:游戏开发、独立应用脚本、Web应用脚本、扩展和数据库插件

nginx上使用lua 实现高并发

Lua环境协作组件

从Redis2.6.0版本开始,通过内置的lua编译/解释器,可以使用EVAL命令对lua脚本进行求值。

脚本的命令是原子的,RedisServer在执行脚本命令中,不允许插入新的命令

脚本的命令可以复制,RedisServer在获得脚本后不执行,生成标识返回,Client根据标识就可以随时执行

EVAL/EVALSHA命令实现

EVAL命令

通过执行redis的eval命令,可以运行一段lua脚本。

2bd9b9e814330cf274a7a0c144f4eacd.png

命令说明:

  • script参数:是一段Lua脚本程序,它会被运行在Redis服务器上下文中,这段脚本不必(也不应该)定义为一个Lua函数。
  • numkeys参数:用于指定键名参数的个数
  • key [key ...]参数: 从EVAL的第三个参数开始算起,使用了numkeys个键(key),表示在脚本中所用到的那些Redis键(key),这些键名参数可以在Lua中通过全局变量KEYS数组,用1为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。
  • arg [arg ...]参数:可以在Lua中通过全局变量ARGV数组访问,访问的形式和KEYS变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)
eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second

lua脚本中调用Redis命令

redis.call():

  • 返回值就是redis命令执行的返回值
  • 如果出错,则返回错误信息,不继续执行

redis.pcall():

  • 返回值就是redis命令执行的返回值
  • 如果出错,则记录错误信息,继续执行

注意事项

在脚本中,使用return语句将返回值返回给客户端,如果没有return,则返回nil

eval "return redis.call('set',KEYS[1],ARGV[1])" 1 n1 zhaoyun 

慢查询日志

我们都知道MySQL有慢查询日志

Redis也有慢查询日志,可用于监视和优化查询

慢查询设置

在redis.conf中可以配置和慢查询日志相关的选项:

#执行时间超过多少微秒的命令请求会被记录到日志上 0 :全记录 <0 不记录 
slowlog-log-slower-than 10000 
#slowlog-max-len 存储慢查询日志条数 
slowlog-max-len 128 

Redis使用列表存储慢查询日志,采用队列方式(FIFO)

config set的方式可以临时设置,redis重启后就无效

config set slowlog-log-slower-than 微秒 config set slowlog-max-len 条数

查看日志:slowlog get [n]

127.0.0.1:6379> config set slowlog-log-slower-than 0 
OK
127.0.0.1:6379> config set slowlog-max-len 2 
OK
127.0.0.1:6379> set name:001 zhaoyun 
OK
127.0.0.1:6379> set name:002 zhangfei
OK
127.0.0.1:6379> get name:002 
"zhangfei" 
127.0.0.1:6379> slowlog get 
1) 1) (integer) 7 #日志的唯一标识符(uid) 
2) (integer) 1589774302 #命令执行时的UNIX时间戳 
3) (integer) 65 #命令执行的时长(微秒) 
4) 1) "get" #执行命令及参数 
2) "name:002" 
5) "127.0.0.1:37277" 
6) "" 
2) 1) (integer) 6 
2) (integer) 1589774281 
3) (integer) 7 
4) 1) "set" 
2) "name:002" 
3) "zhangfei" 
5) "127.0.0.1:37277" 
6) "" 
# set和get都记录,第一条被移除了。

慢查询记录的保存

在redisServer中保存和慢查询日志相关的信息

2ca064e5541e734dcb6fe67e25635811.png

4500b9218c2729fc4f695b118970d2e5.png

941d95a6559d9553b4e444ae4db1ac2f.png

慢查询日志的阅览&删除

d8b613bc57fe0db0b79d689677aa8d50.png

获得慢查询日志记录

e9e1b3fac878b2a163fb0f1eab867582.png

查看日志数量的

slowlog len

7f92f6b885476d5bf7139a36438c9fbc.png

清除日志

slowlog reset

9b1825dd2067aa14437029c2f8ff394e.png

监视器

Redis客户端通过执行MONITOR命令可以将自己变为一个监视器,实时地接受并打印出服务器当前处理的命令请求的相关信息。

此时,当其他客户端向服务器发送一条命令请求时,服务器除了会处理这条命令请求之外,还会将这条命令请求的信息发送给所有监视器。

b6c0f2bdc82ceb7c3a1c03fad764dc32.png

在一个客户端上:

11770ddd57b16b8e23da428c4cbf5360.png

在另一个客户端上:

594ddb9c936e95c01557a21b47235a5a.png

Redis监控平台

grafana、prometheus以及redis_exporter。

Grafana 是一个开箱即用的可视化工具,具有功能齐全的度量仪表盘和图形编辑器,有灵活丰富的图形化选项,可以混合多种风格,支持多个数据源特点。

Prometheus是一个开源的服务监控系统,它通过HTTP协议从远程的机器收集数据并存储在本地的时序数据库上。

redis_exporter为Prometheus提供了redis指标的导出,配合Prometheus以及grafana进行可视化及监控。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
尚硅谷是一个教育机构,他们提供了一份关于Redis学习笔记。根据提供的引用内容,我们可以了解到他们提到了一些关于Redis配置和使用的内容。 首先,在引用中提到了通过执行命令"vi /redis-6.2.6/redis.conf"来编辑Redis配置文件。这个命令可以让你进入只读模式来查询"daemonize"配置项的位置。 在引用中提到了Redis会根据键值计算出应该送往的插槽,并且如果不是该客户端对应服务器的插槽,Redis会报错并告知应该前往的Redis实例的地址和端口。 在引用中提到了通过修改Redis的配置文件来指定Redis的日志文件位置。可以使用命令"sudo vim /etc/redis.conf"来编辑Redis的配置文件,并且在文件中指定日志文件的位置。 通过这些引用内容,我们可以得出结论,尚硅谷的Redis学习笔记涵盖了关于Redis的配置和使用的内容,并提供了一些相关的命令和操作示例。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Redis学习笔记--尚硅谷](https://blog.csdn.net/HHCS231/article/details/123637379)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Redis学习笔记——尚硅谷](https://blog.csdn.net/qq_48092631/article/details/129662119)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值