文章目录
Redis单线程和高性能
所有数据都在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);采用单线程,避免了不必要的上下文切换的性能消耗。
因为Redis是单线程,所以使用Redis指令时需要注意谨慎使用耗时的指令,如keys,避免Redis出现卡顿。
Redis单线程如何处理并发客户端连接
基于IO多路复用,redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器。
Redis默认最大连接数是10000:
ocalhost:6379> config get maxclients
1) "maxclients"
2) "10000"
根据官方的测试,10000连接数QPS约9000,如图:
常见5种数据结构
字符串(String),散列(Hash),列表(List),集合(Set),有序集合(Sorted Sets)
String
应用场景
- 单值缓存
set key value
get key
- 对象缓存
set user:1 value
mset user:1:name Cherry user:1:age 18
mget user:1:name user:1:age
- 分布式锁
setnx user:1 true ex 5 nx <!-- 返回1代表获取锁成功,加"ex 5 nx"是为了防止程序中断了导致死锁 -->
setnx user:1 true ex 5 nx # <!-- 返回0代表获取锁失败,加"ex 5 nx"是为了防止程序中断了导致死锁 -->
<!-- ... 执行业务代码 -->
del user:1
- 计数器(文章阅读量,点赞等)
incr article:readCount:{id}
-
session共享
spring session + redis 实现分布式session共享 -
分布式系统全局序列号(自增id,订单id等)
incrby userId 10000
<!-- 每个服务批量获取id,不需要频繁操作redis -->
Hash
优点:
- 相比string操作消耗内存和cpu更少
- 比string节省空间
缺点:
- 过期功能只能设置在key上,不能作用在field上
- Redis集群下不适合大规模使用
应用场景
- 对象缓存
hmset user {userId}:name Cherry {userId}:age 18
- 购物车实现
用户id未key,商品id为field,商品数量为value
hset cart:{userId} {productId} productCount
假设用户id是userId1,商品id是product1:
-
添加一件商品到购物车:
hset cart:userId1 product1 1
-
增加商品数量
hincrby cart:userId1 product1 1
-
购物车删除商品
hdel cart:userId1 product1
-
获取商品总数
hlen cart:userId1
-
获取购物车所有商品
hgetall cart:userId1
List
两个阻塞指令
blpop:从列表表头弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout设置成0,则一直等待。
brpop:从列表表尾弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout设置成0,则一直等待。
应用场景
- 实现栈和队列数据结构
栈(FILO):
lpush + lpop
队列:
lpush + rpop
阻塞队列:
lpush + brpop
- 微博和微信公众号发送和查看消息
场景描述:用户A关注了汽车之家和本地宝两个公众号:
1. 汽车之家推送新消息时,往用户A的消息队列插入这条消息id
lpush msg:{用户A的ID} {id}
1. 本地宝推送新消息时,往用户A的消息队列插入这条消息id
lpush msg:{用户A的ID} {id}
2. 用户A查看最新消息
lrange msg:{用户A的ID} 0 5
Set
指令
srandmember key [count]
从集合中选出count个元素,元素不从key中删除
spop key [count]
从集合中选出count个元素,元素从key中删除
应用场景
抽奖活动
- 参与抽奖,加入集合
sadd key {userId}
- 查看参与抽奖所有用户
smembers key
- 抽取count名中奖者
srandmember key [count]
(或spop key [count])
点赞,收藏,标签
- 点赞
sadd like:{messagId} {userId}
- 取消点赞
srem like:{messagId} {userId}
- 检查用户是否点赞
sismember like:{messagId} {userId}
- 获取点赞用户列表
smembers like:{messagId}
- 获取点赞用户数
scard like:{messagId}
集合操作,微博微信关注功能模型
交集:sinter set1 set2 set3
结果:{a}
并集:sunion set1 set2 set3
结果:{a,b,c,d,e,f}
差集(以第一个元素为基准):sdiff set1 set2 set3
结果:{b}
微博微信关注功能模型
-
我关注的人
me: {tangyan, luojin,eryingzhang} -
唐嫣关注的人
tangyan: {luojin} -
罗晋关注的人
luojin: {tangyan} -
我和罗晋共同关注的人
sinter me tangyan --> {luojin} -
我关注的人也关注他(唐嫣)
sismember luojin tangyan
sismember eryingzhang tangyan -
我可能认识的人
sdiff luojin me
购物网站商品筛选
如上图,通过redis维护各个筛选参数:
sadd brand:lenovo T50
sadd brand:apple macbook-pro-2020
sadd ram:16G T50 2020
sinter brand:apple ram:16G 可以查询出结果:{macbook-pro-2020}
ZSET
集合操作
- zunionstore destKey numberkeys key[key…]:并集计算
- zinterstore destKey numberkeys key[key…]:交集计算
排行榜
-
点击新闻
incryby hotNews:{日期20200701} 1 {newsId} -
查询排前10的新闻
zrevrange hotNews:20200701 0, 9 withscores -
查询7天搜索榜单
zunionstore hotNews:20200701-20200707 7 hotNews:20200701 hotNews:20200702 hotNews:20200703 hotNews:20200704 hotNews:20200705 hotNews:20200706 hotNews:20200707 -
7天排行前十榜单
zinterstore hotNews:20200701-20200707 0 9 withscores