在 Redis 数据类型 中我写了 Redis 的 5 种数据类型和一些简单的基础命令. 这一章再写一些更加深刻的命令.redis
字符串能够存储如下三种类型的值:segmentfault
整数的取值范围和系统的长整数 (long integer) 的取值范围相同 (在 322 位系统中, 整数就是 32 位有符号整数, 在 64 位系统中, 整数就是 64 位有符号整数), 而浮点数取值范围和精度则与 IEEE 754 标准的双精度浮点数 (double) 相同.数组
能够经过给定一个任意的数值, 对存储着整数或浮点数的字符串执行自增或自减操做, 在有须要的时候, Redis 还会将整数转换成浮点数.
若是用户对一个不存在的键或者一个保存了空串的键执行自增或自减操做, 那么这个键的值看成是 0 来处理. 若是值没法被解释为整数或者浮点数的字符串键执行自增或自减操做, Redis 就会返回一个错误.安全
INCR key-name 将键存储的值加上 1, 返回执行完加 1 操做后的值. INCRBY key-name amount 将键存储的值加上整数 amount . 返回加上 amount 后的值. DECR key-name 将键存储的值减去 1, 返回执行完减 1 操做后的值. DECRBY key-name amount 将键存储的值减去整数 amount. 返回减去 amount 后的值. INCRBYFLOAT key-name amount 将键存储的值加上浮点数 amount. 返回加上 amount 后的值.
INCRBYFLOAT 若是 amount 为 3.0 则会将浮点数转换为整数也就是 3.
APPEND key-name value 将值 value 追加到指定的 key-name 当前存储的值得末尾, 返回追加后的长度. 若是不存在则同等于 key-name value. SETRANGE key-name offset value 字符串替换. 返回替换后的字符串长度. 从 offset 偏移量开始, 替换为 value. GETRANGE key-name start end 从 start 开始到 end 结束, 返回指定部分的字符串.
GETRANGE 包含 start 和 end. 若是读取字符串的时候, 超出字符串末尾的数据, 只会获取到最后.
若是咱们要判断指定 key 是否存在可使用 EXISTS
, 若 key 存在返回 1, 不然返回 0.服务器
LRANGE key-name start end 返回列表从 start 偏移量到 end 偏移量范围内的全部元素. LTRIM key--name start end 对列表进行修剪, 只保留从 start 偏移量到 end 偏移量范围内的元素.
BLPOP key-name [key-name] timeout
阻塞行为函数
若是全部给定 key 都不存在或包含空列表, 那么 BLPOP
命令将阻塞链接, 直到等待超时, 或有另外一个客户端对给定 key 的任意一个执行 LPUSH key value [value …]
或 RPUSH key value [value …]
命令为止.网站
超时参数 timeout
接受一个以秒为单位的数字做为值. 超时参数设为 0
表示阻塞时间能够无限期延长.scala
非阻塞行为code
当 BLPOP
被调用时, 若是给定 key 内至少有一个非空列表, 那么弹出遇到的第一个非空列表的头元素, 并和被弹出元素所属的列表的名字一块儿, 组成结果返回给调用者.排序
当存在多个给定 key 时, BLPOP
按给定 key 参数排列的前后顺序, 依次检查各个列表.
假设如今有 job
、 command
和 request
三个列表, 其中 job
不存在, command
和 request
都持有非空列表. 考虑如下命令:
BLPOP job command request 0
BLPOP
保证返回的元素来自 command
, 由于它是按 ”查找 job -> 查找 command -> 查找 request “ 这样的顺序, 第一个找到的非空列表.
redis> DEL job command request # 确保key都被删除 (integer) 0 redis> LPUSH command "update system..." # 为command列表增长一个值 (integer) 1 redis> LPUSH request "visit page" # 为request列表增长一个值 (integer) 1 redis> BLPOP job command request 0 # job 列表为空,被跳过,紧接着 command 列表的第一个元素被弹出。 1) "command" # 弹出元素所属的列表 2) "update system..." # 弹出元素所属的值
相同的 key 被多个客户端同时阻塞
相同的 key 能够被多个客户端同时阻塞.
不一样的客户端被放进一个队列中, 按『先阻塞先服务』(first-BLPOP, first-served)的顺序为 key 执行 BLPOP
命令.
客户端1 执行参考以下:
blpop job 35
客户端2 执行参考以下:
blpop job 30
key job 是不存在的, 客户端1 超时时间为 35 秒, 客户端2 超时时间为 30 秒. 执行结果以下:
客户端2 先被打印, 而后在打印客户端1, 由于客户端2 的超时时间是 30 秒.
127.0.0.1:6379> blpop job 30 (nil) (30.04s) 127.0.0.1:6379> blpop job 35 (nil) (35.09s)
若是两个客户端的超时时间都为 0
会是怎样的呢?
这个时候就会像前面提到的, 按『先阻塞先服务』的顺序为 key 执行 BLPOP
命令.
RPOPLPUSH source-key dest-key
命令 RPOPLPUSH
在一个原子时间内, 执行如下两个动做:
source-key
中的最后一个元素(尾元素)弹出, 并返回给客户端.source-key
弹出的元素插入到列表 dest-key
, 做为 dest-key
列表的的头元素.若是 source-key
不存在, 值 nil
被返回, 而且不执行其余动做.
若是 source-key
和 dest-key
相同(同一个key), 则列表中的表尾元素被移动到表头, 并返回该元素, 能够把这种特殊状况视做列表的旋转(rotation)操做.
模式: 安全的队列
Redis 的列表常常被用做队列(queue), 用于在不一样程序之间有序地交换消息(message). 一个客户端经过 LPUSH key value [value …]
命令将消息放入队列中, 而另外一个客户端经过 RPOP key
或者 BRPOP key [key …] timeout
命令取出队列中等待时间最长的消息.
不幸的是, 上面的队列方法是『不安全』的, 由于在这个过程当中, 一个客户端可能在取出一个消息以后崩溃, 而未处理完的消息也就所以丢失.
使用 RPOPLPUSH
命令(或者它的阻塞版本 BRPOPLPUSH source destination timeout
` )能够解决这个问题.
由于它不只返回一个消息, 同时还将这个消息添加到另外一个备份列表当中, 若是一切正常的话, 当一个客户端完成某个消息的处理以后, 能够用 LREM key count value
命令将这个消息从备份表删除.
最后, 还能够添加一个客户端专门用于监视备份表, 它自动地将超过必定处理时限的消息从新放入队列中去(负责处理该消息的客户端可能已经崩溃), 这样就不会丢失任何消息了.
模式: 循环列表
经过使用相同的 key 做为 RPOPLPUSH
命令的两个参数, 客户端能够用一个接一个地获取列表元素的方式, 取得列表的全部元素, 而没必要像 LRANGE key start stop
命令那样一会儿将全部列表元素都从服务器传送到客户端中.
以上的模式甚至在如下的两个状况下也能正常工做:
这个模式使得咱们能够很容易实现这样一类系统: 有 N 个客户端, 须要接二连三地对一些元素进行处理, 并且处理的过程必须尽量地快.
一个典型的例子就是服务器的监控程序: 它们须要在尽量短的时间内, 并行地检查一组网站, 确保它们的可访问性.
注意, 使用这个模式的客户端是易于扩展(scala)且安全(reliable)的, 由于就算接收到元素的客户端执行失败, 元素仍是保存在列表里面, 不会丢失, 等到下个迭代来临的时候, 别的客户端又能够继续处理这些元素了.
SCARD key-name 返回集合 key 的基数. 当 key 不存在时, 返回 0.
随机返回元素
SRANDMEMBER key-name [count]
若是命令执行时, 只提供了 key 参数, 那么返回集合中的一个随机元素.
count
参数分为以下两种:
SPOP key-name [count]
移除并返回集合中的一个随机元素. 当 key 不存在或 key 是空集时, 返回 nil
.
组合或处理多个集合
SMOVE source-key dest-key member
若是 source-key
集合不存在或不包含指定的 member
元素, 则 SMOVE
命令不执行任何操做, 仅返回 0(零). 不然, member
` 元素从 source-key
集合中被移除, 并添加到 dest-key
集合中.
当 dest-key
集合已经包含 member
元素时, SMOVE
命令只是简单地将 source-key
集合中的 member
元素删除.
SDIFF key [key …]
返回那些存在于第一个集合, 但不存在于其余集合中的元素.
不存在的 key 被视为空集.
SDIFFSTORE destination key [key …]
这个命令的做用和 SDIFF key [key …]
相似, 但它将结果保存到 destination
集合, 而不是简单地返回结果集.
若是 destination
集合已经存在, 则将其覆盖.
destination
能够是 key 自己.
返回结果集中的元素数量.
SINTER key [key …]
返回存在全部集合中的元素.
SUNION key [key …]
返回一个集合的所有成员, 该集合是全部给定集合的并集.
不存在的 key 被视为空集.
HMSET key field value [field value …] 设置多个键值. HVALS key 返回全部的值. HKEYS key 返回全部的键. HGETALL key 返回全部的键值.
HMGET key field [field …]
返回哈希表 key 中, 一个或多个给定域的值.
若是给定的域不存在于哈希表, 那么返回一个 nil 值.
由于不存在的 key 被看成一个空哈希表来处理, 因此对一个不存在的 key 进行 HMGET 操做将返回一个只带有 nil 值的表.
HEXISTS hash field
检查给定域 field 是否存在于哈希表 hash 当中. 给定域存在时返回 1, 在给定域不存在时返回 0.
HINCRBY key field increment
为哈希表 key 中的域 field 的值加上增量 increment.
增量也能够为负数, 至关于对给定域进行减法操做.
若是 key 不存在, 一个新的哈希表被建立并执行 HINCRBY 命令.
若是域 field 不存在, 那么在执行命令前, 域的值被初始化为 0.
对一个储存字符串值的域 field 执行 HINCRBY 命令将形成一个错误.
本操做的值被限制在 64 位(bit)有符号数字表示以内.
HINCRBYFLOAT key field increment
为哈希表 key 中的域 field 加上浮点数增量 increment.
若是哈希表中没有域 field, 那么 HINCRBYFLOAT
会先将域 field 的值设为 0, 而后再执行加法操做.
若是键 key 不存在, 那么 HINCRBYFLOAT
会先建立一个哈希表, 再建立域 field, 最后再执行加法操做.
当如下任意一个条件发生时, 返回一个错误:
increment
不能解释 (parse) 为双精度浮点数(double precision floating point number).ZADD key score member [[score member] [score member] …]
将一个或多个 member
元素及其 score
值加入到有序集 key 当中.
若是某个 member
已是有序集的成员, 那么更新这个 member
的 score
值, 并经过从新插入这个 member
元素, 来保证该 member
在正确的位置上.
score
值能够是整数值或双精度浮点数.
若是 key
不存在, 则建立一个空的有序集并执行 ZADD
操做.
当 key
存在但不是有序集类型时, 返回一个错误.
返回被成功添加的新成员的数量, 不包括那些被更新的, 已经存在的成员.
ZREM key member [member …] 移除有序集 key 中的一个或多个成员, 不存在的成员将被忽略. 被成功移除的成员的数量, 不包括被忽略的成员. ZCARD key 当 key 存在且是有序集类型时, 返回有序集的基数. 当 key 不存在时, 返回 0. ZCOUNT key min max 返回有序集 key 中, score 值在 min 和 max 之间的成员的数量. ZRANK key member 返回有序集 key 中成员 member 的排名. 其中有序集成员按 score 值递增(从小到大)顺序排列. ZREVRANK key member 返回有序集 key 中成员 member 的排名.其中有序集成员按 score 值递减(从大到小)排序. ZSCORE key member 返回有序集 key 中, 成员 member 的 score 值. 若是 member 元素不是有序集 key 的成员, 或 key 不存在, 返回 nil.
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
返回有序集 key 中, 全部 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员. 有序集成员按 score 值递增(从小到大)次序排列.
具备相同 score 值的成员按字典序(lexicographical order)来排列(该属性是有序集提供的, 不须要额外的计算).
可选的 LIMIT 参数指定返回结果的数量及区间(就像SQL中的 SELECT LIMIT offset, count ), 注意当 offset 很大时, 定位 offset 的操做可能须要遍历整个有序集.
可选的 WITHSCORES 参数决定结果集是单单返回有序集的成员, 仍是将有序集成员及其 score 值一块儿返回.
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] 从大到小.
交集和并集
ZUNIONSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]
计算给定的一个或多个有序集的并集, 其中给定 key 的数量必须以 numkeys 参数指定, 并将该并集(结果集)储存到 destination.
默认状况下, 结果集中某个成员的 score 值是全部给定集下该成员 score 值之和.
WEIGHTS
使用 WEIGHTS 选项, 你能够为每一个给定有序集分别指定一个乘法因子(multiplication factor), 每一个给定有序集的全部成员的 score 值在传递给聚合函数(aggregation function)以前都要先乘以该有序集的因子.
若是没有指定 WEIGHTS 选项, 乘法因子默认设置为 1.
AGGREGATE
使用 AGGREGATE 选项, 你能够指定并集的结果集的聚合方式.
默认使用的参数 SUM
, 能够将全部集合中某个成员的 score 值之和做为结果集中该成员的 score 值; 使用参数 MIN
, 能够将全部集合中某个成员的最小 score 值做为结果集中该成员的 score 值; 而参数 MAX
则是将全部集合中某个成员的最大 score 值做为结果集中该成员的 score 值.
ZINTERSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]
计算给定的一个或多个有序集的交集, 其中给定 key 的数量必须以 numkeys 参数指定, 并将该交集(结果集)储存到 destination.
默认状况下, 结果集中某个成员的 score 值是全部给定集下该成员 score 值之和.
并集和交集的主要区别
咱们如今有三个有序集合, 以下:
ZRANGE test1 0 -1 WITHSCORES "z" "1" "a" "2" "e" "3" ZRANGE test2 0 -1 WITHSCORES "a" "1" ZRANGE test3 0 -1 WITHSCORES "r" "2"
使用交集结果以下:
ZINTERSTORE destination 3 test1 test2 test3 (integer) 0 ZINTERSTORE destination 2 test1 test2 (integer) 1
test1 和 test2 中都存在成员是 "a" 的数据, 因此当咱们执行第二条命令的时候, "a" 的成员被添加到了 destination 有序集中, 而且分值为 3(默认使用 SUM
).
而执行第一条命令时, 并没添加到 destination 有序集中. 缘由是 test3 中没有成员 "a".
交集只会将给定有序集中的相同成员添加到 destination 有序集中. 并集和交集不一样, 只要某个成员存在于任意一个给定的有序集中, 都会被添加到 destination 有序集中.