文章目录
- CLI命令行
-
- 服务器启动
- 客户端启动
- 对象操作命令
-
- KEY操作
-
- Sort
- Scan
-
- SCAN 命令的基本用法
- SCAN 命令的保证
- SCAN 命令每次执行返回的元素数量
- COUNT 选项
- MATCH 选项
- 迭代终结的保证
- String对象操作
-
- SET
- 应用场景
-
- BITCOUNT
- Hash对象操作
- List对象操作
-
- BLPOP
-
- 非阻塞行为
- 阻塞行为
- 相同的key被多个客户端同时阻塞
- 在MULTI/EXEC事务中的BLPOP
- 场景:事件提醒
- **RPOPLPUSH**
-
- 场景
-
- 安全的队列
- 循环列表
- **BRPOPLPUSH**
- SET对象操作
- SortedSet对象操作
-
- ZUNIONSTORE
- ZINTERSTORE
- 发布订阅命令
-
-
- PSUBSCRIBE
- PUBSUB
-
- 事务命令
- 连接命令
- 服务器操作命令
-
- Client List
- CONFIG REWRITE
-
- 原子性重写
- INFO
- SHUTDOWN
- Script(脚本)
CLI命令行
服务器启动
./redis-server /etc/redis/6379.conf
客户端启动
redis-cli -h host -p port -a password
对象操作命令
KEY操作
命令 | 可用版本 | 时间复杂度 | 返回值 | 说明 |
---|---|---|---|---|
DEL key [key …] | 1.0.0 | O(1),O(M) | 被删除 的数量 | 删除给定key列表,不存在忽略 |
DUMP key | 2.6.0 | O(N*M) | 如果 不存在,那么返回 。 否则,返回序列化之后的值。 | 序列化给定 ,并返回被序列化的值, 使用 RESTORE 命令可以将这个值反序列化为 Redis 键。 序列化的值不包括任何生存时间信息。 |
EXISTS key | 1.0.0 | O(1) | 若 存在,返回 ,否则返回 。 | 检查给定 是否存在。 |
EXPIRE key seconds | 1.0.0 | O(1) | 设置成功返回 。其他0 | 为给定 设置生存时间。2.6版本之后延迟精度到毫秒。 |
EXPIREAT key timestamp | 1.2.0 | O(1) | 设置成功返回 。其他0 | 为 设置生存时间,但是设置的是UNIX 时间戳 |
KEYS pattern | 1.0.0 | O(N) | 符合给定模式的 列表。 | 查找所有符合给定模式 的 。支持*,?,[] |
MIGRATE host port key destination-db timeout [COPY] [REPLACE] | 2.6.0 | O(N) | 迁移成功时返回 ,否则返回相应的错误 | 将 原子性地从当前实例传送到目标实例的指定数据库上,一旦传送成功, 保证会出现在目标实例上,而当前实例上的 会被删除。 |
MOVE key db | 1.0.0 | O(1) | 成功返回 ,失败则返回 | 将当前数据库的 移动到给定的数据库 当中。 |
OBJECT subcommand [arguments [arguments]] | 2.2.3 | O(1) | 和 返回数字。 返回相应的编码类型。 | OBJECT 命令允许从内部察看给定 的 Redis 对象 |
PERSIST key | 2.2.0 | O(1) | 成功: ,失败: | 移除给定 的生存时间 |
PEXPIRE key milliseconds | 2.6.0 | O(1) | 成功: ,失败: | 以毫秒为单位设置 的生存时间 |
PEXPIREAT key milliseconds-timestamp | 2.6.0 | O(1) | 成功: ,失败: | 以毫秒为单位设置 的过期 unix 时间戳 |
PTTL key | 2.6.0 | O(1) | key -2 key -1;返回 的剩余生存时间 | 以毫秒为单位返回 的剩余生存时间 |
RANDOMKEY | 1.0.0 | O(1) | 返回一个 | 从当前数据库中随机返回(不删除)一个 。 |
RENAME key newkey | 1.0.0 | O(1) | 成功: ,失败时候返回一个错误。 | 将 改名为 。当 和 相同,或者 不存在时,返回一个错误。当 已经存在时, RENAME 命令将覆盖旧值。 |
RENAMENX key newkey | 1.0.0 | O(1) | 修改成功时,返回 。如果 已经存在,返回 。 | 当且仅当 不存在时,将 改名为 。 |
RESTORE key ttl serialized-value | 2.6.0 | O(N*M) | 成功: ,失败时候返回一个错误。 | 反序列化给定的序列化值,并将它和给定的 关联。 |
SORT … | 太复杂,见后面详解 | |||
TTL key | 1.0.0 | O(1) | key -2 key -1;返回 的剩余生存时间 | 以秒为单位,返回给定 的剩余生存时间(TTL, time to live)。 |
TYPE key | 1.0.0 | O(1) | (key不存在) (字符串) (列表) (集合) (有序集) (哈希表) | 返回 所储存的值的类型 |
SCAN … | 太复杂,见后面详解 | |||
Sort
返回或保存给定列表、集合、有序集合
key
中经过排序的元素。
排序默认以数字作为对象,值被解释为双精度浮点数,然后进行比较。
SORT可以通过 映射来访问其他key。
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [STORE destination]
#简单sort
SORT key
SORT key DESC
#字符串排序:需要加alpha参数
SORT website ALPHA
#使用 LIMIT 修饰符限制返回结果
SORT rank LIMIT 0 5
#
#BY 选项:按其他键的元素来排序,而不是按key的原值排序。其他键指值经过处理的key。
#user_level_* 是一个占位符, 它先取出 uid 中的值, 然后再用这个值来查找相应的key。
SORT uid BY user_level_*
#GET 选项 :根据排序的结果来取出相应的key的值。
SORT uid GET user_name_*
#获取多个外部键
SORT uid GET user_level_* GET user_name_*
参考:http://doc.redisfans.com/key/sort.html
Scan
SCAN 命令及其相关的 SSCAN 命令、 HSCAN 命令和 ZSCAN 命令都用于增量地迭代集合元素。
- SCAN 命令用于迭代当前数据库中的key。
- SSCAN 命令用于迭代Set键中的元素。
- HSCAN 命令用于迭代Hash键中的键值对。
- ZSCAN 命令用于迭代zset中的元素(包括元素成员和元素分值)。
以上列出的四个命令都支持增量式迭代, 它们每次执行都只会返回少量元素, 所以这些命令可以用于生产环境, 而不会出现像 KEYS 命令、 SMEMBERS 命令带来的问题 —— 当 KEYS 命令被用于处理一个大的数据库时, 又或者 SMEMBERS 命令被用于处理一个大的集合键时, 它们可能会阻塞服务器达数秒之久。
对键进行增量式迭代的过程中, 键可能会被修改, 所以增量式迭代命令只能对被返回的元素提供有限的保证
因为 SCAN 、 SSCAN 、 HSCAN 和 ZSCAN 四个命令的工作方式都非常相似, 但是:
- SSCAN 命令、 HSCAN 命令和 ZSCAN 命令的第一个参数总是一个数据库键。
- 而 SCAN 命令则不需要在第一个参数提供任何数据库键 —— 因为它迭代的是当前数据库中的所有数据库键。
SCAN 命令的基本用法
SCAN 命令是一个基于游标的迭代器(cursor based iterator): SCAN 命令每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。
#第一次迭代使用 0 作为游标, 表示开始一次新的迭代。
redis 127.0.0.1:6379> scan 0
1) "17"
2) 1) "key:12"
2) "key:8"
3) "key:4"
4) "key:14"
5) "key:16"
6) "key:17"
7) "key:15"
8) "key:10"
9) "key:3"
10) "key:7"
11) "key:1"
#第二次迭代使用的是第一次迭代时返回的游标, 也即是命令回复第一个元素的值 —— 17 。
redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
2) "key:18"
3) "key:0"
4) "key:2"
5) "key:19"
6) "key:13"
7) "key:6"
8) "key:9"
9) "key:11"
以
作为游标开始一次新的迭代, 一直调用 SCAN 命令, 直到命令返回游标
, 我们称这个过程为一次完整遍历(full iteration)。
SCAN 命令的保证
SCAN 命令, 以及其他增量式迭代命令, 在进行完整遍历的情况下可以为用户带来以下保证: 从完整遍历开始直到完整遍历结束期间, 一直存在于数据集内的所有元素都会被完整遍历返回; 这意味着, 如果有一个元素, 它从遍历开始直到遍历结束期间都存在于被遍历的数据集当中, 那么 SCAN 命令总会在某次迭代中将这个元素返回给用户。
然而因为增量式命令仅仅使用游标来记录迭代状态, 所以这些命令带有以下缺点:
- 同一个元素可能会被返回多次。 处理重复元素的工作交由应用程序负责, 比如说, 可以考虑将迭代返回的元素仅仅用于可以安全地重复执行多次的操作上。
- 如果一个元素是在迭代过程中被添加到数据集的, 又或者是在迭代过程中从数据集中被删除的, 那么这个元素可能会被返回, 也可能不会, 这是未定义的(undefined)。
SCAN 命令每次执行返回的元素数量
增量式迭代命令并不保证每次执行都返回某个给定数量的元素。
增量式命令甚至可能会返回零个元素, 但只要命令返回的游标不是
, 应用程序就不应该将迭代视作结束。
不过命令返回的元素数量总是符合一定规则的, 在实际中:
- 对于一个大数据集来说, 增量式迭代命令每次最多可能会返回数十个元素;
- 而对于一个足够小的数据集来说, 如果这个数据集的底层表示为编码数据结构(encoded data structure,适用于是小集合键、小哈希键和小有序集合键), 那么增量迭代命令将在一次调用中返回数据集中的所有元素。
最后, 用户可以通过增量式迭代命令提供的
COUNT
选项来指定每次迭代返回元素的最大值。
COUNT 选项
虽然增量式迭代命令不保证每次迭代所返回的元素数量, 但我们可以使用
COUNT
选项, 对命令的行为进行一定程度上的调整。
基本上,
COUNT
选项的作用就是让用户告知迭代命令, 在每次迭代中应该从数据集里返回多少元素。
虽然
COUNT
选项只是对增量式迭代命令的一种提示(hint), 但是在大多数情况下, 这种提示都是有效的。
-
参数的默认值为COUNT
。10
- 在迭代一个足够大的、由哈希表实现的数据库、集合键、哈希键或者有序集合键时, 如果用户没有使用
选项, 那么命令返回的元素数量通常和MATCH
选项指定的一样, 或者比COUNT
选项指定的数量稍多一些。COUNT
- 在迭代一个编码为整数集合(intset,一个只由整数值构成的小集合)、 或者编码为压缩列表(ziplist,由不同值构成的一个小哈希或者一个小有序集合)时, 增量式迭代命令通常会无视
选项指定的值, 在第一次迭代就将数据集包含的所有元素都返回给用户。COUNT
并非每次迭代都要使用相同的 COUNT
**值。**只要记得将上次迭代返回的游标用到下次迭代里面就可以了。
MATCH 选项
增量式迭代命令也可以通过提供一个 glob 风格的模式参数, 让命令只返回和给定模式相匹配的元素。
对元素的模式匹配工作是在命令从数据集中取出元素之后, 向客户端返回元素之前的这段时间内进行的, 所以如果被迭代的数据集中只有少量元素和模式相匹配, 那么迭代命令或许会在多次执行中都不返回任何元素。
迭代终结的保证
增量式迭代命令所使用的算法只保证在数据集的大小有界(bounded)的情况下, 迭代才会停止, 换句话说, 如果被迭代数据集的大小不断地增长的话, 增量式迭代命令可能永远也无法完成一次完整迭代。
String对象操作
命令 | 可用版本 | 时间复杂度 | 返回值 | 说明 |
---|---|---|---|---|
APPEND key value | 2.0.0 | O(1) | 中字符串的长度 | 将 追加到 原来的值的末尾, 不存在则set key。 |
BITCOUNT key [start] [end] | 2.6.0 | O(N) | 被设置为 的位的数量。 | 计算给定字符串中,被设置为 的比特位的数量。 |
BITOP operation destkey key [key …] | 2.6.0 | O(N) | 保存到 的字符串的长度 | 对一个或多个保存二进制位的字符串 进行位元操作,并将结果保存到 上。 operation AND OR NOT XOR 较短的那个字符串所缺少的部分会被看作 。NULL key也看做0 |
DECR key | 1.0.0 | O(1) | 执行 DECR 命令之后 的值 | 将 中储存的数字值减一。 key key |
DECRBY key decrement | 1.0.0 | O(1) | 减去 之后, 的值。 | 将 中储存的数字值减decrement。 key key |
GET key | 1.0.0 | O(1) | 不存在: ;不是String:错误。其他: 的值。 | 返回 所关联的字符串值。 |
GETBIT key offset | 2.2.0 | O(1) | 字符串值指定偏移量上的位(bit)。 | 对 所储存的字符串值,获取指定偏移量上的位(bit)。 |
GETRANGE key start end | 2.4.0 | O(N) | 截取得出的子字符串。 | 返回 中字符串值的子字符串,截取范围[ , ] 负数偏移量表示从最后开始计数, 表示最后一个字符. 值域范围超过部分自动被符略 |
GETSET key value | 1.0.0 | O(1) | 返回给定 的旧值。 | 将给定 的值设为 ,并返回 的旧值(old value)。 |
INCR key | 1.0.0 | O(1) | 执行 INCR 命令之后 的值。 | 将 中储存的数字值增一 |
INCRBY key increment | 1.0.0 | O(1) | 执行 INCR 命令之后 的值。 | 将 所储存的值加上增量 。 |
INCRBYFLOAT key increment | 2.6.0 | O(1) | 执行命令之后 的值。 | 为 中所储存的值加上浮点数增量 。 |
MGET key [key …] | 1.0.0 | O(N) | 一个包含所有给定 的值的列表。 | 返回所有(一个或多个)给定 的值。 |
MSET key value [key value …] | 1.0.1 | O(N) | 总是返回 (因为 不可能失败) | 同时设置一个或多个 对。 |
MSETNX key value [key value …] | 1.0.1 | O(N) | 当所有 都成功设置,返回 。其他:0 | 同时设置一个或多个 对,当且仅当所有给定 都不存在。原子性的。所有字段要么全被设置,要么全不被设置。 |
PSETEX key milliseconds value | 2.6.0 | O(1) | 设置成功时返回 。 | 以毫秒为单位设置 的生存时间 |
SET … | 1.0.0 | O(1) | 2.6.12 版本以前,总是OK 2.6.12 版本开始,失败:则返回NULL Bulk Reply | 见后续 |
SETBIT key offset value | 2.2.0 | O(1) | 指定偏移量原来储存的位 | 对 所储存的字符串值,设置或清除指定偏移量上的位(bit)。 参数必须大于或等于 ,小于 2^32 (bit 映射被限制在 512 MB 之内) |
SETEX key seconds value | 2.0.0 | O(1) | 设置成功时返回 。 | 将值 关联到 ,并将 的生存时间设为 (以秒为单位)。 |
SETNX key value | 1.0.0 | O(1) | 设置成功,返回 。设置失败,返回 。 | 将 的值设为 ,当且仅当 不存在。 |
SETRANGE key offset value | 2.2.0 | O(M) | 修改之后,字符串的长度 | 用 参数覆写(overwrite)给定 所储存的字符串值,从偏移量 开始。 |
STRLEN key | 2.2.0 | O(1) | 字符串值的长度。 | 返回 所储存的字符串值的长度。 |
SET
SET key value [EX seconds] [PX milliseconds] [NX|XX]
将字符串值
value
关联到
key
。如果
key
已经持有其他值, SET 就覆写旧值,无视类型。
对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。
从 Redis 2.6.12 版本开始, SET 命令的行为可以通过一系列参数来修改:
-
:设置键的过期时间为EX second
秒。second
效果等同于SET key value EX second
。SETEX key second value
-
:设置键的过期时间为PX millisecond
毫秒。millisecond
效果等同于SET key value PX millisecond
。PSETEX key millisecond value
-
:只在键不存在时,才对键进行设置操作。NX
效果等同于SET key value NX
。SETNX key value
-
:只在键已经存在时,才对键进行设置操作。XX
命令
SET resource-name anystring NX EX max-lock-time
是一种在 Redis 中实现锁的简单方法。
客户端执行以上的命令:
- 如果服务器返回
,那么这个客户端获得锁。OK
- 如果服务器返回
,那么客户端获取锁失败,可以在稍后再重试。NIL
设置的过期时间到达之后,锁将自动释放。
可以通过以下修改,让这个锁实现更健壮:
- 不使用固定的字符串作为键的值,而是设置一个不可猜测(non-guessable)的长随机字符串,作为口令串(token)。
- 不使用 DEL 命令来释放锁,而是发送一个 Lua 脚本,这个脚本只在客户端传入的值和键的口令串相匹配时,才对键进行删除。
这两个改动可以防止持有过期锁的客户端误删现有锁的情况出现。
应用场景
BITCOUNT
使用 bitmap 实现用户上线次数统计。
每当用户在某一天上线的时候,我们就使用 SETBIT ,以用户名作为
key
,将那天所代表的网站的上线日作为
offset
参数,并将这个
offset
上的为设置为
1
。如果今天是网站上线的第 100 天,而用户 peter 在今天阅览过网站,那么执行命令
SETBIT peter 100 1
;如果明天 peter 也继续阅览网站,那么执行命令
SETBIT peter 101 1
,以此类推。执行
BITCOUNT peter
,得出的结果就是 peter 上线的总天数。
参考:http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/
前面的上线次数统计例子,即使运行 10 年,占用的空间也只是每个用户 10*365 比特位(bit),也即是每个用户 456 字节。对于这种大小的数据来说, BITCOUNT 的处理速度就像 GET 和 INCR 这种 O(1) 复杂度的操作一样快。
如果你的 bitmap 数据非常大,那么可以考虑使用以下两种方法:
- 将一个大的 bitmap 分散到不同的 key 中,作为小的 bitmap 来处理。使用 Lua 脚本可以很方便地完成这一工作。
- 使用 BITCOUNT 的 start 和 end 参数,每次只对所需的部分位进行计算,将位的累积工作(accumulating)放到客户端进行,并且对结果进行缓存 (caching)。
Hash对象操作
命令 | 可用版本 | 时间复杂度 | 返回值 | 说明 |
---|---|---|---|---|
HDEL key field [field …] | 2.0.0 | O(N) | 被成功移除的域的数量,不包括被忽略的域。 | 删除哈希表 中的一个或多个指定域,不存在的域将被忽略。 |
HEXISTS key field | 2.0.0 | O(1) | 含有给定域,返回 。其他:0 | 查看哈希表 中,给定域 是否存在。 |
HGET key field | 2.0.0 | O(1) | 给定域的值。 | 返回哈希表 中给定域 的值。 |
HGETALL key | 2.0.0 | O(N) | 以列表形式返回哈希表的域和域的值。 | 返回哈希表 中,所有的域和值。 |
HINCRBY key field increment | 2.0.0 | O(1) | 哈希表 中域 的值。 | 为哈希表 中的域 的值加上增量 。 不存在,一个新的哈希表被创建。 不存在,域的值被初始化为 |
HINCRBYFLOAT key field increment | 2.6.0 | O(1) | 执行加法操作之后 域的值。 | 类似HINCRBY |
HKEYS key | 2.0.0 | O(N) | 一个包含哈希表中所有域的表。 | 返回哈希表 中的所有域。 |
HLEN key | ? | O(1) | 哈希表中域的数量。 | 返回哈希表 中域的数量。 |
HMGET key field [field …] | 2.0.0 | O(N) | 包含多个给定域的关联值的表 | 返回哈希表 中,一个或多个给定域的值。 |
HMSET key field value [field value …] | 2.0.0 | O(N) | 如果命令执行成功,返回 。 | 同时将多个 (域-值)对设置到哈希表 中。 |
HSET key field value | 2.0.0 | O(1) | 新值域返回1,存在值域 返回0 | 将哈希表 中的域 的值设为 。 |
HSETNX key field value | 2.0.0 | O(1) | 设置成功,返回 。域已经存在且没有操作被执行,返回 | 将哈希表 中的域 的值设置为 ,当且仅当域 不存在。 不存在,一个新哈希表被创建 |
HVALS key | 2.0.0 | O(N) | 一个包含哈希表中所有值的表。 | 返回哈希表 中所有域的值。 |
HSCAN | 参考上面SCAN |
List对象操作
命令 | 可用版本 | 时间复杂度 | 返回值 | 说明 |
---|---|---|---|---|
BLPOP key [key …] timeout | 2.0.0 | O(1) | 如果列表为空,返回一个 。否则:[key,value] | 列表的阻塞式(blocking)弹出原语。当List内没有任何元素时候,连接将被阻塞,直到等待超时或发现可弹出元素为止。 |
BRPOP key [key …] timeout | 2.0.0 | O(1) | 如果列表为空,返回一个 。否则:[key,value] | 类似BLPOP,只是从后面弹出。 |
LINDEX key index | 1.0.0 | O(N) | 列表中下标为 的元素。out of range:返回 | 返回列表 中,下标为 的元素。 |
LINSERT key BEFORE|AFTER pivot value | 2.2.0 | O(N) | 执行成功:列表的长度。没有找到 ,返回 。key | 将值 插入到列表 当中,位于值 之前或之后 |
LLEN key | 1.0.0 | O(1) | 列表 的长度。 | 返回列表 的长度。 |
LPOP key | 1.0.0 | O(1) | 列表的头元素。 不存在时,返回 。 | 移除并返回列表 的头元素。 |
LPUSH key value [value …] | 1.0.0 | O(1) | 列表的长度 | 将一个或多个值 插入到列表 的表头。原子操作 |
LPUSHX key value | 2.2.0 | O(1) | 表的长度 | 将值 插入到列表 的表头,当且仅当 存在并且是一个列表。 |
LRANGE key start stop | 1.0.0 | O(S+N) | 一个列表,包含指定区间内的元素。 | 返回列表 中指定区间内的元素。[START,STOP] |
LREM key count value | 1.0.0 | O(N) | 被移除元素的数量。 | 根据参数 的值,移除列表中与参数 相等的元素。 : 从表头, : 从表尾;count = 0:全部元素 |
LSET key index value | 1.0.0 | O(N) | 操作成功返回 ,否则返回错误信息。 | 将列表 下标为 的元素的值设置为 。 |
LTRIM key start stop | 1.0.0 | O(N) | 命令执行成功时,返回 。 | 让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 |
RPOP key | 1.0.0 | O(1) | 列表的尾元素。 | 移除并返回列表 的尾元素。 |
RPUSH key value [value …] | 1.0.0 | O(1) | 表的长度。 | 将一个或多个值 插入到列表 的表尾(最右边)。各个 值按从左到右的顺序依次插入到表尾 |
RPUSHX key value | 2.2.0 | O(1) | 表的长度。 | 将值 插入到列表 的表尾,当且仅当 存在并且是一个列表。 |
BLPOP
BLPOP 是列表的阻塞式(blocking)弹出原语。
它是 LPOP 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BLPOP 命令阻塞,直到等待超时或发现可弹出元素为止。
当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。
非阻塞行为
当 BLPOP 被调用时,如果给定 key 内至少有一个非空列表,那么弹出遇到的第一个非空列表的头元素,并和被弹出元素所属的列表的名字一起,组成结果返回给调用者。
当存在多个给定 key 时, BLPOP 按给定 key 参数排列的先后顺序,依次检查各个列表。
阻塞行为
如果所有给定 key 都不存在或包含空列表,那么 BLPOP 命令将阻塞连接,直到等待超时,或有另一个客户端对给定 key 的任意一个执行 LPUSH 或 RPUSH 命令为止。
超时参数 timeout 接受一个以秒为单位的数字作为值。超时参数设为 0 表示阻塞时间可以无限期延长(block indefinitely) 。
相同的key被多个客户端同时阻塞
相同的 key 可以被多个客户端同时阻塞。
不同的客户端被放进一个队列中,按『先阻塞先服务』(first-BLPOP,first-served)的顺序为 key 执行 BLPOP 命令。
在MULTI/EXEC事务中的BLPOP
BLPOP 可以用于流水线(pipline,批量地发送多个命令并读入多个回复),但把它用在 MULTI / EXEC 块当中没有意义。因为这要求整个服务器被阻塞以保证块执行时的原子性,该行为阻止了其他客户端执行 LPUSH 或 RPUSH 命令。
因此,一个被包裹在 MULTI / EXEC 块内的 BLPOP 命令,行为表现得就像 LPOP 一样,对空列表返回 nil ,对非空列表弹出列表元素,不进行任何阻塞操作。
场景:事件提醒
有时候,为了等待一个新元素到达数据中,需要使用轮询的方式对数据进行探查。
另一种更好的方式是,使用系统提供的阻塞原语,在新元素到达时立即进行处理,而新元素还没到达时,就一直阻塞住,避免轮询占用资源。
对于 Redis ,我们似乎需要一个阻塞版的 SPOP 命令,但实际上,使用 BLPOP 或者 BRPOP 就能很好地解决这个问题。
RPOPLPUSH
RPOPLPUSH source destination
命令 RPOPLPUSH 在一个原子时间内,执行以下两个动作:
- 将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端。
- 将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素。
如果 source 不存在,值 nil 被返回,并且不执行其他动作。
如果 source 和 destination 相同,则列表中的表尾元素被移动到表头,并返回该元素,可以把这种特殊情况视作列表的旋转(rotation)操作。
场景
安全的队列
Redis的列表经常被用作队列(queue),用于在不同程序之间有序地交换消息(message)。一个客户端通过 LPUSH 命令将消息放入队列中,而另一个客户端通过 RPOP 或者 BRPOP 命令取出队列中等待时间最长的消息。
不幸的是,上面的队列方法是『不安全』的,因为在这个过程中,一个客户端可能在取出一个消息之后崩溃,而未处理完的消息也就因此丢失。
使用 RPOPLPUSH 命令(或者它的阻塞版本 BRPOPLPUSH )可以解决这个问题:因为它不仅返回一个消息,同时还将这个消息添加到另一个备份列表当中,如果一切正常的话,当一个客户端完成某个消息的处理之后,可以用 LREM 命令将这个消息从备份表删除。
最后,还可以添加一个客户端专门用于监视备份表,它自动地将超过一定处理时限的消息重新放入队列中去(负责处理该消息的客户端可能已经崩溃),这样就不会丢失任何消息了。
循环列表
通过使用相同的 key 作为 RPOPLPUSH 命令的两个参数,客户端可以用一个接一个地获取列表元素的方式,取得列表的所有元素,而不必像 LRANGE 命令那样一下子将所有列表元素都从服务器传送到客户端中(两种方式的总复杂度都是 O(N))。
以上的模式甚至在以下的两个情况下也能正常工作:
- 有多个客户端同时对同一个列表进行旋转(rotating),它们获取不同的元素,直到所有元素都被读取完,之后又从头开始。
- 有客户端在向列表尾部(右边)添加新元素。
这个模式使得我们可以很容易实现这样一类系统:有 N 个客户端,需要连续不断地对一些元素进行处理,而且处理的过程必须尽可能地快。一个典型的例子就是服务器的监控程序:它们需要在尽可能短的时间内,并行地检查一组网站,确保它们的可访问性。
注意,使用这个模式的客户端是易于扩展(scala)且安全(reliable)的,因为就算接收到元素的客户端失败,元素还是保存在列表里面,不会丢失,等到下个迭代来临的时候,别的客户端又可以继续处理这些元素了。
BRPOPLPUSH
BRPOPLPUSH source destination timeout
BRPOPLPUSH 是 RPOPLPUSH 的阻塞版本,当给定列表
source
不为空时, BRPOPLPUSH 的表现和 RPOPLPUSH 一样。
当列表
source
为空时, BRPOPLPUSH 命令将阻塞连接,直到等待超时,或有另一个客户端对
source
执行 LPUSH 或 RPUSH 命令为止。
超时参数
timeout
接受一个以秒为单位的数字作为值。超时参数设为
表示阻塞时间可以无限期延长(block indefinitely) 。
SET对象操作
命令 | 可用版本 | 时间复杂度 | 返回值 | 说明 |
---|---|---|---|---|
SADD key member [member …] | 1.0.0 | O(N) | 被添加到集合中的新元素的数量,不包括被忽略的元素。 | 将一个或多个 元素加入到集合 当中 |
SCARD key | 1.0.0 | O(1) | 集合的基数。 | 返回集合 的基数(集合中元素的数量)。 |
SDIFF key [key …] | 1.0.0 | O(N) | 差集成员的列表 | 所有给定集合之间的差集 |
SDIFFSTORE destination key [key …] | 1.0.0 | O(N) | 结果集中的元素数量。 | 结果保存到 集合 |
SINTER key [key …] | 1.0.0 | O(N) | 交集成员的列表 | 所有给定集合的交集。 |
SINTERSTORE destination key [key …] | 1.0.0 | O(N) | 结果集中的元素数量。 | 结果保存到 集合 |
SISMEMBER key member | 1.0.0 | O(1) | 元素是集合的成员,返回 。其他:0 | 判断 元素是否集合 的成员。 |
SMEMBERS key | 1.0.0 | O(N) | 集合中的所有成员 | 返回集合 中的所有成员。 |
SMOVE source destination member | 1.0.0 | O(1) | 如果 元素被成功移除,返回 。其他:0 | 将 元素从 集合移动到 集合。 |
SPOP key | 1.0.0 | O(1) | 被移除的随机元素。 | 移除并返回集合中的一个随机元素。 |
SRANDMEMBER key [count] | 1.0.0 | O(N) | 单个元素或者集合 | 返回集合中的一个或count个随机元素。count正数:元素不可重复;负数:元素可重复 |
SREM key member [member …] | 1.0.0 | O(N) | 被成功移除的元素的数量,不包括被忽略的元素。 | 移除集合 中的一个或多个 元素,不存在的 元素会被忽略。 |
SUNION key [key …] | 1.0.0 | O(N) | 并集成员的列表。 | 所有给定集合的并集。 |
SUNIONSTORE destination key [key …] | 1.0.0 | O(N) | 结果集中的元素数量。 | 结果保存到 集合 |
SSCAN … | 参考Scan | |||
SortedSet对象操作
命令 | 可用版本 | 时间复杂度 | 返回值 | 说明 |
---|---|---|---|---|
ZADD key score member [ [score member] …] | 1.2.0 | O(M*log(N)) | 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。 | 将一个或多个 元素及其 值加入到有序集 当中。 |
ZCARD key | 1.2.0 | O(1) | 有序集的基数 | 返回有序集 的基数。 |
ZCOUNT key min max | 2.0.0 | O(log(N)+M) | 值在 和 之间的成员的数量。 | 值在 和 之间(默认包括 值等于 或 )的成员的数量 |
ZINCRBY key increment member | 1.2.0 | O(log(N)) | 成员的新 值,以字符串形式表示。 | 的成员 的 值加上增量 。 |
ZRANGE key start stop [WITHSCORES] | 1.2.0 | O(log(N)+M) | 指定区间内,带有 值(可选)的有序集成员的列表。 | 返回有序集 中,指定区间内的成员。 |
ZREVRANGE key start stop [WITHSCORES] | 1.2.0 | O(log(N)+M) | 指定区间内,带有 值(可选)的有序集成员的列表。 | 返回有序集 中,指定区间内的成员。 值按倒序 排列 |
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] | 1.0.5 | O(log(N)+M) | 指定区间内,带有 值(可选)的有序集成员的列表。 | 返回有序集 中,所有 值介于 和 之间(包括等于 或 )的成员。有序集成员按 值递增(从小到大)次序排列。 |
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] | 1.0.5 | O(log(N)+M) | 指定区间内,带有 值(可选)的有序集成员的列表。 | 返回有序集 中,所有 值介于 和 之间(包括等于 或 )的成员。有序集成员按 值递增(从大到小)次序排列。 |
ZRANK key member | 2.0.0 | O(log(N)) | 返回 的排名 | 返回有序集 中成员 的排名 |
ZREVRANK key member | 2.0.0 | O(log(N)) | 返回 的排名 | 返回有序集 中成员 的排名(从大到小) |
ZREM key member [member …] | 1.2.0 | O(M*log(N)) | 被成功移除的成员的数量 | 移除有序集 中的一个或多个成员 |
ZREMRANGEBYRANK key start stop | 2.0.0 | O(log(N)+M) | 被移除成员的数量 | 移除有序集 中,指定排名(rank)区间内的所有成员。 |
ZREMRANGEBYSCORE key min max | 1.2.0 | O(log(N)+M) | 被移除成员的数量 | 移除有序集 中,所有 值介于 和 之间(包括等于 或 )的成员。 |
ZSCORE key member | 1.2.0 | O(1) | 成员的 值,以字符串形式表示。 | 返回有序集 中,成员 的 值。 |
ZUNIONSTORE | 2.0.0 | O(N)+O(M log(M)) | 保存到 的结果集的基数。 | |
ZINTERSTORE | 2.0.0 | O(N)+O(M log(M)) | 保存到 的结果集的基数。 | |
ZUNIONSTORE
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
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
计算给定的一个或多个有序集的交集,其中给定
key
的数量必须以
numkeys
参数指定,并将该交集(结果集)储存到
destination
。
默认情况下,结果集中某个成员的
score
值是所有给定集下该成员
score
值之和.
关于
WEIGHTS
和
AGGREGATE
选项的描述,参见 ZUNIONSTORE 命令。
发布订阅命令
命令 | 可用版本 | 时间复杂度 | 返回值 | 说明 |
---|---|---|---|---|
PSUBSCRIBE pattern [pattern …] | 2.0.0 | O(N) | 接收到的信息 | 订阅一个或多个符合给定模式的频道。通配符: |
PUBLISH channel message | 2.0.0 | O(N+M) | 接收到信息 的订阅者数量。 | 将信息 发送到指定的频道 。 |
PUBSUB [argument [argument …]] | 2.8.0 | 查看订阅与发布系统状态的内省命令 | ||
PUNSUBSCRIBE [pattern [pattern …]] | 2.0.0 | O(N+M) | 这个命令在不同的客户端中有不同的表现。 | 指示客户端退订所有给定模式。 |
SUBSCRIBE channel [channel …] | 2.0.0 | O(N) | 接收到的信息 | 订阅给定的一个或多个频道的信息。 |
UNSUBSCRIBE [channel [channel …]] | 2.0.0 | O(N) | 这个命令在不同的客户端中有不同的表现。 | 指示客户端退订给定的频道。 |
PSUBSCRIBE
返回结果说明:
# 订阅 news.* 和 tweet.* 两个模式
# 第 1 - 6 行是执行 psubscribe 之后的反馈信息
# 第 7 - 10 才是接收到的第一条信息
# 第 11 - 14 是第二条
# 以此类推。。。
redis> psubscribe news.* tweet.*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe" # 返回值的类型:显示订阅成功
2) "news.*" # 订阅的模式
3) (integer) 1 # 目前已订阅的模式的数量
1) "psubscribe"
2) "tweet.*"
3) (integer) 2
1) "pmessage" # 返回值的类型:信息
2) "news.*" # 信息匹配的模式
3) "news.it" # 信息本身的目标频道
4) "Google buy Motorola" # 信息的内容
1) "pmessage"
2) "tweet.*"
3) "tweet.huangz"
4) "hello"
1) "pmessage"
2) "tweet.*"
3) "tweet.joe"
4) "@huangz morning"
1) "pmessage"
2) "news.*"
3) "news.life"
4) "An apple a day, keep doctors away"
PUBSUB
PUBSUB CHANNELS [pattern]
列出当前的活跃频道。
活跃频道指的是那些至少有一个订阅者的频道, 订阅模式的客户端不计算在内。
pattern
参数是可选的:
- 如果不给出
参数,那么列出订阅与发布系统中的所有活跃频道。pattern
- 如果给出
参数,那么只列出和给定模式pattern
相匹配的那些活跃频道。pattern
复杂度: O(N) ,
N
为活跃频道的数量(对于长度较短的频道和模式来说,将进行模式匹配的复杂度视为常数)。
返回值: 一个由活跃频道组成的列表。
PUBSUB NUMSUB [channel-1 ... channel-N]
返回给定频道的订阅者数量, 订阅模式的客户端不计算在内。
复杂度: O(N) ,
N
为给定频道的数量。
返回值: 一个多条批量回复(Multi-bulk reply),回复中包含给定的频道,以及频道的订阅者数量。 格式为:频道
channel-1
,
channel-1
的订阅者数量,频道
channel-2
,
channel-2
的订阅者数量,诸如此类。 回复中频道的排列顺序和执行命令时给定频道的排列顺序一致。 不给定任何频道而直接调用这个命令也是可以的, 在这种情况下, 命令只返回一个空列表。
PUBSUB NUMPAT
返回订阅模式的数量。
注意, 这个命令返回的不是订阅模式的客户端的数量, 而是客户端订阅的所有模式的数量总和。
复杂度: O(1) 。
返回值: 一个整数回复(Integer reply)。
事务命令
命令 | 可用版本 | 时间复杂度 | 返回值 | 说明 |
---|---|---|---|---|
DISCARD | 2.0.0 | O(1) | 总是返回 。 | 取消事务,放弃执行事务块内的所有命令。 |
EXEC | 1.2.0 | * | 事务块内所有命令的返回值,按命令执行的先后顺序排列。 | 执行所有事务块内的命令。 |
MULTI | 1.2.0 | O(1) | 总是返回 。 | 标记一个事务块的开始。 |
UNWATCH | 2.2.0 | O(1) | 总是 。 | 取消 WATCH 命令对所有 key 的监视。 |
WATCH key [key …] | 2.2.0 | O(1) | 总是 。 | 监视一个(或多个) key |
示例:
# 事务被成功执行
redis> MULTI
OK
redis> INCR user_id
QUEUED
redis> INCR user_id
QUEUED
redis> INCR user_id
QUEUED
redis> PING
QUEUED
redis> EXEC
1) (integer) 1
2) (integer) 2
3) (integer) 3
4) PONG
# 监视 key ,且事务成功执行
redis> WATCH lock lock_times
OK
redis> MULTI
OK
redis> SET lock "huangz"
QUEUED
redis> INCR lock_times
QUEUED
redis> EXEC
1) OK
2) (integer) 1
# 监视 key ,且事务被打断
redis> WATCH lock lock_times
OK
redis> MULTI
OK
redis> SET lock "joe" # 就在这时,另一个客户端修改了 lock_times 的值
QUEUED
redis> INCR lock_times
QUEUED
redis> EXEC # 因为 lock_times 被修改, joe 的事务执行失败
(nil)
连接命令
命令 | 可用版本 | 时间复杂度 | 返回值 | 说明 |
---|---|---|---|---|
AUTH password | 1.0.0 | O(1) | 密码匹配时返回 ,否则返回一个错误。 | |
ECHO message | 1.0.0 | O(1) | 自身。 | 打印一个特定的信息 ,测试时使用。 |
PING | 1.0.0 | O(1) | 如果连接正常就返回一个 ,否则返回一个连接错误。 | 使用客户端向 Redis 服务器发送一个 ,如果服务器运作正常的话,会返回一个 。 |
QUIT | 1.0.0 | O(1) | 返回 | 退出 |
SELECT index | 1.0.0 | O(1) | 返回 | 切换到指定的数据库 |
服务器操作命令
命令 | 可用版本 | 时间复杂度 | 返回值 | 说明 |
---|---|---|---|---|
BGREWRITEAOF | 1.0.0 | O(N) | 反馈信息 | 执行一个 AOF文件 重写操作。重写会创建一个当前 AOF 文件的体积优化版本 |
BGSAVE | 1.0.0 | O(N) | 反馈信息 | 在后台异步(Asynchronously)保存当前数据库的数据到磁盘。 |
CLIENT SETNAME connection-name | 2.6.9 | O(1) | 设置成功时返回 。 | 为当前连接分配一个名字。 |
CLIENT GETNAME | 2.6.9 | O(1) | 如果连接没有设置名字,那么返回空白回复;如果有设置名字,那么返回名字。 | 返回 CLIENT SETNAME 命令为连接设置的名字 |
CLIENT KILL ip:port | 2.4.0 | O(N) | 当指定的客户端存在,且被成功关闭时,返回 。 | 关闭地址为 的客户端。 |
CLIENT LIST | 2.4.0 | O(N) | 以人类可读的格式,返回所有连接到服务器的客户端信息和统计数据。 | |
CONFIG SET parameter value | 2.0.0 | ? | 当设置成功时返回 ,否则返回一个错误。 | 动态地调整 Redis 服务器的配置(configuration)而无须重启 |
CONFIG GET parameter | 2.0.0 | ? | 给定配置参数的值。 | 取得运行中的 Redis 服务器的配置参数 |
CONFIG RESETSTAT | 2.0.0 | O(1) | 总是返回 。 | 重置 INFO 命令中的某些统计数据 |
CONFIG REWRITE | 2.8.0 | 如果配置重写成功则返回 ,失败则返回一个错误。 | 启动 Redis 服务器时所指定的 文件进行改写 | |
DBSIZE | 1.0.0 | O(1) | 当前数据库的 key 的数量。 | 返回当前数据库的 key 的数量。 |
DEBUG OBJECT key | 1.0.0 | O(1) | 当 存在时,返回有关信息。当 不存在时,返回一个错误。 | 一个调试命令,它不应被客户端所使用。 |
DEBUG SEGFAULT | 1.0.0 | 无 | 执行一个不合法的内存访问从而让 Redis 崩溃,仅在开发时用于 BUG 模拟。 | |
FLUSHALL | 1.0.0 | 总是返回 。 | 清空整个 Redis 服务器的数据(删除所有数据库的所有 key )。 | |
FLUSHDB | 1.0.0 | O(1) | 总是返回 。 | 清空当前数据库中的所有 key。 |
INFO [section] | 1.0.0 | O(1) | ||
LASTSAVE | 1.0.0 | O(1) | 一个 UNIX 时间戳。 | 返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示。 |
MONITOR | 1.0.0 | ? | 总是返回 。 | 实时打印出 Redis 服务器接收到的命令,调试用。 |
PSYNC <MASTER_RUN_ID> | 2.8.0 | ? | ? | 用于复制功能(replication)的内部命令。 |
SYNC | 1.0.0 | ? | ? | 用于复制功能(replication)的内部命令。 |
SAVE | 1.0.0 | O(N) | 保存成功时返回 。 | 执行一个同步保存操作 |
SHUTDOWN | ||||
SLAVEOF host port | ||||
SLOWLOG subcommand [argument] | 2.2.12 | O(1) | 子命令:GET,RESET,LEN | |
TIME | 2.6.0 | O(1) | 一个包含两个字符串的列表: 第一个字符串是当前时间(以 UNIX 时间戳格式表示),而第二个字符串是当前这一秒钟已经逝去的微秒数。 | 返回当前服务器时间。 |
Client List
命令返回多行字符串,这些字符串按以下形式被格式化:
- 每个已连接客户端对应一行(以
分割)LF
- 每行字符串由一系列
形式的域组成,每个域之间以空格分开属性=值
以下是域的含义:
-
: 客户端的地址和端口addr
-
: 套接字所使用的文件描述符fd
-
: 以秒计算的已连接时长age
-
: 以秒计算的空闲时长idle
-
: 客户端 flag (见下文)flags
-
: 该客户端正在使用的数据库 IDdb
-
: 已订阅频道的数量sub
-
: 已订阅模式的数量psub
-
: 在事务中被执行的命令数量multi
-
: 查询缓存的长度( 表示没有查询在等待)qbuf
-
: 查询缓存的剩余空间( 表示没有剩余空间)qbuf-free
-
: 输出缓存的长度obl
-
: 输出列表的长度(当输出缓存没有剩余空间时,回复被入队到这个队列里)oll
-
: 输出缓存的内存占用量omem
-
: 文件描述符事件(见下文)events
-
: 最近一次执行的命令cmd
客户端 flag 可以由以下部分组成:
-
: 客户端是 MONITOR 模式下的附属节点(slave)O
-
: 客户端是一般模式下(normal)的附属节点S
-
: 客户端是主节点(master)M
-
: 客户端正在执行事务x
-
: 客户端正在等待阻塞事件b
-
: 客户端正在等待 VM I/O 操作(已废弃)i
-
: 一个受监视(watched)的键已被修改,d
命令将失败EXEC
-
: 在将回复完整地写出之后,关闭链接c
-
: 客户端未被阻塞(unblocked)u
-
: 尽可能快地关闭连接A
-
: 未设置任何 flagN
文件描述符事件可以是:
-
: 客户端套接字(在事件 loop 中)是可读的(readable)r
-
: 客户端套接字(在事件 loop 中)是可写的(writeable)w
CONFIG REWRITE
CONFIG REWRITE 命令对启动 Redis 服务器时所指定的
redis.conf
文件进行改写: 因为 CONFIG SET 命令可以对服务器的当前配置进行修改, 而修改后的配置可能和
redis.conf
文件中所描述的配置不一样, CONFIG REWRITE 的作用就是通过尽可能少的修改, 将服务器当前所使用的配置记录到
redis.conf
文件中。
重写会以非常保守的方式进行:
- 原有
文件的整体结构和注释会被尽可能地保留。redis.conf
- 如果一个选项已经存在于原有
文件中 , 那么对该选项的重写会在选项原本所在的位置(行号)上进行。redis.conf
- 如果一个选项不存在于原有
文件中, 并且该选项被设置为默认值, 那么重写程序不会将这个选项添加到重写后的redis.conf
文件中。redis.conf
- 如果一个选项不存在于原有
文件中, 并且该选项被设置为非默认值, 那么这个选项将被添加到重写后的redis.conf
文件的末尾。redis.conf
- 未使用的行会被留白。 比如说, 如果你在原有
文件上设置了数个关于redis.conf
选项的参数, 但现在你将这些save
参数的一个或全部都关闭了, 那么这些不再使用的参数原本所在的行就会变成空白的。save
即使启动服务器时所指定的
redis.conf
文件已经不再存在, CONFIG REWRITE 命令也可以重新构建并生成出一个新的
redis.conf
文件。
另一方面, 如果启动服务器时没有载入
redis.conf
文件, 那么执行 CONFIG REWRITE 命令将引发一个错误。
原子性重写
对
redis.conf
文件的重写是原子性的, 并且是一致的: 如果重写出错或重写期间服务器崩溃, 那么重写失败, 原有
redis.conf
文件不会被修改。 如果重写成功, 那么
redis.conf
文件为重写后的新文件。
INFO
以一种易于解释(parse)且易于阅读的格式,返回关于 Redis 服务器的各种信息和统计数值。
通过给定可选的参数
section
,可以让命令只返回某一部分的信息:
-
: 一般 Redis 服务器信息,包含以下域:server
-
: Redis 服务器版本redis_version
-
: Git SHA1redis_git_sha1
-
: Git dirty flagredis_git_dirty
-
: Redis 服务器的宿主操作系统os
-
: 架构(32 或 64 位)arch_bits
-
: Redis 所使用的事件处理机制multiplexing_api
-
: 编译 Redis 时所使用的 GCC 版本gcc_version
-
: 服务器进程的 PIDprocess_id
-
: Redis 服务器的随机标识符(用于 Sentinel 和集群)run_id
-
: TCP/IP 监听端口tcp_port
-
: 自 Redis 服务器启动以来,经过的秒数uptime_in_seconds
-
: 自 Redis 服务器启动以来,经过的天数uptime_in_days
-
: 以分钟为单位进行自增的时钟,用于 LRU 管理lru_clock
-
-
: 已连接客户端信息,包含以下域:clients
-
: 已连接客户端的数量(不包括通过从属服务器连接的客户端)connected_clients
-
: 当前连接的客户端当中,最长的输出列表client_longest_output_list
-
: 当前连接的客户端当中,最大输入缓存client_longest_input_buf
-
: 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量blocked_clients
-
-
: 内存信息,包含以下域:memory
-
: 由 Redis 分配器分配的内存总量,以字节(byte)为单位used_memory
-
: 以人类可读的格式返回 Redis 分配的内存总量used_memory_human
-
: 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和used_memory_rss
、top
等命令的输出一致。ps
-
: Redis 的内存消耗峰值(以字节为单位)used_memory_peak
-
: 以人类可读的格式返回 Redis 的内存消耗峰值used_memory_peak_human
-
: Lua 引擎所使用的内存大小(以字节为单位)used_memory_lua
-
:mem_fragmentation_ratio
和used_memory_rss
之间的比率used_memory
-
: 在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc 。mem_allocator
的值应该只比used_memory_rss
used_memory
稍微高一点儿。
当
rss > used
,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。
内存碎片的比率可以通过
mem_fragmentation_ratio
的值看出。
当
used > rss
时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。
Because Redis does not have control over how its allocations are mapped to memory pages, high
used_memory_rss
is often the result of a spike in memory usage.
当 Redis 释放内存时,分配器可能会,也可能不会,将内存返还给操作系统。
如果 Redis 释放了内存,却没有将内存返还给操作系统,那么
used_memory
的值可能和操作系统显示的 Redis 内存占用并不一致。
查看
的值可以验证这种情况是否发生。used_memory_peak
-
-
:persistence
和RDB
的相关信息AOF
-
: 一般统计信息stats
-
: 主/从复制信息replication
-
: CPU 计算量统计信息cpu
-
: Redis 命令统计信息commandstats
-
: Redis 集群信息cluster
-
: 数据库相关的统计信息keyspace
除上面给出的这些值以外,参数还可以是下面这两个:
-
: 返回所有信息all
-
: 返回默认选择的信息default
当不带参数直接调用 INFO 命令时,使用
default
作为默认参数。
SHUTDOWN
SHUTDOWN 命令执行以下操作:
- 停止所有客户端
- 如果有至少一个保存点在等待,执行 SAVE 命令
- 如果 AOF 选项被打开,更新 AOF 文件
- 关闭 redis 服务器(server)
如果持久化被打开的话, SHUTDOWN 命令会保证服务器正常关闭而不丢失任何数据。
另一方面,假如只是单纯地执行 SAVE 命令,然后再执行 QUIT 命令,则没有这一保证 —— 因为在执行 SAVE 之后、执行 QUIT 之前的这段时间中间,其他客户端可能正在和服务器进行通讯,这时如果执行 QUIT 就会造成数据丢失。
SAVE 和 NOSAVE 修饰符
通过使用可选的修饰符,可以修改 SHUTDOWN 命令的表现。比如说:
- 执行
会强制让数据库执行保存操作,即使没有设定(configure)保存点SHUTDOWN SAVE
- 执行
会阻止数据库执行保存操作,即使已经设定有一个或多个保存点(你可以将这一用法看作是强制停止服务器的一个假想的 ABORT 命令)SHUTDOWN NOSAVE
Script(脚本)
略