1.redis入门

1.1 redis简介

Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。

Redis 与其他 key - value 缓存产品有以下三个特点:

  • Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。

1.1.1 Redis 优势

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

1.1.2 Redis与其他key-value存储有什么不同?

  • Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
  • Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,应为数据量不能大于硬件内存。在内存数据库方面的另一个优点是, 相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。 同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。

1.1.3 应用

  • Tips 1:redis用于控制数据库表主键id,为数据库表主键提供生成策略,保障数据库表的主键唯一性
  • Tips 2:redis 控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作
  • Tips 3:redis应用于各种结构型和非结构型高热度数据访问加速
  • Tips 4:redis 应用于购物车数据存储设计
  • Tips 5:redis 应用于抢购,限购类、限量发放优惠卷、激活码等业务的数据存储设计
  • Tips 6:redis 应用于具有操作先后顺序的数据控制
  • Tips 7:redis 应用于最新消息展示
  • Tips 8:redis 应用于随机推荐类信息检索,例如热点歌单推荐,热点新闻推荐,热卖旅游线路,应用APP推荐,大V推荐等
  • Tips 9:redis 应用于同类信息的关联搜索,二度关联搜索,深度关联搜索
  • Tips 10:redis 应用于同类型不重复数据的合并、取交集操作
  • Tips 11:redis 应用于同类型数据的快速去重
  • Tips 12:redis 应用于基于黑名单与白名单设定的服务控制
  • Tips 13:redis 应用于计数器组合排序功能对应的排名
  • Tips 14:redis 应用于定时任务执行顺序管理或任务过期管理
  • Tips 15:redis 应用于及时任务/消息队列执行管理
  • Tips 16:redis 应用于按次结算的服务控制
  • Tips 17:redis 应用于基于时间顺序的数据操作,而不关注具体时间

1.2 redis的下载与安装

参考链接:Centos 7.2 安装目前最新版Redis5.0.3

1.3 redis配置

Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf。

1.3.1 查看配置

你可以通过 CONFIG 命令查看或设置配置项。

语法

Redis CONFIG 命令格式如下:

redis 127.0.0.1:6379> CONFIG GET CONFIG_SETTING_NAME

实例

redis 127.0.0.1:6379> CONFIG GET loglevel

1) "loglevel"
2) "notice"

使用 ***** 号获取所有配置项:

实例

redis 127.0.0.1:6379> CONFIG GET *

1) "dbfilename"
2) "dump.rdb"
3) "requirepass"
4) ""
5) "masterauth"
6) ""
7) "unixsocket"
8) ""
9) "logfile"
10) ""
11) "pidfile"
12) "/var/run/redis.pid"
13) "maxmemory"
14) "0"
15) "maxmemory-samples"
16) "3"
17) "timeout"
18) "0"
19) "tcp-keepalive"
20) "0"
21) "auto-aof-rewrite-percentage"
22) "100"
23) "auto-aof-rewrite-min-size"
24) "67108864"
25) "hash-max-ziplist-entries"
26) "512"
27) "hash-max-ziplist-value"
28) "64"
29) "list-max-ziplist-entries"
30) "512"
31) "list-max-ziplist-value"
32) "64"
33) "set-max-intset-entries"
34) "512"
35) "zset-max-ziplist-entries"
36) "128"
37) "zset-max-ziplist-value"
38) "64"
39) "hll-sparse-max-bytes"
40) "3000"
41) "lua-time-limit"
42) "5000"
43) "slowlog-log-slower-than"
44) "10000"
45) "latency-monitor-threshold"
46) "0"
47) "slowlog-max-len"
48) "128"
49) "port"
50) "6379"
51) "tcp-backlog"
52) "511"
53) "databases"
54) "16"
55) "repl-ping-slave-period"
56) "10"
57) "repl-timeout"
58) "60"
59) "repl-backlog-size"
60) "1048576"
61) "repl-backlog-ttl"
62) "3600"
63) "maxclients"
64) "4064"
65) "watchdog-period"
66) "0"
67) "slave-priority"
68) "100"
69) "min-slaves-to-write"
70) "0"
71) "min-slaves-max-lag"
72) "10"
73) "hz"
74) "10"
75) "no-appendfsync-on-rewrite"
76) "no"
77) "slave-serve-stale-data"
78) "yes"
79) "slave-read-only"
80) "yes"
81) "stop-writes-on-bgsave-error"
82) "yes"
83) "daemonize"
84) "no"
85) "rdbcompression"
86) "yes"
87) "rdbchecksum"
88) "yes"
89) "activerehashing"
90) "yes"
91) "repl-disable-tcp-nodelay"
92) "no"
93) "aof-rewrite-incremental-fsync"
94) "yes"
95) "appendonly"
96) "no"
97) "dir"
98) "/home/deepak/Downloads/redis-2.8.13/src"
99) "maxmemory-policy"
100) "volatile-lru"
101) "appendfsync"
102) "everysec"
103) "save"
104) "3600 1 300 100 60 10000"
105) "loglevel"
106) "notice"
107) "client-output-buffer-limit"
108) "normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60"
109) "unixsocketperm"
110) "0"
111) "slaveof"
112) ""
113) "notify-keyspace-events"
114) ""
115) "bind"
116) ""

1.3.2 编辑配置

你可以通过修改 redis.conf 文件或使用 CONFIG set 命令来修改配置。

语法

CONFIG SET 命令基本语法:

redis 127.0.0.1:6379> CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE

实例

redis 127.0.0.1:6379> CONFIG SET loglevel "notice"
OK
redis 127.0.0.1:6379> CONFIG GET loglevel

1) "loglevel"
2) "notice"

1.3.3 参数说明

redis.conf 配置项说明如下:

  1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程

    daemonize no
  2. 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定

    pidfile /var/run/redis.pid
  3. 指定Redis监听端口,默认端口为6379,作者在自己的一篇博文中解释了为什么选用6379作为默认端口,因为6379在手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字

    port 6379
  4. 绑定的主机地址

    bind 127.0.0.1
  5. 当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能

    timeout 300
  6. 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose

    loglevel verbose
  7. 日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null

    logfile stdout
  8. 设置数据库的数量,默认数据库为0,可以使用SELECT <dbid>命令在连接上指定数据库id

    databases 16
  9. 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合

    save <seconds> <changes>

    Redis默认配置文件中提供了三个条件:

    save 900 1  	#900秒(15分钟)内有1个更改
    save 300 10 #300秒(5分钟)内有10个更改
    save 60 10000 #60秒内有10000个更改
  10. 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大

    rdbcompression yes
  11. 指定本地数据库文件名,默认值为dump.rdb

    dbfilename dump.rdb
  12. 指定本地数据库存放目录

    dir ./
  13. 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步

    slaveof <masterip> <masterport>
  14. 当master服务设置了密码保护时,slav服务连接master的密码

    masterauth <master-password>
  15. 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭

    requirepass foobared
  16. 设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息

    maxclients 128
  17. 指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区

    maxmemory <bytes>
  18. 指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no

    appendonly no
  19. 指定更新日志文件名,默认为appendonly.aof

    appendfilename appendonly.aof
  20. 指定更新日志条件,共有3个可选值: no:表示等操作系统进行数据缓存同步到磁盘(快) always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全) everysec:表示每秒同步一次(折衷,默认值)

    appendfsync everysec
  21. 指定是否启用虚拟内存机制,默认值为no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析Redis的VM机制)

    vm-enabled no
  22. 虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享

    vm-swap-file /tmp/redis.swap
  23. 将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0

    vm-max-memory 0
  24. Redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但一个page上不能被多个对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认值

    vm-page-size 32
  25. 设置swap文件中的page数量,由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,在磁盘上每8个pages将消耗1byte的内存。

    vm-pages 134217728
  26. 设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4

    vm-max-threads 4
  27. 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启

    glueoutputbuf yes
  28. 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法

    hash-max-zipmap-entries 64
    hash-max-zipmap-value 512
  29. 指定是否激活重置哈希,默认为开启(后面在介绍Redis的哈希算法时具体介绍)

    activerehashing yes
  30. 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件

    include /path/to/local.conf

1.4 redis数据类型

1.4.1 String(字符串)

string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。

string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。

string类型是Redis最基本的数据类型,一个键最大能存储512MB。

实例

redis 127.0.0.1:6379> SET name "redis.net.cn"
OK
redis 127.0.0.1:6379> GET name
"redis.net.cn"

在以上实例中我们使用了 Redis 的 SETGET 命令。键为 name,对应的值为redis.net.cn。

注意:一个键最大能存储512MB。

1.4.2 Hash(哈希)

Redis hash 是一个键值对集合。

Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。

实例

redis 127.0.0.1:6379> HMSET user:1 username redis.net.cn password redis.net.cn points 200
OK
redis 127.0.0.1:6379> HGETALL user:1
1) "username"
2) "redis.net.cn"
3) "password"
4) "redis.net.cn"
5) "points"
6) "200"
redis 127.0.0.1:6379>

以上实例中 hash 数据类型存储了包含用户脚本信息的用户对象。 实例中我们使用了 Redis HMSET, HEGTALL 命令,user:1 为键值。

每个 hash 可以存储 2^(32 - 1)键值对(40多亿)。

1.4.3 List(列表)

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)。

实例

redis 127.0.0.1:6379> lpush redis.net.cn redis
(integer) 1
redis 127.0.0.1:6379> lpush redis.net.cn mongodb
(integer) 2
redis 127.0.0.1:6379> lpush redis.net.cn rabitmq
(integer) 3
redis 127.0.0.1:6379> lrange redis.net.cn 0 10
1) "rabitmq"
2) "mongodb"
3) "redis"
redis 127.0.0.1:6379>

列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。

1.4.4 Set(集合)

Redis的Set是string类型的无序集合。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

sadd 命令

添加一个string元素到,key对应的set集合中,成功返回1,如果元素以及在集合中返回0,key对应的set不存在返回错误。

sadd key member

实例

redis 127.0.0.1:6379> sadd redis.net.cn redis
(integer) 1
redis 127.0.0.1:6379> sadd redis.net.cn mongodb
(integer) 1
redis 127.0.0.1:6379> sadd redis.net.cn rabitmq
(integer) 1
redis 127.0.0.1:6379> sadd redis.net.cn rabitmq
(integer) 0
redis 127.0.0.1:6379> smembers redis.net.cn

1) "rabitmq"
2) "mongodb"
3) "redis"

1.4.5 zset(sorted set:有序集合)

Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

zset的成员是唯一的,但分数(score)却可以重复。

zadd 命令

添加元素到集合,元素在集合中存在则更新对应score

zadd key score member 

实例

redis 127.0.0.1:6379> zadd redis.net.cn 0 redis
(integer) 1
redis 127.0.0.1:6379> zadd redis.net.cn 0 mongodb
(integer) 1
redis 127.0.0.1:6379> zadd redis.net.cn 0 rabitmq
(integer) 1
redis 127.0.0.1:6379> zadd redis.net.cn 0 rabitmq
(integer) 0
redis 127.0.0.1:6379> ZRANGEBYSCORE redis.net.cn 0 1000

1) "redis"
2) "mongodb"
3) "rabitmq"

2.redis命令

2.1 如何执行命令

2.1.1 在本地连接执行命令

Redis 命令用于在 redis 服务上执行操作。

要在 redis 服务上执行命令需要一个 redis 客户端。Redis 客户端在我们之前下载的的 redis 的安装包中。

语法

Redis 客户端的基本语法为:

$ redis-cli

实例

以下实例讲解了如何启动 redis 客户端:

启动 redis 客户端,打开终端并输入命令 redis-cli。该命令会连接本地的 redis 服务。

$redis-cliredis 127.0.0.1:6379>redis 127.0.0.1:6379> PING PONG

在以上实例中我们连接到本地的 redis 服务并执行 PING 命令,该命令用于检测 redis 服务是否启动。


2.2.2 在远程服务上执行命令

如果需要在远程 redis 服务上执行命令,同样我们使用的也是 redis-cli 命令。

语法

$ redis-cli -h host -p port -a password

实例

以下实例演示了如何连接到主机为 127.0.0.1,端口为 6379 ,密码为 mypass 的 redis 服务上。

$redis-cli -h 127.0.0.1 -p 6379 -a "mypass"
redis 127.0.0.1:6379>
redis 127.0.0.1:6379> PING

PONG

2.2 key(键)

Redis 键命令用于管理 redis 的键。

语法

Redis 键命令的基本语法如下:

redis 127.0.0.1:6379> COMMAND KEY_NAME

实例

redis 127.0.0.1:6379> SET mykey redis
OK
redis 127.0.0.1:6379> DEL mykey
(integer) 1

在以上实例中 DEL 是一个命令, mykey 是一个键。 如果键被删除成功,命令执行后输出 (integer) 1,否则将输出 (integer) 0

下表给出了与 Redis 键相关常用的基本命令:

命令 语法(可用版本) 返回值 描述
DEL DEL KEY_NAME(>= 1.0.0) 被删除 key 的数量。 删除存在的key,不存在就忽略。
DUMP DUMP KEY_NAME(>= 2.6.0) key不存在,返回 nil 。否则,返回序列化之后的值。 序列化给定 key 并返回值
EXISTS EXISTS KEY_NAME(>= 1.0.0) 存在返回 1 ,否则返回 0 检查给定key是否存在。
EXPIRE EXPIRE KEY_NAME TIME_IN_SECONDS         (>= 1.0.0) 设置成功返回 1 。 不存在或者不能设置过期时间时(低于 2.1.3 版本)返回 0 设置key的过期时间,key 过期后将不再可用。
EXPIREAT EXPIREAT KEY_NAME TIME_IN_UNIX_TIMESTAMP(>= 1.0.0) 设置成功返回1。 不存在或者不能设置过期时间时(低于 2.1.3 版本)返回0 以 UNIX 时间戳(unix timestamp)格式设置key的过期时间。过期后将不再可用。
KEYS KEYS PATTERN(>= 1.0.0) 符合给定模式的 key 列表 (Array)。 用于查找所有符合给定模式 patternkey
MIGRATE MIGRATE HOST PORT KEY_NAME DESTINATION-DB TIMEOUT [COPY] [REPLACE](>= 2.6.0) 迁移成功时返回 OK,否则返回相应的错误。 key原子性地从当前实例传送到目标实例的指定数据库上,一旦传送成功, key 保证会出现在目标实例上,而当前实例上的 key会被删除。
MOVE MOVE KEY_NAME DESTINATION_DATABASE (>= 1.0.0) 移动成功返回 1 ,失败则返回0 将当前数据库的 key 移动到给定的数据库db当中。
PERSIST PERSIST KEY_NAME(>= 2.2.0) 当过期时间移除成功时,返回 1 。 如果key不存在或 key 没有设置过期时间,返回0 移除给定 key 的过期时间,使得 key 永不过期。
PEXPIRE PEXPIREAT KEY_NAME TIME_IN_MILLISECONDS_IN_UNIX_TIMESTAMP (>= 2.6.0) 设置成功返回1。 当key不存在或者不能为 key 设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间)返回 0 用于设置 key 的过期时间,以毫秒记。key 过期后将不再可用。
PEXPIREAT PEXPIREAT KEY_NAME TIME_IN_MILLISECONDS_IN_UNIX_TIMESTAMP (>= 2.6.0) 设置成功返回 1 。 当 key 不存在或者不能为 key 设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间)返回 0 用于设置 key 的过期时间,以毫秒记。key 过期后将不再可用。
PTTL PTTL KEY_NAME(>= 2.6.0) key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以毫秒为单位,返回的剩余生存时间。 以毫秒为单位返回 key 的剩余过期时间。
注意:在 Redis 2.8 以前,当 key 不存在,或者 key 没有设置剩余生存时间时,命令都返回-1
RANDOMKEY RANDOMKEY(>= 1.0.0) 当数据库不为空时,返回一个 key 。 当数据库为空时,返回nil 从当前数据库中随机返回一个 key
RENAME RENAME OLD_KEY_NAME NEW_KEY_NAME (>= 1.0.0) 改名成功时返回OK ,失败时候返回一个错误。当 OLD_KEY_NAME NEW_KEY_NAME 相同,或者 OLD_KEY_NAME 不存在时,返回一个错误。 当 NEW_KEY_NAME 已经存在时, RENAME 命令将覆盖旧值。 用于修改key的名称
RENAMENX RENAMENX OLD_KEY_NAME NEW_KEY_NAME(>= 1.0.0) 修改成功时,返回 1 。 如果 NEW_KEY_NAME 已经存在,返回0 用于在新的 key 不存在时修改key的名称 。
SORT SORT KEY [BY PATTERN] [LIMIT OFFSET COUNT] [GET PATTERN [GET PATTERN …]] [ASC|DESC] [ALPHA] [STORE DESTINATION] 较为复杂见文档 较为复杂见文档
TTL TTL KEY_NAME (>= 1.0.0) key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以秒为单位,返回剩余生存时间。 以秒为单位返回 key 的剩余过期时间。
注意:在 Redis 2.8 以前,当 key 不存在,或者key没有设置剩余生存时间时,命令都返回 -1
TYPE TYPE KEY_NAME (>= 1.0.0) 返回数据类型有:none (key不存在) string (字符串) list (列表) set (集合) zset (有序集) hash (哈希表) 返回key所储存的值的类型

2.3 String(字符串)

Redis 字符串数据类型的相关命令用于管理 redis 字符串值,基本语法如下:

语法

redis 127.0.0.1:6379> COMMAND KEY_NAME

实例

redis 127.0.0.1:6379> SET mykey redis 
OK
redis 127.0.0.1:6379> GET mykey
"redis"

在以上实例中我们使用了 SETGET 命令,键为 mykey。

下表给出了与 Redis字符串相关常用的基本命令:

命令 语法(可用版本) 返回值 描述
APPEND APPEND KEY_NAME NEW_VALUE(>= 2.0.0) 追加指定值之后, key 中字符串的长度。 如果 key 已经存在并且是一个字符串, APPEND 命令将value追加到 key 原来的值的末尾。 如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
BITCOUNT BITCOUNT key [start] [end](>= 2.6.0) 被设置为 1 的位的数量。 计算给定字符串中,被设置为 1 的比特位的数量。一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 startend 参数,可以让计数只在特定的位上进行。不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0
BITOP BITOP operation destkey key [key …](>= 2.6.0) 保存到 destkey 的字符串的长度,和输入 key 中最长的字符串长度相等。 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。
DECR DECR KEY_NAME(>=1.0.0) 执行命令之后 key 的值。 key 中储存的数字值减一。 如果 key 不存在,key 的值会先被初始化为 0 ,然后再执行 DECR 操作。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。本操作的值限制在 64 位(bit)有符号数字表示之内。
DECRBY DECRBY KEY_NAME DECREMENT_AMOUNT (>=1.0.0) 减去指定减量值之后,key的值。 key所储存的值减去指定的减量值。如果 key不存在,key的值会先被初始化为 0 ,然后再执行 DECRBY 操作。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。本操作的值限制在 64 位(bit)有符号数字表示之内。
GET GET KEY_NAME(>=1.0.0) 返回 key 的值,如果 key 不存在时,返回 nil。 如果 key 不是字符串类型,那么返回一个错误。 获取指定 key 的值。 如果 key 不存在,返回 nil 。 如果key 储存的值不是字符串类型,返回一个错误。
GETBIT GETBIT KEY_NAME OFFSET(>=2.4.0) 字符串值指定偏移量上的位(bit)。当偏移量 OFFSET 比字符串值的长度大,或者 key 不存在时,返回 0 key 所储存的字符串值,获取指定偏移量上的位(bit)。
GETRANGE GETRANGE KEY_NAME START END(>=2.4.0) 截取得到的子字符串。 获取存储在指定 key 中字符串的子字符串。字符串的截取范围由 start end两个偏移量决定(包括 start end 在内)。
GETSET GETSET KEY_NAME VALUE(>=1.0.0) 返回给定 key 的旧值。 当 key 没有旧值时,即key不存在时,返回 nil 。当 key 存在但不是字符串类型时,返回一个错误。 设置指定 key 的值,并返回 key 旧的值。
INCR INCR KEY_NAME(>=1.0.0) 执行 INCR 命令之后 key 的值。 key 中储存的数字值增一。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。本操作的值限制在 64 位(bit)有符号数字表示之内。
INCRBY INCRBY KEY_NAME INCR_AMOUNT(>=1.0.0) 加上指定的增量值之后,key的值。 key 中储存的数字加上指定的增量值。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。本操作的值限制在 64 位(bit)有符号数字表示之内。
INCRBYFLOAT INCRBYFLOAT KEY_NAME INCR_AMOUNT(>=2.6.0) 执行命令之后 key 的值。 key 中所储存的值加上指定的浮点数增量值。如果 key 不存在,那么 INCRBYFLOAT 会先将 key 的值设为 0 ,再执行加法操作。
MGET MGET KEY1 KEY2 .. KEYN(>=1.0.0) 一个包含所有给定 key 的值的列表。 如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil
MSET MSET key1 value1 key2 value2 .. keyN valueN(>=1.0.1) 总是返回 OK 同时设置一个或多个 key-value 对。
MSETNX MSETNX key1 value1 key2 value2 .. keyN valueN(>=1.0.1) 当所有key都成功设置,返回 1 。 如果所有给定 key 都设置失败(至少有一个 key 已经存在),那么返回 0 所有给定 key 都不存在时,同时设置一个或多个 key-value 对。
PSETEX PSETEX key1 EXPIRY_IN_MILLISECONDS value1 (>=2.6.0) 总是返回 OK 以毫秒为单位设置 key 的生存时间。
SET SET KEY_NAME VALUE(>=1.0.0) 在 2.6.12 以前版本, SET 命令总是返回 OK 。从 Redis 2.6.12 版本开始, SET 在设置操作成功完成时,才返回 OK 用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。
SETBIT Setbit KEY_NAME OFFSET(>=2.2.0) 指定偏移量原来储存的位。 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
SETEX SETEX KEY_NAME TIMEOUT VALUE(>=2.0.0) 成功返回 OK 为指定的 key 设置值及其过期时间。如果 key 已经存在, SETEX 命令将会替换旧的值。
SETNX SETNX KEY_NAME VALUE(>=1.0.0) 成功返回 1 。 失败返回 0 Setnx(SET if Not eXists) 命令在指定的key不存在时,为 key 设置指定的值。
SETRANGE SETRANGE KEY_NAME OFFSET VALUE(>=2.2.0) 被修改后的字符串长度。 用指定的字符串覆盖给定 key 所储存的字符串值,覆盖的位置从偏移量 offset 开始。
STRLEN STRLEN KEY_NAME(>=2.2.0) 字符串值的长度。 当key 不存在时,返回 0 用于获取指定 key 所储存的字符串值的长度。当 key 储存的不是字符串值时,返回一个错误。

2.4 Hash(哈希)

Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。

Redis 中每个 hash 可以存储 2^(32 - 1 )键值对(40多亿)。

实例

redis 127.0.0.1:6379> HMSET mykey name "redis tutorial" description "redis basic commands for caching" likes 20 visitors 23000
OK
redis 127.0.0.1:6379> HGETALL mykey

1) "name"
2) "redis tutorial"
3) "description"
4) "redis basic commands for caching"
5) "likes"
6) "20"
7) "visitors"
8) "23000"

在以上实例中,我们设置了 redis 的一些描述信息(name, description, likes, visitors) 到哈希表的 mykey 中。

下表给出了与 Redis哈希相关常用的基本命令:

命令 语法(可用版本) 返回值 描述
HDEL HDEL KEY_NAME FIELD1.. FIELDN (>= 2.0.0) 被成功删除字段的数量,不包括被忽略的字段。 用于删除哈希表key中的一个或多个指定字段,不存在的字段将被忽略。
HEXISTS HEXISTS KEY_NAME FIELD_NAME   (>= 2.0.0) 如果哈希表含有给定字段,返回 1 。 如果哈希表不含有给定字段,或 key 不存在,返回 0 查看哈希表的指定字段是否存在。
HGET HGET KEY_NAME FIELD_NAME    (>= 2.0.0) 返回给定字段的值。如果给定的字段或 key 不存在时,返回 nil 返回哈希表中指定字段的值。
HGETALL HGETALL KEY_NAME        (>= 2.0.0) 以列表形式返回哈希表的字段及字段值。 若 key 不存在,返回空列表。 返回哈希表中,所有的字段和值。在返回值里,紧跟每个字段名(field name)之后是字段的值(value),所以返回值的长度是哈希表大小的两倍。
HINCRBY HINCRBY KEY_NAME FIELD_NAME INCR_BY_NUMBER (>= 2.0.0) 执行 HINCRBY 命令之后,哈希表中字段的值。 用于为哈希表中的字段值加上指定增量值。增量也可以为负数,相当于对指定字段进行减法操作。如果哈希表的 key 不存在,一个新的哈希表被创建并执行 HINCRBY 命令。如果指定的字段不存在,那么在执行命令前,字段的值被初始化为 0 。对一个储存字符串值的字段执行 HINCRBY 命令将造成一个错误。本操作的值被限制在 64 位(bit)有符号数字表示之内。
HINCRBYFLOAT HINCRBYFLOAT KEY_NAME FIELD_NAME INCR_BY_NUMBER (>= 2.6.0) 执行 Hincrbyfloat 命令之后,哈希表中字段的值。 为哈希表中的字段值加上指定浮点数增量值。如果指定的字段不存在,那么在执行命令前,字段的值被初始化为 0
HKEYS HKEYS KEY_NAME FIELD_NAME INCR_BY_NUMBER (>= 2.0.0) 包含哈希表中所有字段的列表。 key 不存在时,返回空列表。 获取哈希表中的所有字段名。
HLEN HLEN KEY_NAME (>= 2.0.0) 哈希表中字段的数量。 key不存在时,返回 0 。 获取哈希表中字段的数量。
HMGET HMGET KEY_NAME FIELD1…FIELDN (>= 2.0.0) 包含多个给定字段关联值的表,表值的排列顺序和指定字段的请求顺序一样。 返回哈希表中,一个或多个给定字段的值。如果指定的字段不存在于哈希表,那么返回一个 nil 值。
HMSET HMSET KEY_NAME FIELD1 VALUE1 …FIELDN VALUEN (>= 2.0.0) 如果命令执行成功,返回 OK 同时将多个 field-value (字段-值)对设置到哈希表中。此命令会覆盖哈希表中已存在的字段。如果哈希表不存在,会创建一个空哈希表,并执行 HMSET 操作。
HSET HSET KEY_NAME FIELD VALUE     (>= 2.0.0) 如果字段是哈希表中的一个新建字段,并且值设置成功,返回 1 。 如果哈希表中域字段已经存在且旧值已被新值覆盖,返回 0 为哈希表中的字段赋值 。如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。如果字段已经存在于哈希表中,旧值将被覆盖。
HSETNX HSETNX KEY_NAME FIELD VALUE                  (>= 2.0.0) 设置成功返回 1 。 如果给定字段已经存在且没有操作被执行,返回 0 为哈希表中不存在的的字段赋值 。如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。如果字段已经存在于哈希表中,操作无效。如果 key 不存在,一个新哈希表被创建并执行 HSETNX 命令。
HVALS HVALS KEY_NAME FIELD VALUE      (>= 2.0.0) 一个包含哈希表中所有值的表。 当 key 不存在时,返回一个空表。 返回哈希表所有字段的值。

2.5 List(列表)

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)

一个列表最多可以包含 2^(32 - 1) 个元素 (4294967295, 每个列表超过40亿个元素)。

实例

redis 127.0.0.1:6379> LPUSH mykey redis
(integer) 1
redis 127.0.0.1:6379> LPUSH mykey mongodb
(integer) 2
redis 127.0.0.1:6379> LPUSH mykey mysql
(integer) 3
redis 127.0.0.1:6379> LRANGE mykey 0 10

1) "mysql"
2) "mongodb"
3) "redis"

在以上实例中我们使用了 LPUSH 将三个值插入了名为 mykey 的列表当中。

下表给出了与 Redis列表相关常用的基本命令:

命令 语法(可用版本) 返回值 描述
BLPOP BLPOP LIST1 LIST2 .. LISTN TIMEOUT(>=2.0.0) 假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。 反之,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的 key ,第二个元素是被弹出元素的值。 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
BRPOP BRPOP LIST1 LIST2 .. LISTN TIMEOUT(>=2.0.0) 假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。 反之,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的 key ,第二个元素是被弹出元素的值。 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
BRPOPLPUSH BRPOPLPUSH LIST1 ANOTHER_LIST TIMEOUT(>=2.0.0) 假如在指定时间内没有任何元素被弹出,则返回一个nil和等待时长。 反之,返回一个含有两个元素的列表,第一个元素是被弹出元素的值,第二个元素是等待时长。 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
LINDEX LINDEX KEY_NAME INDEX_POSITION         (>= 1.0.0) 列表中下标为指定索引值的元素。 如果指定索引值不在列表的区间范围内,返回nil 通过索引获取列表中的元素。你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
LINSERT LINSERT KEY_NAME BEFORE EXISTING_VALUE NEW_VALUE (>= 1.0.0) 如果命令执行成功,返回插入操作完成之后,列表的长度。 如果没有找到指定元素 ,返回 -1 。 如果 key 不存在或为空列表,返回 0 在列表的元素前或者后插入元素。 当指定元素不存在于列表中时,不执行任何操作。 当列表不存在时,被视为空列表,不执行任何操作。 如果 key 不是列表类型,返回一个错误。
LLEN LLEN KEY_NAME           (>= 1.0.0) 列表的长度。 返回列表的长度。 如果列表 key 不存在,则key被解释为一个空列表,返回 0 。 如果 key 不是列表类型,返回一个错误。
LPOP LLEN KEY_NAME             (>= 1.0.0) 列表的第一个元素。 当列表 key 不存在时,返回nil 移除并返回列表的第一个元素。
LPUSH LPUSH KEY_NAME VALUE1.. VALUEN              (>= 1.0.0) 执行 LPUSH 命令后,列表的长度。 将一个或多个值插入到列表头部。 如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作。 当 key 存在但不是列表类型时,返回一个错误。注意:在Redis 2.4版本以前的 LPUSH 命令,都只接受单个 value 值。
LPUSHX LPUSHX KEY_NAME VALUE1.. VALUEN         (>= 2.2.0) LPUSHX 命令执行之后,列表的长度。 将一个或多个值插入到已存在的列表头部,列表不存在时操作无效。
LRANGE LRANGE KEY_NAME START END (>= 1.0.0) 一个列表,包含指定区间内的元素。 返回列表中指定区间内的元素,区间以偏移量 START END 指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
LREM LREM KEY_NAME COUNT VALUE (>= 1.0.0) 被移除元素的数量。 列表不存在返回 0 **根据参数 COUNT 的值,移除列表中与参数 VALUE 相等的元素。COUNT 的值可以是以下几种:count > 0 : 从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT 。 count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值。count = 0 : 移除表中所有与VALUE相等的值。**
LSET LSET KEY_NAME INDEX VALUE(>= 1.0.0) 操作成功返回 ok ,否则返回错误信息。 通过索引来设置元素的值。当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误。
LTRIM LTRIM KEY_NAME START STOP (>= 1.0.0) 命令执行成功时,返回 ok 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。
RPOP RPOP KEY_NAME           (>= 1.0.0) 列表的最后一个元素。 当列表不存在时,返回 nil 用于移除并返回列表的最后一个元素。
RPOPLPUSH RPOPLPUSH SOURCE_KEY_NAME DESTINATION_KEY_NAME (>= 1.0.0) 被弹出的元素。 用于移除列表的最后一个元素,并将该元素添加到另一个列表并返回。
RPUSH RPUSH KEY_NAME VALUE1..VALUEN        (>= 1.0.0) 执行 RPUSH 操作后,列表的长度。 用于将一个或多个值插入到列表的尾部(最右边)。如果列表不存在,一个空列表会被创建并执行 RPUSH 操作。 当列表存在但不是列表类型时,返回一个错误。
注意:在 Redis 2.4 版本以前的 RPUSH 命令,都只接受单个value值。
RPUSHX RPUSHX KEY_NAME VALUE1..VALUEN              (>= 2.2.0) 执行 RPUSHX 操作后,列表的长度。 将一个或多个值插入到已存在的列表尾部(最右边)。如果列表不存在,操作无效。

2.6 Set(集合)

Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

实例

redis 127.0.0.1:6379> SADD mykey redis
(integer) 1
redis 127.0.0.1:6379> SADD mykey mongodb
(integer) 1
redis 127.0.0.1:6379> SADD mykey mysql
(integer) 1
redis 127.0.0.1:6379> SADD mykey mysql
(integer) 0
redis 127.0.0.1:6379> SMEMBERS mykey

1) "mysql"
2) "mongodb"
3) "redis"

在以上实例中我们通过 SADD 命令向名为 mykey 的集合插入的三个元素。

下表给出了与 Redis集合相关常用的基本命令:

命令 语法(可用版本) 返回值 描述
SADD SADD KEY_NAME VALUE1..VALUEN(>= 1.0.0) 被添加到集合中的新元素的数量,不包括被忽略的元素。 将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略。假如集合 key 不存在,则创建一个只包含添加的元素作成员的集合。当集合 key 不是集合类型时,返回一个错误。注意:在Redis2.4版本以前, SADD 只接受单个成员值。
SCARD SCARD KEY_NAME (>= 1.0.0) 集合的数量。 当集合 key 不存在时,返回 0 。 返回集合中元素的数量。
SDIFF SDIFF FIRST_KEY OTHER_KEY1..OTHER_KEYN (>= 1.0.0) 包含差集成员的列表。 返回给定集合之间的差集。不存在的集合 key 将视为空集。
SDIFFSTORE SDIFFSTORE DESTINATION_KEY KEY1..KEYN(>= 1.0.0) 结果集中的元素数量。 将给定集合之间的差集存储在指定的集合中。如果指定的集合 key 已存在,则会被覆盖。
SINTER SINTER KEY KEY1..KEYN(>= 1.0.0) 交集成员的列表。 返回给定所有给定集合的交集。 不存在的集合 key 被视为空集。 当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。
SINTERSTORE SINTERSTORE DESTINATION_KEY KEY KEY1..KEYN(>= 1.0.0) 交集成员的列表。 将给定集合之间的交集存储在指定的集合中。如果指定的集合已经存在,则将其覆盖。
SISMEMBER SISMEMBER KEY VALUE(>= 1.0.0) 如果成员元素是集合的成员,返回 1 。 如果成员元素不是集合的成员,或 key 不存在,返回 0 判断成员元素是否是集合的成员。
SMEMBERS SMEMBERS KEY VALUE (>= 1.0.0) 集合中的所有成员。 返回集合中的所有的成员。 不存在的集合 key 被视为空集合。
SMOVE SMOVE SOURCE DESTINATION MEMBER(>= 1.0.0) 如果成员元素被成功移除,返回 1 。 如果成员元素不是 source 集合的成员,并且没有任何操作对 destination 集合执行,那么返回 0 将指定成员 member 元素从 source 集合移动到 destination 集合。SMOVE 是原子性操作。如果 source 集合不存在或不包含指定的 member 元素,则 SMOVE 命令不执行任何操作,仅返回0。否则, member 元素从 source 集合中被移除,并添加到 destination 集合中去。当 destination 集合已经包含 member 元素时, SMOVE 命令只是简单地将 source 集合中的 member 元素删除。当 sourcedestination 不是集合类型时,返回一个错误。
SPOP SPOP KEY(>= 1.0.0) 被移除的随机元素。 当集合不存在或是空集时,返回 nil 移除并返回集合中的一个随机元素。
SRANDMEMBER SRANDMEMBER KEY [count](>= 1.0.0) 只提供集合 key 参数时,返回一个元素;如果集合为空,返回 nil 。 如果提供了 count 参数,那么返回一个数组;如果集合为空,返回空数组。 返回集合中的一个随机元素。从 Redis 2.6 版本开始, Srandmember 命令接受可选的count参数:如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。如果 count 大于等于集合基数,那么返回整个集合。如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值。该操作和 SPOP 相似,但 SPOP 将随机元素从集合中移除并返回,而 Srandmember 则仅仅返回随机元素,而不对集合进行任何改动。
SREM SREM KEY MEMBER1..MEMBERN            (>= 1.0.0) 被成功移除的元素的数量,不包括被忽略的元素。 移除集合中的一个或多个成员元素,不存在的成员元素会被忽略。当 key 不是集合类型,返回一个错误。在 Redis 2.4 版本以前, SREM 只接受单个成员值。
SUNION SUNION KEY KEY1..KEYN (>= 1.0.0) 并集成员的列表。 返回给定集合的并集。不存在的集合 key 被视为空集。
SUNIONSTORE SUNIONSTORE DESTINATION KEY KEY1..KEYN(>= 1.0.0) 结果集中的元素数量。 将给定集合的并集存储在指定的集合destination中。
SSCAN SSCAN KEY [MATCH pattern] [COUNT count](>= 1.0.0) 数组列表。 迭代集合键中的元素。

2.7 zset(sorted set:有序集合)

Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

实例

redis 127.0.0.1:6379> ZADD mykey 1 redis
(integer) 1
redis 127.0.0.1:6379> ZADD mykey 2 mongodb
(integer) 1
redis 127.0.0.1:6379> ZADD mykey 3 mysql
(integer) 1
redis 127.0.0.1:6379> ZADD mykey 3 mysql
(integer) 0
redis 127.0.0.1:6379> ZADD mykey 4 mysql
(integer) 0
redis 127.0.0.1:6379> ZRANGE mykey 0 10 WITHSCORES

1) "redis"
2) "1"
3) "mongodb"
4) "2"
5) "mysql"
6) "4"

在以上实例中我们通过命令 ZADD 向 redis 的有序集合中添加了三个值并关联上分数。

下表给出了与 Redis有序集合相关常用的基本命令:

命令 语法(可用版本) 返回值 描述
ZADD ZADD KEY_NAME SCORE1 VALUE1.. SCOREN VALUEN    (>= 1.2.0) 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。 将一个或多个成员元素及其分数值加入到有序集当中。如果某个成员已经是有序集的成员,那么更新这个成员的分数值,并通过重新插入这个成员元素,来保证该成员在正确的位置上。分数值可以是整数值或双精度浮点数。如果有序集合 key 不存在,则创建一个空的有序集并执行 ZADD 操作。当 key 存在但不是有序集类型时,返回一个错误。
注意: 在 Redis 2.4 版本以前, ZADD 每次只能添加一个元素。
ZCARD ZCARD KEY_NAME     (>= 1.2.0) key 存在且是有序集类型时,返回有序集的基数。 当 key 不存在时,返回 0 计算集合中元素的数量。
ZCOUNT ZCOUNT key min max(>= 2.0.0) 分数值在 min max 之间的成员的数量。 计算有序集合中指定分数区间的成员数量。
ZINCRBY ZINCRBY key increment member(>= 1.2.0) member 成员的新分数值,以字符串形式表示。 对有序集合中指定成员的分数加上增量increment可以通过传递一个负数值 increment ,让分数减去相应的值,比如 ZINCRBY key -5 member ,就是让 member score 值减去 5。当 key 不存在,或分数不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。当 key 不是有序集类型时,返回一个错误。分数值可以是整数值或双精度浮点数。
ZINTERSTORE ZINTERSTORE DESTINATION NUMKEYS KEY [KEY …] [WEIGHTS WEIGHT [WEIGHT …]] [AGGREGATE SUM|MIN|MAX]    (>= 2.0.0) 保存到目标结果集的的成员数量。 计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和。
ZLEXCOUNT ZLEXCOUNT KEY MIN MAX(>= 2.8.9) 指定区间内的成员数量。 计算有序集合中指定字典区间内成员数量。
ZRANGE ZRANGE key start stop [WITHSCORES](>= 1.2.0) 指定区间内,带有分数值(可选)的有序集成员的列表。 返回有序集中,指定区间内的成员。其中成员的位置按分数值递增(从小到大)来排序。具有相同分数值的成员按字典序(lexicographical order )来排列。如果你需要成员按值递减(从大到小)来排列,请使用 ZREVRANGE 命令。下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。
ZRANGEBYLEX ZRANGEBYLEX KEY MIN MAX [LIMIT OFFSET COUNT]    (>= 2.8.9) 指定区间内的元素列表。 通过字典区间返回有序集合的成员。
ZRANGEBYSCORE ZRANGEBYSCORE KEY MIN MAX [WITHSCORES] [LIMIT OFFSET COUNT]     (>= 1.0.5) 指定区间内,带有分数值(可选)的有序集成员的列表。 返回有序集合中指定分数区间的成员列表。有序集成员按分数值递增(从小到大)次序排列。具有相同分数值的成员按字典序来排列(该属性是有序集提供的,不需要额外的计算)。默认情况下,区间的取值使用闭区间 (小于等于或大于等于),你也可以通过给参数前增加 ( 符号来使用可选的开区间 (小于或大于)。
ZRANK ZRANK KEY MEMBER(>= 2.0.0) 如果成员是有序集 key 的成员,返回 member 的排名。 如果成员不是有序集key的成员,返回 nil 返回有序集中指定成员的排名。其中有序集成员按分数值递增(从小到大)顺序排列。
ZREM ZREM KEY MEMBER [MEMBER …]          (>= 1.2.0) 被成功移除的成员的数量,不包括被忽略的成员。 移除有序集中的一个或多个成员,不存在的成员将被忽略。当 key 存在但不是有序集类型时,返回一个错误。
注意: 在 Redis 2.4 版本以前, ZREM 每次只能删除一个元素。
ZREMRANGEBYLEX ZREMRANGEBYLEX KEY MIN MAX       (>= 2.8.9) 被成功移除的成员的数量,不包括被忽略的成员。 移除有序集合中给定的字典区间的所有成员。
ZREMRANGEBYRANK ZREMRANGEBYRANK KEY START STOP      (>= 2.0.0) 被移除成员的数量。 用于移除有序集中,指定排名(rank)区间内的所有成员。
ZREMRANGEBYSCORE ZREMRANGEBYSCORE KEY MIN MAX        (>= 1.2.0) 被移除成员的数量。 移除有序集中,指定分数(score)区间内的所有成员。
ZREVRANGE ZREVRANGE KEY START STOP [WITHSCORES]                (>= 1.2.0) 指定区间内,带有分数值(可选)的有序集成员的列表。 返回有序集中,指定区间内的成员。其中成员的位置按分数值递减(从大到小)来排列。具有相同分数值的成员按字典序的逆序(reverse lexicographical order)排列。除了成员按分数值递减的次序排列这一点外, ZREVRANGE 命令的其他方面和 ZRANGE 命令一样。
ZREVRANK ZREVRANK KEY MEMBER(>= 2.2.0) 如果成员是有序集 key 的成员,返回成员的排名。 如果成员不是有序集 key 的成员,返回 nil 返回有序集中成员的排名。其中有序集成员按分数值递减(从大到小)排序。排名以 0 为底,也就是说, 分数值最大的成员排名为 0 。使用 ZRANK 命令可以获得成员按分数值递增(从小到大)排列的排名。
ZSCAN ZSCAN KEY CURSOR [MATCH PATTERN] [COUNT COUNT]        (>= 2.8.0) 返回的每个元素都是一个有序集合元素,一个有序集合元素由一个成员(member)和一个分值(score)组成。 迭代有序集合中的元素(包括元素成员和元素分值)
ZSCORE ZSCORE KEY MEMBER(>= 1.2.0) 成员的分数值,以字符串形式表示。 返回有序集中,成员的分数值。 如果成员元素不是有序集 key 的成员,或 key 不存在,返回 nil
ZUNIONSTORE ZUNIONSTORE DESTINATION NUMKEYS KEY [KEY …] [WEIGHTS WEIGHT [WEIGHT …]] [AGGREGATE SUM|MIN|MAX](>=2.0.0) 保存到 destination 的结果集的成员数量。 计算给定的一个或多个有序集的并集,其中给定 key 的数量必须以 numkeys 参数指定,并将该并集(结果集)储存到 destination 。默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和 。

2.8 HyperLogLog

用于进行基数统计,不是集合,不保存数据,只记录数量而不是具体数据。

核心是基数估算算法,最终数值存在一定误差。

误差范围:基数估计的结果是一个带有 0.81% 标准错误的近似值。

耗空间极小,每个hyperloglog key占用了12K的内存用于标记基数。

pfadd命令不是一次性分配12K内存使用,会随着基数的增加内存逐渐增大。

Pfmerge命令合并后占用的存储空间为12K,无论合并之前数据量多少 。

实例

redis  127.0.0.1:6379> PFADD  databases  "Redis"  "MongoDB"  "MySQL"
(integer) 1

redis 127.0.0.1:6379> PFCOUNT databases
(integer) 3

redis 127.0.0.1:6379> PFADD databases "Redis" # Redis 已经存在,不必对估计数量进行更新
(integer) 0

redis 127.0.0.1:6379> PFCOUNT databases # 元素估计数量没有变化
(integer) 3

redis 127.0.0.1:6379> PFADD databases "PostgreSQL" # 添加一个不存在的元素
(integer) 1

redis 127.0.0.1:6379> PFCOUNT databases # 估计数量增一
4

下表给出了与 Redis HyperLogLog相关常用的基本命令:

命令 语法(可用版本) 返回值 描述
PFADD PFADD key element [element …](>= 2.8.9) 整型,如果至少有个元素被添加返回 1, 否则返回 0 将所有元素参数添加到 HyperLogLog 数据结构中
PFCOUNT PFCOUNT key [key …]        (>= 2.8.9) 整数,返回给定 HyperLogLog 的基数值,如果多个 HyperLogLog 则返回基数估值之和。 返回给定 HyperLogLog 的基数估算值。
PFMERGE PFMERGE destkey sourcekey [sourcekey …](>= 2.8.9) 返回 OK 将多个 HyperLogLog 合并为一个 HyperLogLog ,合并后的 HyperLogLog 的基数估算值是通过对所有 给定 HyperLogLog 进行并集计算得出的。

2.9 GEO(地理位置)

支持存储地理位置信息用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能。

实例

redis 127.0.0.1:6379> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2

redis 127.0.0.1:6379> GEODIST Sicily Palermo Catania
"166274.15156960039"

redis 127.0.0.1:6379> GEORADIUS Sicily 15 37 100 km
1) "Catania"

redis> GEORADIUS Sicily 15 37 200 km
1) "Palermo"
2) "Catania"

下表给出了与 Redis GEO相关常用的基本命令:

命令 语法(可用版本) 返回值 描述
GEOADD GEOADD key longitude latitude member [longitude latitude member …](>= 3.2.0) 新添加到键里面的空间元素数量, 不包括那些已经存在但是被更新的元素。 将给定的空间元素(纬度、经度、名字)添加到指定的键里面。 这些数据会以有序集合的形式被储存在键里面, 从而使得像 GEORADIUSGEORADIUSBYMEMBER 这样的命令可以在之后通过位置查询取得这些元素。
GEOPOS GEOPOS key member [member …]             (>= 3.2.0) GEOPOS 命令返回一个数组, 数组中的每个项都由两个元素组成: 第一个元素为给定位置元素的经度, 而第二个元素则为给定位置元素的纬度。 当给定的位置元素不存在时, 对应的数组项为空值。 从键里面返回所有给定位置元素的位置(经度和纬度)。因为 GEOPOS 命令接受可变数量的位置元素作为输入, 所以即使用户只给定了一个位置元素, 命令也会返回数组回复。
GEODIST GEODIST key member1 member2 [unit]          (>= 3.2.0) 计算出的距离会以双精度浮点数的形式被返回。 如果给定的位置元素不存在, 那么命令返回空值。 返回两个给定位置之间的距离。如果两个位置之间的其中一个不存在, 那么命令返回空值。
GEORADIUS GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count](>= 3.2.0) 复杂见文档 复杂见文档
GEORADIUSBYMEMBER GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count](>= 3.2.0) 一个数组, 数组中的每个项表示一个范围之内的位置元素。 这个命令和 GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是 GEORADIUSBYMEMBER 的中心点是由给定的位置元素决定的, 而不是像 GEORADIUS 那样, 使用输入的经度和纬度来决定中心点。
GEOHASH GEOHASH key member [member …]                (>= 3.2.0) 一个数组, 数组的每个项都是一个geohash 。 命令返回的 geohash 的位置与用户给定的位置元素的位置一一对应。 返回一个或多个位置元素的 Geohash 表示。

2.10 BitMap(位图)

BitMap,即位图,其实也就是 byte 数组,用二进制表示,只有 0 和 1 两个数字。可以用于实现用户上线次数统计。

实例

redis 127.0.0.1:6379> SETBIT bit 10086 1
(integer) 0

redis 127.0.0.1:6379> GETBIT bit 10086
(integer) 1

redis 127.0.0.1:6379> GETBIT bit 100 # bit 默认被初始化为 0
(integer) 0

下表给出了与 Redis BitMap相关常用的基本命令:

命令 语法(可用版本) 返回值 描述
SETBIT SETBIT key offset value(>=2.2.0) 指定偏移量原来储存的位。 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。位的设置或清除取决于 value 参数,可以是 0 也可以是 1 。当 key 不存在时,自动生成一个新的字符串值。字符串会进行伸展(grown)以确保它可以将 value 保存在指定的偏移量上。当字符串值进行伸展时,空白位置以 0 填充。offset 参数必须大于或等于 0 ,小于 2^32 (bit 映射被限制在 512 MB 之内)。
GETBIT GETBIT key offset(>=2.2.0) 字符串值指定偏移量上的位(bit)。 key 所储存的字符串值,获取指定偏移量上的位(bit)。当 offset 比字符串值的长度大,或者 key 不存在时,返回 0
BITCOUNT BITCOUNT key [start] [end](>= 2.6.0) 被设置为 1 的位的数量。 计算给定字符串中,被设置为 1 的比特位的数量。一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 startend 参数,可以让计数只在特定的位上进行。startend 参数的设置都可以使用负数值: 比如 -1 表示最后一个字节, -2 表示倒数第二个字节,以此类推。不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0
BITPOS BITPOS key bit [start] [end](>= 2.8.7) 整数回复。 返回位图中第一个值为 bit 的二进制位的位置。在默认情况下, 命令将检测整个位图, 但用户也可以通过可选的 start 参数和 end 参数指定要检测的范围。
BITOP BITOP operation destkey key [key …](>= 2.6.0) 保存到 destkey 的字符串的长度,和输入 key 中最长的字符串长度相等。 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。operation 可以是 ANDORNOTXOR 这四种操作中的任意一种:
BITOP AND destkey key [key ...] ,对一个或多个 key 求逻辑并,并将结果保存到 destkey
BITOP OR destkey key [key ...] ,对一个或多个 key 求逻辑或,并将结果保存到 destkey
BITOP XOR destkey key [key ...] ,对一个或多个 key 求逻辑异或,并将结果保存到 destkey
BITOP NOT destkey key ,对给定 key 求逻辑非,并将结果保存到 destkey
除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入。
BITOP处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0 。空的 key 也被看作是包含 0 的字符串序列。
BITFIELD BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL](>= 3.2.0) 复杂见文档 复杂见文档

2.11 Pub/Sub(发布/订阅)

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

Redis 客户端可以订阅任意数量的频道。

实例

以下实例演示了发布订阅是如何工作的。在我们实例中我们创建了订阅频道名为 redisChat:

redis 127.0.0.1:6379> SUBSCRIBE redisChat

Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1

现在,我们先重新开启个 redis 客户端,然后在同一个频道 redisChat 发布两次消息,订阅者就能接收到消息。

redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"

(integer) 1

redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by w3cschool.cc"

(integer) 1

# 订阅者的客户端会显示如下消息
1) "message"
2) "redisChat"
3) "Redis is a great caching technique"
1) "message"
2) "redisChat"
3) "Learn redis by w3cschool.cc"

下表列出了 redis 发布订阅常用命令:

命令 语法(可用版本) 返回值 描述
PSUBSCRIBE PSUBSCRIBE pattern [pattern …](>= 2.0.0) 接收到的信息。 订阅一个或多个符合给定模式的频道。每个模式以 * 作为匹配符,比如 it 匹配所有以 it 开头的频道( it.news 、 it.blog 、 it.tweets 等等)。 news. 匹配所有以 news. 开头的频道( news.it 、 news.global.today 等等),诸如此类。**
PUBSUB PUBSUB [argument [argument …]](>= 2.8.0) 由活跃频道组成的列表。 用于查看订阅与发布系统状态,它由数个不同格式的子命令组成。
PUBLISH PUBLISH channel message(>= 2.0.0) 接收到信息的订阅者数量。 用于将信息发送到指定的频道。
PUNSUBSCRIBE PUNSUBSCRIBE [pattern [pattern …]](>= 2.0.0) 这个命令在不同的客户端中有不同的表现。 用于退订所有给定模式的频道。
SUBSCRIBE SUBSCRIBE channel [channel …](>= 2.0.0) 接收到的信息。 用于订阅给定的一个或多个频道的信息。
UNSUBSCRIBE UNSUBSCRIBE channel [channel …](>= 2.0.0) 这个命令在不同的客户端中有不同的表现。 用于退订给定的一个或多个频道的信息。

2.12 Transaction(事务)

Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:

事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

一个事务从开始到执行会经历以下三个阶段:

  • 开始事务
  • 命令入队
  • 执行事务

实例

以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令::

redis 127.0.0.1:6379> MULTI
OK

redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED

redis 127.0.0.1:6379> GET book-name
QUEUED

redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED

redis 127.0.0.1:6379> SMEMBERS tag
QUEUED

redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
2) "C++"
3) "Programming"

下表列出了 redis 事务的相关命令:

命令 语法(可用版本) 返回值 描述
DISCARD DISCARD(>= 2.0.0) 总是返回 OK 。 用于取消事务,放弃执行事务块内的所有命令。
EXEC EXEC(>= 1.2.0) 事务块内所有命令的返回值,按命令执行的先后顺序排列。 当操作被打断时,返回空值 nil 。 用于执行所有事务块内的命令。
MULTI MULTI(>= 1.2.0) 总是返回 OK 。 用于标记一个事务块的开始。事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。
UNWATCH UNWATCH(>= 2.2.0) 总是返回 OK 。 用于取消 WATCH 命令对所有 key 的监视。
WATCH WATCH(>= 2.2.0) 总是返回 OK 。 用于监视一个(或多个)key ,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断。

2.13 Script(脚本)

Redis 脚本使用 Lua 解释器来执行脚本。 Reids 2.6 版本通过内嵌支持 Lua 环境。执行脚本的常用命令为 EVAL

实例

以下实例演示了 redis 脚本工作过程:

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 脚本的相关命令:

命令 语法(可用版本) 返回值 描述
EVAL EVAL script numkeys key [key …] arg [arg …](>= 2.6.0) 使用 Lua 解释器执行脚本。
参数说明:
script: 参数是一段 Lua 5.1 脚本程序。脚本不必(也不应该)定义为一个 Lua 函数。 numkeys: 用于指定键名参数的个数。 key [key …]: 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。 arg [arg …]: 附加参数,在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。
EVALSHA EVALSHA sha1 numkeys key [key …] arg [arg …](>= 2.6.0) 根据给定的 sha1 校验码,执行缓存在服务器中的脚本。参数说明同上
SCRIPT EXISTS SCRIPT EXISTS scripts(>= 2.6.0) 一个列表,包含 0 1,前者表示脚本不存在于缓存,后者表示脚本已经在缓存里面了。列表中的元素和给定的 SHA1 校验和保持对应关系,比如列表的第三个元素的值就表示第三个 SHA1 校验和所指定的脚本在缓存中的状态。 用于校验指定的脚本是否已经被保存在缓存当中。
SCRIPT FLUSH SCRIPT FLUSH(>= 2.6.0) 总是返回 OK。 用于清除所有 Lua 脚本缓存。
SCRIPT KILL SCRIPT KILL(>= 2.6.0) 总是返回 OK 用于杀死当前正在运行的 Lua 脚本,当且仅当这个脚本没有执行过任何写操作时,这个命令才生效。这个命令主要用于终止运行时间过长的脚本,比如一个因为 BUG 而发生无限循环的脚本。SCRIPT KILL 执行之后,当前正在运行的脚本会被杀死,执行这个脚本的客户端会从 EVAL 命令的阻塞当中退出,并收到一个错误作为返回值。
SCRIPT LOAD SCRIPT LOAD script(>= 2.6.0) 给定脚本的 SHA1 校验和 用于将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。EVAL命令也会将脚本添加到脚本缓存中,但是它会立即对输入的脚本进行求值。如果给定的脚本已经在缓存里面了,那么不执行任何操作。在脚本被加入到缓存之后,通过 EVALSHA命令,可以使用脚本的 SHA1 校验和来调用这个脚本。脚本可以在缓存中保留无限长的时间,直到执行 SCRIPT FLUSH 为止。

2.14 Connection(连接)

Redis 连接命令主要是用于连接 redis 服务。

实例

以下实例演示了客户端如何通过密码验证连接到 redis 服务,并检测服务是否在运行:

redis 127.0.0.1:6379> AUTH "password"
OK
redis 127.0.0.1:6379> PING
PONG

下表列出了 redis 连接的基本命令:

命令 语法(可用版本) 返回值 描述
AUTH AUTH PASSWORD(>=1.0.0) 密码匹配时返回 OK ,否则返回一个错误。 用于检测给定的密码和配置文件中的密码是否相符。
ECHO ECHO message(>=1.0.0) 返回字符串本身。 用于打印给定的字符串。
PING PING (>=1.0.0) 如果连接正常就返回一个 PONG ,否则返回一个连接错误。 使用客户端向 Redis 服务器发送一个 PING ,如果服务器运作正常的话,会返回一个 PONG 。通常用于测试与服务器的连接是否仍然生效,或者用于测量延迟值。
QUIT QUIT(>=1.0.0) 总是返回 OK 。 用于关闭与当前客户端与redis服务的连接。一旦所有等待中的回复(如果有的话)顺利写入到客户端,连接就会被关闭。
SELECT SELECT index(>=1.0.0) 总是返回 OK 。 用于切换到指定的数据库,数据库索引号 index 用数字值指定,以 0 作为起始索引值。

2.15 Server(服务器)

Redis 服务器命令主要是用于管理 redis 服务。

实例

以下实例演示了如何获取 redis 服务器的统计信息:

redis 127.0.0.1:6379> INFO

# Server
# Redis 服务器版本
redis_version:2.8.13
# Git SHA1
redis_git_sha1:00000000
# Git dirty flag
redis_git_dirty:0
redis_build_id:c2238b38b1edb0e2
redis_mode:standalone
# Redis 服务器的宿主操作系统
os:Linux 3.5.0-48-generic x86_64
# 架构(32 或 64 位)
arch_bits:64
# Redis 所使用的事件处理机制
multiplexing_api:epoll
# 编译 Redis 时所使用的 GCC 版本
gcc_version:4.7.2
# 服务器进程的 PID
process_id:3856
# Redis 服务器的随机标识符(用于 Sentinel 和集群)
run_id:0e61abd297771de3fe812a3c21027732ac9f41fe
# TCP/IP 监听端口
tcp_port:6379
# 自 Redis 服务器启动以来,经过的秒数
uptime_in_seconds:11554
# 自 Redis 服务器启动以来,经过的天数
uptime_in_days:0
hz:10
# 以分钟为单位进行自增的时钟,用于 LRU 管理
lru_clock:16651447
config_file:

# Clients
# 已连接客户端的数量(不包括通过从属服务器连接的客户端)
connected_clients:1
# 当前连接的客户端当中,最长的输出列表
client-longest_output_list:0
# 当前连接的客户端当中,最大输入缓存
client-biggest_input_buf:0
# 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量
blocked_clients:0

# Memory
# 由 Redis 分配器分配的内存总量,以字节(byte)为单位
used_memory:589016
# 以人类可读的格式返回 Redis 分配的内存总量
used_memory_human:575.21K
# 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。
used_memory_rss:2461696
# Redis 的内存消耗峰值(以字节为单位)
used_memory_peak:667312
# 以人类可读的格式返回 Redis 的内存消耗峰值
used_memory_peak_human:651.67K
# Lua 引擎所使用的内存大小(以字节为单位)
used_memory_lua:33792
# used_memory_rss 和 used_memory 之间的比率
mem_fragmentation_ratio:4.18
# 在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc 。
mem_allocator:jemalloc-3.6.0

# Persistence RDB 和 AOF 的相关信息
loading:0
rdb_changes_since_last_save:3
rdb_bgsave_in_progress:0
rdb_last_save_time:1409158561
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok

# Stats 一般统计信息
total_connections_received:24
total_commands_processed:294
instantaneous_ops_per_sec:0
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:41
keyspace_misses:82
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:264

# Replication 主/从复制信息
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU CPU计算量统计信息
used_cpu_sys:10.49
used_cpu_user:4.96
used_cpu_sys_children:0.00
used_cpu_user_children:0.01

#commandstats : Redis 命令统计信息
#cluster : Redis 集群信息

# Keyspace 数据库相关的统计信息
db0:keys=94,expires=1,avg_ttl=41638810
db1:keys=1,expires=0,avg_ttl=0
db3:keys=1,expires=0,avg_ttl=0

下表列出了 redis 服务器的相关命令:

命令 语法(可用版本) 返回值 描述
BGREWRITEAOF BGREWRITEAOF(>= 1.0.0) 反馈信息。 用于异步执行一个 AOF(AppendOnly File) 文件重写操作。重写会创建一个当前 AOF 文件的体积优化版本。即使 Bgrewriteaof 执行失败,也不会有任何数据丢失,因为旧的 AOF 文件在 Bgrewriteaof 成功之前不会被修改。
注意:
从 Redis 2.4 开始, AOF 重写由 Redis 自行触发, BGREWRITEAOF 仅仅用于手动触发重写操作。
BGSAVE BGSAVE(>= 1.0.0) 反馈信息。 用于在后台异步保存当前数据库的数据到磁盘。BGSAVE 命令执行之后立即返回 OK ,然后 Redis fork 出一个新子进程,原来的 Redis 进程(父进程)继续处理客户端请求,而子进程则负责将数据保存到磁盘,然后退出。
CLIENT KILL CLIENT KILL ip:port(>= 2.4.0) 成功关闭时,返回 OK 。 用于关闭客户端连接。
CLIENT LIST CLIENT LIST(>= 2.4.0) 命令返回多行字符串,这些字符串按以下形式被格式化:每个已连接客户端对应一行(以 LF 分割) 每行字符串由一系列 属性=值 形式的域组成,每个域之间以空格分开 用于返回所有连接到服务器的客户端信息和统计数据。
CLIENT GETNAME CLIENT GETNAME(>= 2.6.9) 如果连接没有设置名字,那么返回空白回复; 如果有设置名字,那么返回名字。 用于返回 CLIENT SETNAME 命令为连接设置的名字。 因为新创建的连接默认是没有名字的, 对于没有名字的连接, CLIENT GETNAME 返回空白回复。
CLIENT PAUSE CLIENT PAUSE timeout(>= 2.9.50) 返回 OK。如果 timeout 参数是非法的返回错误。 用于阻塞客户端命令一段时间(以毫秒计)。
CLIENT SETNAME CLIENT SETNAME connection-name(>= 2.6.9) 设置成功时返回 OK 。 用于指定当前连接的名称。这个名字会显示在 CLIENT LIST命令的结果中, 用于识别当前正在与服务器进行连接的客户端。
CLUSTER SLOTS CLUSTER SLOTS(>= 3.0.0) IP/端口嵌套的列表数组。 用于当前的集群状态,以数组形式展示。
COMMAND COMMAND(>= 2.8.13) 嵌套的Redis命令的详细信息列表。列表顺序是随机的。 用于返回所有的Redis命令的详细信息,以数组形式展示。
COMMAND COUNT COMMAND COUNT(>= 2.8.13) redis 命令数。 用于统计 redis 命令的个数。
COMMAND GETKEYS COMMAND GETKEYS(>= 2.8.13) key 的列表。 用于获取所有 key。
TIME TIME(>= 2.6.0) 一个包含两个字符串的列表: 第一个字符串是当前时间(以 UNIX 时间戳格式表示),而第二个字符串是当前这一秒钟已经逝去的微秒 用于返回当前服务器时间。
COMMAND INFO COMMAND INFO command-name [command-name …](>= 2.8.13) 命令描述信息的嵌套列表。 用于获取 redis 命令的描述信息。
CONFIG GET CONFIG GET parameter(>= 2.0.0) 给定配置参数的值。 用于获取 redis 服务的配置参数。在 Redis 2.4 版本中, 有部分参数没有办法用 CONFIG GET 访问,但是在最新的 Redis 2.6 版本中,所有配置参数都已经可以用 CONFIG GET 访问了。
CONFIG REWRITE CONFIG REWRITE parameter(>= 2.8.0) 一个状态值:如果配置重写成功则返回 OK ,失败则返回一个错误。 对启动 Redis 服务器时所指定的 redis.conf 配置文件进行改写。对服务器的当前配置进行修改, 而修改后的配置可能和 redis.conf 文件中所描述的配置不一样, CONFIG REWRITE 的作用就是通过尽可能少的修改, 将服务器当前所使用的配置记录到 redis.conf 文件中。
CONFIG SET CONFIG SET parameter value (>= 2.0.0) 当设置成功时返回 OK ,否则返回一个错误。 可以动态地调整 Redis 服务器的配置(configuration)而无须重启。可以使用它修改配置参数,或者改变 Redis 的持久化(Persistence)方式。
CONFIG RESETSTAT CONFIG RESETSTAT(>= 2.0.0) 总是返回 OK 。 用于重置 INFO命令中的某些统计数据,包括:Keyspace hits (键空间命中次数)、Keyspace misses (键空间不命中次数)、Number of commands processed (执行命令的次数)、Number of connections received (连接服务器的次数)、Number of expired keys (过期key的数量)、Number of rejected connections (被拒绝的连接数量)、Latest fork(2) time(最后执行 fork(2) 的时间)、The aof_delayed_fsync counter(aof_delayed_fsync 计数器的值)
DBSIZE DBSIZE(>= 1.0.0) 当前数据库的 key 的数量。 用于返回当前数据库的 key 的数量。
DEBUG OBJECT DEBUG OBJECT key(>= 1.0.0) 当 key 存在时,返回有关信息。 当 key 不存在时,返回一个错误。 是一个调试命令,它不应被客户端所使用。
DEBUG SEGFAULT DEBUG SEGFAULT(>= 1.0.0) 执行一个非法的内存访问从而让 Redis 崩溃,仅在开发时用于 BUG 调试。
FLUSHALL FLUSHALL(>= 1.0.0) 总是返回 OK 。 用于清空整个 Redis 服务器的数据(删除所有数据库的所有 key )。
FLUSHDB FLUSHDB(>= 1.0.0) 总是返回 OK 。 用于清空当前数据库中的所有 key。
INFO INFO [section](>= 1.0.0) 字符串,文本行的集合。 以一种易于理解和阅读的格式,返回关于 Redis 服务器的各种信息和统计数值。通过给定可选的参数 section ,可以让命令只返回某一部分的信息。
LASTSAVE LASTSAVE(>= 1.0.0) 字符串,文本行的集合。 返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示。
MONITOR MONITOR(>= 1.0.0) 总是返回 OK 。 用于实时打印出 Redis 服务器接收到的命令,调试用。
ROLE ROLE(>= 2.8.12) 返回一个数组:第一个参数是 master, slave, sentinel 三个中的一个。 查看主从实例所属的角色,角色有master, slave, sentinel。
SAVE SAVE(>= 1.0.0) 保存成功时返回 OK 。 执行一个同步保存操作,将当前 Redis 实例的所有数据快照(snapshot)以 RDB 文件的形式保存到硬盘。
SHUTDOWN SHUTDOWN [NOSAVE] [SAVE](>= 1.0.0) 执行失败时返回错误。 执行成功时不返回任何信息,服务器和客户端的连接断开,客户端自动退出。 停止所有客户端。如果有至少一个保存点在等待,执行 SAVE 命令。如果 AOF 选项被打开,更新 AOF 文件。关闭 redis 服务器(server)。
SLAVEOF SLAVEOF host port(>= 1.0.0) 总是返回 OK 。 可以将当前服务器转变为指定服务器的从属服务器(slave server)。如果当前服务器已经是某个主服务器(master server)的从属服务器,那么执行 SLAVEOF host port 将使当前服务器停止对旧主服务器的同步,丢弃旧数据集,转而开始对新主服务器进行同步。另外,对一个从属服务器执行命令 SLAVEOF NO ONE 将使得这个从属服务器关闭复制功能,并从从属服务器转变回主服务器,原来同步所得的数据集不会被丢弃。利用『 SLAVEOF NO ONE 不会丢弃同步所得数据集』这个特性,可以在主服务器失败的时候,将从属服务器用作新的主服务器,从而实现无间断运行。
SLOWLOG SLOWLOG subcommand [argument](>= 2.2.12) 取决于不同命令,返回不同的值。 用来记录查询执行时间的日志系统。查询执行时间指的是不包括像客户端响应(talking)、发送回复等 IO 操作,而单单是执行一个查询命令所耗费的时间。另外,slow log 保存在内存里面,读写速度非常快,因此你可以放心地使用它,不必担心因为开启 slow log 而损害 Redis 的速度。
SYNC SYNC(>= 1.0.0) 不明确。 用于同步主从服务器。

3.文档

3.1 KeySpace Notification(键空间通知)

3.2 Transation( 事务)

MULTIEXECDISCARDWATCH是 Redis 事务的基础。

事务可以一次执行多个命令, 并且带有以下两个重要的保证:

  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

    EXEC 命令负责触发并执行事务中的所有命令:

    • 如果客户端在使用 MULTI 开启了一个事务之后,却因为断线而没有成功执行 EXEC ,那么事务中的所有命令都不会被执行。
    • 另一方面,如果客户端成功在开启事务之后执行 EXEC ,那么事务中的所有命令都会被执行。

3.3 Pub/Sub(发布与订阅)

3.4 Replication(主从复制)

3.5 Protocol(通信协议)

3.6 Persistence(持久化)

3.7 Sentinel(哨兵)

3.8 Cluster(集群)

3.9 集群规范

4.jedis

4.1 Jedis简介

4.2 HelloWordl(Jedis版)

  1. jar包导入

    下载地址:https://mvnrepository.com/artifact/redis.clients/jedis

  2. 基于maven

    <dependency> 
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
    </dependency>
  3. 连接redis

    Jedis jedis = new Jedis("localhost", 6379); 
  4. 操作redis

    jedis.set("name", "itheima"); jedis.get("name"); 
  5. 关闭redis连接

    jedis.close(); 
  6. API文档

    http://xetorthio.github.io/jedis/

4.3 Jedis读写redis数据

4.4 Jedis简易工具类开发

4.5 可视化客户端

5. 删除策略

数据删除策略

  1. 定时删除

    创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务立即执行对键的删除操作

    优点:

    ​ 节约内存,到时就删除,快速释放掉不必要的内存占用

    缺点:

    ​ CPU压力很大,无论CPU此时负载量多高,均占用CPU,会影响redis服务器响应时间和指令吞吐量

    总结:

    ​ 用处理器性能换取存储空间 (拿时间换空间)

  2. 惰性删除

    数据到达过期时间,不做处理。等下次访问该数据时

    • 如果未过期,返回数据
    • 发现已过期,删除,返回不存在

    优点:

    ​ 节约CPU性能,发现必须删除的时候才删除

    缺点:

    ​ 内存压力很大,出现长期占用内存的数据

    总结:

    ​ 用存储空间换取处理器性能 (拿时间换空间)

  3. 定期删除

    周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度

    特点1:

    ​ CPU性能占用设置有峰值,检测频度可自定义设置

    特点2:

    ​ 内存压力不是很大,长期占用内存的冷数据会被持续清理

    总结:

    ​ 周期性抽查存储空间 (随机抽查,重点抽查)

三种策略对比

策略 内存 CPU 总结
定时删除 节约内存,无占用 不分时段占用CPU资源,频度高 时间换空间
惰性删除 内存占用严重 延时执行,CPU利用率高 空间换时间
定期删除 内存定期随机清理 每秒花费固定的COU资源维护内存 随机抽查,重点抽查

6. redis高可用

6.1 主从模式

6.1.1 作用

  • 读写分离:master写、slave读,提高服务器的读写负载能力
  • 负载均衡:基于主从结构,配合读写分离,由slave分担master负载,并根据需求的变化,改变slave的数 量,通过多个从节点分担数据读取负载,大大提高Redis服务器并发量与数据吞吐量
  • 故障恢复:当master出现问题时,由slave提供服务,实现快速的故障恢复
  • 数据冗余:实现数据热备份,是持久化之外的一种数据冗余方式
  • 高可用基石:基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案

6.1.2主从复制工作流程

  1. 建立连接阶段(即准备阶段)

    建立slave到master的连接,使master能够识别slave,并保存slave端口号

    • 步骤1:设置master的地址和端口,保存master信息
    • 步骤2:建立socket连接
    • 步骤3:发送ping命令(定时器任务)
    • 步骤4:身份验证
    • 步骤5:发送slave端口信息
    master slave
    ①发送指令:slaveof ip port
    ②接收到指令,响应对方
    ③保存master的IP与端口 masterhost masterport
    ④根据保存的信息创建连接master的socket
    ⑤周期性发送命令:ping
    ⑥响应pong
    ⑦发送指令:auth password
    ⑧验证授权
    ⑨发送指令:replconf listening-port
    ⑩保存slave的端口号
    1. 主从连接(slave连接master)

      • 方式一:客户端发送命令

        slaveof <masterip> <masterport>

      • 方式二:启动服务器参数

        redis-server -slaveof <masterip> <masterport>

      • 方式三:服务器配置

        slaveof <masterip> <masterport>

      • slave系统信息

        1. master_link_down_since_seconds
        2. masterhost
        3. masterport
      • master系统信息

        1. slave_listening_port(多个)
    2. 主从断开连接

      • 客户端发送命令

      slaveof no one

      • 说明

        slave断开连接后,不会删除已有数据,只是不再接受master发送的数据

    3. 授权访问

      • master客户端发送命令设置密码

        requirepass <password>

      • master配置文件设置密码

        config set requirepass <password>

        config get requirepass

      • slave客户端发送命令设置密码

        auth <password>

      • slave配置文件设置密码

        masterauth <password>

      • slave启动服务器设置密码

        redis-server –a <password>

  2. 数据同步阶段

    在slave初次连接master后,复制master中的所有数据到slave

    将slave的数据库状态更新成master当前的数据库状态

    • 步骤1:请求同步数据
    • 步骤2:创建RDB同步数据
    • 步骤3:恢复RDB同步数据
    • 步骤4:请求部分同步数据
    • 步骤5:恢复部分同步数据
    master slave
    ①发送指令:psync2
    ②执行bgsave
    ③第一个slave连接时, 创建命令缓冲区
    ④生成RDB文件,通过 socket发送给slave
    ⑤接收RDB,清空数据,执行RDB文件恢复过程
    ⑥发送命令告知RDB恢复已经完成完成
    ⑦发送复制缓冲区信息
    ⑧接收信息,执行bgrewriteaof,恢复数据
    ⑨发送指令:???
    ⑩接收到指令,响应对方
    1-5:全量复制 6-8部分复制
    1. 数据同步阶段master说明

      1. 如果master数据量巨大,数据同步阶段应避开流量高峰期,避免造成master阻塞,影响业务正常执行

      2. 复制缓冲区大小设定不合理,会导致数据溢出。如进行全量复制周期太长,进行部分复制时发现数据已 经存在丢失的情况,必须进行第二次全量复制,致使slave陷入死循环状态。

        repl-backlog-size 1mb

      3. master单机内存占用主机内存的比例不应过大,建议使用50%-70%的内存,留下30%-50%的内存用于执 行bgsave命令和创建复制缓冲区

    2. 数据同步阶段slave说明

      1. 为避免slave进行全量复制、部分复制时服务器响应阻塞或数据不同步,建议关闭此期间的对外服务

        slave-serve-stale-data yes|no

      2. 数据同步阶段,master发送给slave信息可以理解master是slave的一个客户端,主动向slave发送 命令

      3. 多个slave同时对master请求数据同步,master发送的RDB文件增多,会对带宽造成巨大冲击,如果 master带宽不足,因此数据同步需要根据业务需求,适量错峰

      4. slave过多时,建议调整拓扑结构,由一主多从结构变为树状结构,中间的节点既是master,也是 slave。注意使用树状结构时,由于层级深度,导致深度越高的slave与最顶层master间数据同步延迟 较大,数据一致性变差,应谨慎选择

  3. 命名传播阶段

    当master数据库状态被修改后,导致主从服务器数据库状态不一致,此时需要让主从数据同步到一致的 状态,同步的动作称为命令传播

    master将接收到的数据变更命令发送给slave,slave接收命令后执行命令

    1. 命令传播阶段的部分复制

      • 命令传播阶段出现了断网现象
        • 网络闪断闪连 忽略
        • 短时间网络中断 部分复制
        • 长时间网络中断 全量复制
      • 部分复制的三个核心要素
        • 服务器的运行 id(run id)
        • 主服务器的复制积压缓冲区
        • 主从服务器的复制偏移量
    2. 服务器运行ID(runid)

      1. 概念:服务器运行ID是每一台服务器每次运行的身份识别码,一台服务器多次运行可以生成多个运行id
      2. 组成:运行id由40位字符组成,是一个随机的十六进制字符 例如:fdc9ff13b9bbaab28db42b3d50f852bb5e3fcdce
      3. 作用:运行id被用于在服务器间进行传输,识别身份 如果想两次操作均对同一台服务器进行,必须每次操作携带对应的运行id,用于对方识别
      4. 实现方式:运行id在每台服务器启动时自动生成的,master在首次连接slave时,会将自己的运行ID发 送给slave,slave保存此ID,通过info Server命令,可以查看节点的runid
    3. 复制缓冲区

      1. 概念:复制缓冲区,又名复制积压缓冲区,是一个先进先出(FIFO)的队列,用于存储服务器执行过的命 令,每次传播命令,master都会将传播的命令记录下来,并存储在复制缓冲区
        • 复制缓冲区默认数据存储空间大小是1M,由于存储空间大小是固定的,当入队元素的数量大于队 列长度时,最先入队的元素会被弹出,而新元素会被放入队列
      2. 由来:每台服务器启动时,如果开启有AOF或被连接成为master节点,即创建复制缓冲区
      3. 作用:用于保存master收到的所有指令(仅影响数据变更的指令,例如set,select)
      4. 数据来源:当master接收到主客户端的指令时,除了将指令执行,会将该指令存储到缓冲区中
    4. 复制缓冲区内部工作原理

      1. 组成
        • 偏移量
        • 字节值
      2. 工作原理
        • 通过offset区分不同的slave当前数据传播的差异
        • master记录已发送的信息对应的offset
        • slave记录已接收的信息对应的offset
    5. 主从服务器复制偏移量(offset)

      1. 概念:一个数字,描述复制缓冲区中的指令字节位置
      2. 分类:
      • master复制偏移量:记录发送给所有slave的指令字节对应的位置(多个)
      • slave复制偏移量:记录slave接收master发送过来的指令字节对应的位置(一个)
      1. 数据来源:
      • master端:发送一次记录一次
      • slave端:接收一次记录一次
      1. 作用:同步信息,比对master与slave的差异,当slave断线后,恢复数据使用
    6. 数据同步+命令传播阶段工作流程

      master slave
      ②执行bgsave生成RDB文件,记录当前的复制偏移量offset ①发送指令: psync2 ?-1 psync2
      ③发送 +FULLRESYNC runid offset 通过socket发送RDB文件给slave
      期间接收客户端命令,offset发生了变化
      ④收到 +FULLRESYNC 保存master的runid和offset 清空当前全部数据,通过socket接收RDB文件,恢复RDB数据
      ⑥接收命令,判定runid是否匹配,判定offset是否在复制缓冲区中 ⑤发送命令:psync2 runid offset
      ⑦如果runid或offset有一个不满足,执行全量复制
      ⑦如果runid或offset校验通过,offset与offset相同,忽略
      ⑦如果runid或offset校验通过,offset与offset不相同 发送 +CONTINUE offset 通过socket发送复制缓冲区中offset到offset的数据
      ⑧收到 +CONTINUE 保存master的offset 接收信息后,执行bgrewriteaof,恢复数据
      1-4全量复制 5-8部分复制
    7. 心跳机制

      • 进入命令传播阶段候,master与slave间需要进行信息交换,使用心跳机制进行维护,实现双方连接保持在线
      • master心跳:
        • 指令:PING
        • 周期:由repl-ping-slave-period决定,默认10秒
        • 作用:判断slave是否在线
        • 查询:INFO replication 获取slave最后一次连接时间间隔,lag项维持在0或1视为正常
      • slave心跳任务
        • 指令:REPLCONF ACK {offset}
        • 周期:1秒
        • 作用1:汇报slave自己的复制偏移量,获取最新的数据变更指令
        • 作用2:判断master是否在线
    8. 心跳阶段注意事项

      • 当slave多数掉线,或延迟过高时,master为保障数据稳定性,将拒绝所有信息同步操作

        min-slaves-to-write 2
        min-slaves-max-lag 8

        slave数量少于2个,或者所有slave的延迟都大于等于10秒时,强制关闭master写功能,停止数据同步

      • slave数量由slave发送REPLCONF ACK命令做确认

      • slave延迟由slave发送REPLCONF ACK命令做确认

    9. 主从复制工作流程(完整)

6.1.3 主从复制常见问题

  1. 频繁的全量复制(1)

    伴随着系统的运行,master的数据量会越来越大,一旦master重启,runid将发生变化,会导致全部slave的 全量复制操作

    内部优化调整方案:

    1. master内部创建master_replid变量,使用runid相同的策略生成,长度41位,并发送给所有slave
    2. 在master关闭时执行命令 shutdown save,进行RDB持久化,将runid与offset保存到RDB文件中
    • repl-id repl-offset
    • 通过redis-check-rdb命令可以查看该信息
    1. master重启后加载RDB文件,恢复数据 重启后,将RDB文件中保存的repl-id与repl-offset加载到内存中
    • master_repl_id = repl master_repl_offset = repl-offset
    • 通过info命令可以查看该信息

    作用:本机保存上次runid,重启后恢复该值,使所有slave认为还是之前的master

  2. 频繁的全量复制(2)

    • 问题现象
    • 网络环境不佳,出现网络中断,slave不提供服务
    • 问题原因
      • 复制缓冲区过小,断网后slave的offset越界,触发全量复制
    • 最终结果
      • slave反复进行全量复制
    • 解决方案
      • 修改复制缓冲区大小
    • 建议设置如下:
      1. 测算从master到slave的重连平均时长second
      2. 获取master平均每秒产生写命令数据总量write_size_per_second
      3. 最优复制缓冲区空间 = 2 * second * write_size_per_second
  3. 频繁的网络中断(1)

    • 问题现象

      • master的CPU占用过高 或 slave频繁断开连接
    • 问题原因

      • slave每1秒发送REPLCONF ACK命令到master
      • 当slave接到了慢查询时(keys * ,hgetall等),会大量占用CPU性能
      • master每1秒调用复制定时函数replicationCron(),比对slave发现长时间没有进行响应
    • 最终结果

      • master各种资源(输出缓冲区、带宽、连接等)被严重占用
    • 解决方案

      • 通过设置合理的超时时间,确认是否释放slave

        repl-timeout

 该参数定义了超时时间的阈值(默认60秒),超过该值,释放slave 
  1. 频繁的网络中断(2)

    • 问题现象

      • slave与master连接断开
    • 问题原因

      • master发送ping指令频度较低
      • master设定超时时间较短
      • ping指令在网络中存在丢包
    • 解决方案

      • 提高ping指令发送的频度

        repl-ping-slave-period

  超时时间repl-time的时间至少是ping指令频度的5到10倍,否则slave很容易判定超时 
  1. 数据不一致

    • 问题现象

      • 多个slave获取相同数据不同步
    • 问题原因

      • 网络信息不同步,数据发送有延迟
    • 解决方案

      • 优化主从间的网络环境,通常放置在同一个机房部署,如使用阿里云等云服务器时要注意此现象

      • 监控主从节点延迟(通过offset)判断,如果slave延迟过大,暂时屏蔽程序对该slave的数据访问

        slave-serve-stale-data yes|no

 开启后仅响应info、slaveof等少数命令(慎用,除非对数据一致性要求很高) 

6.2 哨兵模式

6.2.1 作用

  • 监控
    • 不断的检查master和slave是否正常运行。
    • master存活检测、master与slave运行情况检测
  • 通知(提醒)
  • 当被监控的服务器出现问题时,向其他(哨兵间,客户端)发送通知。
  • 自动故障转移
    • 断开master与slave连接,选取一个slave作为master,将其他slave连接到新的master,并告知客户端新的服 务器地址

注意:

​ 哨兵也是一台redis服务器,只是不提供数据服务

​ 通常哨兵配置数量为单数

6.2.2 启用哨兵模式

  1. 配置一拖二的主从结构

  2. 配置三个哨兵(配置相同,端口不同)

    参看sentinel.conf

  3. 启动哨兵

    redis-sentinel sentinel端口号 .conf

配置项 范例 说明
sentinel auth-pass <服务器名称> <服务器名称>
sentinel auth-pass mymaster joey
设置哨兵监听的主服务器信息,最后的参数决定了最终参与选举的服务器(-1)
sentinel down-after-milliseconds <自定义服 务名称><主机地址><端口><主从服务器总量> sentinel monitor mymaster 192.168.194.131 6381 1 指定哨兵在监控Redis服务时,判定服务器挂掉的时间周期,默认30秒(30000),也是主从切换条件之一
sentinel down-after-milliseconds <服务名称><毫秒数(整数)> sentinel down-aftermilliseconds mymaster 3000 指定同时进行主从的slave数量,数值越大,要求的网络资源越高,要求月洗,同步时间越长
sentinel parallel-syncs <服务名称><服务器数(整数)> sentinel parallel-syncs mymaster 指定出现故障后,故障切换的最大超时时间,超过该值,认定切换失败,默认3分钟
sentinel failover-timeout <服务名称><毫秒数(整数)> sentinel failover-timeout mymaster 9000 服务器无法正常联通时,设定的执行脚本,通常调试使用
sentinel notification-script <服务名称><脚本路径>

6.2.3 哨兵工作原理

6.3 redis集群

7.企业级解决方案