Redis应用场景
一、String应用场景
1.1单值缓存
set key value
get key
1.2 对象缓存
set user:1 value(json格式数据)
mset user:1:name alanchen user:1:balance 1888
mget user:1:name user:1:balance
1.3 分布式锁
setnx product:1001 true // 返回1代表获取锁成功
setnx product:1001 true // 返回0代表获取锁失败
... 执行业务操作
del product:1001 // 执行完业务释放锁
set product:1001 true ex 10 nx // 防止程序意外终止导致死锁
补充说明
//setnx 命令基本语法
setnx key value
setnx (SET if Not eXists) 命令在指定的 key 不存在时,为 key 设置指定的值。
1.4 计数器
用作文章点赞数、浏览量
incr article:readcount:{文章ID}
get article:readcount:{文章ID}
1.5 分布式系统全局序列号
incrby orderId 100 //redis批量生成序列号提升性能
二、Hash应用场景
2.1 对象缓存
hmset user {userId} : name alanchen {userId}:balance 1888
hmset user 1: name alanchen 1:balance 1888
hmget user 1:name 1:balance
2.2 电商购物车
1.以用户id为key
2.商品id为field
3.商品数量为value
购物车操作
1.添加商品 hset cart:1001 10088 1
2.增加数量 hinncrby cart 1001 10088 1
3.商品总数 hlen cart 1001
4 删除商品 hdel cart 1001 10088
5 获取购物车所有商品 hgetall cart :1001
![](https://img.haomeiwen.com/i9571610/acdbe5a70b8eba96.png)
三、List应用场景
3.1 List常用操作
// 将一个或多个值value插入到key列表的表头(最左边)
lpush key value [value...]
//将一个或多个值value插入到key列表的表尾(最右边)
rpush key value [value...]
//移除并返回key列表的头元素
lpop key
//移除并返回key列表的尾元素
rpop key
//返回列表key中指定区间内的元素,区间以偏移量start和stop指定
lrange key start stop
//从key列表表头弹出一个元素,若列表中没有元素,阻塞等待timeouot秒,如果timeout=0,一直阻塞等待
blpop key [key...] timeout
//从key列表表尾弹出一个元素,若列表中没有元素,阻塞等待timeouot秒,如果timeout=0,一直阻塞等待
brpop key [key...] timeout
3.2 常用数据结构(分布式场景)
在分布式场景下,Java自带的以下数据结构API就无法使用了
Stack(栈) = LPUSH + LPOP 先进后出
Queue(队列) = LPUSH + RPOP 先进先出
Blocking MQ(阻塞队列) = LPUSH + BRPOP
BRPOP 是列表的阻塞式(blocking)弹出原语。 它是RPOP命令的阻塞版本。
3.2 微博和微信公众号消息流
海量数据+排序+频繁访问 (mysql数据库不合适)
![](https://img.haomeiwen.com/i9571610/b6872ef73dc3ee25.png)
如果粉丝量上百万、千万后这种方式也不合适,大V发布一条状态后,给他的上百万粉丝发消息,每个粉丝都存一份,数量太大且耗时长
四、Set应用场景
4.1 Set常用操作
//往集合key中存入元素,元素存在则忽略,若key不存在则新建
sadd key member [member ...]
//从集合key中删除元素
srem key member [member ...]
//获取集合key中所有元素
smembers key
//获取集合key的元素个数
scard key
//判断member元素是否存在于集合key中
sismember key member
//从集合key中选出count个元素,元素不从key中删除
srandmember key [count]
//从集合key中选出count个元素,元素从key中删除
spop key [count]
4.2 Set运算操作
//交集运算
sinter key [key ...]
//将交集结果存入新集合destination中
sinterstore destination key [key ...]
//并集运算
sunion key [key ...]
//将并集结果存入新集合destination中
sunionsore destination key [key ...]
//差集运算
sdiff key [key ...]
//将差集结果存入新集合destination中
sdiffstore destination key [key ...]
4.3 微信抽奖小程序
1、点击参与抽奖加入集合
sadd key {userId}
2、查看参与抽奖所有用户
smembers key
3、抽取count名中奖者
srandmember key [count] (不会从集合中取出)
spop key [count] (从集合中取出,抽一、二、三等奖)
![](https://img.haomeiwen.com/i9571610/e03da9873b0cc66c.png)
4.4微信微博点赞,收藏,标签
1、点赞
sadd like:{消息ID} {用户ID}
2、取消点赞
srem like:{消息ID} {用户ID}
3、检查用户是否点过赞
sismember like:{消息ID} {用户ID}
4、获取点赞的用户列表
smembers like:{消息ID}
5、获取点赞用户数
scard like:{消息ID}
4.5 集合操作实现微信微博关注模型
用交集、并集、差集等运算实现“共同关注”,“我关注的人也关注他”,“可能认识的人”等
4.6 集合操作实现电商商品筛选
![](https://img.haomeiwen.com/i9571610/09ae2682cac1ebb6.png)
![](https://img.haomeiwen.com/i9571610/4dad8b1d98ce4395.png)
五、ZSet应用场景
5.1 ZSet有序集合结构
ZSet正常操作
//往有序集合key中加入带分值元素
zadd key score member [[score member] ...]
//从有序集合key中删除元素
zrem key member [member ...]
//返回youxu集合key中元素member的分值
zscore key member
//为有序集合key中元素member的分值加上increment
zincrby key increment member
//返回有序集合key中元素个数
zcard key
//正序获取有序集合key从start下标到stop下标的元素
zrange key start stop [withscores]
//倒序获取有序集合key从start下标到stop下标的元素
zrevrange key start stop [withscores]
Zset集合操作
//并集计算
zunionstore destkey numkeys key [key ...]
//交集计算
zinterstore destkey numkeys key [key ...]
![](https://img.haomeiwen.com/i9571610/48919a1925d66dab.png)
5.2 ZSet集合操作实现排行榜
1、点击新闻
zincrby hotNews:20190819 1 守护香港
2、展示当日排行前十
zrevrange hotNews:20190819 0 9 withscores
3、七日搜索榜单计算
zunionstore hotNews:20190813-20190819 7
hotNews:20190813 hotNews:20190814... hotNews:20190819
4、展示七日排行前十
zrevrange hotNews:20190813-20190819 0 9 withscores
![](https://img.haomeiwen.com/i9571610/c55da86ab02f9299.png)
六、总结
Redis可用于实现抽奖,点赞,收藏,排行榜等功能。相比于用Java直接实现这个功能,Redis的优势在于:
1、Redis可以很方便的做集合交、并等操作
2、Redis存储的数据量更小
3、数据量大时,Redis计算,取数据更快
4、Redis实现逻辑更简单,加数量一句话搞定,Java还要先取出来,再加,再存,而且还要判断是否存在,存在则更新,否则先新增;
5、Redis实现抽奖直接有随机命令,Java则要实现随机算法、