数据类型
命令速查: http://doc.redisfans.com/
Key 操作
redis 中不管保存什么类型的数据, 它都要对应一个 key, 先看看 key 的命令有哪些.
keys: 返回所有符合给定模式(正则)的 key
语法 keys regex
key * 匹配所有字符
key ? 匹配一个任意字符
key [] 匹配字符组
key \x 匹配转义字符
exists: 检测指定 key 是否存在
语法 exists key
存在返回 1
不存在返回 0
type: 返回相关 key 的 value 类型
语法 type key
expire: 设置 key 的过期时间, 单位秒
语法 expire key seconds
set/getset 命令, 会清除 key 的过期时间
ttl: 查看相关 key 的剩余时间, 单位秒
语法 ttl key
没有设置 key 的过期时间, 返回 -1
如果 key 不存在, 返回 -2
expireat: 设置 key 的过期时间点(在指定时间戳过期), 单位秒
语法 expireat key timestamp
set/getset 命令, 会清除 key 的过期时间
pexpire: 设置 key 的过期时间, 单位毫秒
语法 pexpire key millisecond
set/getset 命令, 会清除 key 的过期时间
pttl: 查看相关 key 的剩余时间, 单位毫秒
语法 pttl key
没有设置 key 的过期时间, 返回 -1
如果 key 不存在, 返回 -2
pexpireat: 设置 key 的过期时间点(在指定时间戳过期), 单位毫秒
语法 pexpireat key timestamp
set/getset 命令, 会清除 key 的过期时间
persist: 将 key 设置永久
语法 persist key
del: 删除指定 keys
语法 del key1 key2
返回删除 key 的数量
randomkey: 随机取个 key
语法 randomkey
rename: 重命名 key
语法 rename key newkey
如果 newkey 与当前已有 key 重名, 会覆盖掉旧的 key
renamenx: 重命名 key, 但 newkey 必须不存在时才生效
语法 renamenx key newkey
dump: 序列化给定的 key, 返回序列化之后的值
语法 dump key
restore: 反序列化
语法 restore key millisecond value
将 value 反序列化到一个 key 上
millisecond 为生存时间, 设为 0 表示不限制时间
move: 将当前数据库中的 key 移动到另一个数据库
语法 move key dbid
如果另一个数据库已经有同名 key, 则不发生移动
String
一个键最多存储 512 MB.
注意: 所有的 String 命令, 设置 value 时要用引号包起来(数字除外, 输入数字 redis 会自动在内部转化成 str)
set: 设置相关 key 的 value
语法 set key value
get: 获取相关 key 的 value
语法 get key
key 不存在返回 nil
key 持有非字符串 value 则返回一个错误
append: 追加相关 key 中的 value
语法: append key value
如果 key 已经存在并且是一个字符串, 将 value 追加到 key 原来的值的末尾
如果 key 不存在,就简单地将给定 key 设为 value, 就像执行 set key value 一样
返回 key 中追加后的 value 长度
setrange: 替换相关 key 的 value 中的一部分
语法 setrange key offset value
将原 value 中 [offset 至 value 结束] 的部分替换掉
返回被替换部分的内容长度
如果待替换部分的内容长度比要设置的新内容长度长, 则会以 \x00 填充
key 不存在时, 会生成新 key
getrange: 返回字符串的一部分
语法 getrange key start end
下标从 0 开始
支持负数, 表示从字符串末尾开始数(-1 表示最后一个)
getset: 设置相关 key 的 value 并返回旧的 value
语法 getset key value
key 不存在时, 返回 nil, 并新建 key
key 持有非字符串 value 则返回一个错误
mset: 设置多个 key 的 value
语法 mset key1 value1 key2 value2 ...
mget: 获取个 key 的 value
语法 mset key1 key2 ...
返回多行字符串
strlen: 获取相关 key 的 value 的长度
语法 strlen key
key 不存在时, 返回 0
key 持有非字符串 value 则返回一个错误
setnx: 仅当 key 不存在时才设置成功
语法 setnx key value
setex: 设置 key 的过期时间, 即 key 多久后自动销毁, 单位秒
语法 setex key seconds value
可用 ttl key 查看 key 还剩多久, 单位秒
可用 expire key seconds 单独设置 key 的过期时间, 单位秒
msetnx: 设置多个 key 的 value, 仅当所有的 key 都不存在时才设置成功
语法 msetnx key1 value1 key2 value2
成功返回 1, 失败返回 0
psetex: 设置 key 的过期时间, 即 key 多久后自动销毁, 单位毫秒
语法 psetex key millisecond value
可用 pttl key 查看 key 还剩多久, 单位毫秒
可用 pexpire key seconds 单独设置 key 的过期时间, 单位毫秒
set 扩展语法: 设置相关 key 的 value
语法 set key value 扩展参数
ex seconds: 等同于 setex
px millisecond: 等同于 psetex
nx: 等同于 setnx
xx: 只有键已经存在才可以设置成功
incr: 对 key 中存储的数字 +1
语法 incr key
如果 key 不存在, 则会先初始化为 0, 再进行 incr 操作
如果 key 的 value 不是数字(指数字型字符串), 则会报错
incrby: 对 key 中存储的数字加上指定 int 值
语法 incrby key increment
increment 必须是 int 型
如果 key 不存在, 则会先初始化为 0, 再进行 incr 操作
如果 key 的 value 不是数字(指数字型字符串), 则会报错
incrbyfloat: 对 key 中存储的数字加上指定 float 值
语法 incrby key increment
increment 可以是 int 、float 型
如果 key 不存在, 则会先初始化为 0, 再进行 incr 操作
如果 key 的 value 不是数字(指数字型字符串), 则会报错
decr: 对 key 中存储的数字 -1
语法 decr key
如果 key 不存在, 则会先初始化为 0, 再进行 decr 操作
如果 key 的 value 不是数字(指数字型字符串), 则会报错
decrby: 对 key 中存储的数字减去指定 int 值
语法 decrby key decrement
decrement 必须是 int 型
如果 key 不存在, 则会先初始化为 0, 再进行 incr 操作
如果 key 的 value 不是数字(指数字型字符串), 则会报错
decr 系列没有 decrbyfloat 命令
Hash
Redis Hash 其实是 key 的 value 中保存的是一个 HashMap, 如果该 Map 的成员数比较少, 则会采用类似一维线性的紧凑格式来存储该 Map, 即省去了大量指针的内存开销, 这个参数控制对应在 redis.conf 配置文件中下面 2 项:
hash-max-zipmap-entries 64
hash-max-zipmap-value 512
entries 的含义是当 value 中的 Map 内部不超过多少个成员时会采用线性紧凑格式存储, 默认是 64, 超过该值自动转成真正的 HashMap.
value 的含义是当 value 中的 Map 内部的每个成员值长度不超过多少字节就会采用线性紧凑存储来节省空间.
以上 2 个条件任意一个条件超过设置值都会转换成真正的 HashMap, 也就不会再节省内存了, 那么这个值是不是设置的越大越好呢, 答案当然是否定的, HashMap 的优势就是查找和操作的时间复杂度都是O(1)的, 而放弃 Hash 采用一维存储则是O(n)的时间复杂度,如果成员数量很少, 则影响不大, 否则会严重影响性能, 所以要权衡好这个值的设置, 一般默认即可.
hset: 设置相关 key 中保存的 Hash 的 field 的值
语法 hset key field value
hget: 获取相关 key 中保存的 Hash 的 field 的值
语法 hget key field
key 或者 field 不存在, 返回 nil
hsetnx: 设置相关 key 中保存的 Hash 的 field 的值, field 不存在时才设置成功
语法 hsetnx key field value
hmset: 设置相关 key 中保存的 Hash 的多个 field 的值
语法 hmset key field1 value1 field2 value2 ...
hmget: 获取相关 key 中保存的 Hash 的多个 field 的值
语法 hmget key field1 field2 ...
返回多行字符串
hgetall: 获取相关 key 中保存的 Hash 所有 field 和 value
语法 hgetall key
返回多行字符串
奇数序号是 field
偶数序号是 value
hkeys: 获取相关 key 中保存的 Hash 所有 field
语法 hkeys key
hvals: 获取相关 key 中保存的 Hash 所有 value
语法 hvals key
hexists: 检测相关 key 中保存的 Hash 的 field 是否存在
语法 hexists key field
存在返回 1
不存在返回 0
hlen: 获取相关 key 中保存的 Hash 的 field 的数量
语法 hlen key
hincrby: 对 key 中保存的 hash 的 field 存储的数字上指定 int 数值
语法 hincrby key field increment
increment 只能是 int 型
hincrbyfloat: 对 key 中保存的 hash 的 field 存储的数字上指定值
语法 hincrbyfloat key field increment
increment 可以是 int 和 float 型
hdel: 删除 key 中保存的 hash 的 fields
语法 hdel key field field
返回被删除 field 的数量
List
List 型的 value 最多存储 (2^32 - 1) 个元素
List 类型的数据的弊端和常规 List 一样 -- 通过下标(索引)来访问, 效率很低.
使用 Rdies List, 可以简单实现 MQ 功能.
注意, 列表的 左端 的下标为 0, 即为列表头.
lpush: 向左端添加元素(一个或多个)
语法 lpush key value1 value2 ...
如果 key 不存在, 则新建
如果 key 中原有 value 不是 list, 则报错
返回插入后的 List 长度
rpush: 向右端添加元素(一个或多个)
同 lpush
lpushx: 向左端添加元素(一个)
语法 lpushx key value
必须 key 已经存在时才添加成功, 不存在返回 0
rpushx: 向左端添加元素(一个)
语法 rpushx key value
必须 key 已经存在时才添加成功, 不存在返回 0
lpop: 弹出左端的第一个元素
语法 lpop key
返回元素
key 不存在, 返回 nil
rpop: 弹出右端的第一个元素
同 lpop
llen: 获取列表的长度(元素数量)
语法 llen key
key 不存在, 返回 0
lrange: 获取列表片段
语法 lrange key start end
下标从 0 开始
支持负数, 表示从字符串末尾开始数(-1 表示最后一个)
ltrim: 截取列表片段(类似字符串截取)
语法 ltrim key start end
lrem: 删除列表中 N 个指定的值的元素
语法 lrem key count value
删除列表中值为 value 的元素, 移除 count 个
count > 0, 从列表左向右开始删除 count 个, 即从列表头开始删
count < 0, 从列表右向左开始删除 count 个, 即从列表尾开始删
count = 0, 删除所得符合条件的元素
lindex: 获得指定索引元素的值
语法 lindex key index
index 超出范围, 返回 nil
lset: 设置指定索引元素的值
语法 lset key index value
linsert: 插入元素
语法 linsert key before/after pivot value
在列表中值为 pivot 的元素前或者后插入新元素 value
如果列表中没有值为 pivot 的元素, 则不进行插入, 返回 -1
如果 key 不存在, 返回 0
rpoplpush: 将元素从一个列表右端弹出, 插入另一个列表左端
语法 rpoplpush key1 key2
返回操作元素的值
如果 key1 == key2, 则相当于把一个元素从列表头移到列表尾
注意, 没有 lpoprpush
blpop: lpop 的阻塞版本, 但它支持多个 key
语法 blpop key1 key2 ... timeout
如果给定列表中没有元素, 则该命令不会返回, 直到 timeout 或者有元素可 pop(即有另一个客户端对列表执行 push 命令)
timeout 设为 0 表示永久等待
多个 key 参数时, 按参数 key 的先后顺序依次检查各个列表, 弹出第一个非空列表的头元素
返回多行字符串
第一行表示是哪个 key 返回的
第二行表示返回的值
brpop: rpop 的阻塞版本, 但它支持多个 key
同 blpop
brpoplpush: rpoplpush 的阻塞版本
语法 brpoplpush source destination timeout
当列表 source 为空时, brpoplpush 命令将阻塞连接, 直到等待超时, 或有另一个客户端对 source 执行 push 命令为止
timeout 设为 0 表示永久等待
Set
可以理解成一种特殊的 list.
但和 List 类型不同的是, Set 集合中不允许出现重复的元素, 这一点和 C++ 标准库中的 set 容器是完全相同的.
和 List 类型相比, Set 类型在功能上还存在着一个非常重要的特性, 即完成多个 Set 之间的聚合计算操作, 如并集、差集.
例如做 QQ号 好友推荐功能, 两个 QQ号 的好友都用集合来存储, 就可以通过集合的差集功能.
sadd: 向集合中添加元素
语法 sadd key member1 member2 ...
返回添加元素的个数
scard: 返回集合中元素个数
语法 scard key
集合不存在, 返回 0
smembers: 查看集合中的元素
语法 smembers key
返回多行字符串
sismember: 检测 member 是否是集合中的成员
语法 sismember key member
srem: 删除集合中的一个或多个成员
语法 srem key member1 member2 ...
返回成功删除的元素个数
spop: 弹出集合中的随机元素
语法 spop key
srandmember: 返回集合中的随机元素(注意, 不是弹出)
语法 srandmember key count
count 指定返回元素的个数
count > 0, 返回指定个数的元素, 返回的元素不重复
count < 0, 返回指定个数的元素, 返回的元素可重复
smove: 将一个集合中的元素移动到另一个集合
语法: smove source destination member
将集合 source 中的元素 member 移动到集合 destination 中
sdiff: 返回集合间的差集
语法 sdiff key1 key2 ...
key 的顺序很重要, 谁在前面, 就返回谁的差集
如 key1 = [1, 2, 3], key2 = [2, 3, 4]
sdiff key1 key2
返回 1
sdiff key2 key1
返回 4
sinter: 返回集合间的交集
语法 sinter key1 key2 ...
sunion: 返回集合间的并集
语法 sunion key1 key2 ...
sdiffstore: 将差集结果保存到指定集合中
语法 sdiffstore destination key1 key2 ...
将 key1 key2 集合的差集保存到集合 destination 中
destination 也可以中 key1/key2 本身
sinterstore: 将交集结果保存到指定集合中
语法 参考 sdiffstore
sunionstore: 将并集结果保存到指定集合中
语法 参考 sdiffstore
Sorted Set
相当于给 set 中的元素都关联一个权值, SortedSet 根据权值可以为集合进行排序.
zrank: 获取元素的排名(下标)
语法: zrank key member
所谓排名, 就是这个元素在集合中的下标
按权值从小到大排序, 所以下标 0 就是权值最小的元素
zrevrank: 获取元素的排名(下标)
语法: zrank key member
所谓排名, 就是这个元素在集合中的下标
按权值从大到小排序, 所以下标 0 就是权值最大的元素
zdd: 将元素及其分数添加到集合中
语法 zdd key score1(权值) member1(元素) score2 member2 ...
返回添加的成员数量
score1 可以是 +inf(正, 无穷大) -inf(负, 无穷小)
zscore: 获取指定元素的权值
语法 zscore key member
key 或 member 不存在, 返回 nil
zcard: 获取集合中元素的数量
语法 zcard key
zcount: 获取指定权值内的元素数量
语法 zcount key min max
(score 表示不包含 score, 参考下面的 zrangebyscore
zrange: 获取一段区间内的元素, 从小到大
语法 zrange start end
对 zrange 来说, 按权值从小到大排序, 所以下标 0 就是权值最小的元素
如果元素权值相同, 对元素的值按字典序排序
可选参数 withscores, 表示返回元素的权值
zrevrange: 获取一段区间内的元素, 从大到小
语法 zrevrange start end
对 zrevrange 来说, 按权值从大到小排序, 所以下标 0 就是权值最大的元素
其他的同 zrange
zrangebyscore: 获取指定权值范围内的元素, 从小到大
语法 zrangebyscore key min max [withscores] [limit offset count]
单独的写 score 表示包含 score
如 zrangebyscore key 80 90 表示权值包含 80 和 90
(score 表示不包含 score,
如 zrangebyscore key 80 (90 表示权值包含 80, 但不包含 90
如 zrangebyscore key (80 90 表示权值不包含 80, 但包含 90
可选参数 withscores, 表示返回元素的权值
可选参数 limit, 表示从返回的结果中从 offset 处截取 count 个元素
zrevrangebyscore: 获取指定权值范围内的元素, 从大到小
参考 zrangebyscore
zincrby: 增加元素的权值, 可以是负数
语法 zincrby key increment member
返回操作后的权值
zrem: 删除一个或多个元素
语法 rem key member1 member2 ...
返回删除元素的个数
zremrangebyrank: 删除指定下标范围内的元素
语法 zremrangebyrank key start end
按权值从小到大排序, 所以下标 0 就是权值最小的元素
zremrangebyscore: 删除指定权值范围内的元素
语法 zremrangebyscore key min max
(score 表示不包含 score, 参考 zrangebyscore
zinterstore: 返回集合间的交集
语法 zinterstore destination numkeys key1 key2 [weight weight1 weight2 ...] [aggregate SUM | MIN | MAX]
返回 destination 元素的个数
计算给定的一个或多个有序集的交集, 并将该交集(结果集)储存到 destination
给定 key 的数量必须以 numkeys 参数指定
默认情况下, destination 成员的权值为所有给定集合下该成员权值之和(可通过 aggregate 指定)
可选参数 weight
使用 weight 选项, 可以为每个给定集合分别指定一个乘法因子(multiplication factor), 每个给定集合的所有成员的权值在传递之前都要先乘以该集合的乘法因子
如果没有指定 weight 选项,乘法因子默认设置为 1
可选参数 aggregate
使用 aggregate 选项,可以指定 destination 中元素权值的计算方式
SUM, 默认使用的参数, 即求和
MIN, 取所有集合中最小的权值
MAX, 取所有集合中最大的权值
zunionstore: 返回集合间的并集
参考 zinterstore
HyperLogLog
这是 Redis 在 2.8.9 版本新添加的类型.
使用上面的方式来解决这个问题, 随着集合记录的 ip 越来越多, 消耗的内存也会越来越大.
为了更好地解决像独立 IP 地址计算这种问题,引了 HyperLogLog 类型.
HyperLogLog 可以接受多个元素作为输入, 并给出输入元素的基数估算值
基数
集合中不同元素的数量
比如 {'apple', 'banana', 'cherry', 'banana', 'apple'} 的基数就是 3
估算值
算法给出的基数并不是精确的, 可能会比实际稍微多一些或者稍微少一些,但会控制在合理的范围之内
HyperLogLog 的优点是, 即使输入元素的数量或者体积非常非常大, 计算基数所需的空间总是固定 的、并且是很小的. 但是, 因为 HyperLogLog 只会根据输入元素来计算基数, 而不会储存输入元素本身, 所以 HyperLogLog 不能像集合那样, 返回输入的各个元素.
也就是说, 如果业务关心的是元素的数量而不是元素本身, 就使用 HyperLogLog
下表列出了使用 HyperLogLog 记录不同数量的独立 IP 时,需要耗费的内存数量:
独立 IP 数量 | 一天 | 一个月 | 一年(使用 HyperLogLog) | 一年(使用set) |
一百万 | 12 KB | 360 KB | 4.32 MB | 5.4 GB |
一千万 | 120 KB | 3600 KB | 43.2 MB | 54 GB |
一亿 | 1200 kb | 36000 KB | 432 MB | 540 GB |
HyperLogLog 的具体命令请自行搜索, 不在这里记录了.
Last updated