一、命令
http://doc.redisfans.com/
二、使用场景
1、String 字符串
# 存储简单数据或者不需要部分修改的数据
#SET <key> <value>
SET newsinfo:001 {json}
#分布式锁,key 不存在则设置
#SET <key> <value> NX EX <second>
SET lock:a xxx NX EX 5
#点赞数、浏览数累加
#加 1 INCR <key>
INCR news:001:view
#api 权限判断,offset 为 API 权限编号
#SETBIT <key> <offset> <0 or 1>
#GETBIT <key> <offset>
SETBIT user_tk:001 5 1
GETBIT user_tk:001 5
2、Hash 哈希表
# 存储对象,部分数据经常读取或者修改
#批量设置 HMSET <key> [<field> <value>]...
HMSET user:001 name tony token tk3333 qzNo 111
#获取单个字段 HGET <key> <field>
HGET user:001 token
#获取所有字段 HGETALL <key>
HGETALL user:001
3、List 列表
#简单实现 FIFO 队列,要保证消息安全消费,建议使用 MQ 中间件
#左插入 LPUSH <key> <value>...
#右弹出 RPOP <key>
#按照下单顺序发送消息通知
LPUSH order_pay_notify 101 102 103
RPOP order_pay_notify
#栈,后插入的先弹出
#左插入 LPUSH <key> <value>...
#右弹出 LPOP <key>
#按照新闻发布时间推荐
LPUSH recent_news 101 102 103
LPOP recent_news
#循环列表,循环从队尾取出,队头插入
#更新服务器最新状态
#RPOPLPUSH <source> <destination>
LPUSH host_list 192.168.1.1 192.168.1.2 192.168.1.3 192.168.1.4
RPOPLPUSH host_list host_list
4、Set 集合
4.1 抽奖
#抽奖,可多次获奖
#随机获取成员,不移除 SRANDMEMBER <key> <count>
SADD pool a b c d e f g h
SRANDMEMBER pool 2
#抽奖,只可获奖一次
#随机获取成员并移除 SPOP <key> <count>
SPOP pool 2
4.2 朋友圈点赞
#点赞
#集合添加成员 SADD <key> <member>
SADD status_like:101 a
SADD status_like:101 b
SADD status_like:101 c
#取消点赞
#SREM <key> <member>
SREM status_like:101 b
#检查用户是否点过赞
#SISMEMBER <key> <member>
SISMEMBER status_like:101 a
SISMEMBER status_like:101 b
#获取点赞的用户列表
#SMEMBERS <key>
SMEMBERS status_like:101
4.3 微博关注
#某人关注某人
SADD focus:a b c d f
SADD focus:b c d f g
SADD focus:c b d f
#a 和 b 共同关注的人
#获取集合交集 SINTER <key>...
SINTER focus:a focus:b
#a 关注的人也关注 b
#获取集合成员 SMEMBERS <key>
#判断集合中存在成员 SISMEMBER <key> <member>
#获取 a 关注的所有人
SMEMBERS focus:a
#循环成员,判断 b 是否在成员关注集合中
#for(<people> : c,d,f){
# SISMEMBER focus:<people> b
#}
#即:
SISMEMBER focus:c b
SISMEMBER focus:d b
SISMEMBER focus:f b
#获取集合差集 SDIFF <key>...
#a 在 b 主页中,可能认识的人
SDIFF focus:b focus:a
#获取集合并集 SUNION <key>...
#获取 a、b 所有关注的人
SUNION focus:a focus:b
5、SortedSet(ZSet) 有序集合
#排行榜、新闻列表等有序列表
#添加元素 ZADD <key> <score> <member>
#分值降序排列 ZREVRANGEBYSCORE <key> <max score> <min score> WITHSCORES LIMIT <offset> <count>
#score 为 double 类型,尾数取值范围为 0 到 2^52
#准备数据,新热度作为 score,确保没有重复的 score
ZADD news_range:202101 315 id101
ZADD news_range:202101 199 id102
ZADD news_range:202101 23 id103
ZADD news_range:202101 2 id104
ZADD news_range:202101 1 id105
#取第一页数据,每页 2 条 maxscore=极大值, count=2
ZREVRANGEBYSCORE news_range:202101 10000000 0 WITHSCORES LIMIT 0 2
#取第二页数据 maxscore=199-1
ZREVRANGEBYSCORE news_range:202101 198 0 WITHSCORES LIMIT 0 2
#取第三页数据 maxscore=2-1
ZREVRANGEBYSCORE news_range:202101 10 WITHSCORES LIMIT 0 2
#2021 年第一季度排行榜
#多个有序列表取并集,并重新计算 score
#ZUNIONSTORE <destination> <numkeys> <key>... [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
#准备数据
ZADD news_range:202102 100 id103
ZADD news_range:202102 10 id104
#合并三个月数据
ZUNIONSTORE news_range:202101-03 3 news_range:202101 news_range:202102 news_range:202103 WEIGHTS 1 2 1
#全部数据降序排列
ZREVRANGE news_range:202101-03 0 -1 WITHSCORES
三、性能优化
1、命名
Key 要有层级,以”模块:实体:[id | 分类]”等形式分隔,在保证语义的情况下可缩写。
base:usr:2333882291
2、大 Key 限制
1)字符串不超过 10KB。
2)哈希表、列表、集合、有序集合不超过 5000 个元素,超过的可通过 key 命名拆分 key:1、key:2…。
3、批量操作
1)使用 mset、mget 等批量操作命令,同时处理多个 key。
2)客户端程序可使用 pipeline 提高操作效率,但命令数量不宜过多,注意:pipeline 没有原子性。
4、设置过期时间
对于非永久存储的数据,必须设置过期时间。
四、常见问题
1、热点缓存重复创建
对于热点资源,缓存失效的瞬间,会有大量线程重建同一个缓存。
解决:
使用分布式锁,保障同一时间只有一个线程重建缓存。
2、缓存同时失效
大批量的缓存的过期时间相同。在缓存过期时,大量请求访问数据库,造成数据库奔溃。
解决:
使用固定值+随机值作为过期时间。
3、缓存穿透
非法请求或者恶意请求访问不存在的 Key,导致大量请求直接穿透到数据库。
解决:
1)若查询到不存在的数据,设置一个空缓存,并指定过期时间。如:
SET base:usr:9999999 '' EX 30
2)使用布隆过滤器。预先用存在的 Key 初始化,判断 Key 不存在,直接返回。
4、缓存雪崩
缓存服务宕机导致流量进入后端存储。
解决:
1)使用缓存集群;
2)做限流和降级;
来源:UP 技术控
© 版权声明
博主的文章没有高度、深度和广度,只是凑字数。利用读书、参考、引用、抄袭、复制和粘贴等多种方式打造成自己的纯镀 24k 文章!如若有侵权,请联系博主删除。
喜欢就点个赞吧