返回

Redis 数据类型

String

String 的底层数据结构是 int 和 SDS(Simple Dynamic String),相比 C 的原生字符串,增加了以下功能

  1. 保存二进制文件
  2. 获取字符串长度的时间复杂度是 O(1)
  3. SDS API 内存安全,保证不会造成缓冲区溢出

内部编码

  1. int,若字符串保存的是整数值,并且可以转换为 long,那么该字符串对象的编码被设置为 int

    image-20241218215412113

  2. embstr,若字符串长度小于等于 44 字节(博主测试环境为 Redis 7.4.1),那么使用 embstr 编码,一次内存分配。只读,修改内容需先转换 raw 编码。

    image-20241218215051546

  3. raw,若字符串长度大于 44 字节,那么使用 raw 编码,两次内存分配

    image-20241218215124643

常用指令

  1. SET

    设置 key 为字符串值。 如果 key 已有值,无论其类型如何,都会被覆盖。 在 SET 操作成功后,之前与键值相关的任何生存时间都将被丢弃。

    1
    2
    
    SET key value [NX | XX] [GET] [EX seconds | PX milliseconds |
      EXAT unix-time-seconds | PXAT unix-time-milliseconds | KEEPTTL]
    
    • EX – 设置指定的过期时间,以秒(正整数)为单位。
    • PX – 设置指定的过期时间,以毫秒(正整数)为单位。
    • EXAT – 设置指定的密钥过期时间,以秒(正整数)为单位。
    • PXAT – 设置密钥过期的 Unix 时间,以毫秒为单位(正整数)。
    • NX – 当且仅当 key 不存在时才设置。
    • XX – 无论如何都会设置 key。
    • KEEPTTL – 继承上一个 key 的有效时间。
    • GET – 返回存储在密钥中的旧字符串,如果密钥不存在,则返回 nil。 如果键值不是字符串,会返回错误并中止 SET。
  2. MSET / MSETNX

    将给定的键设置为各自的值。 两者都是原子式的,因此所有给定键都会被一次性设置。

    1
    2
    
    MSET key value [key value ...] 
    MSETNX key value [key value ...]  # key 必须均不存在
    
  3. INCR / INCRBY

    对 key 中存储数字进行加法操作,如果键不存在,则在执行操作前将其设置为 0。

    1
    2
    
    INCR key  # 将存储在键上的数字递增 1。 
    INCRBY key increment  # 将存储在键上的数字递增 increment
    
  4. DECR / DECRBY

    对 key 中存储数字进行减法操作,如果键不存在,则在执行操作前将其设置为 0。

    1
    2
    
    DECR key  # 将存储在键上的数字递减 1。 
    DECRBY key increment  # 将存储在键上的数字递减 increment
    
  5. GET / MGET

    获取 key 的值。 如果键不存在,则返回特殊值 nil。

    1
    2
    
    GET key
    MGET key [key ...]
    

应用场景

  • 缓存对象

  • 计数器

  • 分布式锁

    • 若 key 不存在,则显示插入成功,表示加锁成功

    • 若 key 存在,则显示插入失败,表示加锁失败

    • 需要配合 Lua 脚本实现原子性

  • 共享 Session 信息

List

List 是简单的字符串列表(按照插入顺序排序),可以从头部或者尾部向 List 添加元素,链表最大长度为 $2^{32}-1$

内部实现

  • 3.2 版本之前由双向链表或压缩链表实现。
  • 3.2 版本之后由 QuickList 实现。其是多个节点(压缩列表)组成的双向链表,每个元素可以是一个整数或一个字节数组。

常用指令

  1. LPUSH / RPUSH

    将所有指定值插入存储在 key 处的列表头部。 如果 key 不存在,则在执行推送操作前将其创建为空列表。 如果 key 持有的值不是 list,则会返回错误信息。

    1
    
    LPUSH/RPUSH key element [element ...]
    
LPUSH 命令
LPUSH 命令
RPUSH 命令
RPUSH 命令
  1. LPUSHX / RPUSHX

    仅在 key 已存在并持有一个列表的情况下,在 key 所在列表的首部插入指定值。 如果 key 不存在,则不会执行任何操作。

    1
    
    LPUSHX/RPUSHX key element [element ...]
    
  2. LPOP / RPOP

    删除并返回存储在 key 处的列表的 最初/最后 一个元素。 默认情况下,该命令从列表 头部/尾部 弹出一个元素。 如果提供了可选的 count 参数,则根据列表的长度,回复最多包含 count 个元素。

    1
    
    LPOP/RPOP key [count]
    

    image-20241227135404729

  3. BLPOP / BRPOP

    BLPOP/BRPOP 是一种阻塞列表弹出原语。 它是 LPOP/RPOP 的阻塞版本,因为当没有元素从任何给定列表中弹出时,它会阻塞连接。 元素会从第一个非空列表的 头部/尾部 弹出,并按照给定键的顺序进行检查。

    1
    
    BLPOP/RLPOP key [key ...] timeout
    
  4. LINDEX

    返回存储在 key 中的列表中位于 index 索引处的元素。 索引以 0 为单位,因此 0 表示第一个元素,1 表示第二个元素,以此类推。 负指数可用于指定从列表尾部开始的元素。 这里,-1 表示最后一个元素,-2 表示倒数第二个元素,以此类推。

    1
    
    LINDEX key index
    
  5. LLEN

    返回存储在 key 处的 list 的长度。 如果 key 不存在,则将其解释为空列表,并返回 0。 如果 key 中存储的值不是 list,则会返回错误信息。

    1
    
    LLEN key
    
  6. LRANGE

    返回存储在 key 处的列表的指定元素。 偏移量 start 和 stop 是基于 0 的索引,0 代表列表的第一个元素(列表的头),1 代表下一个元素,以此类推。 这些偏移量也可以是负数,表示从列表的末尾开始的偏移量。 例如,-1 是列表的最后一个元素,-2 是倒数第二个元素,以此类推。

    1
    
    LRANGE key start stop
    
  7. LREM

    从存储在 key 处的列表中移除与元素相同的元素的第一个出现次数。 计数参数对操作的影响如下:count > 0:删除从头部移到尾部的与元素相同的元素。 count < 0:删除从尾部移到头部的与元素相同的元素。 例如,LREM list -2 “hello “将删除存储在 list 中的 “hello “的最后两次出现。 请注意,不存在的键会被当作空 list 处理。

    1
    
    LREM key count element
    
  8. LTRIM

    裁剪现有列表,使其只包含指定范围的元素。 start 和 stop 都是基于 0 的索引,其中 0 代表列表的第一个元素(头部),1 代表下一个元素,依此类推。 例如,LTRIM foobar 0 2 将修改存储在 foobar 处的列表,使其只保留列表的前三个元素: start 和 end 也可以是负数,表示与列表末尾的偏移量,其中 -1 表示列表的最后一个元素,-2 表示倒数第二个元素,依此类推。 超出范围的索引不会产生错误:如果 start 大于列表末尾,或 start > end,结果将是一个空列表(导致键被移除)。 如果 end 大于列表末尾,Redis 会将其视为列表的最后一个元素。

    1
    
    LTRIM key start stop
    
  9. LSET

    将索引处的列表元素设置为指定值。

    1
    
    LSET key index element
    
  10. LINSERT

    将元素插入存储在 key 处的列表中的参考值 pivot 之前或之后。 如果 key 不存在,则视为空列表,不执行任何操作。 如果 key 存在但不包含列表值,则返回错误信息。

    1
    
    LINSERT key <BEFORE | AFTER> pivot element
    
  11. BRPOPLPUSH

    BRPOPLPUSH 是 RPOPLPUSH 的阻塞变体。 当源代码包含元素时,该命令的行为与 RPOPLPUSH 完全相同。 在 MULTI/EXEC 块内使用时,该命令的行为与 RPOPLPUSH 完全相同。 当源为空时,Redis 会阻塞连接,直到有其他客户端向其推送或超时。 如果超时为零,则会无限期阻塞。

    1
    
    BRPOPLPUSH source destination timeout
    

应用场景

  • 消息队列
    • 消息保存:LPUSH + RPOP / RPUSH+LPOP 实现消息队列(使用 BRPOP 命令进行阻塞式读取,减少消费者性能损失)
    • 重复消息处理:生产者实现全局唯一 ID
    • 消息可靠性:BRPOPLPUSH(使得消费者从一个 List 中读取消息,同时 Redis 还会把消息再插入到另一个 List 留存)
    • List 不支持多个消费者消费同一条信息

Hash

Hash 是一个 key-value 集合,

内部实现

压缩列表
listpack
哈希表
hashtable
  • 如果 Hash 元素小于 512(默认) 个,所有值小于 64 字节(默认)时,Redis 会使用 listpack 作为底层数据结构。
  • 剩余情况,Redis 会使用 hashtable实现

常用命令

  1. HSET / HSETNX

    将指定字段的值设置为存储在 key 的哈希值中各自的值。 HSET 会覆盖哈希值中存在的指定字段的值,HSETNX 对于已存在的字段操作无效。 如果 key 不存在,则会创建一个新的散列键。

    1
    2
    
    HSET key field value [field value ...]
    HSETNX key field value
    
  2. HGET / HMGET / HGETALL

    HGET/HMGET 返回键存储的哈希值中与字段相关的值。 对于散列中不存在的每个字段,都会返回一个 nil 值。 由于不存在的键被视为空哈希值,因此针对不存在的键运行 HMGET 将返回一个 nil 值列表。

    HGETALL 返回存储在 key 处的哈希值的所有字段和值。

    1
    2
    3
    
    HGET key field
    HMGET key field [field ...]
    HGETALL key
    
  3. HDEL

    从存储在 key 中的哈希值中删除指定字段。 不存在于散列中的指定字段将被忽略。 如果没有字段,则删除散列。 如果键不存在,则将其视为空散列,此命令返回 0。

    1
    
    HDEL key field [field ...]
    
  4. HLEN

    返回存储在 key 中的哈希值所包含字段的数量。

    1
    
    HLEN key
    
  5. HEXISTS

    如果字段是存储在 key 处的哈希值中的现有字段,则返回 1,否则返回 0。

    1
    
    HEXISTS key field
    
  6. HKEYS / HVALS

    HKEYS 返回存储在 key 处的哈希值中的所有字段名。

    HVALS 返回键存储的哈希值中的所有值。

    1
    2
    
    HKEYS key
    HVALS key
    
  7. HINCRBY / HINCRBYFLOAT

    HINCRBY 按增量递增存储在 key 的哈希值中的字段数字。 如果 key 不存在,则会创建一个新的哈希值键。 如果字段不存在,则在执行操作前将其值设置为 0。

    HINCRBYFLOAT 按指定增量递增存储在键值处的散列指定字段,该字段代表一个浮点数。 如果增量为负值,结果是哈希字段值递减而不是递增。 如果字段不存在,则在执行操作前将其设置为 0。

    1
    2
    
    HINCRBY key field increment
    HINCRBYFLOAT key field increment
    

应用场景

  • 缓存对象
    • (key,field,value) 对应 (对象,属性,值)
  • 购物车
    • 添加商品:HSET cart:{user_id}{goods_id} 1
    • 增加数量:HINCRBY cart:{user_id}{goods_id} 2
    • 商品总数:HLEN cart:{user_id}
    • 删除商品:HDEL cart:{user_id} {goods_id}
    • 获取所有商品:HGETALL cart:{usert_id}

Set

Set 是一个集合(最多支持存储 $2^{32}-1$ 个元素),其中元素无序、唯一。除了支持集合内的增删改查,还支持多个集合交集、并集、差集。

内部实现

  • 如果集合元素都是整数,并且元素个数小于 512(默认),Redis 会使用 整数集合作为底层数据结构。
  • 其他情况,Redis 会使用 listpack 作为底层数据结构
整数集合
intset
哈希表
listpack

常用命令

  1. SADD

    将指定的成员添加到存储在 key 处的集合中。 如果指定的成员已经是这个集合的成员,则会被忽略。 如果 key 不存在,则会先创建一个新集合,然后再添加指定的成员。 如果存储在 key 中的值不是一个集合,则会返回错误信息。

    1
    
    SADD key member [member ...]
    
  2. SREM

    从存储在 key 处的集合中删除指定的成员。 不属于此集合的指定成员将被忽略。 如果 key 不存在,则将其视为空集,此命令返回 0。

    1
    
    SREM key member [member ...]
    
  3. SMEMBERS

    返回存储在 key 处的集合值的所有成员。

    1
    
    SMEMBERS key
    
  4. SISMEMBER

    返回成员是否是存储在 key 中的集合的成员。

    1
    
    SISMEMBER key member
    
  5. SCARD

    返回存储在 key 处的集合的元素个数。

    1
    
    SCARD key
    
  6. SRANDMEMBER / SPOP

    SRANDMEMBER 将从存储在 key 处的集合值中随机返回 count 个元素,元素不从 key 中删除。

    SPOP 将从存储在 key 处的集合值中随机返回 count 个元素,元素从 key 中删除。

    1
    2
    
    SRANDMEMBER key [count]
    SPOP key [count]
    
  7. SMOVE

    将成员从源集合移动到目标集合。 该操作是原子操作。 如果源集合不存在或不包含指定元素,则不执行任何操作,并返回 0。 否则,该元素将从源集合中删除,并添加到目标集合中。 如果指定的元素已存在于目标集合中,则只会从源集合中移除。 如果源集合或目标集合中不存在集合值,则会返回错误信息。

    1
    
    SMOVE source destination member
    
  8. SINTER / SINTERSTORE

    SINTER 返回所有给定集合的交集所产生的集合的成员。

    SINTERSTORE 该命令等同于 SINTER,但不是返回结果集,而是将其存储在目的地中。 如果目的地已经存在,则会被覆盖。

    1
    2
    
    SINTER key [key ...]
    SINTERSTORE destination key [key ...]
    

应用场景

  • 点赞(元素唯一)
  • 共同好友(集合运算)
    • 数据量较大时,可以让从库进行集合运算,将结果返回给客户端,防止 Redis 阻塞。
  • 抽奖(元素唯一,去重)

Zset

Zset 相较于 Set 多了个排序属性 score,每个存储元素相当于两个值组成,一个是有序集合的元素值,一个是排序值。

内部实现

  • 若 Zset 中元素小于 128 个,且每个元素小于 64 字节,Redis 使用 listpack 作为底层数据结构。
  • 剩余情况,Redis 会使用
listpack
listpack
跳表
skiplist

常用命令

  1. ZADD

    将具有指定分数的所有指定成员添加到存储在 key 处的排序集合中。 可以指定多个分数/成员对。 如果指定的成员已经是排序集合的成员,则会更新得分,并将元素重新插入正确的位置,以确保排序正确。 如果 key 不存在,则会创建一个新的排序集合,并将指定的成员作为唯一成员,就像排序集合为空一样。 如果键存在,但没有排序集,则会返回错误信息。 分数值应是双精度浮点数的字符串表示。 +inf 和 -inf 值也是有效值。

    1
    
    ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member ...]
    
    • XX: 只更新已存在的元素,不添加新元素。
    • NX: 只添加新元素,不更新已存在的元素。
    • LT: 只在新分数小于当前分数时更新现有元素。此标记不会阻止添加新元素。
    • GT: 仅在新分数大于当前分数时更新现有元素。 此标记不会阻止添加新元素。
    • CH: 将返回值从增加的新元素数量修改为改变的元素总数(CH 是 changed 的缩写)。 更改的元素是指新增的元素和已存在的元素,这些元素的分值已被更新。 因此,命令行中指定的元素如果得分与过去相同,则不计算在内。 注意:通常情况下,ZADD 的返回值只计算新增元素的数量。
    • INCR: 指定该选项时,ZADD 的作用与 ZINCRBY 类似。 在这种模式下,只能指定一个分数元素对。
  2. ZREM

    从存储在 key 中的排序集合中删除指定的成员。 如果 key 存在但没有排序集,则会返回错误信息。

    1
    
    ZREM key member [member ...]
    
  3. ZSCORE

    返回排序集合中 key 处成员的得分。 如果排序集合中不存在成员或 key 不存在,则返回 nil。

    1
    
    ZSCORE key member
    
  4. ZCARD

    返回存储在 key 处的排序集的元素个数。

    1
    
    ZCARD key
    
  5. ZINCRBY

    用增量递增键值存储的排序集合中成员的得分。 如果成员不存在于排序集合中,则会以增量作为其得分(就像它之前的得分是 0.0)。 如果 key 不存在,则会创建一个以指定成员为唯一成员的新排序集。 如果 key 存在但不包含排序集,则会返回错误信息。 分数值应是数值的字符串表示,并接受双精度浮点数。 可以提供一个负值来递减分数。

    1
    
    ZINCRBY key increment member
    
  6. ZRANGE

    返回存储在 key 中的排序集合中元素的指定范围。 ZRANGE 可以执行不同类型的范围查询:按索引(秩)、按分数或按词典顺序。

    默认情况下,该命令执行索引范围查询。 start 和 stop 参数代表基于零的索引,其中 0 代表第一个元素。 这些参数指定了一个包含范围,例如,ZRANGE myzset 0 1 将同时返回排序集的第一个和第二个元素。 索引也可以是负数,表示从排序集末尾开始的偏移量,-1 表示排序集的最后一个元素。

    当提供 BYSCORE 选项时,命令的行为与 ZRANGEBYSCORE 类似,返回排序集中分数等于或介于 start 和 stop 之间的元素范围。

    使用 REV 选项会反转排序集,索引 0 将作为得分最高的元素。

    当使用 BYLEX 选项时,命令的行为与 ZRANGEBYLEX 类似,并返回排序集合中 start 和 stop 之间的元素范围。 请注意,词典排序依赖于所有元素具有相同的分数。 有效的 start 和 stop 必须以 ( 或 [ 开头,以便分别指定范围区间是排他的还是包含的。

    1
    
    ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count] [WITHSCORES]
    
  7. ZUNIONSTORE / ZDIFFSTORE

    1
    2
    
    ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>]  # 并集
    ZDIFFSTORE destination numkeys key [key ...]  # 第一个集合和之后集合的差集
    

应用场景

  • 排行榜(有序唯一)

  • 电话、姓名排序

BitMap

BitMap 是一串连续的二进制数组,可以通过偏移量定位元素,适合数据量大且使用二值统计的场景。

内部实现

String 类型是会保存为二进制的字节数组

常用命令

  1. SETBIT

    设置或清除存储在 key 处字符串值偏移量的位。 位的设置或清除取决于值,值可以是 0 或 1。当 key 不存在时,将创建一个新的字符串值。 字符串的增长是为了确保它能容纳偏移量处的位。 偏移参数必须大于或等于 0,且小于 2^32(这将位图限制在 512MB)。

    1
    
    SETBIT key offset value
    
  2. GETBIT

    返回存储在 key 处的字符串值中偏移量处的比特值。

    1
    
    GETBIT key offset
    
  3. BITCOUNT

    获取指定范围内值为 1 的个数,默认以字节为单位。

    1
    
    BITCOUNT key [start end [BYTE | BIT]]
    
  4. BITOP

    在多个键(包含字符串值)之间执行位操作,并将结果存储到目标键中。

    1
    
    BITOP <AND | OR | XOR | NOT> destkey key [key ...]
    

应用场景

  • 签到统计

  • 判断用户登陆态

HyperLogLog

HyperLogLog 是一种用于统计基数的数据集合类型,基数统计就是指统计一个集合中不重复的元素个数。HyperLogLog 的统计规则基于概率完成,标准误算率为 0.81%

内部实现

^ - ^

常见命令

  1. PFADD

    将所有元素参数添加到存储在作为第一个参数指定的变量名下的 HyperLogLog 中。

    1
    
    PFADD key [element [element ...]]
    
  2. PFCOUNT

    使用单键调用时,返回存储在指定变量中的 HyperLogLog 的基数估算值,如果变量不存在,则返回 0。 使用多键调用时,通过内部合并存储在所提供键中的 HyperLogLog 成一个临时的 HyperLogLog,返回所传递的 HyperLogLog 联合的基数估算值。

    1
    
    PFCOUNT key [key ...]
    
  3. PFMERGE

    将多个 HyperLogLog 值合并为一个 HyperLogLog 。如果目标 HyperLogLog 不存在(默认为空 HyperLogLog),则创建。 如果存在,则将其视为源集之一。

    1
    
    PFMERGE destkey [sourcekey [sourcekey ...]]
    

应用场景

  • 网页用户访问(UV)计数

GEO

主要用于存储地理信息

内部实现

底层复用 Zset,使用 GeoHash 实现了经纬度到 Zset 中元素的权重分数的转换,关键机制是 二维地图区间划分区间编码 。地理位置转换为经纬度后,使用区间编码标识,并将编码值作为 Zset 的权重分数。

常用命令

  1. GEOADD

    存储指定的地理位置信息,将经度,纬度,位置名称添加到指定的 key 中

    1
    
    GEOADD key [NX | XX] [CH] longitude latitude member [longitude latitude member ...]
    
    • XX: 只更新已存在的元素,从不添加元素。
    • NX: 不更新已存在的元素。
    • CH: 不更新已存在的元素。 总是添加新元素: 将返回值从添加的新元素数修改为更改的元素总数。 更改的元素是指新增的元素和坐标已更新的已有元素。
  2. GEOPOS

    返回关键字处排序集所代表的地理空间索引中所有指定成员的位置(经度、纬度)。

    1
    
    GEOPOS key [member [member ...]]
    
  3. GEODIST

    返回排序集所代表的地理空间索引中两个成员之间的距离。 单位必须是以下之一,默认为米:m 表示米。 km 表示公里。 mi 表示英里。 ft 表示英尺。

    1
    
    GEODIST key member1 member2 [M | KM | FT | MI]
    
  4. GEORADIUS

    返回使用 GEOADD 填充了地理空间信息的排序集合的成员,这些成员位于以中心位置和距中心最大距离(半径)指定的区域边界内。

    1
    2
    3
    
    GEORADIUS key longitude latitude radius <M | KM | FT | MI>
      [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC | DESC]
      [STORE key | STOREDIST key]
    

应用场景

  • 位置信息服务

Stream

专为消息队列设计的数据类型,支持消息持久化、自动生成全局唯一 ID、支持 ACK 确认消息、支持消费组模式

内部实现

^ - ^

常见命令

  1. XADD

    将指定的数据流条目添加到指定键的数据流中。 如果键值不存在,则使用流的值创建键值。 可以使用 NOMKSTREAM 选项禁用创建数据流键。

    1
    2
    
    XADD key [NOMKSTREAM] [<MAXLEN | MINID> [= | ~] threshold
      [LIMIT count]] <* | id> field value [field value ...]
    
  2. XLEN

    返回数据流中的条目数。 如果指定的键不存在,命令将返回 0。

    1
    
    XLEN key
    
  3. XREAD / XREADGROUP

    XREAD 从一个或多个数据流中读取数据,只返回 ID 大于调用者报告的最后接收 ID 的条目。 该命令有一个选项,可在项目不可用时阻塞。

    XREADGROUP 命令是 XREAD 命令的一个特殊版本,支持消费者组。

    1
    2
    
    XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]
    XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] id [id ...]
    
  4. XDEL

    从数据流中删除指定条目,并返回已删除条目的数量。

    1
    
    XDEL key id [id ...]
    
  5. XRANGE

    该命令返回与给定 ID 范围匹配的数据流条目。

    1
    
    XRANGE key start end [COUNT count]
    
  6. XPENDING / XACK

    XPENDING 查询每个消费组内所有消费者 已读取、尚未确认 的消息。

    XACK 向消息队列确认消息处理已完成

    1
    2
    
    XPENDING key group [[IDLE min-idle-time] start end count [consumer]]
    XACK key group id [id ...]
    
Licensed under CC BY-NC-SA 4.0
载入天数...载入时分秒...
使用 Hugo 构建
主题 StackJimmy 设计