Redis核心数据结构
Redis核心数据结构
- 1 数据结构
- 1.1 String
- 1.2 Hash
- 1.3 List
- 1.4 Set
- 1.5 ZSet
- 1.6 Bitmap
- 1.7 Hyperloglog
- 1.8 Geo
- 1.9 stream
- 2 Springboot集成redis
1 数据结构
在学习核心数据结构之前,有一个强大的help命令,可以快速让我们看到这些数据结构的使用方法,例如:
help @string
help @hash
...
1.1 String
- 常用操作
# 存入字符串键值对
SET key value
# 批量存储字符串键值对
MSET key value[key value ...]
# 存入一个不存在的字符串键值对
SETNX key value
# 获取一个字符串键值
GET key
# 批量获取字符串键值
MGET key[key ...]
# 删除一个键
DEL key[key ...]
# 设置一个键的过期时间(秒)
EXPIRE key seconds
- 原子加减
# 将key中存储的数字值加1
INCR key
# 将key中存储的数字值减1
DECR key
# 将key所存储的值加上increment
INCRBY key increment
# 将key所存储的值减去decrement
DECRBY key decrement
- 应用场景
- 单值缓存
SET key value APPEND key value
- 对象缓存
SET user:1 '{"name": "tacy", "balance": 8888}' MSET user:1:name tacy user:1:balance 8888
- 分布式锁
SETNX product:10001 true # 返回1代表获取锁成功,返回0代表获取锁失败 # 获取锁成功后...执行业务操作 DEL product:10001 # 执行完业务释放锁 # 防止程序意外终止导致死锁,设置过期时间,
1.2 Hash
- 常用操作
# 存储一个哈希表key的键值
HSET key filed value
# 存储一个不存在的哈希表key的键值
HSETNX key filed value
# 在一个哈希表key中存储多个键值对
HMSET key filed value [filed value ...]
# 获取哈希表key对应的filed键值
HGET key field
# 批量获取哈希表key中的多个filed键值
HMGET key field [field...]
# 删除哈希表key中的filed键值
HDEL key field [field...]
# 获取哈希表key中field的数量
HLEN key
# 返回哈希表key中所有的键值
HGETALL key
# 为哈希表中的key中的field键值加上增量increment
HINCRBY key field increment
-
应用场景
- 对象缓存
HSET user:1 name tacy balance 8888 HMGET user:1 name balance HSET user 1:name tacy 1:balance 8888 HMGET user 1:name 1:balance
- 购物车
用户ID为key ; 商品ID为filed; 商品数量为value
# 添加商品 hset cart:1001 10001 1 # 增加商品数量 hincrby cart:1001 10001 1 # 商品总数 hlen cart:1001 # 删除商品 hdel cart:1001 10001 # 获取购物车所有商品 hgetall cart:1001
- 对象缓存
-
优缺点
-
优点
同类数据归类整个存储,方便数据管理
相比string操作消耗的内存和cpu更小
相比string存储更加的节省空间 -
缺点
过期功能不可以使用在field,只能用在key上
在redis集群架构下不适合大规模使用
-
Redis Hash 在集群模式下存在一些设计上的限制,主要原因与数据分片、内存效率和性能有关:
1)数据分片问题 Redis 集群采用 CRC16 算法对 key 进行分片,而 Hash 类型的所有字段(field)会被视为同一个 key 的一部分。这导致整个 Hash 必须存储在同一个节点上,无法分散到多个节点。当 Hash 体积过大时,会造成单个节点内存和负载压力激增。
2)内存效率瓶颈 Redis 的 ziplist 编码优化对小型 Hash 有效(默认阈值 512 个字段),但超过阈值后转为 hashtable 编码,内存占用会显著上升。集群环境下大 Hash 无法享受分片带来的内存分散优势。
3)性能影响 大 Hash 的 HGETALL/HSCAN 等操作会阻塞节点,影响集群整体吞吐量。集群的跨节点操作(如事务)对 Hash 的支持也有限,MGET/MSET 等多键命令要求所有 key 必须在同一槽位。
1.3 List
- 常用操作
# 在列表前添加一个或多个元素。如果键不存在,则创建该键。
LPUSH key element [element ...]
# 向列表追加一个或多个元素。如果键不存在,则创建该键。
RPUSH key element [element ...]
# 移除列表中的第一个元素并返回该元素。如果移除的是最后一个元素,则删除该列表。
LPOP key [count]
# 返回并删除列表的最后一个元素。如果弹出最后一个元素,则删除列表。
RPOP key [count]
# 返回列表中的元素范围。
LRANGE key start stop
# 移除并返回列表中的第一个元素。阻塞,直到元素可用为止。如果弹出最后一个元素,则删除列表。
BLPOP key [key ...] timeout
# 移除并返回列表中的最后一个元素。阻塞,直到元素可用为止。如果弹出最后一个元素,则删除列表。
BRPOP key [key ...] timeout
- 常用数据结构
- Stack(栈) = LPUSH + LPOP
- Queue(队列) = LPUSH + RPOP
- Blocking MQ(阻塞队列) = LPUSH + BRPOP
- 应用场景
- 视频列表,签到列表
- 排队机
- 简化版MQ
1)一个list的容量是2的32次方减1个元素,大概40多亿,但在应用时,要注意big key
2) list底层是一个双向链表,对双端的操作性能很高,但通过索引下表直接操作某一个中间节点的性能就会较低
1.4 Set
常用操作
# 向集合添加一个或多个成员。如果键不存在,则创建该键。
SADD key member [member ...]
# 从集合中删除一个或多个成员。如果最后一个成员被删除,则删除该集合。
SREM key member [member ...]
# 返回集合的所有成员
SMEMBERS key
# 返回集合中成员的数目
SCARD key
# 确定成员是否属于集合。
SISMEMBER key member
# 从集合中获取一个或多个随机成员
SRANDMEMBER key [count]
# 从集合中删除一个或多个随机成员后返回它们。如果最后一个成员被弹出,则删除该集合。
SPOP key [count]
运算操作
# 返回多个集合的交集
SINTER key [key ...]
# 将交集结果存入新集合destination中
SINTERSTORE destination key [key ...]
# 并集运算
SUNION key [key ...]
# 将并集结果存入新的集合destination中
SUNIONSTORE destination key [key ...]
# 差集运算
SDIFF key [key ...]
# 将差集结果存入新的集合destination中
SDIFFSTORE destination key [key ...]
应用场景
- 抽奖
# 参与抽奖
SADD key [userId]
# 查看所有参与抽奖的用户
SMEMBERS key
# 随机抽取获奖用户,一个或者多个
SRANDMEMBER key [count] / SPOP key [count]