Redis常用命令手册
http://c.biancheng.net/redis_command/
Redis客户端(client)命令
Redis 提供了一些操作客户端(client)的命令,比如查询所有已连接到服务器的客户端数量,控制客户端的连接状态(关闭或者挂起)等。通过客户命令我们可以轻松的实现对客户端的管理、控制。
Redis 服务器通过监听 TCP 端口的方式来接受客户端的连接。当一个连接建立后,Redis 会自动执行以下过程:
- 首先客户端 socket 被设置为非阻塞模式,这是因为 Redis 在网络事件处理上采用了非阻塞式 IO(即 IO 多路复用模型);
- 其次设置 socket 的 TCP_NODELAY 属性,从而禁用 Nagle 算法;
- 最后创建一个可读的文件事件,用它来监听客户端 socket 的数据发送。
客户端最大连接数
在 Redis 配置文件中,有一个maxclients
的配置项,它指定了连接到 Redis 服务器的最大客户端数量。其默认值是 10000。配置项如下所示:
127.0.0.1:6379> config get maxclients 1) "maxclients" 2) "10000" #更改最大连接数量 127.0.0.1:6379> config set maxclients 20000 OK 127.0.0.1:6379> config get maxclients 1) "maxclients" 2) "20000"
常用命令
命令 | 说明 |
---|---|
CLIENT LIST | 以列表的形式返回所有连接到 Redis 服务器的客户端。 |
CLIENT SETNAME | 设置当前连接的名称。 |
CLIENT GETNAME | 获取通过 CLIENT SETNAME 命令设置的服务名称。 |
CLIENT PAUSE | 挂起客户端连接,将所有客户端挂起指定的时间(以毫秒为计算)。 |
CLIENT KILL | 关闭客户端连接。 |
CLIENT ID | 返回当前客户端 ID。 |
CLIENT REPLY | 控制发送到当前连接的回复,可选值包括 on|off|skip。 |
命令应用应用
下面看一组简单的使用示例,如下所示:
127.0.0.1:6379> CLIENT ID (integer) 2557 127.0.0.1:6379> CLIENT LIST id=2556 addr=127.0.0.1:64684 fd=30 name= age=2422 idle=339 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=client id=2557 addr=127.0.0.1:49502 fd=43 name= age=537 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=32742 obl=0 oll=0 omem=0 events=r cmd=client 127.0.0.1:6379> CLIENT REPLY ON OK 127.0.0.1:6379> CLIENT SETNAME "www.biancheng.net" OK 127.0.0.1:6379> CLIENT GETNAME "www.biancheng.net" 127.0.0.1:6379> CLIENT KILL 127.0.0.1:49502 OK
Redis服务器命令
Redis 服务器是对客户端提供服务的主体,只要是安装了 Redis 数据库的计算机都可以通过本地,或者远程的方式对外提供服务。
Redis 服务器能够以高可用集群的方式对外提供服务。所谓高可用集群,指的是多台 Redis 服务器组成的服务器架构,每台服务器都提供相同的服务,从而让服务器达到一个稳定,高效的运行状态。有关 Redis 集群的相关知识在后续内容中详介绍。
从 3.0 版本开始,Redis 已经实现了对 Redis-cluster 集群部署的支持。
Redis 提供了诸多操作服务器的命令,这些命令都有着各自重要的作用,比如BGSAVE
命令,用异步的方式将 Redis 数据库的数据同步到本地磁盘中,实现数据的持久化存储,这对服务器的数据安全有着重要的作用。
常用服务器命令
下表介绍了 Redis 服务器的常用命令:
命令 | 说明 |
---|---|
BGREWRITEAOF | 在后台以异步的方式执行一个 AOF 文件的重写操作,对源文件进行压缩,使其体积变小。 AOF 是实现数据持久化存储的方式之一。 |
BGSAVE | 在后台执行初始化操作,并以异步的方式将当前数据库的数据保存到磁盘中。 |
CLIENT KILL [ip:port] [ID client-id] | 关闭客户端连接。 |
CLIENT LIST | 获取连接到服务器的客户端连接列表。 |
CLIENT GETNAME | 获取当前连接客户端的名称。 |
CLIENT PAUSE timeout | 使服务器在指定的时间停止执行来自客户端的命令。 |
CLIENT SETNAME connection-name | 设置当前连接客户端的名称。 |
COMMAND | 返回所有 Redis 命令的详细描述信息。 |
COMMAND COUNT | 此命令用于获取 Redis 命令的总数。 |
COMMAND GETKEYS | 获取指定命令的所有键。 |
INFO [section] | 获取 Redis 服务器的各种信息和统计数值。 |
COMMAND INFO command-name [command-name ...] | 用于获取指定 Redis 命令的描述信息。 |
CONFIG GET parameter | 获取指定配置参数的值。 |
CONFIG REWRITE | 修改启动 Redis 服务器时所指定的 redis.conf 配置文件。 |
CONFIG SET parameter value | 修改 Redis 配置参数,无需重启。 |
CONFIG RESETSTAT | 重置 INFO 命令中的某些统计数据。 |
DBSIZE | 返回当前数据库中 key 的数量。 |
DEBUG OBJECT key | 获取 key 的调试信息。当 key 存在时,返回有关信息;当 key 不存在时,返回一个错误。 |
DEBUG SEGFAULT | 使用此命令可以让服务器崩溃。 |
FLUSHALL | 清空数据库中的所有键。 |
FLUSHDB | 清空当前数据库的所有 key。 |
LASTSAVE | 返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 格式表示。 |
MONITOR | 实时打印出 Redis 服务器接收到的命令。 |
ROLE | 查看主从实例所属的角色,角色包括三种,分别是 master、slave、sentinel。 |
SAVE | 执行数据同步操作,将 Redis 数据库中的所有数据以 RDB 文件的形式保存到磁盘中。 RDB 是 Redis 中的一种数据持久化方式。 |
SHUTDOWN [NOSAVE] [SAVE] | 将数据同步到磁盘后,然后关闭服务器。 |
SLAVEOF host port | 此命令用于设置主从服务器,使当前服务器转变成为指定服务器的从属服务器, 或者将其提升为主服务器(执行 SLAVEOF NO ONE 命令)。 |
SLOWLOG subcommand [argument] | 用来记录查询执行时间的日志系统。 |
SYNC | 用于同步主从服务器。 |
SWAPDB index index | 用于交换同一 Redis 服务器上的两个数据库,可以实现访问其中一个数据库的客户端连接,也可以立即访问另外一个数据库的数据。 |
TIME | 此命令用于返回当前服务器时间。 |
注意:上述一些命令在后续内容还会做相应介绍,比如 Redis 主从服务器设置,以及 Redis 数据持久化等。
基本命令演示
下面是对上述的命令做简单的演示,您可以跟着敲一遍命令,从加深对命令的理解与记忆:
#查看redis命令的描述信息 127.0.0.1:6379> COMMAND INFO SET GET ZADD 1) 1) "set" 2) (integer) -3 3) 1) write 2) denyoom 4) (integer) 1 5) (integer) 1 6) (integer) 1 2) 1) "get" 2) (integer) 2 3) 1) readonly 2) fast 4) (integer) 1 5) (integer) 1 6) (integer) 1 3) 1) "zadd" 2) (integer) -4 3) 1) write 2) denyoom 3) fast 4) (integer) 1 5) (integer) 1 6) (integer) 1 #最近一次执行数据持久化存储的时间 127.0.0.1:6379> LASTSAVE (integer) 1610717455 127.0.0.1:6379> LASTSAVE (integer) 1610717455 #实时打印redis服务器接收的命令 127.0.0.1:6379> MONITOR OK 1610951376.523762 [0 127.0.0.1:60257] "COMMAND" ^C #查看前两条日志信息 127.0.0.1:6379> SLOWLOG get 2 1) 1) (integer) 13 2) (integer) 1610950258 3) (integer) 46499 4) 1) "info" 5) "127.0.0.1:58561" 6) "" 2) 1) (integer) 12 2) (integer) 1610950201 3) (integer) 19917 4) 1) "COMMAND" 5) "127.0.0.1:58561" 6) "" #共有多少条日志记录 127.0.0.1:6379> SLOWLOG len (integer) 14 #清空所有日志记录 127.0.0.1:6379> SLOWLOG reset OK 127.0.0.1:6379> SLOWLOG len (integer) 0 #用于同步主从服务器数据 127.0.0.1:6379> SYNC Entering replica output mode... (press Ctrl-C to quit) SYNC with master, discarding 1719 bytes of bulk transfer... SYNC done. Logging commands from master. "PING" "PING" "PING" "PING" "PING" ^C C:\Users\Administrator>redis-cli #查看当前服务器时间 #第一个字符串是当前时间以 UNIX 时间戳格式表示 #第二个字符串表示:当前这一秒钟已经逝去的微秒数 127.0.0.1:6379> TIME 1) "1610953086" 2) "17499"
键(Key)命令
我们知道 Redis 是 key-value 型数据库,使用 key 对 value 进行存储,因此,键(Key)命令是 Redis 中经常使用的一类命令。常用的键命令如下所示:
命令 | 说明 |
---|---|
DEL | 若键存在的情况下,该命令用于删除键 |
DUMP | 用于序列化给定 key ,并返回被序列化的值 |
EXISTS | 用于检查键是否存在,若存在则返回 1,否则返回 0 |
EXPIRE | 设置 key 的过期时间,以秒为单位 |
EXPIREAT | 该命令与 EXPIRE 相似,用于为 key 设置过期时间,不同在于,它的时间参数值采用的是时间戳格式。 |
KEYS | 此命令用于查找与指定 pattern 匹配的 key |
MOVE | 将当前数据库中的 key 移动至指定的数据库中(默认存储为 0 库,可选 1-15中的任意库) |
PERSIST | 该命令用于删除 key 的过期时间,然后 key 将一直存在,不会过期 |
PEXPIRE | 设置 key 的过期,以毫秒为单位 |
RANDOMKEY | 从当前数据库中随机返回一个 key |
RENAME | 修改 key 的名称 |
SCAN | 基于游标的迭代器,用于迭代数据库中存在的所有键,cursor 指的是迭代游标 |
TTL | 用于检查 key 还剩多长时间过期,以秒为单位 |
TYPE | 该命令用于获取 value 的数据类型。 |
Hash 命令
Hash(哈希散列)是 Redis 基本数据类型之一,它以字符串映射表的形式来进行存储。Hash 特别适合用于存储对象。常用的命令如下所示:
命令 | 说明 |
---|---|
HDEL | 用于删除一个或多个哈希表字段 |
HEXISTS | 用于确定哈希字段是否存在 |
HGET | 获取存储在 key 中的哈希字段的值 |
HGETALL | 获取存储在 key 中的所有哈希字段值 |
HINCRBY | 为存储在 key 中的哈希表指定字段做整数增量运算 |
HKEYS | 获取存储在 key 中的哈希表的所有字段 |
HLEN | 获取存储在 key 中的哈希表的字段数量 |
HSET | 用于设置存储在 key 中的哈希表字段的值 |
HVALS | 用于获取哈希表中的所有值 |
String 命令
Strings(字符串)结构是 Redis 的基本数据类型之一,我们可以通过相关字符串命令对其进行操作,比如设置、检索、删除等等。字符串类型有诸多的应用场景,比如微博粉丝的关注与取消等。
下面介绍了 Redis 中常营的字符串命令:
命令 | 说明 |
---|---|
APPEND | 该命令将 value 追加到 key 所存储值的末尾 |
BITCOUNT | 该命令用于计算字符串中,被设置为 1 的比特位的数量。 |
DECR | 将 key 所存储的整数值减 1 |
DECRBY | 将 key 所储存的值减去给定的递减值(decrement) |
GET | 用于检索指定键的值 |
GETBIT | 对 key 所存储的字符串值,获取其指定偏移量上的位(bit) |
GETRANGE | 返回 key 中字符串值的子字符 |
GETSET | 将给定 key 的值设置为 value,并返回 key 的旧值 |
INCR | 将 key 所存储的整数值加 1 |
INCRBY | 将 key 所储存的值加上给定的递增值(increment) |
INCRBYFLOAT | 将 key 所储存的值加上指定的浮点递增值(increment) |
MGET | 一次性获取一个或多个 key 所存储的值 |
MSET | 该命令允许同时设置多个键值对 |
MSETNX | 当指定的 key 都不存在时,用于设置多个键值对 |
SET | 用于设定指定键的值 |
SETBIT | 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit) |
SETEX | 将值 value 存储到 key中 ,并将 key 的过期时间设为 seconds (以秒为单位) |
STRLEN | 返回 key 所储存的字符串值的长度 |
SETNX | 当 key 不存在时设置 key 的值 |
SETRANGE | 从偏移量 offset 开始,使用指定的 value 覆盖的 key 所存储的部分字符串值 |
List 命令
List 是 Redis 中最常用数据类型之一。Redis 提供了诸多用于操作列表类型的命令,通过这些命令你可以实现将一个元素添加到列表的头部,或者尾部等诸多操作。
List 常用的命令如下所示:
命令 | 说明 |
---|---|
BLPOP | 用于删除并返回列表中的第一个元素(头部操作),如果列表中没有元素,就会发生阻塞,直到列表等待超时或发现可弹出元素为止 |
BRPOP | 用于删除并返回列表中的最后一个元素(尾部操作),如果列表中没有元素,就会发生阻塞,直到列表等待超时或发现可弹出元素为止 |
BRPOPLPUSH | 从列表中取出最后一个元素,并插入到另一个列表的头部。如果列表中没有元素,就会发生阻塞,直到等待超时或发现可弹出元素时为止 |
LINDEX | 通过索引获取列表中的元素 |
LINSERT | 指定列表中一个元素在它之前或之后插入另外一个元素 |
LLEN | 用于获取列表的长度 |
LPOP | 从列表的头部弹出元素,默认为第一个元素 |
LPUSH | 在列表头部插入一个或者多个值 |
LPUSHX | 当储存列表的 key 存在时,用于将值插入到列表头部 |
LRANGE | 获取列表指定范围内的元素 |
LREM | 表示从列表中删除元素与 value 相等的元素。count 表示删除的数量,为 0 表示全部移除 |
LSET | 表示通过其索引设置列表中元素的值 |
LTRIM | 保留列表中指定范围内的元素值 |
Set 命令
Redis set 数据类型由键值对组成,这些键值对具有无序、唯一的性质,这与 Python 的 set 相似。当集合中最后一个元素被移除之后,该数据结构也会被自动删除,内存也同样会被收回。
由于 set 集合可以实现去重,因此它有很多适用场景,比如用户抽奖活动,使用 set 集合可以保证同一用户不被第二次选中。
Redis set 常用的命令如下所示:
命令 | 说明 |
---|---|
SADD | 向集合中添加一个或者多个元素,并且自动去重 |
SCARD | 返回集合中元素的个数 |
SDIFF | 求两个或对多个集合的差集 |
SDIFFSTORE | 求两个集合或多个集合的差集,并将结果保存到指定的集合(key)中 |
SINTER | 求两个或多个集合的交集 |
SINTERSTORE | 求两个或多个集合的交集,并将结果保存到指定的集合(key)中 |
SMEMBERS | 查看集合中所有元素 |
SMOVE | 将集合中的元素移动到指定的集合中 |
SPOP | 弹出指定数量的元素 |
SRANDMEMBER | 随机从集合中返回指定数量的元素,默认返回 1个 |
SREM | 删除一个或者多个元素,若元素不存在则自动忽略 |
SUNION | 求两个或者多个集合的并集 |
SUNIONSTORE | 求两个或者多个集合的并集,并将结果保存到指定的集合(key)中 |
Zset 命令
zset 是 Redis 提供的最具特色的数据类型之一,首先它是一个 set,这保证了内部 value 值的唯一性,其次它给每个 value 添加了一个 score(分值)属性,通过对分值的排序实现了有序化。比如用 zset 结构来存储学生的成绩,value 值代表学生的 ID,score 则是的考试成绩。我们可以对成绩按分数进行排序从而得到学生的的名次。
下面列出了 zset 的常用命令,如下所示:
命令 | 说明 |
---|---|
ZADD | 用于将一个或多个成员添加到有序集合中,或者更新已存在成员的 score 值 |
ZCARD | 获取有序集合中成员的数量 |
ZCOUNT | 用于统计有序集合中指定 score 值范围内的元素个数 |
ZINCRBY | 用于增加有序集合中成员的分值 |
ZINTERSTORE | 求两个或者多个有序集合的交集,并将所得结果存储在新的 key 中 |
ZRANGE | 返回有序集合中指定索引区间内的成员数量 |
ZRANGEBYLEX | 返回有序集中指定字典区间内的成员数量 |
ZRANGEBYSCORE | 返回有序集合中指定分数区间内的成员 |
ZRANK | 返回有序集合中指定成员的排名 |
ZREM | 移除有序集合中的一个或多个成员 |
ZREMRANGEBYRANK | 移除有序集合中指定排名区间内的所有成员 |
ZREMRANGEBYSCORE | 移除有序集合中指定分数区间内的所有成员 |
ZREVRANGE | 返回有序集中指定区间内的成员,通过索引,分数从高到低 |
ZREVRANK | 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序 |
ZSCORE | 返回有序集中,指定成员的分数值 |
ZUNIONSTORE | 求两个或多个有序集合的并集,并将返回结果存储在新的 key 中 |
Redis SCAN 命令
Redis Scan 命令用于迭代数据库中的数据库键。
SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。
SCAN 返回一个包含两个元素的数组, 第一个元素是用于进行下一次迭代的新游标, 而第二个元素则是一个数组, 这个数组中包含了所有被迭代的元素。如果新游标返回 0 表示迭代已结束。
相关命令:
语法
redis Scan 命令基本语法如下:
SCAN cursor [MATCH pattern] [COUNT count]
- cursor - 游标。
- pattern - 匹配的模式。
- count - 指定从数据集里返回多少元素,默认值为 10 。
可用版本
>= 2.8.0
返回值
数组列表。
实例
使用 SCAN 命令迭代:
redis 127.0.0.1:6379> scan 0 # 使用 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"
redis 127.0.0.1:6379> scan 17 # 使用的是第一次迭代时返回的游标 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"
Redis HSCAN 命令
Redis HSCAN 命令用于迭代哈希表中的键值对。
语法
redis HSCAN 命令基本语法如下:
HSCAN key cursor [MATCH pattern] [COUNT count]
- cursor - 游标。
- pattern - 匹配的模式。
- count - 指定从数据集里返回多少元素,默认值为 10 。
可用版本
>= 2.8.0
返回值
返回的每个元素都是一个元组,每一个元组元素由一个字段(field) 和值(value)组成。
实例
> HMSET sites google "google.com" runoob "runoob.com" weibo "weibo.com" 4 "taobao.com"
OK
> HSCAN sites 0 match "run*"
1) "0"
2) 1) "runoob"
2) "runoob.com"
Redis Ltrim 命令
Redis Ltrim 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
语法
redis Ltrim 命令基本语法如下:
redis 127.0.0.1:6379> LTRIM KEY_NAME START STOP
返回值
命令执行成功时,返回 ok 。
实例
redis 127.0.0.1:6379> RPUSH mylist "hello"
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist "hello"
(integer) 2
redis 127.0.0.1:6379> RPUSH mylist "foo"
(integer) 3
redis 127.0.0.1:6379> RPUSH mylist "bar"
(integer) 4
redis 127.0.0.1:6379> LTRIM mylist 1 -1
OK
redis 127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "foo"
3) "bar"
Redis Lrem 命令
Redis Lrem 根据参数 COUNT 的值,移除列表中与参数 VALUE 相等的元素。
COUNT 的值可以是以下几种:
- count > 0 : 从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT 。
- count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值。
- count = 0 : 移除表中所有与 VALUE 相等的值。
语法
redis Lrem 命令基本语法如下:
redis 127.0.0.1:6379> LREM key count VALUE
返回值
被移除元素的数量。 列表不存在时返回 0 。
实例
redis> RPUSH mylist "hello"
(integer) 1
redis> RPUSH mylist "hello"
(integer) 2
redis> RPUSH mylist "foo"
(integer) 3
redis> RPUSH mylist "hello"
(integer) 4
redis> LREM mylist -2 "hello"
(integer) 2
redis> LRANGE mylist 0 -1
1) "hello"
2) "foo"
redis>
Redis Linsert 命令
Redis Linsert 命令用于在列表的元素前或者后插入元素。当指定元素不存在于列表中时,不执行任何操作。
当列表不存在时,被视为空列表,不执行任何操作。
如果 key 不是列表类型,返回一个错误。
语法
redis Linsert 命令基本语法如下:
LINSERT key BEFORE|AFTER pivot value
将值 value 插入到列表 key 当中,位于值 pivot 之前或之后。
返回值
如果命令执行成功,返回插入操作完成之后,列表的长度。 如果没有找到指定元素 ,返回 -1 。 如果 key 不存在或为空列表,返回 0 。
实例
redis> RPUSH mylist "Hello"
(integer) 1
redis> RPUSH mylist "World"
(integer) 2
redis> LINSERT mylist BEFORE "World" "There"
(integer) 3
redis> LRANGE mylist 0 -1
1) "Hello"
2) "There"
3) "World"
redis>
Redis Sdiff 命令
Redis Sdiff 命令返回第一个集合与其他集合之间的差异,也可以认为说第一个集合中独有的元素。不存在的集合 key 将视为空集。
差集的结果来自前面的 FIRST_KEY ,而不是后面的 OTHER_KEY1,也不是整个 FIRST_KEY OTHER_KEY1..OTHER_KEYN 的差集。
实例:
key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SDIFF key1 key2 key3 = {b,d}
语法
redis Sdiff 命令基本语法如下:
redis 127.0.0.1:6379> SDIFF FIRST_KEY OTHER_KEY1..OTHER_KEYN
Redis Sdiffstore 命令
Redis Sdiffstore 命令将给定集合之间的差集存储在指定的集合中。如果指定的集合 key 已存在,则会被覆盖。
语法
redis Sdiffstore 命令基本语法如下:
redis 127.0.0.1:6379> SDIFFSTORE DESTINATION_KEY KEY1..KEYN
返回值
结果集中的元素数量。
实例
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset "bar"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "world"
(integer) 1
redis 127.0.0.1:6379> SDIFFSTORE destset myset myset2
(integer) 2
redis 127.0.0.1:6379> SMEMBERS destset
1) "foo"
2) "bar"
Redis Sinter 命令
Redis Sinter 命令返回给定所有给定集合的交集。 不存在的集合 key 被视为空集。 当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。
语法
redis Sinter 命令基本语法如下:
redis 127.0.0.1:6379> SINTER KEY KEY1..KEYN
返回值
交集成员的列表。
实例
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset "bar"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "world"
(integer) 1
redis 127.0.0.1:6379> SINTER myset myset2
1) "hello"
Redis Smembers 命令
Redis Smembers 命令返回集合中的所有的成员。 不存在的集合 key 被视为空集合。
语法
redis Smembers 命令基本语法如下:
redis 127.0.0.1:6379> SMEMBERS key
返回值
集合中的所有成员。
实例
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "world"
(integer) 1
redis 127.0.0.1:6379> SMEMBERS myset1
1) "World"
2) "Hello"
Redis Sismember 命令
Redis Sismember 命令判断成员元素是否是集合的成员。
语法
redis Sismember 命令基本语法如下:
redis 127.0.0.1:6379> SISMEMBER KEY VALUE
返回值
如果成员元素是集合的成员,返回 1 。 如果成员元素不是集合的成员,或 key 不存在,返回 0 。
实例
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SISMEMBER myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SISMEMBER myset1 "world"
(integer) 0
Redis Sunion 命令
Redis Sunion 命令返回给定集合的并集。不存在的集合 key 被视为空集。
语法
redis Sunion 命令基本语法如下:
redis 127.0.0.1:6379> SUNION KEY KEY1..KEYN
返回值
并集成员的列表。
实例
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SUNION key1 key2
1) "a"
2) "c"
3) "b"
4) "e"
5) "d"
Redis Sscan 命令
Redis Sscan 命令用于迭代集合中键的元素,Sscan 继承自 Scan。
语法
redis Sscan 命令基本语法如下:
SSCAN key cursor [MATCH pattern] [COUNT count]
- cursor - 游标。
- pattern - 匹配的模式。
- count - 指定从数据集里返回多少元素,默认值为 10 。
(integer) 1
> SADD myset1 "Runoob"
(integer) 1
> SADD myset1 "Taobao"
(integer) 1
> SSCAN myset1 0 match R*
1) "0"
2) 1) "Runoob"
Redis Zinterstore 命令
Redis Zinterstore 命令计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。
默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和。
语法
redis Zinterstore 命令基本语法如下:
redis 127.0.0.1:6379> ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
返回值
保存到目标结果集的的成员数量。
实例
# 有序集 mid_test
redis 127.0.0.1:6379> ZADD mid_test 70 "Li Lei"
(integer) 1
redis 127.0.0.1:6379> ZADD mid_test 70 "Han Meimei"
(integer) 1
redis 127.0.0.1:6379> ZADD mid_test 99.5 "Tom"
(integer) 1
# 另一个有序集 fin_test
redis 127.0.0.1:6379> ZADD fin_test 88 "Li Lei"
(integer) 1
redis 127.0.0.1:6379> ZADD fin_test 75 "Han Meimei"
(integer) 1
redis 127.0.0.1:6379> ZADD fin_test 99.5 "Tom"
(integer) 1
# 交集
redis 127.0.0.1:6379> ZINTERSTORE sum_point 2 mid_test fin_test
(integer) 3
# 显示有序集内所有成员及其分数值
redis 127.0.0.1:6379> ZRANGE sum_point 0 -1 WITHSCORES
1) "Han Meimei"
2) "145"
3) "Li Lei"
4) "158"
5) "Tom"
6) "199"
Redis Zrangebyscore 命令
Redis Zrangebyscore 返回有序集合中指定分数区间的成员列表。有序集成员按分数值递增(从小到大)次序排列。
具有相同分数值的成员按字典序来排列(该属性是有序集提供的,不需要额外的计算)。
默认情况下,区间的取值使用闭区间 (小于等于或大于等于),你也可以通过给参数前增加 ( 符号来使用可选的开区间 (小于或大于)。
举个例子:
ZRANGEBYSCORE zset (1 5
返回所有符合条件 1 < score <= 5 的成员,而
ZRANGEBYSCORE zset (5 (10
则返回所有符合条件 5 < score < 10 的成员。
语法
redis Zrangebyscore 命令基本语法如下:
redis 127.0.0.1:6379> ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
返回值
指定区间内,带有分数值(可选)的有序集成员的列表。
实例
redis 127.0.0.1:6379> ZADD salary 2500 jack # 测试数据
(integer) 0
redis 127.0.0.1:6379> ZADD salary 5000 tom
(integer) 0
redis 127.0.0.1:6379> ZADD salary 12000 peter
(integer) 0
redis 127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf # 显示整个有序集
1) "jack"
2) "tom"
3) "peter"
redis 127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf WITHSCORES # 显示整个有序集及成员的 score 值
1) "jack"
2) "2500"
3) "tom"
4) "5000"
5) "peter"
6) "12000"
redis 127.0.0.1:6379> ZRANGEBYSCORE salary -inf 5000 WITHSCORES # 显示工资 <=5000 的所有成员
1) "jack"
2) "2500"
3) "tom"
4) "5000"
redis 127.0.0.1:6379> ZRANGEBYSCORE salary (5000 400000 # 显示工资大于 5000 小于等于 400000 的成员
1) "peter"
Redis bitmap位图操作(图解)
在平时开发过程中,经常会有一些 bool 类型数据需要存取。比如记录用户一年内签到的次数,签了是 1,没签是 0。如果使用 key-value 来存储,那么每个用户都要记录 365 次,当用户成百上亿时,需要的存储空间将非常巨大。为了解决这个问题,Redis 提供了位图结构。
位图(bitmap)同样属于 string 数据类型。Redis 中一个字符串类型的值最多能存储 512 MB 的内容,每个字符串由多个字节组成,每个字节又由 8 个 Bit 位组成。位图结构正是使用“位”来实现存储的,它通过将比特位设置为 0 或 1来达到数据存取的目的,这大大增加了 value 存储数量,它存储上限为2^32
。
位图本质上就是一个普通的字节串,也就是 bytes 数组。您可以使用getbit/setbit
命令来处理这个位数组,位图的结构如下所示:
位图适用于一些特定的应用场景,比如用户签到次数、或者登录次数等。上图是表示一位用户 10 天内来网站的签到次数,1 代表签到,0 代表未签到,这样可以很轻松地统计出用户的活跃程度。相比于直接使用字符串而言,位图中的每一条记录仅占用一个 bit 位,从而大大降低了内存空间使用率。
Redis 官方也做了一个实验,他们模拟了一个拥有 1 亿 2 千 8 百万用户的系统,然后使用 Redis 的位图来统计“日均用户数量”,最终所用时间的约为 50ms,且仅仅占用 16 MB内存。
位图应用原理
某网站要统计一个用户一年的签到记录,若用 sring 类型存储,则需要 365 个键值对。若使用位图存储,用户签到就存 1,否则存 0。最后会生成 11010101... 这样的存储结果,其中每天的记录只占一位,一年就是 365 位,约为 46 个字节。如果只想统计用户签到的天数,那么统计 1 的个数即可。
位图操作的优势,相比于字符串而言,它不仅效率高,而且还非常的节省空间。
Redis 的位数组是自动扩展的,如果设置了某个偏移位置超出了现有的内容范围,位数组就会自动扩充。
下面设置一个名为 a 的 key,我们对这个 key 进行位图操作,使得 a 的对应的 value 变为“he”。
首先我们分别获取字符“h”和字符“e”的八位二进制码,如下所示:
>>> bin(ord("h")) '0b1101000' >>> bin(ord("e")) '0b1100101'
接下来,只要对需值为 1 的位进行操作即可。如下图所示:
把 h 和 e 的二进制码连接在一起,第一位的下标是 0,依次递增至 15,然后将数字为 1 的位置标记出来,得到 1/2/4/9/10/13/15,我们把这组数字称为位的“偏置数”,最后按照上述偏置数对字符 a 进行如下位图操作。注意,key 的初始二进制位全部为 0。
C:\Users\Administrator>redis-cli 127.0.0.1:6379> SETBIT a 1 1 (integer) 0 127.0.0.1:6379> SETBIT a 2 1 (integer) 0 127.0.0.1:6379> SETBIT a 4 1 (integer) 0 127.0.0.1:6379> get hello "h" 127.0.0.1:6379> SETBIT a 9 1 (integer) 0 127.0.0.1:6379> SETBIT a 10 1 (integer) 0 127.0.0.1:6379> SETBIT a 13 1 (integer) 0 127.0.0.1:6379> SETBIT a 15 1 (integer) 0 127.0.0.1:6379> get hello "he"
从上述示例可以得出,位图操作会自动对 key 进行扩容。
如果对应位的字节是不可以被打印的,那么 Redis 会以该字符的十六进制数来表示它,如下所示:
127.0.0.1:6379> SETBIT b 0 1 (integer) 0 127.0.0.1:6379> SETBIT b 1 1 (integer) 0 127.0.0.1:6379> get b "\xc0"
位图常用命令
1) SETBIT命令
用来设置或者清除某一位上的值,其返回值是原来位上存储的值。key 在初始状态下所有的位都为 0 ,语法格式如下:
SETBIT key offset value
其中 offset 表示偏移量,从 0 开始。示例如下:
127.0.0.1:6379> SET user:1 a OK #设置偏移量为0 127.0.0.1:6379> SETBIT user:1 0 1 (integer) 0 #当对应位的字符是不可打印字符,redis会以16进制形式显示 127.0.0.1:6379> GET user:1 "\xe1"
2) GETBIT命令
用来获取某一位上的值。示例如下:
127.0.0.1:6379> GETBIT user:1 0 (integer) 1
当偏移量 offset 比字符串的长度大,或者当 key 不存在时,返回 0。
redis> EXISTS bits (integer) 0 redis> GETBIT bits 100000 (integer) 0
3) BITCOUNT命令
统计指定位区间上,值为 1 的个数。语法格式如下:
BITCOUNT key [start end]
示例如下:
127.0.0.1:6379> BITCOUNT user:1 (integer) 8
通过指定的 start 和 end 参数,可以让计数只在特定的字节上进行。start 和 end 参数和 GETRANGE 命令的参数类似,都可以使用负数,比如 -1 表示倒数第一个位, -2 表示倒数第二个位。
Redis连接命令
命令 | 说明 |
---|---|
AUTH password | 验证密码是否正确 |
ECHO message | 打印字符串 |
PING | 查看服务是否运行正常 |
QUIT | 关闭当前连接 |
SELECT index | 切换到指定的数据库 |
连接命令应用
2) 验证连接
下面看一组实例演示:
#通过配置文件或者或者config命令配置客户端连接密码 redis 127.0.0.1:6379> CONFIG SET requirepass 123456 OK #验证给定的密码和配置文件密码是否一致 redis 127.0.0.1:6379> AUTH 123456 OK #检测客户端与服务器是否连接正常 redis 127.0.0.1:6379> PING PONG #切换到2库 127.0.0.1:6379> SELECT 2 OK 127.0.0.1:6379[2]> ECHO "hello www.biancheng.net" "hello www.biancheng.net" #中断连接 127.0.0.1:6379> QUIT C:\Users\Administrator>
命令配置密码
通过执行以下命令查看是否设置了密码验证:
127.0.0.1:6379> CONFIG get requirepass 1) "requirepass" 2) ""
在默认情况下 requirepass 参数值为空的,表示无需通过密码验证就可以连接到 Redis 服务。
下面执行以下命令设置密码。如下所示:
127.0.0.1:6379> CONFIG set requirepass "www.biancheng.net" OK 127.0.0.1:6379> CONFIG get requirepass 1) "requirepass" 2) "www.biancheng.net"
Redis HyperLoglog基数统计
Redis 经常使用的数据类型有字符串、列表、散列、集合和有序集合,但这些类型并不能满足所有的应用场景,因此,Redis 的后续版本不断的扩增其他数据类型来增强 Redis 适用能力。在 Redis 2.8.9 版本中新增了 HyperLogLog 类型。
什么是HyperLoglog
HyperLoglog 是 Redis 重要的数据类型之一,它非常适用于海量数据的计算、统计,其特点是占用空间小,计算速度快。
HyperLoglog 采用了一种基数估计算法,因此,最终得到的结果会存在一定范围的误差(标准误差为 0.81%)。每个 HyperLogLog key 只占用 12 KB 内存,所以理论上可以存储大约2^64
个值,而 set(集合)则是元素越多占用的内存就越多,两者形成了鲜明的对比 。
HyperLoglog 使用起来较为方便,但是其内部原理较为复杂,不建议大家深入研究,只要会用即可。
基数定义
基数定义:一个集合中不重复的元素个数就表示该集合的基数,比如集合 {1,2,3,1,2} ,它的基数集合为 {1,2,3} ,所以基数为 3。HyperLogLog 正是通过基数估计算法来统计输入元素的基数。
HyperLoglog 不会储存元素值本身,因此,它不能像 set 那样,可以返回具体的元素值。HyperLoglog 只记录元素的数量,并使用基数估计算法,快速地计算出集合的基数是多少。
场景应用
HyperLogLog 也有一些特定的使用场景,它最典型的应用场景就是统计网站用户月活量,或者网站页面的 UV(网站独立访客)数据等。
UV 与 PV(页面浏览量) 不同,UV 需要去重,同一个用户一天之内的多次访问只能计数一次。这就要求用户的每一次访问都要带上自身的用户 ID,无论是登陆用户还是未登陆用户都需要一个唯一 ID 来标识。
当一个网站拥有巨大的用户访问量时,我们可以使用 Redis 的 HyperLogLog 来统计网站的 UV (网站独立访客)数据,它提供的去重计数方案,虽说不精确,但 0.81% 的误差足以满足 UV 统计的需求。
常用命令
命令 | 说明 |
---|---|
PFADD key element [element ...] | 添加指定元素到 HyperLogLog key 中。 |
PFCOUNT key [key ...] | 返回指定 HyperLogLog key 的基数估算值。 |
PFMERGE destkey sourcekey [sourcekey ...] | 将多个 HyperLogLog key 合并为一个 key。 |
基本命令
HyperLogLog 提供了三个常用命令,分别是PFADD
、PFCOUNT
和PFMERGE
。
下面看一组实例演示:假设有 6 个用户(user01-user06),他们分别在上午 8 与 9 点访问了www.biancheng.net
C语言中文网。
#向指定的key中添加用户 127.0.0.1:6379> PFADD user:uv:2021011308 user01 user02 user03 (integer) 1 #向指定的key中添加用户 127.0.0.1:6379> PFADD user:uv:2021011309 user04 user05 (integer) 1 #统计基数值 127.0.0.1:6379> PFCOUNT user:uv:2021011308 (integer) 3 #重复元素不能添加成功,其基数仍然为3 127.0.0.1:6379> PFADD user:uv:2021011308 user01 user02 (integer) 0 127.0.0.1:6379> PFCOUNT user:uv:2021011308 (integer) 3 #添加新元素值 127.0.0.1:6379> PFADD user:uv:2021011308 user06 (integer) 1 #基数值变为4 127.0.0.1:6379> PFCOUNT user:uv:2021011308 (integer) 4 #统计两个key的基数值 127.0.0.1:6379> PFCOUNT user:uv:2021011308 user:uv:2021011309 (integer) 6 #将两个key值合并为一个 127.0.0.1:6379> PFMERGE user:uv:2021011308-09 user:uv:2021011308 user:uv:2021011309 OK #使用合并后key统计基数值 127.0.0.1:6379> PFCOUNT user:uv:2021011308-09 (integer) 6
Redis PubSub发布订阅(详细图解)
Redis PubSub 模块又称发布订阅者模式,是一种消息传递系统,实现了消息多播功能。发布者(即发送方)发送消息,订阅者(即接收方)接收消息,而用来传递消息的链路则被称为 channel。在 Redis 中,一个客户端可以订阅任意数量的 channel(可译为频道)。
1) 订阅者/等待接收消息
首先打开 Redis 客户端,然后订阅了一个名为“www.biancheng.net”的 channel,使用如下命令:
#订阅channel 127.0.0.1:6379> SUBSCRIBE www.biancheng.net Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "www.biancheng.net" 3) (integer) 1
上述示例使用SUBSCRIBE
命令订阅了名为 www.biancheng.net 的 channel。命令执行后该客户端会出处于等待接收消息的阻塞状态。
2) 发布者/发送消息
下面再启动一个 Redis 客户端,输入如下命令:
127.0.0.1:6379> PUBLISH www.biancheng.net "this is website" (integer) 1 127.0.0.1:6379> PUBLISH www.biancheng.net "hello world" (integer) 1 127.0.0.1:6379> PUBLISH www.biancheng.net "how are you" (integer) 1
通过上述PUBLISH
命令发布了三条信息。现在两个客户端在处于同一个名为“www.biancheng.net”的频道上,前者负责接收消息,后者负责发布消息。
3) 订阅者/成功接收消息
完成了上述操作后,您会在接收消息的客户端得到如下输出结果:
127.0.0.1:6379> SUBSCRIBE www.biancheng.net Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "www.biancheng.net" 3) (integer) 1 1) "message" 2) "www.biancheng.net" 3) "this is website" 1) "message" 2) "www.biancheng.net" 3) "hello world" 1) "message" 2) "www.biancheng.net" 3) "how are you"
常用命令汇总
命令 | 说明 |
---|---|
PSUBSCRIBE pattern [pattern ...] | 订阅一个或多个符合指定模式的频道。 |
PUBSUB subcommand [argument [argument ...]] | 查看发布/订阅系统状态,可选参数 1) channel 返回在线状态的频道。 2) numpat 返回指定模式的订阅者数量。 3) numsub 返回指定频道的订阅者数量。 |
PUBSUB subcommand [argument [argument ...]] | 将信息发送到指定的频道。 |
PUNSUBSCRIBE [pattern [pattern ...]] | 退订所有指定模式的频道。 |
SUBSCRIBE channel [channel ...] | 订阅一个或者多个频道的消息。 |
UNSUBSCRIBE [channel [channel ...]] | 退订指定的频道。 |
Redis Stream消息队列
Redis Stream 是 Redis 5.0 版本引入的一种新数据类型,同时它也是 Redis 中最为复杂的数据结构,本节主要对 Stream 做相关介绍。
什么是Stream?
Stream 实际上是一个具有消息发布/订阅功能的组件,也就常说的消息队列。其实这种类似于 broker/consumer(生产者/消费者)的数据结构很常见,比如 RabbitMQ 消息中间件、Celery 消息中间件,以及 Kafka 分布式消息系统等,而 Redis Stream 正是借鉴了 Kafaka 系统。
Redis Stream 主要用于消息队列(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。
简单来说发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。
而 Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。
1) 优点
Strean 除了拥有很高的性能和内存利用率外, 它最大的特点就是提供了消息的持久化存储,以及主从复制功能,从而解决了网络断开、Redis 宕机情况下,消息丢失的问题,即便是重启 Redis,存储的内容也会存在。
2) 流程
Stream 消息队列主要由四部分组成,分别是:消息本身、生产者、消费者和消费组,对于前述三者很好理解,下面了解什么是消费组。
一个 Stream 队列可以拥有多个消费组,每个消费组中又包含了多个消费者,组内消费者之间存在竞争关系。当某个消费者消费了一条消息时,同组消费者,都不会再次消费这条消息。被消费的消息 ID 会被放入等待处理的 Pending_ids 中。每消费完一条信息,消费组的游标就会向前移动一位,组内消费者就继续去争抢下消息。
Redis Stream 消息队列结构程如下图所示:
Redis Stream 的结构如下所示,它有一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的 ID 和对应的内容:
每个 Stream 都有唯一的名称,它就是 Redis 的 key,在我们首次使用 xadd 指令追加消息时自动创建。
上图解析:
- Consumer Group :消费组,使用 XGROUP CREATE 命令创建,一个消费组有多个消费者(Consumer)。
- last_delivered_id :游标,每个消费组会有个游标 last_delivered_id,任意一个消费者读取了消息都会使游标 last_delivered_id 往前移动。
- pending_ids :消费者(Consumer)的状态变量,作用是维护消费者的未确认的 id。 pending_ids 记录了当前已经被客户端读取的消息,但是还没有 ack (Acknowledge character:确认字符)。
下面对上图涉及的专有名词做简单解释:
- Stream direction:表示数据流,它是一个消息链,将所有的消息都串起来,每个消息都有一个唯一标识 ID 和对应的消息内容(Message content)。
- Consumer Group :表示消费组,拥有唯一的组名,使用 XGROUP CREATE 命令创建。一个 Stream 消息链上可以有多个消费组,一个消费组内拥有多个消费者,每一个消费者也有一个唯一的 ID 标识。
- last_delivered_id :表示消费组游标,每个消费组都会有一个游标 last_delivered_id,任意一个消费者读取了消息都会使游标 last_delivered_id 往前移动。
- pending_ids :Redis 官方称为 PEL,表示消费者的状态变量,它记录了当前已经被客户端读取的消息 ID,但是这些消息没有被 ACK(确认字符)。如果客户端没有 ACK,那么这个变量中的消息 ID 会越来越多,一旦被某个消息被 ACK,它就开始减少。
3) ACK
ACK(Acknowledge character)即确认字符,在数据通信中,接收方传递给发送方的一种传输类控制字符。表示发来的数据已确认接收无误。在 TCP/IP 协议中,如果接收方成功的接收到数据,那么会回复一个 ACK 数据。通常 ACK 信号有自己固定的格式,长度大小,由接收方回复给发送方。
消息队列相关命令:
- XADD - 添加消息到末尾
- XTRIM - 对流进行修剪,限制长度
- XDEL - 删除消息
- XLEN - 获取流包含的元素数量,即消息长度
- XRANGE - 获取消息列表,会自动过滤已经删除的消息
- XREVRANGE - 反向获取消息列表,ID 从大到小
- XREAD - 以阻塞或非阻塞方式获取消息列表
消费者组相关命令:
- XGROUP CREATE - 创建消费者组
- XREADGROUP GROUP - 读取消费者组中的消息
- XACK - 将消息标记为"已处理"
- XGROUP SETID - 为消费者组设置新的最后递送消息ID
- XGROUP DELCONSUMER - 删除消费者
- XGROUP DESTROY - 删除消费者组
- XPENDING - 显示待处理消息的相关信息
- XCLAIM - 转移消息的归属权
- XINFO - 查看流和消费者组的相关信息;
- XINFO GROUPS - 打印消费者组的信息;
- XINFO STREAM - 打印流信息
常用命令汇总
命令 | 说明 |
---|---|
XADD | 添加消息到末尾。 |
XTRIM | 对 Stream 流进行修剪,限制长度。 |
XDEL | 删除指定的消息。 |
XLEN | 获取流包含的元素数量,即消息长度。 |
XRANGE | 获取消息列表,会自动过滤已经删除的消息。 |
XREVRANGE | 反向获取消息列表,ID 从大到小。 |
XREAD | 以阻塞或非阻塞方式获取消息列表。 |
XGROUP CREATE | 创建消费者组。 |
XREADGROUP GROUP | 读取消费者组中的消息。 |
XACK | 将消息标记为"已处理"。 |
XGROUP SETID | 为消费者组设置新的最后递送消息ID。 |
XGROUP DELCONSUMER | 删除消费者。 |
XGROUP DESTROY | 删除消费者组。 |
XPENDING | 显示待处理消息的相关信息。 |
XCLAIM | 转移消息的归属权。 |
XINFO | 查看 Stream 流、消费者和消费者组的相关信息。 |
XINFO GROUPS | 查看消费者组的信息。 |
XINFO STREAM | 查看 Stream 流信息。 |
XINFO CONSUMERS key group | 查看组内消费者流信息。 |
基本命令应用
下面通过一组示例演示有关 Stream 命令的使用:
#添加一个消息, * 表示以时间戳自动创建id 127.0.0.1:6379> XADD mystream * username www.biancheng.net age 10 c.biancheng.net age 9 "1610619132674-1" #自定义id等于001,注意id只增不减 127.0.0.1:6379> XADD mystream1 001 name zhangsan addr hebei "1-0" 127.0.0.1:6379> XADD mystream1 002 name lisi addr hunan "2-0" #如果插入重复的id号会报错 127.0.0.1:6379> XADD mystream1 001 name wangwu addr fujian (error) ERR The ID specified in XADD is equal or smaller than the target stream top item 127.0.0.1:6379> XADD mystream1 003 name wangwu addr fujian "3-0" #删除id=001的数据 127.0.0.1:6379> XDEL mystream1 001 (integer) 1 #查看stream队列包含的消息数量,也就消息长度 127.0.0.1:6379> XLEN mystream1 (integer) 2 #获取消息列表,-表示最小,+表示最大 127.0.0.1:6379> XRANGE mystream - + 1) 1) "1610619132674-0" 2) 1) "username" 2) "www.biancheng.net" 3) "age" 4) "10" 2) 1) "1610619178028-0" 2) 1) "username" 2) "c.biancheng.net" 3) "age" 4) "9" #获取消息列表 127.0.0.1:6379> XRANGE mystream1 - 003 1) 1) "2-0" 2) 1) "name" 2) "lisi" 3) "addr" 4) "hunan" 2) 1) "3-0" 2) 1) "name" 2) "wangwu" 3) "addr" 4) "fujian" #使用count指定返回数据的数量 127.0.0.1:6379> XRANGE mystream1 - 003 count 1 1) 1) "2-0" 2) 1) "name" 2) "lisi" 3) "addr" 4) "hunan" #删除整个Stream 127.0.0.1:6379> DEL mystream #使用xread读取消息 127.0.0.1:6379> XREAD count 2 STREAMS mystream1 2-0 1) 1) "mystream1" 2) 1) 1) "3-0" 2) 1) "name" 2) "wangwu" 3) "addr" 4) "fujian"
Redis布隆过滤器(原理+图解)
布隆过滤器(Bloom Filter)是 Redis 4.0 版本提供的新功能,它被作为插件加载到 Redis 服务器中,给 Redis 提供强大的去重功能。
相比于 Set 集合的去重功能而言,布隆过滤器在空间上能节省 90% 以上,但是它的不足之处是去重率大约在 99% 左右,也就是说有 1% 左右的误判率,这种误差是由布隆过滤器的自身结构决定的。俗话说“鱼与熊掌不可兼得”,如果想要节省空间,就需要牺牲 1% 的误判率,而且这种误判率,在处理海量数据时,几乎可以忽略。
应用场景
布隆过滤器是 Redis 的高级功能,虽然这种结构的去重率并不完全精确,但和其他结构一样都有特定的应用场景,比如当处理海量数据时,就可以使用布隆过滤器实现去重。
下面举两个简单的例子:
1) 示例:
百度爬虫系统每天会面临海量的 URL 数据,我们希望它每次只爬取最新的页面,而对于没有更新过的页面则不爬取,因策爬虫系统必须对已经抓取过的 URL 去重,否则会严重影响执行效率。但是如果使用一个 set(集合)去装载这些 URL 地址,那么将造成资源空间的严重浪费。
2) 示例:
垃圾邮件过滤功能也采用了布隆过滤器。虽然在过滤的过程中,布隆过滤器会存在一定的误判,但比较于牺牲宝贵的性能和空间来说,这一点误判是微不足道的。
工作原理
布隆过滤器(Bloom Filter)是一个高空间利用率的概率性数据结构,由二进制向量(即位数组)和一系列随机映射函数(即哈希函数)两部分组成。
布隆过滤器使用exists()
来判断某个元素是否存在于自身结构中。当布隆过滤器判定某个值存在时,其实这个值只是有可能存在;当它说某个值不存在时,那这个值肯定不存在,这个误判概率大约在 1% 左右。
1) 工作流程-添加元素
布隆过滤器主要由位数组和一系列 hash 函数构成,其中位数组的初始状态都为 0。
下面对布隆过滤器工作流程做简单描述,如下图所示:
当使用布隆过滤器添加 key 时,会使用不同的 hash 函数对 key 存储的元素值进行哈希计算,从而会得到多个哈希值。根据哈希值计算出一个整数索引值,将该索引值与位数组长度做取余运算,最终得到一个位数组位置,并将该位置的值变为 1。每个 hash 函数都会计算出一个不同的位置,然后把数组中与之对应的位置变为 1。通过上述过程就完成了元素添加(add)操作。
2) 工作流程-判定元素是否存在
当我们需要判断一个元素是否存时,其流程如下:首先对给定元素再次执行哈希计算,得到与添加元素时相同的位数组位置,判断所得位置是否都为 1,如果其中有一个为 0,那么说明元素不存在,若都为 1,则说明元素有可能存在。
3) 为什么是可能“存在”
您可能会问,为什么是有可能存在?其实原因很简单,那些被置为 1 的位置也可能是由于其他元素的操作而改变的。比如,元素1 和 元素2,这两个元素同时将一个位置变为了 1(图1所示)。在这种情况下,我们就不能判定“元素 1”一定存在,这是布隆过滤器存在误判的根本原因。
安装与使用
在 Redis 4.0 版本之后,布隆过滤器才作为插件被正式使用。布隆过滤器需要单独安装,下面介绍安装 RedisBloom 的几种方法:
1) docker安装
docker 安装布隆过滤器是最简单、快捷的一种方式:
docker pull redislabs/rebloom:latest docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest docker exec -it redis-redisbloom bash redis-cli #测试是否安装成功 127.0.0.1:6379> bf.add www.biancheng.net hello
2) 直接编译安装
如果您对 docker 不熟悉,也可以采用直接编译的方式来安装。
下载地址: https://github.com/RedisBloom/RedisBloom 解压文件: unzip RedisBloom-master.zip 进入目录: cd RedisBloom-master 执行编译命令,生成redisbloom.so 文件: make 拷贝至指定目录: cp redisbloom.so /usr/local/redis/bin/redisbloom.so 在redis配置文件里加入以下配置: loadmodule /usr/local/redis/bin/redisbloom.so 配置完成后重启redis服务: sudo /etc/init.d/redis-server restart #测试是否安装成功 127.0.0.1:6379> bf.add www.biancheng.net hello
常用命令汇总
命令 | 说明 |
---|---|
bf.add | 只能添加元素到布隆过滤器。 |
bf.exists | 判断某个元素是否在于布隆过滤器中。 |
bf.madd | 同时添加多个元素到布隆过滤器。 |
bf.mexists | 同时判断多个元素是否存在于布隆过滤器中。 |
bf.reserve | 以自定义的方式设置布隆过滤器参数值,共有 3 个参数分别是 key、error_rate(错误率)、initial_size(初始大小)。 |
1) 命令应用
127.0.0.1:6379> bf.add spider:url www.biancheng.net (integer) 1 127.0.0.1:6379> bf.exists spider:url www.biancheng.net (integer) 1 127.0.0.1:6379> bf.madd spider:url www.taobao.com www.123qq.com 1) (integer) 1 2) (integer) 1 127.0.0.1:6379> bf.mexists spider:url www.jd.com www.taobao.com 1) (integer) 0 2) (integer) 1
Python使用布隆过滤器
下面使用 Python 测试布隆过滤器的误判率,代码如下所示:
- import redis
- size=10000
- r = redis.Redis()
- count = 0
- for i in range(size):
- #添加元素,key为userid,值为user0...user9999
- r.execute_command("bf.add", "userid", "user%d" % i)
- #判断元素是否存在,此处切记 i+1
- res = r.execute_command("bf.exists", "userid", "user%d" % (i + 1))
- if res == 1:
- print(i)
- count += 1
- #求误判率,round()中的5表示保留的小数点位数
- print("size: {} ,error rate:{}%".format(size, round(count / size * 100, 5)))
执行三次测试,size 从小到大。输出结果如下:
size: 1000 , error rate: 1.0% size: 10000 , error rate: 1.25% size: 100000 , error rate: 1.305%
通过上述结果可以看出布隆过滤器的错误率为 1% 多点,当 size 越来越大时,布隆过滤器的错误率就会升高,那么有没有办法降低错误率呢?这就用到了布隆过滤器提供的bf.reserve
方法。如果不使用该方法设置参数,那么布隆过滤器将按照默认参数进行设置,如下所示:
key #指定存储元素的键,若已经存在,则bf.reserve会报错 error_rate=0.01 #表示错误率 initial_size=100 #表示预计放入布隆过滤器中的元素数量
当放入过滤器中的元素数量超过了 initial_size 值时,错误率 error_rate 就会升高。因此就需要设置一个较大 initial_size 值,避免因数量超出导致的错误率上升。
解决错误率过高的问题
错误率越低,所需要的空间也会越大,因此就需要我们尽可能精确的估算元素数量,避免空间的浪费。我们也要根据具体的业务来确定错误率的许可范围,对于不需要太精确的业务场景,错误率稍微设置大一点也可以。
注意:如果要使用自定义的布隆过滤器需要在 add 操作之前,使用 bf.reserve 命令显式地创建 key,格式如下:
client.execute_command("bf.reserve", "keyname", 0.001, 50000)
布隆过滤器相比于平时常用的的列表、散列、集合等数据结构,其占用空间更少、效率更高,但缺点就是返回的结果具有概率性,并不是很准确。在理论情况下,添加的元素越多,误报的可能性就越大。再者,存放于布隆过滤器中的元素不容易被删除,因为可能出现会误删其他元素情况。
Redis GEO地理位置
Redis GEO 操作方法有:
- geoadd:添加地理位置的坐标。
- geopos:获取地理位置的坐标。
- geodist:计算两个位置之间的距离。
- georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。
- georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。
- geohash:返回一个或多个位置对象的 geohash 值。
Redis GEO 提供了 6 个常用命令:
- GEOADD
- GEOPOS
- GEODIST
- GEORADIUS
- GEORADIUSBYMEMBER
- GEOHASH
Redis GEO 有很多应用场景,举一个简单的例子,你一定点过外卖,或者用过打车软件,在这种 APP上会显示“店家距离你有多少米”或者“司机师傅距离你有多远”,类似这种功能就可以使用 Redis GEO 实现。数据库中存放着商家所处的经纬度,你的位置则由手机定位获取,这样 APP 就计算出了最终的距离。再比如微信中附近的人、摇一摇、实时定位等功能都依赖地理位置实现。
GEO 提供以下操作命令,如下表所示:
序号 | 命令 | 说明 |
---|---|---|
1 | GEOADD | 将指定的地理空间位置(纬度、经度、名称)添加到指定的 key 中。 |
2 | GEOPOS | 从 key 里返回所有给定位置元素的位置(即经度和纬度) |
3 | GEODIST | 返回两个地理位置间的距离,如果两个位置之间的其中一个不存在, 那么命令返回空值。 |
4 | GEORADIUS | 根据给定地理位置坐标(经纬度)获取指定范围内的地理位置集合。 |
5 | GEORADIUSBYMEMBER | 根据给定地理位置(具体的位置元素)获取指定范围内的地理位置集合。 |
6 | GEOHASH | 获取一个或者多个的地理位置的 GEOHASH 值。 |
7 | ZREM | 通过有序集合的 zrem 命令实现对地理位置信息的删除。 |
1) GEOADD
将指定的地理空间位置(纬度、经度、名称)添加到指定的 key 中。语法格式如下:
GEOADD key longitude latitude member [longitude latitude member ...]
- longitude:位置地点所处的经度;
- latitude:位置地点所处的纬度;
- member:位置名称。
将给定的经纬度的位置名称(纬度、经度、名字)与 key 相对应,这些数据以有序集合的形式进行储存。GEOADD
命令以标准的x,y
形式接受参数, 所以用户必须先输入经度,然后再输入纬度。GEOADD
命令能够记录的坐标数量是有限的,如果位置非常接近两极(南极/北极)区域,那么将无法被索引到。因此当您输入经纬度时,需要注意以下规则:
- 有效的经度介于 -180 度至 180 度之间。
- 有效的纬度介于 -85.05112878 度至 85.05112878 度之间。
注意:如果您输入一个超出范围的经纬度时,GEOADD 命令将返回一个错误。
示例演示如下:
#添加城市地理位置 127.0.0.1:6379> geoadd city 116.20 39.56 beijing 120.52 30.40 shanghai (integer) 2 #查询城市地理位置 127.0.0.1:6379> GEOPOS city beijing shanghai 1) 1) "116.19999736547470093" 2) "39.56000019952067248" 2) 1) "120.52000075578689575" 2) "30.39999952668997452"
2) GEODIST
该命令用于获取两个地理位置间的距离。返回值为双精度浮点数,其语法格式如下:
GEODIST key member1 member2 [unit]
参数 unit 是表示距离单位,取值如下所示:
- m 表示单位为米;
- km 表示单位为千米;
- mi 表示单位为英里;
- ft 表示单位为英尺。
注意:如果没有指出距离单位,那么默认取值为m
。示例如下:
127.0.0.1:6379> GEODIST city beijing shanghai "1091868.8970" 127.0.0.1:6379> GEODIST city beijing shanghai km "1091.8689" 127.0.0.1:6379> GEODIST city beijing shanghai mi "678.4576"
注意:计算举例时存在 0.5% 左右的误差,这是由于 Redis GEO 把地球假设成了完美的球体。
3) GEORADIUS
以给定的经纬度为中心,计算出 key 包含的地理位置元素与中心的距离不超过给定最大距离的所有位置元素,并将其返回。
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]
参数说明:
- WITHDIST :在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。
- WITHCOORD :返回位置元素的经度和维度。
- WITHHASH :采用 GEOHASH 对位置元素进行编码,以 52 位有符号整数的形式返回有序集合的分值,该选项主要用于底层调试,实际作用不大。
- COUNT:指定返回位置元素的数量,在数据量非常大时,可以使用此参数限制元素的返回数量,从而加快计算速度。
注意:该命令默认返回的是未排序的位置元素。通过 ASC 与 DESC 可让返回的位置元素以升序或者降序方式排列。
命令应用示例如下:
#添加几个地理位置元素 127.0.0.1:6379> GEOADD city 106.45 29.56 chongqing 120.33 36.06 qingdao 103.73 36.03 lanzhou (integer) 3 127.0.0.1:6379> GEOADD city 106.71 26.56 guiyang (integer) 1 #以首都的坐标为中心,计算各个城市距离首都的距离,最大范围设置为1500km #同时返回距离,与位置元素的经纬度 127.0.0.1:6379> GEORADIUS city 116.41 39.91 1500 km WITHCOORD WITHDIST 1) 1) "chongqing" 2) "1465.5618" 3) 1) "106.4500012993812561" 2) "29.56000053864853072" 2) 1) "lanzhou" 2) "1191.2793" 3) 1) "103.72999995946884155" 2) "36.03000049919800318" 3) 1) "shanghai" 2) "1121.4882" 3) 1) "120.52000075578689575" 2) "30.39999952668997452" 4) 1) "qingdao" 2) "548.9304" 3) 1) "120.3299984335899353" 2) "36.05999892411877994" 5) 1) "beijing" 2) "42.8734" 3) 1) "116.19999736547470093" 2) "39.56000019952067248"
4) GEORADIUSBYMEMBER
根据给定的地理位置坐标(即经纬度)获取指定范围内的位置元素集合。其语法格式如下:
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DES]
- m :米,默认单位;
- km :千米(可选);
- mi :英里(可选);
- ft :英尺(可选);
- ASC:根据距离将查找结果从近到远排序;
- DESC:根据距离将查找结果从远到近排序。
该命令与 GEORADIUS 命令相似,不过它选择的中心的是具体的位置元素,而非经纬度坐标。示例如下:
#以贵阳为中心,最大距离不超过900km 127.0.0.1:6379> GEORADIUSBYMEMBER city guiyang 900 km WITHCOORD WITHDIST 1) 1) "guiyang" 2) "0.0000" 3) 1) "106.70999854803085327" 2) "26.56000089385899798" #只有重庆符合条件 2) 1) "chongqing" 2) "334.6529" 3) 1) "106.4500012993812561" 2) "29.56000053864853072"
5) GEOHASH
返回一个或多个位置元素的哈希字符串,该字符串具有唯一 ID 标识,它与给定的位置元素一一对应。示例如下:
127.0.0.1:6379> GEOHASH city lanzhou beijing shanghai 1) "wq3ubrjcun0" 2) "wx49h1wm8n0" 3) "wtmsyqpuzd0"
6) ZREM
用于删除指定的地理位置元素,示例如下:
127.0.0.1:6379> zrem city beijing shanghai (integer) 2
Redis Transaction事务
Redis 事务的目的是方便用户一次执行多个命令。执行 Redis 事务可分为三个阶段:
- 开始事务
- 命令入队
- 执行事务
Redis事务特性
Redis 事务具有两个重要特性:
1) 单独的隔离操作
事务中的所有命令都会被序列化,它们将按照顺序执行,并且在执行过的程中,不会被其他客户端发送来的命令打断。
2) 不保证原子性
在 Redis 的事务中,如果存在命令执行失败的情况,那么其他命令依然会被执行,不支持事务回滚机制。
注意:Redis 不支持事务回滚,原因在于 Redis 是一款基于内存的存储系统,其内部结构比较简单,若支持回滚机制,则让其变得冗余,并且损耗性能,这与 Redis 简单、快速的理念不相符合。
Redis事务命令
命令 | 说明 |
---|---|
MULTI | 开启一个事务 |
EXEC | 执行事务中的所有命令 |
WATCH key [key ...] | 在开启事务之前用来监视一个或多个key 。如果事务执行时这些 key 被改动过,那么事务将被打断。 |
DISCARD | 取消事务。 |
UNWATCH | 取消 WATCH 命令对 key 的监控。 |
Redis事务应用
您可以把事务可以理解为一个批量执行 Redis 命令的脚本,但这个操作并非原子性操作,也就是说,如果中间某条命令执行失败,并不会导致前面已执行命令的回滚,同时不会中断后续命令的执行(不包含监听 key 的情况)。示例如下:
开启事务 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> INCR 1 QUEUED #命令入队成功 127.0.0.1:6379> SET num 10 QUEUED #批量执行命令 127.0.0.1:6379> EXEC 1) (integer) 1 2) OK
若您在事务开启之前监听了某个 key,那么您不应该在事务中尝试修改它,否则会导致事务中断。
开启事务之前设置key/value,并监听 127.0.0.1:6379> set www.biancheng.net hello OK 127.0.0.1:6379> WATCH www.biancheng.net OK 127.0.0.1:6379> get www.biancheng.net "hello" #开启事务 127.0.0.1:6379> MULTI OK #更改key的value值 127.0.0.1:6379> set www.biancheng.net HELLO QUEUED 127.0.0.1:6379> GET www.biancheng.net QUEUED #命令执行失败 127.0.0.1:6379> EXEC (error) EXECABORT Transaction discarded because of previous errors. #取消监听key 127.0.0.1:6379> UNWATCH OK
使用Lua脚本
虽然 Redis 官网提供了丰富指令集(200多个),但是在某些特定的领域需要对指令进行扩充,因此 Redis 允许我们使用 Lua 语言以自定义的方式编写脚本命令,这满足了一部分用户的需求。Redis 服务器会以单线程、原子性的方式执行 Lua 脚本,保证 Lua 脚本在处理过程中不会被其他请求中断。
使用 Lua 脚本有如下好处:
- 减少网络开销:可以将多个请求通过脚本的形式一次发送,从而减少网络时延,比如本来 10 次网络请求,我们就可以通过 Lua 脚本一次性完成。
- 原子操作:Redis 会将整个脚本作为一个整体执行,中间不会被其他请求干扰。因此在脚本运行过程中无需使用事务。
- 脚本复用:客户端发送的脚本会一直存储在 Redis 中,这样其他客户端只需对这个脚本稍作修改就可以达到复用的目的,极大地提升了编写脚本的效率。
常用脚本命令
命令 | 说明 |
---|---|
EVAL script numkeys key [key ...] arg [arg ...] | 使用 Lua 解释器执行脚本。 |
EVALSHA sha1 numkeys key [key ...] arg [arg ...] | Lua 解释器根据 sha1 校验码执行脚本。 |
SCRIPT EXISTS script [script ...] | 查看指定的脚本是否保存在于缓存当中。 |
SCRIPT FLUSH | 从脚本缓存中移除所有脚本。 |
SCRIPT KILL | 杀死当前正在运行的 Lua 脚本。 |
SCRIPT LOAD script | 将脚本 script 添加到脚本缓存中,但不马上执行这个脚本。 |
基本命令应用
EVAL 命令使用示例:
redis 127.0.0.1:6379> EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second 1) "key1" 2) "key2" 3) "first" 4) "second"
Redis Pipeline管道技术
为什么需要Pipeline
Redis 是使用了客户端-服务器(C/S)模型和请求/响应
协议的 TCP 服务器。这意味着发送一个请求会遵循以下步骤:
- 客户端通常以阻塞的方式向服务器发送命令,以获取服务器的响应。
- 服务器接收并处理命令,然后将响应发送回客户端。
所谓阻塞式,指的是只有当客户端接收完当前命令的响应信息,服务端才可以继续处理下一条指令,即一条一条的逐次执行。
不管命令是以数据包的形式从客户端传输到服务端,还是客户端获得服务端的响应信息,这个过程都需要花费一定的时间,我把这个时间称为“往返延时”。因此当客户端执行一串请求的时候很容易看出延时对其性能造成的影响。
如果我们可以减少网络请求的次数,那么就可以大幅度提高 Redis 应用性能。Redis 的 Pipeline 就是这样一种技术,它能够把多次网络请求打包成一次请求发送给服务端,从而减少多次请求的“往返时间”。
注意,记住“速度不够,管道来凑”这句话,能够帮助你牢记管道技术的作用。
执行Pipeline语句
Pipeline 技术有其固定的语法格式,以下是在 Linux 终端执行的语句,具体命令如下:
(echo -en "PING\r\n SET name www.biancheng\r\n GET name\r\n INCR num\r\n INCR num\r\n INCR num\r\n"; sleep 2)|nc localhost 6379
上述语句,首先使用 PING 命令检查 Redis 是否正常工作,然后又分别使用了 SET/GET/INCR 命令,以及 sleep 阻塞 2 秒,最后将这些命令一次性的提交给 Redis 服务器,Redis 服务器在阻塞了 2 秒之后,一次性输出了所有命令的响应信息。
注意: 每个命令字符串必须以 \r\n 结尾。至于语句最后的 nc localhost 6379 是固定格式无需更改。
客户端一次性接收到所有命令的执行结果,如下所示:
$(echo -en "PING\r\n SET name www.biancheng\r\n GET name\r\n INCR num\r\n INCR num\r\n INCR num\r\n"; sleep 2)|nc localhost 6379 +PONG +OK www.bianchneg.net :1 :2 :3
Redis数据备份和还原
Redis SAVE 命令用于创建当前数据库的备份。
语法
redis Save 命令基本语法如下:
redis 127.0.0.1:6379> SAVE
实例
redis 127.0.0.1:6379> SAVE
OK
该命令将在 redis 安装目录中创建dump.rdb文件。
恢复数据
如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可。获取 redis 目录可以使用 CONFIG 命令,如下所示:
redis 127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/usr/local/redis/bin"
以上命令 CONFIG GET dir 输出的 redis 安装目录为 /usr/local/redis/bin。
Bgsave
创建 redis 备份文件也可以使用命令 BGSAVE,该命令在后台执行。
实例
127.0.0.1:6379> BGSAVE
Background saving started
127.0.0.1:6379> BGREWRITEAOF Background append only file rewriting started
Redis分布式锁命令
分布式锁的本质其实就是要在 Redis 里面占一个“坑”,当别的进程也要来占时,发现已经有人蹲了,就只好放弃或者稍做等待。这个“坑”同一时刻只允许被一个客户端占据,也就是本着“先来先占”的原则。
1) 常用命令
Redis 分布式锁常用命令如下所示:
- SETNX key val:仅当key不存在时,设置一个 key 为 value 的字符串,返回1;若 key 存在,设置失败,返回 0;
- Expire key timeout:为 key 设置一个超时时间,以 second 秒为单位,超过这个时间锁会自动释放,避免死锁;
- DEL key:删除 key。
上述 SETNX 命令相当于占“坑”操作,EXPIRE 是为避免出现意外用来设置锁的过期时间,也就是说到了指定的过期时间,该客户端必须让出锁,让其他客户端去持有。
但还有一种情况,如果在 SETNX 和 EXPIRE 之间服务器进程突然挂掉,也就是还未设置过期时间,这样就会导致 EXPIRE 执行不了,因此还是会造成“死锁”的问题。为了避免这个问题,Redis 作者在 2.6.12 版本后,对 SET 命令参数做了扩展,使它可以同时执行 SETNX 和 EXPIRE 命令,从而解决了死锁的问题。
直接使用 SET 命令实现,语法格式如下:
SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
- EX second:设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
- PX millisecond:设置键的过期时间为毫秒。SET key value PX millisecond 效果等同于 PSETEX key millisecondvalue 。
- NX:只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
- XX:只在键已经存在时,才对键进行设置操作。
2) 命令应用
下面进行简单的命令演示:
127.0.0.1:6379> SETNX WEBNAME www.biancheng.net (integer) 1 127.0.0.1:6379> EXPIRE WEBNAME 60 (integer) 1 127.0.0.1:6379> GET WEBNAME "www.biancheng.net" 127.0.0.1:6379> TTL WEBNAME (integer) 33 127.0.0.1:6379> SET name www.biancheng.net EX 60 NX OK
Redis配置项汇总(超级详细)
基本配置
port 6379 # 监听端口号,默认为6379,如果你设为 0 ,redis 将不在 socket 上监听任何客户端连接。 daemonize no #指定redis是否以守护线程的方式启动 databases 16 #创建database的数量,默认为0库 save 900 1 #刷新快照到硬盘中。必须满足下列三个要求之一才会触发,即900秒内至少有1个key发生变化。 save 300 10 #在300秒内至少10个key发生变化。 save 60 10000 #在60秒之内至少有10000个可以发生变化。 stop-writes-on-bgsave-error yes #后台存储错误并停止写入命令。 rdbcompression yes #使用LZF方式压缩rdb文件。如果你想节省一些CPU可设置成'no' rdbchecksum yes #在存储、加载rdb文件时进行校验。 dbfilename dump.rdb #设置rdb文件名。 dir ./ #设置工作目录,rdb文件会自动存放在该目录。
主从服务配置
slaveof <masterip> <masterport> #将本机设为某台机器的从服务器 masterauth <master-password> #连接主服务器的密码 slave-serve-stale-data yes # 当主机和从机断开时或这正处于在复制过程中,是否让从服务器是应答请求 slave-read-only yes #设置从服务器为只读模式 repl-diskless-sync no #是否同时向多个从服务器节点同时发数据 repl-diskless-sync-delay 5 #发送数据的延迟时间 repl-ping-slave-period 10 #主节点默认每隔 10 秒对从节点发送 ping 命令 repl-timeout 60 #主从服务器超时时间(超时认为断线了),要比period设置的时间大 #如果master不能再正常工作,那么会在多个slave中,选择优先值最小的一个slave提升为master, #优先值为0表示不能提升为master,一般在哨兵sentinel环境中使用。 slave-priority 100 #在slave和master同步后,后续的同步是否设置成TCP_NODELAY,设置成no,则redis master会立即发送同步数据,没有延迟 repl-disable-tcp-nodelay no min-slaves-to-write 3 #主节点仅允许当能够通信的从节点数量大于等于此处的值时,才允许接受写操作; min-slaves-max-lag 10 #从节点延迟时长超出此处指定的时间时,主节点会拒绝写入操作;
安全配置
requirepass foobared # 用来配置密码 rename-command CONFIG b84 #在公共环境下重命名部分敏感命令 如config、flushall等
限制配置
maxclients 10000 #最大连接数 maxmemory <bytes> #最大使用内存 maxmemory-policy volatile-lru #内存到极限后的处理策略 #内存处理策略,用于在超出内存限制时,删除一些key volatile-lru # LRU算法删除过期key allkeys-lru # LRU算法删除key(不区分过不过期) volatile-random # 随机删除过期key allkeys-random # 随机删除key(不区分过不过期) volatile-ttl # 删除快过期的key noeviction # 禁止删除key,这如果内存不足,会直接返回错误。默认配置 #用于提高LRU/TTL算法的精准度,在自动清理内存时,指定的数字越大,CPU消耗就越多,默认为5。 maxmemory-samples 5
AOF日志模式
appendonly no #是否启用日志模式 appendfsync no # 有系统决定何时写,统一写,速度快 appendfsync always # 系统不缓冲,一直写,但是慢,这种方式几乎不丢失数据 appendfsync everysec #每秒写1次 no-appendfsync-on-rewrite no #相当于将appendfsync设置为no,不存在磁盘操作,只是将数据写入了缓冲区,写入速度非常快 auto-AOF-rewrite-percentage 100 #触发aof重写操作,要求本次文件大小比上次重写时要增加1(100%)倍 auto-AOF-rewrite-min-size 64mb #触发aof重写操作,至少要达到的aof文件大小
慢查询配置
Redis slowlog 是一个记录 Redis 执行查询命令时所耗费时间的日志系统,它仅记录执行一个查询命令所耗费的时间,不记录其他内容。
slowlog-log-slower-than 10000 #记录响应时间大于10000微秒的慢查询 slowlog-max-len 128 # 最多记录128条
服务端命令
time #返回时间戳+微秒 dbsize #返回key的数量 bgrewriteaof #重写aof bgsave #后台开启子进程来执行数据持久化 save #以阻塞的方式对数据进行持久化 lastsave #返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示。 slaveof host port #设置为host:port的从服务器(数据清空,复制新的主服务器内容) slaveof no one #变成主服务器(原数据不丢失,一般用于主服失败后) flushdb 清空当前数据库的所有数据 flushall 清空所有数据库的所有数据 shutdown [save/nosave] 关闭服务器,保存数据,修改AOF slowlog get 获取慢查询日志 slowlog len 获取慢查询日志条数 slowlog reset 清空慢查询
客户端命令
#以易于理解和阅读的方式返回Redis服务器的各种信息、统计数值 info [server|clients|memory|stats|] config get [配置项] #获取配置文件选项 config set [配置项] [参数值] #重新设置配置文件选项和对应参数 config rewrite #对启动Redis服务器时所指定的配置文件进行改写 config resetstat #重置info命令中的某些统计信息 debug object key #调试选项,看一个key的情况 debug segfault #该命令能够让服务器崩溃 object key (refcount|encoding|idletime) monitor #调试用,打开控制台,观察命令 client list #列出所有连接 client kill #杀死某个连接 CLIENT KILL 127.0.0.1:6379 client getname #获取连接的名称 默认nil client setname #设置连接名称,便于调试
连接命令
auth 密码 #验证登录密码(如果设置了密码) ping #测试服务器是否可用 echo "hello www.biancheng.net" #测试服务器是否正常交互 select 0/1/2/3/4... #选择数据库0-15 quit #退出连接