Redis常见使用场景
1、缓存
热点数据缓存(例如报表、明星出轨),对象缓存、全页缓存、可以提升热点数据的访问数据。
2、数据共享分布式
String 类型,因为 Redis 是分布式的独立服务,可以在多个应用之间共享。
例如:分布式Session
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
3、分布式锁
4、全局ID
int类型,incrby,利用原子性
incrby userid 1000
分库分表的场景,一次性拿一段
5、计数器
int类型,incr方法
例如:文章的阅读量、微博点赞数、允许一定的延迟,先写入Redis再定时同步到数据库
6、限流
int类型,incr方法
以访问者的ip和其他信息作为key,访问一次增加一次计数,超过次数则返回false
7、位统计
String类型的bitcount(1.6.6的bitmap数据结构介绍)
字符是以8位二进制存储的
set k1 a
setbit k1 6 1
setbit k1 7 0
get k1
/* 6 7 代表的a的二进制位的修改
a 对应的ASCII码是97,转换为二进制数据是01100001
b 对应的ASCII码是98,转换为二进制数据是01100010
因为bit非常节省空间(1 MB=8388608 bit),可以用来做大数据量的统计。
*/
例如:在线用户统计,留存用户统计
setbit onlineusers 01
setbit onlineusers 11
setbit onlineusers 20
支持按位与、按位或等等操作
BITOP AND destkey key[key...] ,对一个或多个 key 求逻辑并,并将结果保存到 destkey
BITOP OR destkey key[key...] ,对一个或多个 key 求逻辑或,并将结果保存到 destkey
BITOP XOR destkey key[key...] ,对一个或多个 key 求逻辑异或,并将结果保存到 destkey
BITOP NOT destkey key ,对给定 key 求逻辑非,并将结果保存到 destkey
计算出7天都在线的用户
BITOP "AND" "7_days_both_online_users" "day_1_online_users" "day_2_online_users" ... "day_7_online_users"
8、购物车
String 或hash。所有String可以做的hash都可以做
- key:用户id;field:商品id;value:商品数量
- +1:hincr
- -1:hdecr
- 删除:hdel
- 全选:hgetall
- 商品数:hlen
9、用户消息时间线timeline
list,双向链表,直接作为timeline就好了。插入有序。
10、消息队列
List提供了两个阻塞的弹出操作:blpop/brpop,可以设置超时时间
- blpop:blpop key1 timeout 移除并获取列表的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
- brpop:brpop key1 timeout 移除并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
上面的操作。其实就是java的阻塞队列。
- 队列:先进先除:rpush blpop,左头右尾,右边进入队列,左边出队列
- 栈:先进后出:rpush brpop
11、抽奖
自带一个随机获得值
spop myset
12、点赞、签到、打卡
假如上面的微博ID是t1001,用户ID是u3001
用 like:t1001 来维护 t1001 这条微博的所有点赞用户
- 点赞了这条微博:sadd like:t1001 u3001
- 取消点赞:srem like:t1001 u3001
- 是否点赞:sismember like:t1001 u3001
- 点赞的所有用户:smembers like:t1001
- 点赞数:scard like:t1001
是不是比数据库简单多了。
13、商品标签
老规矩,用 tags:i5001 来维护商品所有的标签。
- sadd tags:i5001 画面清晰细腻
- sadd tags:i5001 真彩清晰显示屏
- sadd tags:i5001 流程至极
14、商品筛选
// 获取差集
sdiff set1 set2
// 获取交集(intersection )
sinter set1 set2
// 获取并集
sunion set1 set2
假如:iPhone11 上市了
sadd brand:apple iPhone11
sadd brand:ios iPhone11
sadd screensize:6.0-6.24 iPhone11
sadd screentype:lcd iPhone 11
赛选商品,苹果的、ios的、屏幕在6.0-6.24之间的,屏幕材质是LCD屏幕
sinter brand:apple brand:ios screensize:6.0-6.24 screentype:lcd
15、用户关注、推荐模型
follow 关注 fans 粉丝
相互关注:
- sadd 1:follow 2
- sadd 2:fans 1
- sadd 1:fans 2
- sadd 2:follow 1
我关注的人也关注了他(取交集):
- sinter 1:follow 2:fans
可能认识的人:
- 用户1可能认识的人(差集):sdiff 2:follow 1:follow
- 用户2可能认识的人:sdiff 1:follow 2:follow
16、排行榜
id 为 6001 的新闻点击数加1:zincrby hotNews:20190926 1 n6001
获取今天点击最多的15条:zrevrange hotNews:20190926 0 15 withscores
17、发布订阅
创建channel名为 redisChat,订阅消息:
SUBSCRIBE redisChat
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1
发布消息:
PUBLISH redisChat "Redis is a great caching technique"
(integer) 1
PUBLISH redisChat "Learn redis by w3cschool.cc"
(integer) 1
18、最近地理位置(附近的人)
1. geoadd: 添加经纬度及地点信息
geoadd key longitude latitude member [longitude latitude member ...]
时间复杂度为o(log(n))
有效经度范围:-180度至180度之间
有效纬度范围:-85.05112878度至85.05112878度之间
当坐标位置超出上述指定范围时,该命令将会返回一个错误
geoadd location 103.73 36.03 lanzhou 101.74 36.56 xining 104.06 30.67 chengdou 114.48 38.03 shijiazhuang
2. geopos: 查找指定地点的经纬度信息
geopos key member [member ...]
时间复杂度为O(logn)
geopos location beijing
1) 1) "116.45999997854232788"
2) "39.9199990416181052"
3. geodist: 返回两个地点的距离
geodist key member1 member2 [unit]
unit:距离单位,m(米,默认单位),km(千米),mi(英里),ft(英尺)
时间复杂度为O(logn)
geodist location beijing tianjin km
"108.4037"
geodist location beijing tianjin
"108403.7082"
geodist location beijing aaa km
(nil)
4. georadius: 查找指定坐标对应方圆范围内的所有地点位置
georadius key longitude latitude radius m|km|ft|mi [withcoord][withdist][withhash][asc|desc][count count][store key][storedist key]
时间复杂度:O(n+logm), 其中 n 为指定半径范围内的位置元素数量, 而 m 则是被返回位置元素的数量.
m|km|ft|mi: 指定范围的距离单位
withcoord: 匹配位置的经纬度
withdist: 匹配位置与给定地理位置的距离
asc|desc: 默认结果是未排序的,传入asc为从近到远排序,传入desc为从远到近排序
withhash: 匹配位置的geohash值
count: 匹配位置数量
store: 位置信息转存到指定zset中,不能与withcoord,withdist,withhash参数同时使用
storedist: 位置信息转存到指定zset中,并以距离作为分数,不能与withcoord,withdist,withhash参数同时使用
georadius location 121 31 300 km withcoord withdist withhash count 100 asc
1) 1) "shanghai"
2) "51.8477"
3) (integer) 4054757652758722
4) 1) "121.48000091314315796"
2) "31.21999956478423854"
2) 1) "hangzhou"
2) "113.0672"
3) (integer) 4054134100314554
4) 1) "120.18999785184860229"
2) "30.25999927289620928"
5. georadiusbymember: 指定位置对应方圆范围内的所有地点位置
georadiusbymember key member radius m|km|ft|mi[withcoord][withdist][withhash][count count][asc|desc][store key][storedist key]
参数含义与georadius相同
时间复杂度:O(logn+m), 其中 n 为指定范围之内的元素数量, 而m则是被返回的元素数量
127.0.0.1:6379> georadiusbymember location beijing 300 km withcoord withdist withhash count 100 asc
1) 1) "beijing"
2) "0.0000"
3) (integer) 4069886062674726
4) 1) "116.45999997854232788"
2) "39.9199990416181052"
2) 1) "tianjin"
2) "108.4037"
3) (integer) 4069186820975087
4) 1) "117.19999998807907104"
2) "39.12999996316577977"
3) 1) "shijiazhuang"
2) "271.1001"
3) (integer) 4068411467887772
4) 1) "114.47999864816665649"
2) "38.02999941748397106
6. geohash: 返回位置经纬度计算后端52位geohash值,具体含义参考geohash
geohash key member [member ...]
geohash location beijing
1) "wx4g455wfe0"
7. 删除位置信息
因为geo的底层实现是zset,所以可以使用 zrem 命令删除功能
type location
zset
geopos location xian
1) 1) "108.95000249147415161"
2) "34.26999911916288966"
zrem location xian
(integer) 1
geopos location xian
1) (nil)
参考:
https://www.redis.net.cn/tutorial/3501.html
https://zhuanlan.zhihu.com/p/412504258