Redis
命令中心
这些篇文章专门以应用为主,原理性的后续博主复习到的时候再详细阐述
set
集合,为了描述它的特征,我们可称呼为无序集合;集合的特征是唯一,集合中的元素是唯一存在 的;
存储结构
元素都为整数且节点数量少时,使用整数数组存储;否则使用字典存储;
基础命令
# 添加一个或多个指定的member元素到集合的 key中
SADD key member [member ...]
# 计算集合元素个数
SCARD key
# SMEMBERS key
SMEMBERS key
# 返回成员 member 是否是存储的集合 key的成员
SISMEMBER key member
# 随机返回key集合中的一个或者多个元素,不删除这些元素
SRANDMEMBER key [count]
# 从存储在key的集合中移除并返回一个或多个随机元素
SPOP key [count]
# 返回一个集合与给定集合的差集的元素
SDIFF key [key ...]
# 返回指定所有的集合的成员的交集
SINTER key [key ...]
# 返回给定的多个集合的并集中的所有成员
SUNION key [key ...]
应用
抽奖
# 添加抽奖用户
sadd Award:1 10001 10002 10003 10004 10005 10006
sadd Award:1 10009
# 查看所有抽奖用户
smembers Award:1
# 抽取多名幸运用户
srandmember Award:1 10
# 如果抽取一等奖1名,二等奖2名,三等奖3名,该如何操作
共同关注
sadd follow:A person1 person2 person3 person4 person5
sadd follow:C person3 person4
# 交集
sinter follow:A follow:C
推荐好友
sadd follow:A person1 person2 person3 person4 person5
sadd follow:C person3 person4
# C可能认识的人:
sdiff follow:A follow:C
zset
有序集合;它的特征是有序唯一的集合;通常用来实现排行榜;
基础命令
# 添加到键为key有序集合(sorted set)里面
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
# 从键为key有序集合中删除 member 的键值对
ZREM key member [member ...]
# 返回有序集key中,成员member的score值
ZSCORE key member
# 为有序集key的成员member的score值加上增量increment
ZINCRBY key increment member
# 返回key的有序集元素个数
ZCARD key
# 返回有序集key中成员member的排名
ZRANK key member
# 返回存储在有序集合key中的指定范围的元素 order by id limit 1,100
ZRANGE key start stop [WITHSCORES]
# 返回有序集合key中,分数在min和max之间的所有元素(且包含min和max); limit 指定从第几个开始返回多少个元素
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
有序集合比较规则,先通过比较 score 来确定排序,如果 score 相同则比较 member; member 比较规则是按照字母顺序来进行比较;
存储结构
节点数量少且字符串长度小时使用压缩列表存储;否则使用跳表来进行存储;
应用
热榜
# 点击新闻:
zincrby hot:20210601 1 10001
zincrby hot:20210601 1 10002
zincrby hot:20210601 1 10003
zincrby hot:20210601 1 10004
zincrby hot:20210601 1 10005
zincrby hot:20210601 1 10006
zincrby hot:20210601 1 10007
zincrby hot:20210601 1 10008
zincrby hot:20210601 1 10009
zincrby hot:20210601 1 10010
# 获取排行榜:
zrevrange hot:20210601 0 9 withscores
延时队列
将消息序列化成一个字符串作为 zset 的 member;这个消息的到期处理时间作为 score,然后用 多个线程轮询 zset 获取到期的任务进行处理。
# delay thread
zadd delay:1 now+5 task1
zadd delay:1 now+10 task2
# check thread
# for {
# vals :=
zrangebyscore delay:1 0 now limit 0 1
# val := vals[0]
zrem delay:1 val
# handle(val)
# }
分布式定时器
生产者将定时任务 hash 到不同的 redis 实体中,为每一个 redis 实体分配一个 dispatcher 进 程,用来定时获取 redis 中超时事件并发布到不同的消费者中
时间窗口限流
限流是窗口移动,在一个窗口内限流比如六秒窗口:1s-7s, 2-8s, 3s-9s
熔断则是分成一个个时间区间,区间内不能超过多少次请求:1s-6s, 7s-12s
# 指定用户 user_id 的某个行为 action 在特定时间内 period 只允许发生操作次数
max_count
# key limit:10001:action1
# now 时间单位为 毫秒
zadd limit:10001:action1 now now
# 删除score 在0~now-period*1000 内的元素,保留最近period*1000 内的元素
zremrangebyscore limit:10001:action1 0 now - period*1000
# count =
zcard limit:10001:action1
expire limit:10001:action1 60+1
# 比较 count 与 max_count
# 如果 count > max_count 说明超过次数;否则没有超过限定次数
# 第二种实现
# 比较 string + expire
# val =
incr limit:10001:action1
# val =
incr limit:10001:action1
expire limit:10001:action1 60+1