Redis 学习指南

《Redis 入门指南》(第二版)

第一章

Redis 是什么

Redis (REmote Dictionary Server 远程字典服务器)是一个开源的、高性能的、基于键值对的缓存与存储系统,通过提供多种键值数据类型来适应不同场景下的缓存与存储需要。同时 Redis 的诸多高级功能使其可以胜任消息队列,任务队列等不同的角色。

特性

存储结构

Redis 它以字典结构存储数据,并允许其它应用通过 TCP 协议读取字典中的内容

目前 Redis 支持的数据类型(键值):

  • 字符串类型
  • 散列类型
  • 列表类型
  • 集合类型
  • 有序集合类型

内存存储与持久化

Redis 数据存储在内存中。在一台普通的笔记本电脑上,Redis 可以在一秒内读写超过 10 万个键值。

如果程序退出内存,数据会丢失,不过 Redis 提供了对持久化的支持,可以将内存中的数据异步写入到硬盘中,同时不影响继续提供服务。

功能丰富

  • Redis 可以为每个键设置生存时间(TTL),这一出色的性能让 Redis 可以作为缓存系统来使用。
  • Redis 支持持久化和丰富的数据类型
  • Redis 列表类型键可以用来实现队列,并且支持阻塞式读取

PS: Redis 与 Memcached 性能上的区别, Redis 是单线程模型,而 Memcached 是多线程支持的,所以在多核服务器上后者的性能理论上相对更高一些。而 Redis 在性能上也是非常高的,所以不用担心性能问题,而更多的去考虑功能问题。随着 Redis 3.0 的推出,标志着 Memcached 几乎成为了 Redis 的子集。同时 Redis 对集群的支持,也使得 Memcahced 原有的第三方集群工具不再成为优势。

作为缓存系统, Redis 还可以限定数据占用的最大内存空间,在数据达到空间限制后,可以按照一定的规则自动淘汰不需要的键。

为什么使用 Redis

  • Redis 提供了 100 多个命令,常用的只有十几个,并且每个命令都很容易记忆。
  • Redis 提供了几十种编程语言的客户端库。
  • Redis 是开源的

第二章

Redis 版本规则

Redis 规定次版本号(小数点后的数字)为偶数的版本是稳定版本(如 2.8 版本、3.0 版本),奇数为非稳定版,生产环境一般需要稳定版本

安装

在 POSIX 系统中的安装

$ wget http://download.redis.io/xxxx.3-0.tar.gz
$ tar zxvf xxxx-3.0.tar.gz
$ cd redis-stable
$ make

Redis 没有外部依赖,安装过程简单。编译后的 Redis 源代码目录的 src 文件夹中可以找到若干个可执行程序,最好在编译后直接执行 make install 命令来将这些可执行程序复制到 /usr/local/bin 目录中以便以后执行程序时可以不用输入完整的路径。

软件包管理器中的 redis 比较古老,对升级和性能有影响,不推荐使用。

在 OS X 系统中的安装

在 Windows 中的安装

启动和停止 Redis

直接启动

$ redis-server

默认使用 Redis 会使用 6379 端口,通过 --port 参数可以自定义端口号:

$ redis-server --port 6380

注意在使用的时候也需要指定相应的端口:

$ redis-cli -p 6380

通过初始化脚本启动 Redis

生产环境推荐使用此方法运行,可以使得 Redis 能随系统自动运行。在 Redis 安装目录下有一个 utils 目录中,有一个名为 redis_init_script 的初始化脚本文件。

具体方式,可以参考本书中第二章 2.2.1 小节。

但是完全没有必要,可以执行安装目录下的 utils/install_server.sh 脚本。

$ ./install_server.sh
Please select the redis port for this instance: [6379] 
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf] 
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log] 
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379] 
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server] 
Selected config:
Port           : 6379
Config file    : /etc/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /var/lib/redis/6379
Executable     : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!

需要注意的是第一步的时候可以选择端口号,如果需要指定不同的端口或运行多个 Redis 服务器,可以多次执行该文件,然后指定不同的端口即可。

根据最后的提示,可以得知,在 345 的运行级别下,默认开机启动的。可以执行 chkconfig 命令查看:

$ chkconfig --list redis_6379
redis_6379         0:关    1:关    2:开    3:开    4:开    5:开    6:关

停止 Redis

考虑到 Redis 有可能正在将内存中的数据同步到硬盘中,强行终止可能会造成数据丢失。正确停止的方式是向 Redis 发送 SHUTDOWN 命令:

$ redis-cli SHUTDOWN

注意,不是使用的默认端口需要加上端口号,如果端口号为 6380,则:

$ redis-cli -p 6380 SHUTDOWN

Redis 命令行客户端

发送命令

通过 redis-cli 向 Redis 发送命令有两种方式:

  • 第一种方式是将命令作为 redis-cli 的参数执行,后面不跟参数会自动按照默认配置来执行,也可以通过指定 -h-p 指定地址和端口,Redis 提供了 PING 命令来测试客户端与 Redis 的连接是否正常,如果正常会收到 PONG;
  • 第二种方式是不附带参数运行 redis-cli,这样会进入交互模式,可以自由输入命令,这种方式在要输入多条命令时比较方便

命令返回值

1. 状态回复

最简单的一种答复,如执行 SET 会返回状态 OK 表示成功。

redis> PING
PONG

2. 错误回复

当出现命令不存在或命令格式有错误等情况时会返回错误回复,错误回复以(error)开头,并在后面跟上错误信息。

3. 整数回复

Redis 虽然没有整数类型,但是提供了一些用于整数操作的命令,如递增键值的 INCR 命令会以整数形式返回递增后的键值。除此之外还有一些其它的操作,如获取当前数据库的键的数量的 DBSIZE 命令。

redis> INCR foo
(integer) 1

4. 字符串回复

是最常见的一种回复类型,当请求一个字符串类型的键的键值或一个其它类型键中的元素时,就会返回一个字符串,用引号包裹:

redis> GET foo
"1"

5. 多行字符串回复

多行字符串回复中的每行字符串都以一个序号开头,如:

redis> keys *
1) "name"
2) "num"

配置

配置文件可以设置端口号、是否开启持久化、日志级别等。可以在启动 Redis 服务时指定配置文件,如:

$ redis-server /path/to/redis.conf

同时可以指定一些配置项,这样会覆盖配置文件里面的参数,如:

$ redis-server /path/to/redis.conf --loglevel warning

源代码目录中有一个配置文件的模板 redis.conf。

除此之外,还可以在 Redis 运行时通过 CONFIG SET 命令在不重新启动 Redis 的情况下动态修改部分 Redis 配置:

redis> CONFIG SET loglevel warning
OK

PS:并不是所有配置都可以使用 CONFIG SET 命令修改。

查看配置:

redis> config get loglevel
1) "loglevel"
2) "notice"

第一行表示选项名,第二行即是选项值。

多数据库

Redis 提供了多个用于存储数据的字典,可以将其中的每个字典都理解成一个独立的数据库。

每个数据库对外都是以一个从0开始的递增数字命名, Redis 默认支持 16 个数据库。可以通过配置参数 databases 来修改这一数字。 客户端与 Redis 建立连接后会自动选择 0 号数据库,不过可以随时使用 SELSECT 命令更换数据库,如选择 1 号数据库:

redis> select 1
OK
  • Redis 不支持自定义数据库的名字,每个数据库都以编号命名,开发者必须记录哪些数据库存储了哪些数据。
  • Redis 不支持为每个数据库设置不同的访问密码,所以一个客户端要么可以访问全部库,要么一个库也不能访问。
  • Redis 多个数据库之间并不是完全隔离的,如果 FLUSHALL 命令可以清空一个实例下的所有数据库中的内容。不同的应用应该使用不同的 Redis 实例来存储,由于 Redis 占用的内存只有 1MB 左右,所以不用担心多个 Redis 实例会额外占用很多内存。


第三章

数据类型

热身

几个基础命令:

1、获取符合规则的键名列表

KEYS pattern

pattern 支持 glob 风格通配符格式:

  • ? 匹配一个字符
  • * 匹配任意个(包括0个)字符
  • [] 匹配括号间的任一字符,可以使用 - 表示一个范围,如 a[b-d] 可以匹配 "ab"、"ac"、"ad"
  • \x 匹配字母 x ,用于转义符号,如要匹配 ? ,可以使用 ?

注意: KEYS 命令需要遍历 Redis 中的所有键,当键的数量较多时会影响性能,不建议在生产环境中使用。
PS: Redis 不区分命令大小写

2、判断一个键是否存在

EXISTS key

如果存在返回 1,不存在返回 0.

3、删除键

DEL key [key1 ... ]

可以删除一个或多个键,返回值是删除的键的个数。

Tips: DEL 命令参数不支持通配符,但可以做类似 Linux 的管道符的操作。比如要删除以 "user:"开关的键,可以执行 redis-cli KEYS "user:*" | xargs redis-cli DEL,另外由于 DEL 命令支持多个键作为参数,可以执行 redis-cli DEL 'redis-cli KEYS "user:*"'(注意,里面是 "`" 号,操蛋的 markdown)。达到的效果一样,但效率更高。

4、获取得键值的数据类型

TYPE key

返回值可能是 string(字符串类型)、hash(散列)、list(列表类型)、set(集合类型)、zset(有序集合类型)。

字符串类型

介绍

它能存储任何形式的字符串,包括二进制数据。一个字符串类型键允许存储的数据的最大容量是 512MB。

命令

1、赋值与取值

SET key value
GET key

存值时如果有空格要加引号,取值当不存在时,会返回空结果。

2、递增数字

INCR key

当存储的字符串是整数时,INCR 命令的作用是让当前键值递增,并返回增后的值。

redis> INCR pv
(integer) 2

PS: 当要操作的键不存在时会默认键值为 0,所以第一次递增后的结果是 1

PS: 如果 key 不是整数类型,会报错

127.0.0.1:6379> SET name "Eden"
127.0.0.1:6379> INCR name
(error) ERR value is not an integer or out of range

PS: 不建议使用 GET SET 方式去将一个值取出来,然后写一个函数去自己实现它,如果两个客户端同时取出了这个 value,就会出竞态条件。而 Redis 本身上原子操作的,无论多少个客户端同时连接,都不会出现这种情况。

实践

TIPS: Redis 键命名

Redis 本身对于键的命名并没有强制的要求,但比较有用的实践是用 “对象类型:对象ID:对象属性” 来命名的,如 user:1:friends

对于多个单词则推荐使用 “.” 分隔。

为了维护方便,命名一定要有意义。

如果用 Redis 作为数据库,可以使用 INCR 命令来设置自增 ID。

存储数据,如数组,我们需要使用序列化的函数(如PHP的 serialize 和 Javascript 的 JSON.stringify ),除此之外,字符串类型键可以存储二进制数据,可以使用 MessagePack 进行序列化,速度更快,占用空间更小。

命令拾遗

  1. 增加指定的整数, INCRBY key incrementINCR 相似,只不过后者每次增加 1 个,前者可以指定数值。
  2. 减少指定的整数, DECR keyDECRBY key decrementINCR 相似,只不过是让键值递减。
  3. 增加指定浮点数, INCRBYFLOAT key increment,可以增加一个双精度浮点数。incrbyfloat salary 100.23
  4. 向尾部追加值, APPEND key value 向键值的尾部追加值,如果键不存在则将该键的值设置为 value,返回值是追加字符串后的总长度。
  5. 获取字符串长度, STRLEN key,返回键值的长度,如果不存在则返回 0,计算中文时,如果为 utf-8 编码,则每个中文相当于 3 个出字节。
  6. 同时获取/设置多个键值,MGET key [key1 key2 ...]MSET key value [key1 value1 ...],如果位数有错误,会报错。
  7. 位操作,GETBIT key offset SETBIT key offset value BITCOUNT key [start] [end] BITOP operation destkey key [key ... ],略书 29 页。
redis>incr c
(integer) 1
redis> incrby c 5
(integer) 6

redis>decr c
(integer) 5
redis> decrby c 3
(integer) 2

redis>incrbyfloat c 1.5
"3.5"

redis>set greeting Hello
OK
redis>append greeting " world."
(integer) 11

127.0.0.1:6379> mset name ZhangSan sex man age 18
OK
127.0.0.1:6379> mget name sex age
1) "ZhangSan"
2) "man"
3) "18"

散列类型 (hash)

介绍

散列类型的键值也是一种字典结构,其存储了字段和字段值的映射,但字段值只能是字符串,不支持其它数据类型。换句话说,散列类型不能嵌套其他的数据类型。一个散列类型键可以包含至多 232 - 1个字段。

除了散列类型, Redis 的其他数据类型同样不支持数据类型嵌套。比如集合类型的每个元素都只能是字符串,不能是另一个集合或散列表等

散列类型适合存储对象:使用对象类别和 ID 构成键名,使用字段表示对象的属性,而字段值则存储属性值。

命令

1、赋值与取值

HSET key field value
HGET key field
HMSET key field value [field value ...]
HMGET key field [field ...]
HGETALL key

HSET 命令不区分插入和更新操作,这意味着修改数据时不用事先判断字段是否存在来决定要执行的是插入还是更新操作。

2、判断字段是否存在

HEXISTS key field

如果存在则返回1,否则返回0(如果键不存在也会返回0)

3、当字段不存在时赋值

HSETNX key field value

PS:NX 表示 if not exists

4、增加数字

HINCRBY key field increment

散列类型没有 HINCR 命令,但是可以通过 HINCRBY key filed 1 来实现,之前不存在的 key 会自动建立。

5、删除字段

HDEL key field [field2 ...]

实践

命令拾遗

1、只获取字段名或字段值

HKEYS key
HVALS key

2、获取字段数量

HLEN key

列表类型

介绍

列表类型可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。

列表类型内部是使用双向链表实现的,所以向列表两端添加元素的时间复杂度都是一样的 O(1)。

不过使用链表的代价是通过索引访问元素比较慢,也即从一个链表中获取某一个元素,这种场景下不如 散列 类型。

借助链表的类型,Redis 还可以作为队列使用,与散列类型键最多能容纳的字段数量相同,一个列表类型键最多能容纳 232 - 1 个元素。

命令

1、向列表两端增加元素

// 向左边增加元素,支持多个元素
LPUSH key value [value2 ... ]
// 向右边增加元素,支持多个元素
RPUSH key value [value2 ... ]

2、从列表两端弹出元素

// 从左边弹出一个元素
LPOP key
// 从右边弹出一个元素
RPOP key

弹出一个元素分两步操作:一是将列表两边的某个元素删除,二是返回该元素。

3、获取列表中的元素个数

LLEN key

当键不存在时 LLEN 返回 0.

4、获取列表片断

LRANGE key start stop

返回从 start 到 stop 之间的元素(包括两端的元素), Redis 的列表起始索引为 0。

LRANGE 命令在取得列表片段的同时不会像 LPOP 一样删除该片段。

LRANGE 命令也支持负数索引,表示从右边开始计算序数。如 -1 就表示右边第一个元素。

特殊情况:

  1. 如果 start 的索引位置比 stop 的位置靠后,则会返回空列表。
  2. 如果 stop 大于实际的索引范围,则会返回到列表最右边的元素。

5、删除列表中指定的值

LREM key count value

删除列表中前 count 个值为 value 的元素。返回值是实际删除的元素的个数。

  1. 当 count > 0 时,LREM 命令会从列表左边开始删除前 count 个值为 value 的元素。
  2. 当 count < 0 时,LREM 命令会从列表右边开始删除前 |count| 个值为 value 的元素。
  3. 当 count = 0 时,LREM 命令会删除所有值为 value 的元素。

实践

略 P45

命令拾遗

1、获取 / 设置指定索引的元素

// 获取索引为 index 的元素
LINDEX key index

// 设置索引为 index 的元素的值为 value
LSET key index value

索引从 0 开始,如果 index 是负数表示从右边开始索引,右边第一个元素的索引是 -1。

2、只保留列表指定片段

LTRIM key start end

删除指定索引范围之外的所有元素,指定列表范围的方法和 LRANGE 相同。

LTRIM 命令常和 LPUSH 命令一起来限制列表中元素的数量,比如记录一个日志时我们希望只保留最新的 100 条日志。

redis> LPUSH numbers 1
redis> LTRIM numbers 0 99

3、向列表中插入元素

LINSERT key BEFORE|AFTER  pivot value

LINSERT 命令先会在列表中从左到右查找值为 pivot 的元素,然后根据第二个参数是 BEFORE 还是 AFTER 来决定将 value 插入到该元素的前面还是后面。

返回值为插入后列表的元素的个数。

PS:如果列表中有多个元素的值都是一样的,也即有多个 pivot 的值,那么使用 LINSERT 命令只会插入到第一个元素的前面或后面。

4、将一个元素从一个列表转到另一个列表

RPOPLPUSH source destination

RPOPLPUSH 会先从 source 列表类型键的右边弹出一个元素,然后将其插入到 destination 的左边。并返回这个元素的值。

当 source 和 destination 相同时,RPOPLPUSH 命令会不断地将队尾的元素移到队首,这个特性可以实现一个网站监控系统,具体需求见 P48。

集合类型(set)

介绍

在集合中的每个元素都是不同的,且没有顺序。一个集合类型键可以存储至多 232 - 1个字符串。

由于集合类型在 Redis 内部是使用值为空的散列表实现的,所以这些操作的时间复杂度都是 O(1)。最方便的是多个集合类型键之间还可以进行并集、交集和差集运算。

命令

1、增加删除元素

// 向集合中增加一个或多个元素,如果键不存在则会自动创建
// 因为在一个集合中不能有相同元素,所以如果要加入的元素已经存在于集合中就会忽略这个元素
// 该命令返回成功加入的数量(忽略的元素不计在内)
SADD key member [member2 ...]

// 返回删除成功的个数
SREM key member [member2 ...]

2、获取集合中的所有元素

SMEMBERS key

返回集合中的所有元素

3、判断元素是否在集合中

SISMEMBER key member

key 集合中如果存在 member 值则返回 1,如果不存在则返回 0。

4、集合间的运算

// 求差集
// 计算在 key 中出现,但在 key2 中没出现,得到的结果与 key3 进行计算
SDIFF key [key2 key3 ...]

// 求交集
// 在 key 中出现,同时也在 key2 中出现
SINTER key [key2 key3 ...]

// 求并集
// 
SUNION key [key2 key3 ...]

实践

  • 存储文章标签
  • 通过标签搜索文章

命令拾遗

1、获取元素中集合的个数

SCARD key

2、进行集合运算并将结果存储

SDIFFSTORE destination key [key2 ...]
SINTERSTORE destination key [key2 ...]
SUNIONSTORE destination key [key2 ...]

以上三个命令都将 SDIFF SINTER SUNION 计算得到的结果保存在键为 destination 的集合中。

3、随机获取集合中的元素

SRANDMEMBER key [count]

可以传递 count 参数来一次随机获取一个或多个元素。

根据 count 的正负不同,具体表现也不同:

  • 当 count 为正数时, SRANDMEMBER 会随机从集合里获得 count 个不重复的元素,如果 count 的值大于集合中的元素个数(SCARD),则返回集合中的全部元素,这些元素不会重复的
  • 当 count 为负时,会随机从集合里获得 |count | 个元素,这些元素可能重复

4、从集合中弹出一个元素

SPOP key

但由于集合类型的元素是无序的,所以 SPOP 命令会从集合中随机选择一个元素弹出。

有序集合类型

介绍

在集合类型的基础上有序集合中的每个元素都关联了一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在等集合类型的操作,还能够获得分数最高(或最低)的前N个元素,获得指定分数范围内的元素等与分数有关的操作。

集合中的元素是不同的,但它们中的分数是可以相同的。

有序集合与列表的相似点:

  • 二者都是有序的。
  • 二者都可以获取一定范围的元素。

有序集合与列表的不同点:

  • 列表是通过链表实现的,获取靠近两端的数据非常快,而当元素增多后,访问中间的元素会比较慢,所以列表比较适合实现如“新鲜事” 或 “日志”这样很少访问中间元素的应用;
  • 有序集合类型是使用散列表和跳跃表实现的,即使位于中间部位的数据,速度也很快
  • 列表中不能简单地调整某个元素的位置,但是不序集合可以(通过改变这个元素的分数)
  • 有序集合要比列表类型更耗费内存

命令

1、增加元素

ZADD key score member [score2 member2 ...]

ZADD 命令用来向有序集合中加入一个元素和该元素的分数,如果该元素已经存在,则会用新的分数替换原有的分数, ZADD 命令的返回值是新加入到集合中的元素的个数(不包含之前已经存在的元素)

2、获取元素的分数

ZSCORE key member

3、获取排名在某个范围的元素列表

ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]

ZRANGE 命令会按照元素分数从小到大的顺序返回索引从 start 到 stop 之间的所有元素(包含两端的元素),负数从后往前找(-1表示最后一个)。ZREVRANGE 命令会逆序查找。在尾部加上 WITHSCORE 可以连同分数一起查出来。

# 返回所有 keys 集合中的元素
redis> ZRANGE keys 0 -1 

4、获得指定分数范围的元素

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset limit]

按元素分数从小到大的顺序返回分数在 min 和 max 之间(包含 min 和 max)的元素。

如果希望分数范围不包含端点值,可以在分数前加上“(”符号。

min 和 max 还支持无穷大, -inf+inf 分别表示负无穷和正无穷。

offset 和 limit 类似于 SQL 语句。

# 获取键为 scoreboard 的有序集合分数为80(不包含)到正无穷的元素
redis> ZRANGEBYSCORE scoreboard (80 +inf

5、增加某个元素的分数

ZINCRBY key increment member

ZINCRBY 命令可以增加一个元素的分数,返回值是更改后的分数。

实践

命令拾遗

1、获得集合中元素的数量

ZCARD key

2、获取指定分数范围内的元素个数

ZCOUNT key min max

min 和 max 参数的特性与 ZRANGEBYSCORE 命令中的一样。

3、删除一个或多个元素

ZREM key member [member2 ...]

返回值是成功删除的元素的个数(不包含本身就不存在的元素)

4、按照排名范围删除元素

ZREMRANGEBYRANK key start stop

按元素分数从小到大的顺序(即索引从0开始)删除处在指定排名范围内的元素,并返回删除的元素数量。

5、按分数范围删除元素

ZREMRANGEBYSCORE key min max

删除指定分数范围内的元素,min 和 max 特性和 ZRANGEBYSCORE 一样。返回值为删除元素的数量。

6、获得元素的排名

ZRANK key member
ZREVRANK key member

按元素分数从小到大的顺序获得指定的元素的排名(从0开始)。后者相反。

第四章

事务

  • Redis 保证一个事务中的所有命令要么都执行,要么都不执行
  • Redis 中的事务保证一个事务内的命令依次执行而不被其它命令插入

错误处理

# 事务开始
redis> MULTI

redis> set str A
redis> set str B

# 事务结束
redis> EXEC
  1. 语法错误。语法错误指命令不存在或者命令参数的个数不对,只要有一个命令有语法错误,执行 EXEC 命令后 Redis 就会直接返回错误,连语法正确的命令也不例外。
  2. 运行错误。指在命令执行时出现的错误,比如使用散列类型的命令操作集合类型的健,如果事务里的一条命令运行错误,其它命令会继续执行(包含出错命令之后的命令)。

WATCH 命令介绍

注意: 因为事务中的每个命令的执行结果都是最后一起返回的,所以无法将前一条命令的结果作为下一条命令的参数。

WATCH 命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行。监控一直持续到 EXEC 命令(事务中的命令是在 EXEC 之后才执行的,所以在 MULTI 命令后可以修改 WATCH 监控的键值)。这是一种防止竞态条件的做法,如:

redis> set key 1
OK
redis> watch key
OK
redis> set key 2
OK
redis> multi
OK
redis> set key 3
QUEUED
redis> exec
(nil)
redis> get key
"2"

执行 EXEC 命令后会取消对所有键的监控,如果不想执行事务中的命令也可以使用 UNWATCH 命令来取消监控。

过期时间

设置过期时间命令

# 单位是秒
EXPIRE key time

# 单位是毫秒
PEXPIRE key microtime

查看过期时间命令

# 返回毫秒数
TTL key

# 返回秒数
PTTL key

PS:如果键不存在,返回值为 -2, 如果永久保存,返回值为 -1

取消过期时间

  • 使用命令 PERSIST,如果成功清除则返回 1, 否则返回 0(因为键不存在或键本来就是永久的)。
  • 使用 SETGETSET 命令也会清除过期时间(设置永不过期 -1)
  • 使用 EXPIRE 能够重新设置过期时间 expire key time

其他只对键值进行操作的命令 (如 INCRLPUSHHSETZREM),均不会影响键的过期时间。

访问频率限制

P76

缓存

修改 Redis 配置文件(/usr/redis/6379.conf)。

  • 限制 Redis 能够使用的最大内存, maxmemory 参数,单位是 Byte
  • 超过这个限制时 Redis 会依据 maxmemory-policy 参数指定的策略来删除不需要的键,其策略参考 P78 页
  • 当超过限制时每次从数据库中随机删除的几个键的数量会依据 maxmemory-samples 参数来设置

排序

SORT 命令

SORT 命令可以对列表类型、集合类型和有序集合类型键进行排序,并且可以完成与关系数据库中的连接查询相类似的任务。

SORT key

除了可以排列数字外,SORT 命令可以通过 ALPHA 参数实现按字典顺序排列非数字元素

SORT key ALPHA

SORT 命令默认是正序排序,还可以逆序排序

SORT key DESC

还可以支持 LIMIT 参数来返回指定范围的结果

SORT key DESC LIMIT offset limit

BY 参数

语法

~ BY 参考键

其中参考键可以是字符串类型键或者是散列类型键的某个字段(表示为 键名->字段名),如果提供了 BY 参数, SORT 命令将不再依据元素自身的值进行排序,而是对每个元素使用元素的值替换参数键中的第一个 "*" 并获取其值,其后依据该值对元素排序,如:

redis> SORT key BY posts:*->time DESC

上例中的posts:*->time 表示,有一个散列类型的键值为 posts 的数据类型数据,其中有一个属性叫做 time,以上就是根据这个 time 的值来做为排序的依据。

如果几个元素的参考键值相同,则 SORT 命令会再比较元素本身的值来决定元素的顺序。

当某个元素的参考键不存在时,会默认参考键的值为 0。

第五章

如何在编程语言中使用 Redis

第六章

Redis 脚本的强大功能

沙盒、随机结果

第七章

Redis 持久化知识

RDB

AOF

第八章

多个 Redis 实例维护的方法。

第九章

Redis 安全和协议

推荐阅读更多精彩内容