Redis高级应用

96 阅读3分钟

Redis高级应用

1、Redis与Lua脚本 Lua脚本类似于存储过程,可以把多个命令放在一个脚本中运行,Redis会将Lua脚本作为整体执行(原子性),中间不会有其他线程打断,因为Redis是单线程的,Lua会存储在Redis中,其他客户端可以复用同一个Lua脚本完成相同的功能。 (1)Redis中使用如下命令执行Lua脚本 |- script:Lua脚本; |- numkeys:作为参数的key的数量; |- key:参数key; |- arg:设置值; |- KEYS和ARGV区分大小写;

(2)可以将Lua脚本的保存起来(标识为sha1编码),使用evalsha命令执行

2、Redis结合Lua脚本实现限流 固定窗口(计数器)限流算法。 实现一个60s内最大访问量10次,将key设置为60s过期时间,然后每到一个请求,将key加1后判断是否超过阈值,将计算逻辑封装在Lua脚本中,就可以实现计算的原子性,从而使限流逻辑支持分布式。

Lua脚本如下

固定窗口算法在临界点容易发生大量流量涌入的情况,可以使用滑动窗口算法,演示如下 Selective Repeat Protocol (pearsoncmg.com) 此外,限流算法还有漏桶算法和令牌桶算法。

3、Redis实现发布订阅 (1)使用publish命令发布消息 |- 返回0表示没有订阅者,返回1表示有1个订阅者,数据会丢失,发送即忘,不推荐使用,新版本引入Stream数据结构; |- 客户端1发布消息

|- 客户端2使用subscribe命令订阅消息(首先启动订阅者)

(2)使用pubsub channels命令查看所有的频道 |- 支持通配符*筛选

(3)使用pubsub numsub命令查看指定频道的订阅者数量

(4)发布订阅模型

4、Redis Stream数据结构(MQ) Redis Stream参考了Kafka的设计,可以实现MQ的功能。 MQ的三大功能:解耦、异步、削峰。 群组消费:每个群组之间是独立的。

(1)xadd命令创建命令 |- *表示使用默认ID生成规则:毫秒时间戳-计数

|- 创建一个名为stream1的stream,存入键值对,id生成规则使用redis默认实现

(2)xrange命令查看stream中的消息 |- strat和end参数指消息的ID; |- (-,+)表示查询全部; |- COUNT参数可以指定查询的条数;

(3)xdel命令删除指定消息

(4)xread命令消费消息 |- 不写BLOCK则立即返回,不会阻塞,0表示一直阻塞 |- COUNT表示读取几条消息 |- ID表示表示从哪条消息开始读(不包含),特殊取值$表示从后往前读(该命令执行时间之前的消息不会读取)

(5)xinfo命令查看stream信息

|- stream1队列的信息

|- stream1上所有群组的信息

|- stream1上cg1群组的消费信息

群组消费 (1)xgroup命令创建消费群组 |- ID|$:从哪个消息开始消费;

|- 在stream1上创建名为cg1的消费群组

(2)xreadgroup命令进行群组消费 |- 该命令在多个客户端执行,每个客户端都会最为消费者加入该消费群组,信息不会重复消费

(3)acck命令确认消费(Redis需要手动ack确认,不能自动提交)

(4)xcalim命令实现客户端故障转移 (5)Stream的队列中,消息超过容量时,会干掉最老的那一条消息 |- PEL:pending队列,消费者待ACK确认的队列 |- PEL故障转移:客户端故障后,为确认的消息可以转移到其他消费者消费确认 |- 死信问题:一直没有ACK确认的问题,可以使用xdel命令删除,不要占用空间 |- 消息丢失:主从同步时会有丢失 |- 分区:Redis分区需要自己实现

5、Redis中的渐进式rehash Redis中的数据都是key-value结构,即hash表,那么如果发生hash表在扩容后rehash元素时,就会导致Redis进入IO阻塞,导致卡顿,Redis使用了渐进式rehash策略解决这个问题,即需要rehash时,每来一个客户端请求Redis时,顺带就rehash一个hash槽位的元素。