Redis的8种数据类型,什么场景使用?
mhr18 2024-11-21 17:57 21 浏览 0 评论
Redis是一个KV存储系统,使用C语言编写的。我们的key是字符串类型,是唯一的,value的数据类型如下
5种常用的
- String字符串类型
- list列表类型
- set集合类型
- sortedset(zset)有序集合类型
- hash类型
2种不常用的
- bitmap位图类型
- geo地理位置类型
1种redis5.0新增的
- stream类型
既然key是字符串类型,那么key有没有一些约定俗成的一些规则,或者说一些建议的规则呢?
redis key如何设计?
- 一般使用冒号分隔
- 一般会把表名或者表名的缩写作为key的前缀
- 比如:认证系统的用户表的id为001的key, auth:user:001
- 命名要具有一定的识别性,一看就知道是什么意思
- key要尽量短一点,短key的效率比长key好一些,后面会讲到
1、String字符串
Redis的string能存储3种值的类型:字符串,整数,浮点数
1.1、应用场景
key和value都是字符串类型的应用场景极为广泛
- 普通的赋值操作
- 所有的kv存储都可以转换为value为字符串的存储,通过序列化转string,或者普通类型转string. 所以这种场景是最多的。
- incr可以加上watch监听,实现乐观锁
incr实现的是数字递增
- setnx可以实现分布式锁
- value不存在时,可以用于分布式锁,最终可以一个会设置成功,设置成功的就是抢到锁资源的
1.2、String字符串类型命令
命令行罗列
命令 | 帮助 | 描述 |
set | set key value | 赋值 |
get | get key | 取值 |
getset | getset key value | 取值赋值 |
setnx | setnx key value | 当key不存在时才赋值成功,存在时赋值失败 set key value NX PX 3000 原子操作,可用于分布式锁,px 设置毫秒数 |
append | append key value | 向尾部追加值 |
strlen | strlen key | 获取字符串长度 |
incr | incr key | 递增数字 |
incrby | incrby key increment | 增加指定的整数 |
decr | decr key | 递减数字 |
decrby | decrby key decrement | 减少指定的整数 |
命令行实际操作
127.0.0.1:6379> set name zhangsan
OK
127.0.0.1:6379> get name
"zhangsan"
127.0.0.1:6379> getset age 20
(nil)
127.0.0.1:6379> get age
"20"
127.0.0.1:6379> setnx lock_01 1001
(integer) 1
127.0.0.1:6379> setnx lock_01 1001
(integer) 0
127.0.0.1:6379> setnx lock_01 1002
(integer) 0
127.0.0.1:6379> append name 1
(integer) 9
127.0.0.1:6379> get name
"zhangsan1"
127.0.0.1:6379> strlen name
(integer) 9
127.0.0.1:6379> incr myid
(integer) 1
127.0.0.1:6379> incrby myid 2
(integer) 3
127.0.0.1:6379> decr myid
(integer) 2
127.0.0.1:6379> decrby myid 2
(integer) 0
# 设置分布式锁后的值,有效期20s
127.0.0.1:6379> set lock_02 1002 NX PX 30000
OK
# 30s内重新设置值失败
127.0.0.1:6379> set lock_02 1002 NX
(nil)
# 30s内获取值成功
127.0.0.1:6379> get lock_02
"1002"
# 30s后获取值为空
127.0.0.1:6379> get lock_02
(nil)
# 重新设置值成功
127.0.0.1:6379> set lock_02 1003 NX PX 30000
OK
127.0.0.1:6379> get lock_02
"1003"
127.0.0.1:6379>
2、list列表
2.1、应用场景
list列表可以存储有序并且可以重复的元素。
- 获取头部或尾部的数据极快
- 列表最多存储2^32 -1个元素,大概40亿
看下面的命令,我们就知道这是一个双向列表。左进右出可以作为队列,左进左出可以作为栈使用。其实就是先进先出队列,后进先出为栈。
可以存储各种各样的列表数据。比如用户列表
2.2、list列表命令
命令罗列
命令 | 帮助 | 描述 |
lpush | lpush key v1 v2 n3 ... vn | 从左侧插入列表 |
lpop | lpop key | 从列表左侧取出 |
rpush | rpush key v1 v2 n3 ... vn | 从右侧插入列表 |
rpop | rpop key | 从列表右侧取出 |
lpushx | lpushx key value | 将值插入到列表头部 |
rpushx | rpushx key value | 将值插入到列表尾部 |
blpop | blpop key timeout | 从列表左侧取出,如果为空阻塞,timeout最大阻塞时间(s) |
brpop | brpop key timeout | 从列表右侧取出,如果为空阻塞,timeout最大阻塞时间(s) |
llen | llen key | 获得列表中元素个数 |
lindex | lindex key index | 获得列表中下标为index的元素 index从0开始 |
lrange | lrange key start end | 返回列表中指定区间的元素,区间通过start和end指定 |
lrem | lrem key count value | 删除列表中与value相等的元素 当count>0时, lrem会从列表左边开始删除;当count<0时, lrem会从列表后边开始删除;当count=0时, lrem删除所有值为value的元素 |
lset | lset key index value | 将列表index位置的元素设置成value的值 |
ltrim | ltrim key start end | 对列表进行修剪,只保留start到end区间 |
rpoplpush | rpoplpush key1 key2 | 从key1列表右侧弹出并插入到key2列表左侧 |
brpoplpush | brpoplpush key1 key2 | 从key1列表右侧弹出并插入到key2列表左侧,会阻塞 |
linsert | linsert key BEFORE/AFTER pivot value | 将value插入到列表,且位于值pivot之前或之后 |
命令执行
127.0.0.1:6379> lpush name2 zhangsan lisi wangwu
(integer) 3
127.0.0.1:6379> lpop name2
"wangwu"
127.0.0.1:6379> rpush name3 zhangsan lisi wangwu
(integer) 3
127.0.0.1:6379> rpop name3
"wangwu"
127.0.0.1:6379> lpushx name2 niuqi
(integer) 3
127.0.0.1:6379> lrange name2 0 5
1) "niuqi"
2) "lisi"
3) "zhangsan"
127.0.0.1:6379> rpushx name3 niuqi
(integer) 3
127.0.0.1:6379> lrange name3 0 5
1) "zhangsan"
2) "lisi"
3) "niuqi"
127.0.0.1:6379> blpop name2 1
1) "name2"
2) "niuqi"
127.0.0.1:6379> brpop name3 1
1) "name3"
2) "niuqi"
127.0.0.1:6379> llen name2
(integer) 2
127.0.0.1:6379> lindex name2 0
"lisi"
127.0.0.1:6379> lindex name2 1
"zhangsan"
3、set集合
3.1、应用场景
Set集合,就是表示value唯一,并且无需的集合。
存储各种不需要顺序的数据集合。比如用户随机随机抽奖
3.2、Set集合命令
命令罗列
命令 | 帮助 | 描述 |
sadd | sadd key v1 v2 n3 ... vn | 为集合添加新成员 |
srem | srem key mem1 mem2 ...memn | 删除集合中指定成员 |
smembers | rsmembers key | 从获得集合中所有元素 |
spop | spop key | 返回集合中一个随机元素,并将该元素删除 |
srandmember | srandmember key | 将返回集合中一个随机元素,不会删除该元素 |
scard | scard key | 获得集合中元素的数量 |
sismember | sismember key member | 判断元素是否在集合内 |
sinter | sinter key1 key2 key3 | 求多集合的交集 |
sdiff | sdiffff key1 key2 key3 | 求多集合的差集 |
sunion | sunion key1 key2 key3 | 求多集合的并集 |
命令操作
127.0.0.1:6379> sadd name4 zhangsan lisi wangwu
(integer) 3
127.0.0.1:6379> srem zhangsan
(error) ERR wrong number of arguments for 'srem' command
127.0.0.1:6379> srem name4 zhangsan
(integer) 1
127.0.0.1:6379> smembers name4
1) "lisi"
2) "wangwu"
127.0.0.1:6379> spop name4
"lisi"
127.0.0.1:6379> srandmember name4
"wangwu"
127.0.0.1:6379> scard name4
(integer) 1
127.0.0.1:6379> sismember name4 wangwu
(integer) 1
127.0.0.1:6379> sismember name4 wangwu
(integer) 1
# 定义两个集合 求交集,差集,并集
127.0.0.1:6379> sadd name5 zhangsan lisi
(integer) 2
127.0.0.1:6379> sadd name6 lisi wangwu
(integer) 2
127.0.0.1:6379> sinter name5 name6
1) "lisi"
127.0.0.1:6379> sdiff name5 name6
1) "zhangsan"
127.0.0.1:6379> sunion name5 name6
1) "lisi"
2) "wangwu"
3) "zhangsan"
4、sortedset有序集合(zset)
4.1、应用场景
sortedset是一个有序集合,元素本身跟set一样,是不重复的,为每一个元素添加了一个分数(score)根据分数的不同可以进行排序。分数可以重复。
有序列表被广泛使用在各种排行榜业务上:比如销量排行,用户点击率排行等
4.2、sortedset命令
命令罗列
命令 | 帮助 | 描述 |
zadd | zadd key score1 v1 score2 v2 score1v3 ... scoren vn | 为有序集合添加新成员 |
zrem | zrem key mem1 mem2 ...memn | 删除有序集合中指定成员 |
zcard | zcard key | 获得有序集合中的元素数量 |
zcount | zcount key min max | 返回集合中score值在[min,max]区间的元素数量 |
zincrby | zincrby key increment member | 在集合的member分值上加increment |
zscore | zscore key member | 获得集合中member的分值 |
zrank | zrank key member | 获得集合中member的排名(按分值从小到大) |
zrevrank | zrevrank key member | 获得集合中member的排名(按分值从大到小) |
zrange | zrange key start end | 获得集合中指定区间成员,按分数递增排序 |
zrevrange | zrevrange key start end | 获得集合中指定区间成员,按分数递减排序 |
命令操作
127.0.0.1:6379> zadd test:001 20 zhangsan 50 lisi 30 wangwu 90 niuqi
(integer) 4
127.0.0.1:6379> zcount test:001 0 2
(integer) 0
127.0.0.1:6379> zcount test:001 20 30
(integer) 2
127.0.0.1:6379> zcard test:001
(integer) 4
127.0.0.1:6379> zrem test:001 wangwu
(integer) 1
127.0.0.1:6379> zincrby test:001 10 zhangsan
"30"
127.0.0.1:6379> zscore test:001 zhangsan
"30"
127.0.0.1:6379> zrank test:001 zhangsan
(integer) 0
127.0.0.1:6379> zrank test:001 niuqi
(integer) 2
127.0.0.1:6379> zrevrank test:001 niuqi
(integer) 0
127.0.0.1:6379> zrevrank test:001 zhangsan
(integer) 2
127.0.0.1:6379> zrange test:001 0 5
1) "zhangsan"
2) "lisi"
3) "niuqi"
127.0.0.1:6379> zrevrange test:001 0 5
1) "niuqi"
2) "lisi"
3) "zhangsan"
5、hash散列表
5.1、应用场景
hash就是要存储一个key对应多个值。比如以key的用户ID,value为用户整个对象的缓存为例,这种数据就很适合使用hash存储。
5.2、hash命令
命令罗列
命令 | 帮助 | 描述 |
hset | hset key field value | 赋值,不区别新增或修改 |
hmset | hmset key field1 value1 field2 value2 | 批量赋值 |
hsetnx | hsetnx key field value | 获得有序集合中的元素数量 |
hexists | hexists key filed | 查看某个field是否存在 |
hget | hget key field | 获取一个字段值 |
hmget | hmget key field1 field2 ... | 获取所有 |
hgetall | hgetall key | 获得集合中member的排名(按分值从小到大) |
hdel | hdel key field1 field2 | 删除指定字段 |
hincrby | hincrby key field increment | 指定字段自增increment |
hlen | hlen key | 获得字段数量 |
命令操作
# 其实直接使用hset多个key value也是可以的
127.0.0.1:6379> hset user:001 id 001 name zhangsan
(integer) 2
127.0.0.1:6379> hget user:001 id
"001"
127.0.0.1:6379> hget user:001 name
"zhangsan"
127.0.0.1:6379> hmset user:001 age 20 sex 1
OK
127.0.0.1:6379> hsetnx user:001 age 30
(integer) 0
127.0.0.1:6379> hexists user:001 age
(integer) 1
127.0.0.1:6379> hget user:001 age
"20"
# 使用hget多个就会报错
127.0.0.1:6379> hget user:001 age name
(error) ERR wrong number of arguments for 'hget' command
127.0.0.1:6379> hmget user:001 age name
1) "20"
2) "zhangsan"
127.0.0.1:6379> hgetall user
(empty list or set)
127.0.0.1:6379> hgetall user:001
1) "id"
2) "001"
3) "name"
4) "zhangsan"
5) "age"
6) "20"
7) "sex"
8) "1"
6、bitmap位图
bitmap是进行按位操作的,可以极大的节省空间,如果需要小空间存储大量值的时候可以使用它,并且存储的值很简单,就是1bit即可存储。
比如:用户每月签到,客户以用户id为key, 日期作为偏移量,1 表示签到
命令罗列
命令 | 帮助 | 描述 |
setbit | setbit key offffset value | 设置key在offffset处的bit值(只能是0或者1)。 |
getbit | getbit key offffset | 获得key在offffset处的bit值 |
bitcount | bitcount key | 获得key的bit位为1的个数 |
bitpos | bitpos key value | 返回第一个被设置为bit值的索引值 |
bitop | bitop and[or/xor/not] destkey key [key …] | 对多个key 进行逻辑运算后存入destkey中 |
命令操作
# 本月用户签到了四天
127.0.0.1:6379> setbit user:sign:001 20220801 1
(integer) 0
127.0.0.1:6379> setbit user:sign:001 20220803 1
(integer) 0
127.0.0.1:6379> setbit user:sign:001 20220809 1
(integer) 0
127.0.0.1:6379> setbit user:sign:001 20220820 1
(integer) 0
# 查看20220801是否签到了 1表示签到了 0表示没有签到
127.0.0.1:6379> getbit user:sign:001 20220801
(integer) 1
127.0.0.1:6379> getbit user:sign:001 20220802
(integer) 0
# 统计用户签到的次数
127.0.0.1:6379> bitcount user:sign:001
(integer) 4
# 查看第一次签到的时间
127.0.0.1:6379> bitpos user:sign:001 1
(integer) 20220801
7、geo地理位置类型
7.1、应用场景
geo是Redis用来处理位置信息的。在Redis3.2中正式使用。
应用场景:
- 记录地理位置
- 计算距离
- 查找"附近的人"
7.2、geo地理位置命令
命令罗列
命令 | 帮助 | 描述 |
geoadd | geoadd key 经度 纬度 成员名称1 经度1 纬度1 成员名称2 | 添加地理坐标 |
geohash | geohash key 成员名称1 成员名称2 | 返回标准的geohash串 |
geopos | geopos key 成员名称1 成员名称2 | 返回成员经纬度 |
geodist | geodist key 成员1 成员2 单位 | 计算成员间距离 |
georadiusbymember | georadiusbymember key 成员 值单位 count 数asc[desc] | 根据成员查找附近的成员 |
# 添加坐标
127.0.0.1:6379> geoadd user:addr 116.21 40.00 zhangsan 116.23 49.9 lisi
(integer) 2
# 获取坐标的hash
127.0.0.1:6379> geohash user:addr zhangsan lisi
1) "wx4es3v8ck0"
2) "y8feuuh0e60"
# 获取坐标的经纬度
127.0.0.1:6379> geopos user:addr zhangsan
1) 1) "116.21000200510025024"
2) "39.99999991084916218"
# 计算两个用户的距离 单位米
127.0.0.1:6379> geodist user:addr zhangsan lisi
"1101141.4665"
# 计算两个用户的距离 单位千米
127.0.0.1:6379> geodist user:addr zhangsan lisi km
"1101.1415"
# 计算张三1200km之内的人的经纬度,距离,由近到远排出顺序
127.0.0.1:6379> georadiusbymember user:addr zhangsan 1200 km withcoord withdist count 3 asc
1) 1) "zhangsan"
2) "0.0000"
3) 1) "116.21000200510025024"
2) "39.99999991084916218"
2) 1) "lisi"
2) "1101.1415"
3) 1) "116.23000055551528931"
2) "49.89999975254306719"
8、stream数据流类型
8.1、应用场景
stream是Redis5.0后新增的数据结构,用于可持久化的消息队列。
应用场景,没有使用第三方消息队列,但是使用了redis,redis实现了消息队列功能,但是没有专门左中间件的成熟。所以需要谨慎选择。学习一下还是不错的。
8.2、stream类型命令
命令罗列
命令 | 帮助 | 描述 |
xadd | xadd key id <*> field1 value1 | 将指定消息数据追加到指定队列(key)中,*表示最新生成的id(当前时间+序列号) |
xread | xread [COUNT count] [BLOCKmilliseconds] STREAMS key[key ...] ID [ID ...] | 从消息队列中读取,COUNT:读取条数,BLOCK:阻塞读(默认不阻塞)key:队列名称 id:消息id |
xrange | xrange key start end [COUNT] | 读取队列中给定ID范围的消息 COUNT:返回消息条数(消息id从小到大) |
xrevrange | xrevrange key start end [COUNT] | 读取队列中给定ID范围的消息 COUNT:返回消息条数(消息id从大小到大) |
xdel | xdel key id | 删除队列的消息 |
xgroup | xgroup create key groupname id | 创建一个新的消费组 |
xgroup | xgroup destory key groupname | 删除指定消费组 |
xgroup | xgroup delconsumer key groupname cname | 删除指定消费组中的某个消费者 |
xgroup | xgroup setid key id | 修改指定消息的最大id |
xreadgroup | xreadgroup group groupname consumer COUNT streams key | 从队列中的消费组中创建消费者并消费数据(consumer不存在则创建) |
命令操作
# 创建消息
127.0.0.1:6379> xadd topic:001 * name zhangsan age 20
"1661008860267-0"
127.0.0.1:6379> xadd topic:001 * name wangwu age 24 name lisi age 35
"1661008909085-0"
# 查看消息
127.0.0.1:6379> xrange topic:001 - +
1) 1) "1661008860267-0"
2) 1) "name"
2) "zhangsan"
3) "age"
4) "20"
2) 1) "1661008909085-0"
2) 1) "name"
2) "wangwu"
3) "age"
4) "24"
5) "name"
6) "lisi"
7) "age"
8) "35"
# 读取一个消息
127.0.0.1:6379> xread count 1 streams topic:001 0
1) 1) "topic:001"
2) 1) 1) "1661008860267-0"
2) 1) "name"
2) "zhangsan"
3) "age"
4) "20"
# 创建一个消费组
127.0.0.1:6379> xgroup create topic:001 group1 0
OK
# 使用消费组消费数据
127.0.0.1:6379> xreadgroup group group1 user1 count 1 streams topic:001 >
1) 1) "topic:001"
2) 1) 1) "1661008860267-0"
2) 1) "name"
2) "zhangsan"
3) "age"
4) "20"
# 使用消费组消费数据 继续消费 总共两条
127.0.0.1:6379> xreadgroup group group1 user1 count 1 streams topic:001 >
1) 1) "topic:001"
2) 1) 1) "1661008909085-0"
2) 1) "name"
2) "wangwu"
3) "age"
4) "24"
5) "name"
6) "lisi"
7) "age"
8) "35"
# 消费完了,没有啦
127.0.0.1:6379> xreadgroup group group1 user1 count 1 streams topic:001 >
(nil)
9、小结
redis的功能之所以这么强大,也与它的各种数据类型有关,不同的业务场景可以使用不同的数据类型,从而更加高效的实现需求。
10、相关文章
本人还写了Redis的其他相关文章,有兴趣的可以点击查看!
相关推荐
- 【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...
- Pure Storage推出统一数据管理云平台及新闪存阵列
-
PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...
- 对Java学习的10条建议(对java课程的建议)
-
不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...
- SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!
-
官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...
- JDK21有没有什么稳定、简单又强势的特性?
-
佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...
- 「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了
-
在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...
- Java面试题及答案最全总结(2025版)
-
大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...
- 数据库日常运维工作内容(数据库日常运维 工作内容)
-
#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...
- 分布式之系统底层原理(上)(底层分布式技术)
-
作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...
- oracle 死锁了怎么办?kill 进程 直接上干货
-
1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...
- SpringBoot 各种分页查询方式详解(全网最全)
-
一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...
- 《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略
-
《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...
- LoadRunner(loadrunner录制不到脚本)
-
一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...
- Redis数据类型介绍(redis 数据类型)
-
介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...
- RMAN备份监控及优化总结(rman备份原理)
-
今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)