Redis入门篇
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Redis入门篇,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含40561字,纯文字阅读大概需要58分钟。
内容图文
![Redis入门篇](/upload/InfoBanner/zyjiaocheng/865/3155226a63f7488bb611a85f97a45e16.jpg)
Redis入门篇
- Redis官方文档
- Redis下载
- Redis存储结构
- Redis内存存储与持久化
- Redis启动和停止
- Redis命令返回值
- 多数据库
- Redis五种基本数据类型命令
- Redis事务
- Redis过期时间
- Redis持久化
- Redis复制
Redis官方文档
Redis英文官网文档:https://redis.io/
因为英文文档访问有点慢,所以这里在写个中文文档。
Redis中文文档:http://www.redis.cn/
Redis下载
Linux版本下载
Redis版本中Linux下载,这里给的是英文官方文档的地址链接:
https://redis.io/download
这里下载稳定版6.0.10
Windows版本下载
Redis中的Windows版本下载要在github上面去下载。
链接地址:https://github.com/MicrosoftArchive/redis/releases
最新的是3.2.100版本是开发版,推荐下载3.0.504稳定版本。
Redis存储结构
Redis是REmote DIctionary Server(远程字典服务器)的缩写,它是由C语言进行开发的,它以字典结构(key-vlaue形式)存储数据,并允许其他应用通过TCP协议读写字典中的内容。Redis支持的基础键值数据类型如下:字符串类型、散列类型(hash类型)、列表类型(list类型)、集合类型(set类型)、有序集合类型(zset类型)。
Redis内存存储与持久化
Redis数据库中的所有数据都存储在内存中。由于内存的读写速度远快于硬盘,因此 Redis在性能上对比其他基于硬盘存储的数据库有非常明显的优势,在一台普通的笔记本电 脑上,Redis可以在一秒内读写超过10万个键值。
将数据存储在内存中也有问题,比如程序退出后内存中的数据会丢失。不过Redis提供 了对持久化的支持,即可以将内存中的数据异步写入到硬盘中,同时不影响继续提供服务。
Redis启动和停止
Redis可执行文件说明
Redis-server服务端启动
1.直接鼠标双击启动redis-server.exe,默认是以6379端口启动的,Windows的Redis启动服务默认加载的配置文件是redis.windows-service.conf。
2.用cmd方式启动
在windows电脑中输入Ctrl+R然后输入cmd打开窗口命令,这里以win10为例。如下先进入自己安装好的redis文件夹,然后输入redis-server.exe redis.windows.conf命令启动即可,这里启动后是使用的redis.windows.conf配置文件,不是用的默认配置文件redis.windows-service.conf。
Redis-cli客户端启动
1.直接鼠标双击启动redis-cli.exe,默认是只能连接6379端口。
2.用cmd命令连接
进入自己的redis安装文件里面,输入redis-cli.exe -p 6379 即可启动。
-h 是指定服务端地址,默认是本地,如果服务端在本地可不写。
-a 如果redis有配置密码,那么就需要加上该参数,没有配置可不写。
-p 是指定连接的端口号,如果服务端端口修改为6380了,那么就需要去指定端口号来启动。
–raw 是防止查询出来的中文乱码,如果不加该参数,查询出来的中文会乱码。
注意:如果出现输入中文是乱码的话,可以先退出redis再使用CHCP 65001将cmd默认的gbk改为utf-8编码,我试过了一次,不过在redis-cli输入中文的时候直接闪退了。是可以输入中文的,不知道是不是我系统win10的问题。
Redis-cli服务端停止
考虑到Redis有可能正在将内存中的数据同步到硬盘中,强行终止Redis进程可能会 导致数据丢失。正确停止Redis的方式应该是向Redis发送SHUTDOWN命令,然后在输入exit退出。
因为我有在redis.windows.conf配置文件配置连接密码,所以在操作redis数据库前,要先认证密码,不然就会报:(error) NOAUTH Authentication required。
requirepass后面的123abc就是连接密码。
如果上面忘记使用-a参数验证密码,可以使用auth命令来认证密码,auth+空格+密码即可。
客户端输入shutdown命令结束后,看到服务端很明显停止运行了。
Redis命令返回值
在大多数情况下,执行一条命令后我们往往会关心命令的返回值,命令的返回值有5种类型, 对于每种类型redis-cli的展现结果都不同,下面分别说明。
状态回复
状态回复(status reply)是最简单的一种回复,比如向Redis发送SET命令设置某个 键的值时,Redis会回复状态0K表示设置成功。另外之前演示的对PING命令的回复PONG 也是状态回复。状态回复直接显示状态信息,如:
错误回复
当出现命令不存在或命令格式有错误等情况时Redis会返回错误回复(error reply)。 错误回复以(error)开头,并在后面跟上错误信息。如执行一个不存在的命令:
在2.6版本时,错误信息均是以“ERR”开头,而在2.8版以后,部分错误信息会以具体的错误类型开头,如:
整数回复
Redis虽然没有整数类型,但是却提供了一些用于整数操作的命令,如递增键值的 INCR命令会以整数,形式返回递增后的键值。除此之外,一些其他命令也会返回整数,如 可以获取当前数据库中键的数量的DBSIZE命令等。整数回复(integer reply)以(integer) 开头,并在后面跟上整数数据:
字符串回复
字符串回复(bulkreply)是最常见的一种回复类型,当请求一个字符串类型键的键值 或一个其他类型键中的某个元素时就会得到一个字符串回复。字符串回复以双引号包裹:
特殊情况是当请求的键值不存在时会得到一个空结果,显示为(nil)。如:
多行字符串回复
多行字符串回复(multi-bulk reply)同样很常见,如当请求一个非字符串类型键的元 素列表时就会收到多行字符串回复。多行字符串回复中的每行字符串都以一个序号开头,如:
keys * 命令也可以理解为查找当前数据库中所有的键(key)值。
多数据库
Redis是一个字典结构的存储服务器,而实际上一个Redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存储在哪个字典中。这与我们熟知的在一个关系数据库实例中可以创建多个数据库类似,所以可以将其中的每个字典都理解成一 个独立的数据库。
每个数据库对外都是以一个从0开始的递增数字命名,Redis默认支持16个数据库, 可以通过配置参数databases来修改这一数字。客户端与Redis建立连接后会自动选择0号数据库,不过可以随时使用SELECT命令更换数据库,如要选择1号数据库:
这就是为什么当我们使用Redis Desktop Manager工具连redis服务时会出现16个数据库的原因。
可以看到,Redis的数据库都以db+编号的方式命名,这是因为Redis不支持自定义数据库名。开发者则需要自己记录存储的数据与数据库之间的对应关系。此外,Redis不支持为每个数据库设置不同的访问密码,即客户端要么可以访问全部的数据库,要么所有的数据库都不能被访问。
最重要的一点是多个数据库之间并不是完全隔离的,比如FLUSHALL命令可以清空一个Redis实例中所有数据库中的数据。 综上所述,这些数据库更像是一种命名空间,而不适宜存储不同应用程序的数据。比如可以使用0号数据库存储某个应用生产环境中的数据,使用1号数据库存储测试环境中的数 据,但不适宜使用0号数据库存储A应用的数据而使用1号数据库存储B应用的数据,不同的应用应该使用不同的Redis实例存储数据。由于Redis非常轻量级,一个空Redis实例 占用的内存只有1MB左右,所以不用担心多个Redis实例会额外占用很多内存。
Redis五种基本数据类型命令
字符串(string)类型介绍
字符串类型是Redis中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据。你可以用其存储用户的邮箱、JSON化的对象甚至是一张图片。一个字符串类型键允许存储的数据的最大容量是512MB。
字符串(string)类型命令
使用set命令创建一个字符串键值对
set 是命令,name 是(key)键,哈哈是name键对应的value值。这里输入中文乱码了。后面就不展示中文了。
使用get命令得到key键对应的值
使用keys *命令查询当前数据库中所有的键(key)值
注意:KEYS命令需要遍历Redis中的所有键,当键的数量较多时会影响性能,不建议 在生产环境中使用。
提示:Redis不区分命令大小写。
使用exists命令判断一个键是否存在
如果键存在则返回整数类型1,否则返回0。
使用del命令删除一个键
可以删除一个或多个键,返回值是删除的键的个数。
第二次执行DEL命令时因为name键己经被删除了,实际上并没有删除任何键,所以返回0。
删除多个键del命令后面接多个键,空格分开。
使用type命令获得键对应的值的数据类型
TYPE命令用来获得键值的数据类型,返回值可能是string (字符串类型)、hash (散列类型)、list (列表类型)、set (集合类型)、zset (有序集合类型)。
LPUSH命令的作用是向指定的列表类型键中增加一个元素,如果键不存在则创建它。
使用incr命令递增键对应的数字
当存储的字符串是整数形式时, Redis提供了一个实用的命令INCR,其作用是让当前键值递增(在原有的数值上加1),并返回递增后的值。如:
当要操作的键不存在时会默认键值为0,所以第一次递增后的结果是1。当键值不是整数时Redis会提示错误:
适用于场景:点赞数、收藏数、文章访问量统计等。也可用于redis数据库做id自增。
使用incrby命令递增指定的整数
让当前键值在原有的数值上加2,2是你要输入的递增值。并返回递增后的值。
使用decr命令递减键对应的数字
让当前键值递减(在原有的数值上减1),并返回递减后的值。
使用decrby命令递减指定的整数
让当前键值在原有的数值上减2,2是你要输入的递减值。并返回递减后的值。
递减的值可以为负数
使用incrbyfloat命令增加指定浮点数
没有decrbyfloat命令来减少指定浮点数
使用append命令向尾部追加值
append作用是向键值的末尾追加value。如果键不存在则将该键的值设置为value, 即相当于set key value。返回值是追加后字符串的总长度。如:
使用strlen命令获取字符串长度
使用mset命令设置多个字符串和mget获取多个值
散列(hash)类型介绍
我们现在已经知道Redis是采用字典结构以键值对的形式存储数据的,而散列类型 (hash)的键值也是一种字典结构,其存储了字段(field)和字段值的映射,但字段值只能 是字符串,不支持其他数据类型,换句话说,散列类型不能嵌套其他的数据类型。一个散 列类型键可以包含至多2的32次方-1个字段。
提示:除了散列类型,Redis的其他数据类型同样不支持数据类型嵌套。比如集合类型 的每个元素都只能是字符串,不能是另一个集合或散列表等。
散列类型适合存储对象:使用对象类别和ID构成键名,使用字段表示对象的属性, 而字段值则存储属性值。例如要存储ID为2的汽车对象,可以分别使用名为color、name 和price的3个字段来存储该辆汽车的颜色、名称和价格。
如下:
关系型数据库汽车存储结构表:
如果想为ID为1的汽车增加生产日期属性,就需要把数据表在加一个date字段,对于ID为2和3的列来说,很明显数据是冗余的,因为它们不需要这个date字段。
而Redis的散列类型则不存在这个问题。Redis并不要求每个键都依据此结构存储,我们完全可以自由地为任何键增减字段而不影响其他键。
散列(hash)类型命令
使用hset命令设置值和hget获取值
hset car name BMW的意思是设置一个car键,car键里面的name字段赋值为BMW。
HSET命令的方便之处在于不区分插入和更新操作,这意味着修改数据时不用事先判断字段是否存在来决定要执行的是插入操作(insert)还是更新操作(update)。当执行的是插入操作时(即之前字段不存在)HSET命令会返回1,当执行的是更新操作时(即之前字段已经存在)HSET命令会返回0。更进一步,当键本身不存在时,HSET命令还会自动建 立它。如更新操作返回0:
使用hmset命令设置多个值和hmget获取多个值
如果想获取键中所有字段和字段值却不知道键中有哪些字段时,应该使用HGETALL命令:
使用hexists命令判断字段是否存在
格式:hexists key field
HEXISTS命令用来判断一个字段是否存在。如果存在则返回1,否则返回0 (如果键不存在也会返回0)。
使用hsetnx命令字段不存在时赋值
格式:hsetnx key field value
HSETNX命令与HSET命令类似,区别在于如果字段己经存在,HSETNX命令将不执行任何操作。
使用hincrby命令增加数字
上面介绍了字符串类型的命令INCRBY,HINCRBY命令与之类似,可以使字段值增加指定的整数。散列类型没有HINCR命令,但是可以通过HINCRBY key field 1来实现。
如果car键不存在,HINCRBY命令会自动建立该键并默认price字段在执行命令前的值为“0”。命令的返回值是增值后的字段值。
散列类型没有hdecrby命令来减少数字。
使用hdel命令删除一个或多个字段
HDEL命令可以删除一个或多个字段,返回值是被删除的字段个数。
使用hkeys命令获得字段名和hvals命令获取字段对应值
使用hlen命令获得字段数量
返回的数字表示键里面的字段数量。
列表(list)类型介绍
- 列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素, 或者获得列表的某一个片段。
- 列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万 个元素的列表,获取头部或尾部的10条记录也是极快的(和从点有20个元素的列表中获取头部或尾部的10条记录的速度是一样的)。
- 这种特性使列表类型能非常快速地完成关系数据库难以应付的场景:如社交网站的新鲜事,我们关心的只是最新的内容,使用列表类型存储,即使新鲜事的总数达到几千 万个,获取其中最新的100条数据也是极快的。同样因为在两端插入记录的时间复杂度是 0(1),列表类型也适合用来记录日志,可以保证加入新日志的速度不会受到已有日志数量 的影响。
- 与散列类型键最多能容纳的字段数量相同,一个列表类型键最多能容纳2的32次方-1个元素。
列表(list)类型命令
使用lpush命令和rpush命令向列表两端增加元素
LPUSH命令用来向列表左边增加元素,返回值表示增加元素后列表的长度。
LPUSH会先向列表左边加入”2"(也就是向元素1的左边加),然后再加入"3”,所以此时numbers键中的数据如下:
向列表右边增加元素的话则使用RPUSH命令,其用法和LPUSH命令一样:
使用lpop命令和rpop命令向列表两端弹出元素
有进有出,LPOP命令可以从列表左边弹出一个元素。LPOP命令执行两步操作:第一步是将列表最左边的元素从列表中移除,第二步是返回被移除的元素值。例如,从numbers 列表左边弹出一个元素(也就是"3”):
同样,RPOP命令可以从列表最右边弹出一个元素:
使用llen命令获取列表中元素的个数
当键不存在时LLEN会返回0:
使用lrange命令获得列表片段
LRANGE命令是列表类型最常用的命令之一,它能够获得列表中的某一片段。LRANGE 命令将返回索引从start到stop之间的所有元素(包含两端的元素)。Redis的列表起始索引为0,0表示从元素最左边第一个开始获取。
LRANGE命令也支持负索引,表示从右边开始计算序数,如”-1”表示最右边第一个元素,”-2"表示最右边第二个元素,依次类推:
显然,LRANGE numbers 0 -1可以获取列表中的所有元素。另外一些特殊情况如下。
- 如果start的索引位置比stop的索引位置靠后,则会返回空列表。
- 如果stop大于实际的索引范围,则会返回到列表最右边的元素:
使用lrem命令删除列表中指定的值
LREM命令会删除列表中前count个值为value的元素,返回值是实际删除的元素个
数。根据count值的不同,LREM命令的执行方式会略有差异。
(1) 当count > 0时LREM命令会从列表左边开始删除前count个值为value 的元素。
(2) 当count < 0时LREM命令会从列表右边开始删除前丨count丨个值为value的 元素。
(3) 当count =0是LREM命令会删除所有值为value的元素。
从右边开始删除第一个值为"2”的元素:
使用lindex命令返回指定索引的元素
索引从0开始,0是表示从最左边第一个元素
如果index是负数则表示从右边开始计算的索引,最右边元素的索引是-1。
使用lset命令通过指定索引赋值
lset也有点类似修改。原来索引为0的值为2,现在将索引为0的值变为3了。
使用ltrim命令只保留列表指定片段
LTRIM命令可以删除指定索引范围之外的所有元素,其指定列表范围的方法和 LRANGE命令相同。就像这样:
发现索引为0的值已经删掉了,只保留了索引为1和2的值。
使用linsert命令向列表中插入元素
格式:LINSERT key BEFORE]AFTER pivot value
LINSERT命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参 数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。
LINSERT命令的返回值是插入后列表的元素个数。示例如下(向元素1后面插入元素2):
使用rpoplpush命令将元素从一个列表移到另外一个列表
格式:RPOPLPUSH source destination
RPOPLPUSH是个很有意思的命令,从名字就可以看出它的功能:先执行RPOP命令再执行LPUSH命令。RPOPLPUSH命令会先从source列表类型键的最右边弹出一个元素,然后将其加入到destination列表类型键的左边,并返回这个元素的值,整个过程是原子的。
集合(set)类型介绍
在集合中的每个元素都是不同的,且没有顺序。 一个集合类型(set)键可以存储至多2的32次方-1个字符串。
集合类型和列表类型区别:
集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,由于集 合类型在Redis内部是使用值为空的散列表(hash table)实现的,所以这些操作的时间复 杂度都是0(1)。最方便的是多个集合类型键之间还可以进行并集、交集和差集运算,稍后 就会看到灵活运用这一特性带来的便利。
集合(set)类型命令
使用sadd命令增加元素
SADD命令用来向集合中增加一个或多个元素,如果键不存在则会自动创建。因为在 一个集合中不能有相同的元素,所以如果要加入的元素已经存在于集合中就会忽略这个元 素。本命令的返回值是成功加入的元素数量(忽略的元素不计算在内)。例如:
第二条SADD命令的返回值为2是因为元素“a”已经存在,所以实际上只加入了两个元素。
使用srem命令删除元素
SREM命令用来从集合中删除一个或多个元素,并返回删除成功的个数,例如:
由于元素“d”在集合中不存在,所以只删除了一个元素,返回值为1。
使用smembers命令获取所有元素
SMEMBERS命令会返回集合中的所有元素,例如:
使用sismember命令判断元素是否在集合中
判断一个元素是否在集合中是一个时间复杂度为0(1)的操作,无论集合中有多少个元 素,SISMEMBER命令始终可以极快地返回结果。当值存在时SISMEMBER命令返回1,当 值不存在或键不存在时返回0,例如:
使用SDIFF和SINTER和SUNION进行集合间运算
1.SDIFF命令
SDIFF命令的使用方法如下:
SDIFF命令支持同时传入多个键,例如:
计算顺序是先计算setA - setB,再计算结果与setC的差集。
2.SINTER命令
SINTER命令的使用方法如下:
3.SUNION命令
SUNION命令使用方法如下:
进行集合运算并将结果存储
命令格式:SDIFFSTORE destination key [key …]
命令格式:SINTERSTORE destination key [key …]
命令格式:SUNIONSTORE destination key [key …]
- SDIFFSTORE命令和SDIFF命令功能一样,唯一的区别就是前者不会直接返回运算结 果,而是将结果存储在destination键中。
- SDIFFSTORE命令常用于需要进行多步集合运算的场景中,如需要先计算差集再将结 果和其他键计算交集。
- SINTERSTORE和SUNIONSTORE命令与之类似,不再赘述。
使用SCARD命令获取集合中的元素个数
使用SRANDMEMBER命令随机获取集合中的元素
还可以传递count参数来一次随机获得多个元素,根据count的正负不同,具体表现
也不同。
(1 )当count为正数时,SRANDMEMBER会随机从集合里获得count个不重复的元素。 如果count的值大于集合中的元素个数,则SRANDMEMBER会返回集合中的全部元素。
(2)当count为负数时,SRANDMEMBER会随机从集合里获得count个的元素,这些元素有可能相同。
使用SPOP命令从集合中弹出一个元素
有序集合(zset)类型介绍
有序集合类型(sorted set)的特点从它的名字中就可以猜到,它与上一节介绍的集合 类型的区别就是“有序”二字。
在集合类型的基础上有序集合类型为集合中的每个元素都关联了一个分数,这使得我 们不仅可以完成插入、删除和判断元素是否存在等集合类型支持的操作,还能够获得分数 最高(或最低)的前N个元素、获得指定分数范围内的元素等与分数有关的操作。虽然集 合中每个元素都是不同的,但是它们的分数却可以相同。
有序集合类型在某些方面和列表类型有些相似。
(1)二者都是有序的。
(2)二者都可以获得某一范围的元素。
但是二者有着很大的区别,这使得它们的应用场景也是不同的。
(1) 列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后, 访问中间数据的速度会较慢,所以它更加适合实现如“新鲜事”或“日志”这样很少访问 中间元素的应用。
(2) 有序集合类型是使用散列表和跳跃表(Skip list)实现的,所以即使读取位于中间 部分的数据速度也很快(时间复杂度是O(log(N)))。
(3) 列表中不能简单地调整某个元素的位置,但是有序集合可以(通过更改这个元素的分数)。
(4) 有序集合要比列表类型更耗费内存。
有序集合(zset)类型命令
使用ZADD命令增加元素
命令格式:ZADD key score member [score member …]
ZADD命令用来向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则 会用新的分数替换原有的分数。ZADD命令的返回值是新加入到集合中的元素个数(不包含 之前己经存在的元素)。
分数不仅可以是整数,还支持双精度浮点数。
使用ZSCORE命令获取元素的分数
使用ZRANGE命令获得排名在某个范围的元素列表
ZRANGE命令会按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)。ZRANGE命令与LRANGE命令十分相似,如索引都是从0开始, 负数代表从后向前査找(-1表示最后一个元素)。就像这样:
如果需要同时获得元素的分数的话可以在ZRANGE命令的尾部加上WITHSCORES参 数,这时返回的数据格式就从“元素1,元素2,…,元素/T变为了 “元素1,分数1,元素 2,分数2,…,元素A7,分数/7”,例如:
如果两个元素的分数相同,Redis会按照字典顺序(即”0” < ”9" < “A” < ”Z" < “a” < ”z” 这样的顺序)来进行排列。再进一步,如果元素的值是中文怎么处理呢?答案是取决于中文的编码方式,如使用UTF-8编码:
ZREVRANGE命令和ZRANGE的唯一不同在于ZREVRANGE命令是按照元素分数从大到小的顺序给出结果的。
使用ZRANGEBYSCOR命令获得指定分数范围的元素
命令格式:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
ZRANGEBYSCORE命令参数虽然多,但是都很好理解。该命令按照元素分数从小到大的顺序返回分数在min和/nax之间(包含/nin和max)的元素:
如果希望分数范围不包含端点值,可以在分数前加上“(”符号。例如,希望返回”80分到100分的数据,可以含80分,但不包含100分,则稍微修改一下上面的命令即可:
/nin和max还支持无穷大,同ZADD命令一样,-inf和+inf分别表示负无穷和正无 穷。比如你希望得到所有分数高于80分(不包含80分)的人的名单,但你却不知道最高 分是多少(虽然有些背离现实,但是为了叙述方便,这里假设可以获得的分数是无上限的), 这时就可以用上+inf 了:
WITHSCORES参数的用法与ZRANGE命令一样,不再赘述。
limit offset count与SQL中的用法基本相同,即在获得的元素列表的基础上向后偏移 offset个元素,并且只获取前count个元素。为了便于演示,我们先向scoreboard键 中再增加些元素:
想获得分数高于60分的从第二个人开始的3个人:
使用ZINCRBY命令增加某个元素的分数
ZINCRBY命令可以增加一个元素的分数,返回值是更改后的分数。
也可以是个负数表示减分。例如:
如果指定的元素不存在,Redis在执行命令前会先建立它并将它的分数赋为0再执行操作。
使用ZCARD命令获得集合中元素的数量
使用ZCOUNT命令获得指定分数范围内的元素个数
命令格式:zcount key min max
ZCOUNT命令的min和max参数的特性与ZRANGEBYSCORE命令中的一样:
使用ZREMRANGEBYRANK命令按照排名范围删除元素
命令格式:ZREMRANGEBYRANK key start stop
ZREMRANGEBYRANK命令按照元素分数从小到大的顺序(即索引0表示最小的值)删除处在指定排名范围内的所有元素,并返回删除的元素数量。如:
使用ZREMRANGEBYSCORE命令按照分数范围删除元素
命令格式:ZREMRANGEBYSCORE key min max
ZREMRANGEBYSCORE命令会删除指定分数范围内的所有元素,参数min和max的特
性和ZRANGEBYSCORE命令中的一样。返回值是删除的元素数量。如:
使用ZRANK命令获得元素的排名
ZRANK命令会按照元素分数从小到大的顺序获得指定的元素的排名(从0开始,即分 数最小的元素排名为0)。如:
ZREVRANK命令则相反(分数最大的元素排名为0):
计算有序集合的交集
命令格式:ZINTERSTORE destination numkeys key [key …] [WEIGHTS weight [weight …] ] [AGGREGATE SUMIMINI MAX]
ZINTERSTORE命令用来计算多个有序集合的交集并将结果存储在destination键中 (同样以有序集合类型存储),返回值为destination键中的元素个数。
destination键中元素的分数是由AGGREGATE参数决定的。
(1)当AGGREGATE是SUM时(也就是默认值),destination键中元素的分数是每 个参与计算的集合中该元素分数的和。例如:
redis> ZADD sortedSets1 1 a 2 b
(integer) 2
redis> ZADD sortedSets2 10 a 20 b
(integer) 2
redis> ZINTERSTORE sortedSetsResult 2 sortedSets1 sortedSets2 (integer) 2
redis> ZRANGE sortedSetsResult 0 -1 WITHSCORES
- “a”
- “11”
- “b”
- “22”
(2)当AGGREGATE是MIN时,destination键中元素的分数是每个参与计算的集合 中该元素分数的最小值。例如:
redis> ZINTERSTORE sortedSetsResult 2 sortedSets1 sortedSets2 AGGREGATE MIN
(integer) 2
redis> ZRANGE sortedSetsResult 0 -1 WITHSCORES
- “a”
- “1”
- “b”
- “2”
(3)当AGGREGATE是MAX时,destination键中元素的分数是每个参与计算的集合 中该元素分数的最大值。例如:
redis> ZINTERSTORE sortedSetsResult 2 sortedSets1 sortedSets2 AGGREGATE MAX
(integer) 2
redis> ZRANGE sortedSetsResult 0 -1 WITHSCORES
- “a”
- “10”
- “b”
- “20”
ZINTERSTORE命令还能够通过WEIGHTS参数设置每个集合的权重,每个集合在参与 计算时元素的分数会被乘上该集合的权重。例如:
redis> ZINTERSTORE sortedSetsResult 2 sortedSetsl sortedSets2 WEIGHTS 1 0.1
(integer) 2
redis> ZRANGE sortedSetsResult 0 -1 WITHSCORES - “a”
- “2”
- “b”
- “4”
另外还有一个命令与ZINTERSTORE命令的用法一样,名为ZUNIONSTORE,它的作用 是计算集合间的并集,这里不再赘述。
Redis事务
Redis中的事务(transaction)是一组命令的集合。事务同命令一样都是Redis的最小 执行单位,一个事务中的命令要么都执行,要么都不执行。
事务的原理是先将属于一个事务的命令发送给Redis,然后再让Redis依次执行这些命 令。例如:
redis> MULTI OK
redis> SADD “user:1:following” 2 QUEUED
redis> SADD “user:2:followers” 1 QUEUED
redis> EXEC
- (integer) 1
- (integer) 1
上面的代码演示了事务的使用方式。首先使用MULTI命令告诉Redis: “下面我发给 你的命令属于同一个事务,你先不要执行,而是把它们暂时存起来。” Redis回答:“OK。”
而后我们发送了两个SADD命令来实现关注和被关注操作,可以看到Redis遵守了承 诺,没有执行这些命令,而是返回QUEUED表示这两条命令已经进入等待执行的事务队列中了。
当把所有要在同一个事务中执行的命令都发给Redis后,我们使用EXEC命令告诉 Redis将等待执行的事务队列中的所有命令(即刚才所有返回QUEUED的命令)按照发送顺 序依次执行。EXEC命令的返回值就是这些命令的返回值组成的列表,返回值顺序和命令的 顺序相同。
Redis保证一个事务中的所有命令要么都执行,要么都不执行。如果在发送EXEC命令 前客户端断线了,则Redis会清空事务队列,事务中的所有命令都不会执行。而一旦客户 端发送了 EXEC命令,所有的命令就都会被执行,即使此后客户端断线也没关系,因为Redis 中己经记录了所有要执行的命令。
除此之外,Redis的事务还能保证一个事务内的命令依次执行而不被其他命令插入。 试想客户端A需要执行几条命令,同时客户端B发送了一条命令,如果不使用事务,则客 户端B的命令可能会插入到客户端A的几条命令中执行。如果不希望发生这种情况,也可 以使用事务。
Redis过期时间
在实际的开发中经常会遇到一些有时效的数据,比如限时优惠活动、缓存或验证码等, 过了一定的时间就需要删除这些数据。在关系数据库中一般需要额外的一个字段记录到期 时间,然后定期检测删除过期数据。而在Redis中可以使用EXPIRE命令设置一个键的过 期时间,到时间后Redis会自动删除它。
EXPIRE命令的使用方法为EXPIRE key seconds,其中seconds参数表示键的过 期时间,单位是秒。
可见随着时间的不同,foo键的过期时间逐渐减少,20秒后foo键会被删除。当键不存在时TTL命令会返回-2。
那么没有为键设置过期时间(即永久存在,这是建立一个键后的默认情况)的情况下 会返回什么呢?答案是返回-1。
如果想取消键的过期时间设置(即将键恢复成永久的),则可以使用PERSIST命令。
如果过期时间被成功清除则返回1;否则返回0 (因为键不存在或键本来就是永久的):
另外还有两个相对不太常用的命令:EXPIREAT和PEXPIREAT。
PEXPIREAT命令与EXPIREAT命令的区别是前者的时间单位是毫秒。
Redis持久化
Redis的强劲性能很大程度上是由于其将所有数据都存储在了内存中,然而当Redis重 启后,所有存储在内存中的数据就会丢失。在一些情况下,我们会希望Redis在重启后能 够保证数据不丢失,例如:
(1)将Redis作为数据库使用时。
(2)将Redis作为缓存服务器,但缓存被穿透后会对性能造成较大影响,所有缓存同 时失效会导致缓存雪崩,从而使服务无法响应。
这时我们希望Redis能将数据从内存中以某种形式同步到硬盘中,使得重启后可以根 据硬盘中的记录恢复数据。这一过程就是持久化。
Redis支持两种方式的持久化,一种是RDB方式,另一种是AOF方式。前者会根据 指定的规则“定时”将内存中的数据存储在硬盘上,而后者在每次执行命令后将命令本身 记录下来。两种持久化方式可以单独使用其中一种,但更多情况下是将二者结合使用。
RDB持久化
RDB方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时Redis会自 动将内存中的所有数据生成一份副本并存储在硬盘上,这个过程即为“快照”。Redis会在 以下几种情况下对数据进行快照:
- 根据配置规则进行自动快照;
- 用户执行SAVE或BGSAVE命令;
- 执行FLUSHALL命令;
- 执行复制(replication)时。
根据配置规则进行自动快照
Redis允许用户自定义快照条件,当符合快照条件时,Redis会自动执行快照操作。进 行快照的条件可以由用户在配置文件中自定义,由两个参数构成:时间窗口M和改动的键 的个数N。每当时间M内被更改的键的个数大于N时,即符合自动快照条件。例如Redis 安装目录中包含的样例配置文件中预置的3个条件:
save 900 1
save 300 10
save 60 10000
每条快照条件占一行,并且以save参数幵头。同时可以存在多个条件,条件之间是 “或”的关系。就这个例子而言,save 900 1的意思是在15分钟(900秒)内有一个或 一个以上的键被更改则进行快照。同理,save 300 10表示在300秒内至少有10个键被 修改则进行快照。
用户执行SAVE或BGSAVE命令
除了让Redis自动进行快照外,当进行服务重启、手动迁移以及备份时我们也会需要 手动执行快照操作。Redis提供了两个命令来完成这一任务。
1.SAVE命令
当执行SAVE命令时,Redis同步地进行快照操作,在快照执行的过程中会阻塞所有来 自客户端的请求。当数据库中的数据比较多时,这一过程会导致Redis较长时间不响应, 所以要尽量避免在生产环境中使用这一命令。
2.BGSAVE 命令
需要手动执行快照时推荐使用BGSAVE命令。BGSAVE命令可以在后台异步地进行快 照操作,快照的同时服务器还可以继续响应来自客户端的请求。执行BGSAVE后Redis会 立即返回0K表示开始执行快照操作,如果想知道快照是否完成,可以通过LASTSAVE命 令获取最近一次成功执行快照的时间,返回结果是一个Unix时间戳,如:
redis> LASTSAVE
(integer) 1423537869
执行 FLUSHALL 命令
当执行FLUSHALL命令时,Redis会清除数据库中的所有数据。需要注意的是,不论 清空数据库的过程是否触发了自动快照条件,只要自动快照条件不为空,Redis就会执行一 次快照操作。例如,当定义的快照条件为当1秒内修改10 000个键时进行自动快照,而当 数据库里只有一个键时,执行FLUSHALL命令也会触发快照,即使这一过程实际上只有一 个键被修改了。
当没有定义自动快照条件时,执行FLUSHALL则不会进行快照。
执行复制时
当设置了主从模式时,Redis会在复制初始化时进行自动快照。关于主从模式和复制 的过程会在第8章详细介绍,这里只需要了解当使用复制操作时,即使没有定义自动快照 条件,并且没有手动执行过快照操作,也会生成RDB快照文件。
快照原理
Redis默认会 将快照文件存储在Redis当前进程的工作目录中的dump.rdb文件中,可以通过配置dir和 dbfilename两个参数分别指定快照文件的存储路径和文件名。快照的过程如下。
(1)Redis使用fork函数复制一份当前进程(父进程)的副本(子进程);
(2)父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入硬 盘中的临时文件;
(3)当子进程写入完所有数据后会用该临时文件替换旧的RDB文件,至此一次快照 操作完成。
Redis在进行快照的过程中不会修改RDB文件,只有快照结束 后才会将旧的文件替换成新的,也就是说任何时候RDB文件都是完整的。这使得我们可 以通过定时备份RDB文件来实现Redis数据库备份。RDB文件是经过压缩(可以配置 rdbcompression参数以禁用压缩节省CPU占用)的二进制格式,所以占用的空间会小于 内存中的数据大小,更加利于传输。
Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。根据数据量大小与结 构和服务器性能不同,这个时间也不同。通常将一个记录1000万个字符串类型键、大小为 1 GB的快照文件载入到内存中需要花费20?30秒。
通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将 可能发生的数据损失控制在能够接受的范围。例如,使用Redis存储缓存数据时,丢失最近几秒的数据或者丢失最近更新的几十个键并不会有很大的影响。如果数据相对重要,希望将损失降到最小,则可以使用AOF方式进行持久化。
AOF持久化
当使用Redis存储非临时数据时,一般需要打开AOF持久化来降低进程中止导致的数 据丢失。AOF可以将Redis执行的每一条写命令追加到硬盘文件中,这一过程显然会降低 Redis的性能,但是大部分情况下这个影响是可以接受的,另外使用较快的硬盘可以提髙 AOF的性能。
开启AOF
默认情况下Redis没有开启AOF(append only file)方式的持久化,可以通过appendonly参数启用:appendonly yes
开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写 入硬盘中的AOF文件。A0F文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof,可以通过appendfilename参数修改:appendfilename appendonly.aof
AOF的实现
AOF文件以纯文本的形式记录了 Redis执行的写命令,例如在开启AOF持久化的情 况下执行了如下4个命令:
SET foo 1
SET foo 2
SET foo 3
GET foo
Redis会将前3条命令写入AOF文件中,此时AOF文件中的内容如下:
*2
$6
SELECT
$1
0
*3
$3
set
$3
foo
$1
1
*3
$3
set
$3
foo
$1
2
*3
$3
set
$3
foo
$1
3
可见A0F文件的内容正是Redis客户端向Redis发送的原始通信协议的内容,从中 可见Redis确实只记录了前3条命令。然而这时有一个问题是前2条命令其实都是冗余的, 因为这两条的执行结果会被第三条命令覆盖。随着执行的命令越来越多,AOF文件的大小也会越来越大,即使内存中实际的数据可能并没有多少。很自然地,我们希望Redis可以自动优化AOF文件,就上例而言,就是将前两条无用的记录删除,只保留第三条。实际上 Redis也正是这样做的,每当达到一定条件时Redis就会自动重写AOF文件,这个条件可以在配置文件中设置:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage参数的意义是当目前的AOF文件大小超过上一次重写时的AOF文件大小的百分之多少时会再次进行重写,如果之前没有重写过,则以启动时的AOF文件大小为依据。
auto-aof-rewrite-min-size参数限制了允许重写的最小 AOF文件大小,通常在AOF文件很小的情况下即使其中有很多冗余的命令我们也并不太 关心除了让Redis自动执行重写外 我们还可以主动使用BGREWRITEAOF命令手动执行AOF 重写。
上例中的AOF文件重写后的内容为:
*2
$6
SELECT
$1
0
*3
$3
SET
$3
foo
$1
3
可见冗余的命令己经被删除了。重写的过程只和内存中的数据有关,和之前的AOF文件无关,这与RDB很相似,只不过二者的文件格式完全不同。
在启动时Redis会逐个执行AOF文件中的命令来将硬盘中的数据载入到内存中,载入 的速度相较RDB会慢一些。
同步硬盘数据
虽然每次执行更改数据库内容的操作时,AOF都会将命令记录在AOF文件中,但是事实上,由于操作系统的缓存机制,数据并没有真正地写入硬盘,而是进入了系统的硬盘 缓存。在默认情况下系统每30秒会执行一次同步操作,以便将硬盘缓存中的内容真正地写 入硬盘,在这30秒的过程中如果系统异常退出则会导致硬盘缓存中的数据丢失。一般来讲 启用AOF持久化的应用都无法容忍这样的损失,这就需要Redis在写入AOF文件后主动 要求系统将缓存内容同步到硬盘中。在Redis中我们可以通过appendfsync参数设置同步的时机:
#appendfsync always
#appendfsync everysec
#appendfsync no
默认情况下Redis采用everysec规则,即每秒执行一次同步操作。always表示每次执行写入都会执行同步,这是最安全也是最慢的方式。no表示不主动进行同步操作,而是完全交由操作系统来做(即每30秒一次),这是最快但最不安全的方式。一般情况下使用默认值everysec就足够了,既兼顾了性能又保证了安全。
Redis允许同时开启AOF和RDB,既保证了数据安全又使得进行备份等操作十分容 易。此时重新启动Redis后Redis会使用AOF文件来恢复数据,因为AOF方式的持久化 可能丢失的数据更少。
Redis复制
通过持久化功能,Redis保证了即使在服务器重启的情况下也不会损失(或少量损失) 数据。但是由于数据是存储在一台服务器上的,如果这台服务器出现硬盘故障等问题,也 会导致数据丢失。为了避免单点故障,通常的做法是将数据库复制多个副本以部署在不同 的服务器上,这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务。为此, Redis提供了复制(replication)功能,可以实现当一台数据库中的数据更新后,自动将更 新的数据同步到其他数据库上。
配置
在复制的概念中,数据库分为两类,一类是主数据库(master),另一类是从数据库® (slave)。主数据库可以进行读写操作,当写操作导致数据变化时会自动将数据同步给从数 据库。而从数据库一般是只读的,并接受主数据库同步过来的数据。一个主数据库可以拥 有多个从数据库,而一个从数据库只能拥有一个主数据库,如图8-1所示。
在Redis中使用复制功能非常容易,只需要在从数据库的配置文件中加入“slaveof 主数据库地址主数据库端口”即可,主数据库无需进行任何配置。
这里redis主从复制具体怎么操作就不具体说了,可以百度redis主从复制来学习具体操作。
原理
当一个从数据库启动后,会向主数据库发送SYNC命令。同时主数据库接收到SYNC 命令后会开始在后台保存快照(即RDB持久化的过程),并将保存快照期间接收到的命令缓存 起来。当快照完成后,Redis会将快照文件和所有缓存的命令发送给从数据库。从数据库收到后,会载入快照文件并执行收到的缓存的命令。以上过程称为复制初始化。复制初始化结束后,主数据库每当收到写命令时就会将命令同步给从数据库,从而保证主从数据库数据一致。
当主从数据库之间的连接断开重连后,Redis 2.6以及之前的版本会重新进行复制初始化(即主数据库重新保存快照并传送给从数据库),即使从数据库可以仅有几条命令没有收到,主数据库也必须要将数据库里的所有数据重新传送给从数据库。这使得主从数据库断线重连后的数据恢复过程效率很低下,在网络环境不好的时候这一问题尤其明显。Redis 2.8 版的一个重要改进就是断线重连能够支持有条件的增量数据传输,当从数据库重新连接上主数据库后,主数据库只需要将断线期间执行的命令传送给从数据库,从而大大提高Redis 复制的实用性。
乐观复制
Redis采用了乐观复制(optimistic replication)的复制策略,容忍在一定时 间内主从数据库的内容是不同的,但是两者的数据会最终同步。具体来说,Redis在主 从数据库之间复制数据的过程本身是异步的,这意味着,主数据库执行完客户端请求 的命令后会立即将命令在主数据库的执行结果返回给客户端,并异步地将命令同步给 从数据库,而不会等待从数据库接收到该命令后再返回给客户端。这一特性保证了启 用复制后主数据库的性能不会受到影响,但另一方面也会产生一个主从数据库数据不 一致的时间窗口,当主数据库执行了一条写命令后,主数据库的数据已经发生的变动,然而在主数椐库将该命令传送给从数据库之前,如果两个数据库之间的网络连接断开 了,此时二者之间的数据就会是不一致的。从这个角度来看,主数据库是无法得知某 个命令最终同步给了多少个从数据库的,不过Redis提供了两个配置选项来限制只有 当数据至少同步给指定数量的从数据库时,主数据库才是可写的:
min-slaves-to-write 3 min-slaves-max-lag 10
上面的配置中,min-slaves-to-write表示只有当3个或3个以上的从数据库连接 到主数据库时,主数据库才是可写的,否则会返回错误,例如:
redis> SET foo bar
(error) NOREPLICAS Not enough good slaves to write.
min-slaves-max-lag表示允许从数据库最长失去连接的时间,如果从数据库最后与 主数据库联系(即发送REPLCONF ACK命令)的时间小于这个值,则认为从数据库还在 保持与主数据库的连接。举个例子,按上面的配置,主数据库假设与3个从数据库相连, 其中一个从数据库上一次与主数据库联系是9秒前,这时主数据库可以正常接受写入, 一旦1秒过后这台从数据库依旧没有活动,则主数据库则认为目前连接的从数据库只有2个,从而拒绝写入。这一特性默认是关闭的,在分布式系统中,打开并合理配置该选项 后可以降低主从架构中因为网络分区导致的数据不一致的问题。
读写分离与一致性
通过复制可以实现读写分离,以提高服务器的负载能力。在常见的场景中(如电子商 务网站),读的频率大于写,当单机的Redis无法应付大量的读请求时(尤其是较耗资源的 请求,如SORT命令等)可以通过复制功能建立多个从数据库节点,主数据库只进行写操 作,而从数据库负责读操作。这种一主多从的结构很适合读多写少的场景,而当单个的主 数据库不能够满足需求时,就需要使用Redis 3.0推出的集群功能。
从数据库持久化
另一个相对耗时的操作是持久化,为了提高性能,可以通过复制功能建立一个(或若 干个)从数据库,并在从数据库中启用持久化,同时在主数据库禁用持久化。当从数据库崩溃重启后主数据库会自动将数据同步过来,所以无需担心数据丢失。
然而当主数据库崩溃时,情况就稍显复杂了。手工通过从数据库数据恢复主数据库数据时,需要严格按照以下两步进行。
(1)在从数据库中使角SLAVEOF NO ONE命令将从数据库提升成主数据库继续服务。
(2)启动之前崩溃的主数据库,然后使用SLAVEOF命令将其设置成新的主数据库的从 数据库,即可将数据同步回来。
注意:当开启复制且主数据库关闭持久化功能时,一定不要使用Supervisor以及类似的进程管理工具令主数据库崩溃后自动重启。同样当主数据库所在的服务器因故关闭 时,也要避免直接重新启动。这是因为当主数据库重新启动后,因为没有开启持久化功能,所以数据库中所有数据都被清空,这时从数据库依然会从主数据库中接收数据,使得所有从数据库也被清空,导致从数据库的持久化失去意义。
无硬盘复制
上面介绍Redis复制的工作原理时介绍了复制是基于RDB方式的持久化实现的, 即主数据库端在后台保存RDB快照,从数据库端则接收并载入快照文件。这样的实现优 点是可以显著地简化逻辑,复用已有的代码,但是缺点也很明显。
(1) 当主数据库禁用RDB快照时(即删除了所有的配置文件中的save语句),如果 执行了复制初始化操作,Redis依然会生成RDB快照,所以下次启动后主数据库会以该快 照恢复数据。因为复制发生的时间不能确定,这使得恢复的数据可能是任何时间点的。
(2) 因为复制初始化时需要在硬盘中创建RDB快照文件,所以如果硬盘性能很慢(如 网络硬盘)时这一过程会对性能产生影响。举例来说,当使用Redis做缓存系统时,因为 不需要持久化,所以服务器的硬盘读写速度可能较差。但是当该缓存系统使用一主多从的 集群架构时,每次和从数据库同步,Redis都会执行一次快照,同时对硬盘进行读写,导致性能降低。
因此从2.8.18版本开始,Redis引入了无硬盘复制选项,开启该选项时,Redis在与从 数据库进行复制初始化时将不会将快照内容存储到硬盘上,而是直接通过网络发送给从数 据库,避免了硬盘的性能瓶颈。
目前无硬盘复制的功能还在试验阶段,可以在配置文件中使用如下配置来开启该功能:
repl-diskless-sync yes
增量复制
上面在介绍复制的原理时提到当主从数据库连接断开后,从数据库会发送SYNC命 令来重新进行一次完整复制操作。这样即使断开期间数据库的变化很小(甚至没有),也需 要将数据库中的所有数据重新快照并传送一次。在正常的网络应用环境中,这种实现方式 显然不太理想。Redis 2.8版相对2.6版的最重要的更新之一就是实现了主从断线重连的情 况下的增量复制。
增量复制是基于如下3点实现的。
(1)从数据库会存储主数据库的运行ID (run id)。每个Redis运行实例均会拥有一 个唯一的运行ID,每当实例重启后,就会自动生成一个新的运行ID。
(2)在复制同步阶段,主数据库每将一个命令传送给从数据库时,都会同时把该命令 存放到一个积压队列(backlog)中,并记录下当前积压队列中存放的命令的偏移量范围。
(3)同时,从数据库接收到主数据库传来的命令时,会记录下该命令的偏移量。
这3点是实现增量复制的基础。回到8.L2节的主从通信流程,可以看到,当主从连接 准备就绪后,从数据库会发送一条SYNC命令来告诉主数据库可以开始把所有数据同步过 来了。而2.8版之后,不再发送SYNC命令,取而代之的是发送PSYNC,格式为“PSYNC 主数据库的运行ID断开前最新的命令偏移量”。主数据库收到PSYNC命令后,会执行以下判断来决定此次重连是否可以执行增量复制。
(1)首先主数据库会判断从数据库传送来的运行ID是否和自己的运行ID相同。这一 步骤的意义在于确保从数据库之前确实是和自己同步的,以免从数据库拿到错误的数据(比如主数据库在断线期间重启过,会造成数据的不一致)。
(2)然后判断从数据库最后同步成功的命令偏移量是否在积压队列中,如果在则可以 执行增量复制,并将积压队列中相应的命令发送给从数据库。
如果此次重连不满足增量复制的条件,主数据库会进行一次全部同步(即与Redis 2.6 的过程相同)。
大部分情况下,增量复制的过程对幵发者来说是完全透明的,开发者不需要关心增量 复制的具体细节。2.8版本的主数据库也可以正常地和旧版本的从数据库同步(通过接收 SYNC命令),同样2.8版本的从数据库也可以与旧版本的主数据库同步(通过发送SYNC 命令)。唯一需要开发者设置的就是积压队列的大小了。
积压队列在本质上是一个固定长度的循环队列,默认情况下积压队列的大小为1 MB, 可以通过配置文件的repl-backlog-size选项来调整。很容易理解的是,积压队列越大,其允许的主从数据库断线的时间就越长。根据主从数据库之间的网络状态,设置一个合理的 积压队列很重要。因为积压队列存储的内容是命令本身,如SET foo bar,所以估算积压 队列的大小只需要估计主从数据库断线的时间中主数据库可能执行的命令的大小即可。
与积压队列相关的另一个配置选项是repl-backlog-ttl,即当所有从数据库与主数 据库断开连接后,经过多久时间可以释放积压队列的内存空间。默认时间是1小时。
好了,我的学习先到这里了。后面还有哨兵、集群等知识等以后自己对redis了解更深在学习吧!
内容总结
以上是互联网集市为您收集整理的Redis入门篇全部内容,希望文章能够帮你解决Redis入门篇所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。