1.缓存相关概念
1.1 缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
解决方案:1.布隆过滤器(guava实现);2.从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
1.2 缓存击穿
缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
解决方案:1.热点数据永不过期;2.读取数据的时候加上互斥锁
1.3 缓存雪崩
缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
解决方案:缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
1.4 Redis常用数据结构
- string
- hash
- list
- set
- zset
2.运维篇
2.1 单机
简单易用,对于不重要的系统,单机够用
2.2 主从复制
图片1.png数据备份,但是主节点挂了,还是得人工切换
2.3 哨兵模式
图片2.png数据备份,主节点挂了,自动切换,高可用
2.4 集群
图片3.png数据备份,高可用,高并发,16384个slot,通过CRC函数确定分配的slot。若集群中的某个节点的主从节点都挂了,响应的slot均不可用。
3.应用场景篇
3.1 朋友圈点赞
图片1.png1)点赞
Sadd like:{消息ID} {用户ID}
2)取消点赞
Srem like:{消息ID} {用户ID}
3)检查用户是否点赞
Sismember like:{消息ID} {用户ID}
4)获取点赞的用户列表
Smembers like:{消息ID}
5)获取点赞用户数
Scard like:{消息ID}
3.2 人员关注
1)邹浩关注的人
ZouhaoSet -> {zhengpeng, liujianhui, weizepeng}
2)郑鹏关注的人
ZhengpengSet -> {chenwang, lanminchao, weizepeng}
3)敏超关注的人
lanminchaoSet -> {chenwang, zhengpeng, huanglehu}
4)我和郑鹏共同关注的人
SINTER ZouhaoSet ZhengpengSet -> {weizepeng}
5)我可能认识的人
Sdiff lanminchaoSet ZouhaoSet -> {chenwang, huanglehu}
6)我关注的人也关注他(敏超)
Sismember zhengpengSet lanminchao 判断郑鹏是否关注lanminchao
Sismember liujianhuiSet lanminchao 判断刘剑辉是否关注 lanminchao
3.3 人员关注消息通知
我关注了MacTalk,必胜客公众号
1)MackTalk发微博,消息ID为95557
lpush <msg:userid> 95557
2)必胜客发微博,消息为ID为95558
lpush <msg:userid> 95558
3)查看最新的微博消息
lrange <msg:userid> 0 5
3.4 排行榜
图片3.png1)点击新闻
zincrby hotnews:20200609 1 [newsId]
2)展示当日新闻前十
zrevrange hotnews:20200609 0 10 withscores
3)七日搜索榜单计算
zunionstore hotnews:20200609-20200616 7 hotnews:20200609 ... hotnews:20200616
合并后面7个zset集合,并且命名为hotnews:20200609-20200616
4)展示七日排行前十
zrevrange hotnews:20200609-2020-616 0 10 withscores
3.5 抽奖小程序
图片4.png1)点击参与抽奖
sadd <lottery:id> <user:id>
2)查看抽奖用户
smembers <lottery:id>
3)抽奖
sranmember <lottery:id> <count> 仅返回元素
spop <lottery:id> <count> 返回count个元素并删除
3.6 购物车
shopping-cart.JPG图片5.png
1)添加商品
hset <card:userid> <goodsid> <num>
2)增加数量
hincrby <card:userid> <goodsid> 1
3)商品总数
hlen <card:userid>
4)删除商品
hdel <card:userid> <goodsid>
5)获取购物车所有商品
hgetall <card:userid>
3.7 分布式锁
4. 应用场景进阶
抢红包、秒杀活动
5.参考来源
B站 图灵学院 相关视频学习资料
附录.常用命令
set <key> <value>
mset <key1> <value1> <key2> <value2>
get <key>
mget <key1> <key2>
getset <key> <new-value> 设置一个新值,并返回其原始值
del <key>
exists <key>
ttl <key> time to leave 单位秒,返回-1表示这个key没有过期时间
expire <key> <expire-time-in-seconds>
setex <key> <expire-time-in-seconds> <value>
psetex <key> <expire-time-in-milliseconds> <value> 返回-2的时候表示这个key已经不存在了
incr/decr <key>
Incrby/decrby <key> <step>
hset <field> <key> <value>
hexists <field> <key> <field>
hget <field> <key>
hgetall <field>
hkeys <field> 获取<field>的所有<key>
hmget <field> <key1>[ <key2>]
hmset <field> <key1> <value1> [<key2> <value2>]
hdel <field> <key1>[ <key2> [<key3> [...]]]
lpush <list-name> <ele1> [<ele2>]
lpop <list-name> <ele1> [<ele2>]
lset <list-name> <index> <value>
llen <list-name>
lrange <list-name> <start-index-included> <end-index-included>
lindex <list-name> <index>
sadd <set-name> <ele1> [<ele2>]
scard <set-name> 获取set元素的数量
smembers <set-name> 获取所有set的元素
sdiff <set-name1> <set-name2> 计算两个集合的差集
sinter <set-name1> <set-name2> 计算两个集合的交集
sunion <set-name1> <set-name2> 计算两个集合的并集
sismember <set-name> <ele> 判断元素在不在集合中
srem <set-name> <ele> 移除元素
zadd <zset-name> <score1> <ele1> [ <score2> <ele2>]
zcard <zset-name>
zscore <zset-name> <ele> 获取zset中元素分数
zcount <zset-name> <begin-score-include> <end-score-include>获取分数区间的元素个数
zrank <zset-name> <ele> 获取元素的索引,即排名
zincrby <zset-name> <score> <ele> 增加某个元素的score
zrank <zset-name> <begin-index-include> <end-index-include> [ withscores]
zrevrange <zset-name> <begin-index-include> <end-index-include>[ withscores] 按照从大到小的顺序获取某个区间的元素
网友评论