String
String 的底层数据结构是 int 和 SDS(Simple Dynamic String),相比 C 的原生字符串,增加了以下功能
- 保存二进制文件
- 获取字符串长度的时间复杂度是 O(1)
- SDS API 内存安全,保证不会造成缓冲区溢出
内部编码
int,若字符串保存的是整数值,并且可以转换为 long,那么该字符串对象的编码被设置为
int
。embstr,若字符串长度小于等于 44 字节(博主测试环境为 Redis 7.4.1),那么使用
embstr
编码,一次内存分配。只读,修改内容需先转换raw
编码。raw,若字符串长度大于 44 字节,那么使用
raw
编码,两次内存分配。
常用指令
设置 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。
将给定的键设置为各自的值。 两者都是原子式的,因此所有给定键都会被一次性设置。
1 2
MSET key value [key value ...] MSETNX key value [key value ...] # key 必须均不存在
对 key 中存储数字进行加法操作,如果键不存在,则在执行操作前将其设置为 0。
1 2
INCR key # 将存储在键上的数字递增 1。 INCRBY key increment # 将存储在键上的数字递增 increment
对 key 中存储数字进行减法操作,如果键不存在,则在执行操作前将其设置为 0。
1 2
DECR key # 将存储在键上的数字递减 1。 DECRBY key increment # 将存储在键上的数字递减 increment
获取 key 的值。 如果键不存在,则返回特殊值 nil。
1 2
GET key MGET key [key ...]
应用场景
缓存对象
计数器
分布式锁
若 key 不存在,则显示插入成功,表示加锁成功
若 key 存在,则显示插入失败,表示加锁失败
需要配合 Lua 脚本实现原子性
共享 Session 信息
List
List 是简单的字符串列表(按照插入顺序排序),可以从头部或者尾部向 List 添加元素,链表最大长度为 $2^{32}-1$
内部实现
- 3.2 版本之前由双向链表或压缩链表实现。
- 3.2 版本之后由 QuickList 实现。其是多个节点(压缩列表)组成的双向链表,每个元素可以是一个整数或一个字节数组。
常用指令
将所有指定值插入存储在 key 处的列表头部。 如果 key 不存在,则在执行推送操作前将其创建为空列表。 如果 key 持有的值不是 list,则会返回错误信息。
1
LPUSH/RPUSH key element [element ...]
![]() LPUSH 命令 | ![]() RPUSH 命令 |
仅在 key 已存在并持有一个列表的情况下,在 key 所在列表的首部插入指定值。 如果 key 不存在,则不会执行任何操作。
1
LPUSHX/RPUSHX key element [element ...]
删除并返回存储在 key 处的列表的 最初/最后 一个元素。 默认情况下,该命令从列表 头部/尾部 弹出一个元素。 如果提供了可选的 count 参数,则根据列表的长度,回复最多包含 count 个元素。
1
LPOP/RPOP key [count]
BLPOP/BRPOP 是一种阻塞列表弹出原语。 它是 LPOP/RPOP 的阻塞版本,因为当没有元素从任何给定列表中弹出时,它会阻塞连接。 元素会从第一个非空列表的 头部/尾部 弹出,并按照给定键的顺序进行检查。
1
BLPOP/RLPOP key [key ...] timeout
返回存储在 key 中的列表中位于 index 索引处的元素。 索引以 0 为单位,因此 0 表示第一个元素,1 表示第二个元素,以此类推。 负指数可用于指定从列表尾部开始的元素。 这里,-1 表示最后一个元素,-2 表示倒数第二个元素,以此类推。
1
LINDEX key index
返回存储在 key 处的 list 的长度。 如果 key 不存在,则将其解释为空列表,并返回 0。 如果 key 中存储的值不是 list,则会返回错误信息。
1
LLEN key
返回存储在 key 处的列表的指定元素。 偏移量 start 和 stop 是基于 0 的索引,0 代表列表的第一个元素(列表的头),1 代表下一个元素,以此类推。 这些偏移量也可以是负数,表示从列表的末尾开始的偏移量。 例如,-1 是列表的最后一个元素,-2 是倒数第二个元素,以此类推。
1
LRANGE key start stop
从存储在 key 处的列表中移除与元素相同的元素的第一个出现次数。 计数参数对操作的影响如下:count > 0:删除从头部移到尾部的与元素相同的元素。 count < 0:删除从尾部移到头部的与元素相同的元素。 例如,LREM list -2 “hello “将删除存储在 list 中的 “hello “的最后两次出现。 请注意,不存在的键会被当作空 list 处理。
1
LREM key count element
裁剪现有列表,使其只包含指定范围的元素。 start 和 stop 都是基于 0 的索引,其中 0 代表列表的第一个元素(头部),1 代表下一个元素,依此类推。 例如,LTRIM foobar 0 2 将修改存储在 foobar 处的列表,使其只保留列表的前三个元素: start 和 end 也可以是负数,表示与列表末尾的偏移量,其中 -1 表示列表的最后一个元素,-2 表示倒数第二个元素,依此类推。 超出范围的索引不会产生错误:如果 start 大于列表末尾,或 start > end,结果将是一个空列表(导致键被移除)。 如果 end 大于列表末尾,Redis 会将其视为列表的最后一个元素。
1
LTRIM key start stop
将索引处的列表元素设置为指定值。
1
LSET key index element
将元素插入存储在 key 处的列表中的参考值 pivot 之前或之后。 如果 key 不存在,则视为空列表,不执行任何操作。 如果 key 存在但不包含列表值,则返回错误信息。
1
LINSERT key <BEFORE | AFTER> pivot element
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实现
常用命令
将指定字段的值设置为存储在 key 的哈希值中各自的值。 HSET 会覆盖哈希值中存在的指定字段的值,HSETNX 对于已存在的字段操作无效。 如果 key 不存在,则会创建一个新的散列键。
1 2
HSET key field value [field value ...] HSETNX key field value
HGET/HMGET 返回键存储的哈希值中与字段相关的值。 对于散列中不存在的每个字段,都会返回一个 nil 值。 由于不存在的键被视为空哈希值,因此针对不存在的键运行 HMGET 将返回一个 nil 值列表。
HGETALL 返回存储在 key 处的哈希值的所有字段和值。
1 2 3
HGET key field HMGET key field [field ...] HGETALL key
从存储在 key 中的哈希值中删除指定字段。 不存在于散列中的指定字段将被忽略。 如果没有字段,则删除散列。 如果键不存在,则将其视为空散列,此命令返回 0。
1
HDEL key field [field ...]
返回存储在 key 中的哈希值所包含字段的数量。
1
HLEN key
如果字段是存储在 key 处的哈希值中的现有字段,则返回 1,否则返回 0。
1
HEXISTS key field
HKEYS 返回存储在 key 处的哈希值中的所有字段名。
HVALS 返回键存储的哈希值中的所有值。
1 2
HKEYS key HVALS key
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 |
常用命令
将指定的成员添加到存储在 key 处的集合中。 如果指定的成员已经是这个集合的成员,则会被忽略。 如果 key 不存在,则会先创建一个新集合,然后再添加指定的成员。 如果存储在 key 中的值不是一个集合,则会返回错误信息。
1
SADD key member [member ...]
从存储在 key 处的集合中删除指定的成员。 不属于此集合的指定成员将被忽略。 如果 key 不存在,则将其视为空集,此命令返回 0。
1
SREM key member [member ...]
返回存储在 key 处的集合值的所有成员。
1
SMEMBERS key
返回成员是否是存储在 key 中的集合的成员。
1
SISMEMBER key member
返回存储在 key 处的集合的元素个数。
1
SCARD key
SRANDMEMBER 将从存储在 key 处的集合值中随机返回 count 个元素,元素不从 key 中删除。
SPOP 将从存储在 key 处的集合值中随机返回 count 个元素,元素从 key 中删除。
1 2
SRANDMEMBER key [count] SPOP key [count]
将成员从源集合移动到目标集合。 该操作是原子操作。 如果源集合不存在或不包含指定元素,则不执行任何操作,并返回 0。 否则,该元素将从源集合中删除,并添加到目标集合中。 如果指定的元素已存在于目标集合中,则只会从源集合中移除。 如果源集合或目标集合中不存在集合值,则会返回错误信息。
1
SMOVE source destination member
SINTER 返回所有给定集合的交集所产生的集合的成员。
SINTERSTORE 该命令等同于 SINTER,但不是返回结果集,而是将其存储在目的地中。 如果目的地已经存在,则会被覆盖。
1 2
SINTER key [key ...] SINTERSTORE destination key [key ...]
应用场景
- 点赞(元素唯一)
- 共同好友(集合运算)
- 数据量较大时,可以让从库进行集合运算,将结果返回给客户端,防止 Redis 阻塞。
- 抽奖(元素唯一,去重)
Zset
Zset 相较于 Set 多了个排序属性 score,每个存储元素相当于两个值组成,一个是有序集合的元素值,一个是排序值。
内部实现
- 若 Zset 中元素小于 128 个,且每个元素小于 64 字节,Redis 使用 listpack 作为底层数据结构。
- 剩余情况,Redis 会使用
![]() listpack | ![]() skiplist |
常用命令
将具有指定分数的所有指定成员添加到存储在 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 类似。 在这种模式下,只能指定一个分数元素对。
从存储在 key 中的排序集合中删除指定的成员。 如果 key 存在但没有排序集,则会返回错误信息。
1
ZREM key member [member ...]
返回排序集合中 key 处成员的得分。 如果排序集合中不存在成员或 key 不存在,则返回 nil。
1
ZSCORE key member
返回存储在 key 处的排序集的元素个数。
1
ZCARD key
用增量递增键值存储的排序集合中成员的得分。 如果成员不存在于排序集合中,则会以增量作为其得分(就像它之前的得分是 0.0)。 如果 key 不存在,则会创建一个以指定成员为唯一成员的新排序集。 如果 key 存在但不包含排序集,则会返回错误信息。 分数值应是数值的字符串表示,并接受双精度浮点数。 可以提供一个负值来递减分数。
1
ZINCRBY key increment member
返回存储在 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]
1 2
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>] # 并集 ZDIFFSTORE destination numkeys key [key ...] # 第一个集合和之后集合的差集
应用场景
排行榜(有序唯一)
电话、姓名排序
BitMap
BitMap 是一串连续的二进制数组,可以通过偏移量定位元素,适合数据量大且使用二值统计的场景。
内部实现
String 类型是会保存为二进制的字节数组
常用命令
设置或清除存储在 key 处字符串值偏移量的位。 位的设置或清除取决于值,值可以是 0 或 1。当 key 不存在时,将创建一个新的字符串值。 字符串的增长是为了确保它能容纳偏移量处的位。 偏移参数必须大于或等于 0,且小于 2^32(这将位图限制在 512MB)。
1
SETBIT key offset value
返回存储在 key 处的字符串值中偏移量处的比特值。
1
GETBIT key offset
获取指定范围内值为 1 的个数,默认以字节为单位。
1
BITCOUNT key [start end [BYTE | BIT]]
在多个键(包含字符串值)之间执行位操作,并将结果存储到目标键中。
1
BITOP <AND | OR | XOR | NOT> destkey key [key ...]
应用场景
签到统计
判断用户登陆态
HyperLogLog
HyperLogLog 是一种用于统计基数的数据集合类型,基数统计就是指统计一个集合中不重复的元素个数。HyperLogLog 的统计规则基于概率完成,标准误算率为 0.81%。
内部实现
^ - ^
常见命令
将所有元素参数添加到存储在作为第一个参数指定的变量名下的 HyperLogLog 中。
1
PFADD key [element [element ...]]
使用单键调用时,返回存储在指定变量中的 HyperLogLog 的基数估算值,如果变量不存在,则返回 0。 使用多键调用时,通过内部合并存储在所提供键中的 HyperLogLog 成一个临时的 HyperLogLog,返回所传递的 HyperLogLog 联合的基数估算值。
1
PFCOUNT key [key ...]
将多个 HyperLogLog 值合并为一个 HyperLogLog 。如果目标 HyperLogLog 不存在(默认为空 HyperLogLog),则创建。 如果存在,则将其视为源集之一。
1
PFMERGE destkey [sourcekey [sourcekey ...]]
应用场景
- 网页用户访问(UV)计数
GEO
主要用于存储地理信息
内部实现
底层复用 Zset,使用 GeoHash 实现了经纬度到 Zset 中元素的权重分数的转换,关键机制是 二维地图区间划分 和 区间编码 。地理位置转换为经纬度后,使用区间编码标识,并将编码值作为 Zset 的权重分数。
常用命令
存储指定的地理位置信息,将经度,纬度,位置名称添加到指定的 key 中
1
GEOADD key [NX | XX] [CH] longitude latitude member [longitude latitude member ...]
- XX: 只更新已存在的元素,从不添加元素。
- NX: 不更新已存在的元素。
- CH: 不更新已存在的元素。 总是添加新元素: 将返回值从添加的新元素数修改为更改的元素总数。 更改的元素是指新增的元素和坐标已更新的已有元素。
返回关键字处排序集所代表的地理空间索引中所有指定成员的位置(经度、纬度)。
1
GEOPOS key [member [member ...]]
返回排序集所代表的地理空间索引中两个成员之间的距离。 单位必须是以下之一,默认为米:m 表示米。 km 表示公里。 mi 表示英里。 ft 表示英尺。
1
GEODIST key member1 member2 [M | KM | FT | MI]
返回使用 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 确认消息、支持消费组模式
内部实现
^ - ^
常见命令
将指定的数据流条目添加到指定键的数据流中。 如果键值不存在,则使用流的值创建键值。 可以使用 NOMKSTREAM 选项禁用创建数据流键。
1 2
XADD key [NOMKSTREAM] [<MAXLEN | MINID> [= | ~] threshold [LIMIT count]] <* | id> field value [field value ...]
返回数据流中的条目数。 如果指定的键不存在,命令将返回 0。
1
XLEN key
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 ...]
从数据流中删除指定条目,并返回已删除条目的数量。
1
XDEL key id [id ...]
该命令返回与给定 ID 范围匹配的数据流条目。
1
XRANGE key start end [COUNT count]
XPENDING 查询每个消费组内所有消费者 已读取、尚未确认 的消息。
XACK 向消息队列确认消息处理已完成
1 2
XPENDING key group [[IDLE min-idle-time] start end count [consumer]] XACK key group id [id ...]