redis多实例

#创建多实例目录
[root@db01 ~]# /etc/redis/{6379,6380,6381}
#编辑多实例配置文件
[root@db01 ~]# cat /etc/redis/6379/redis.conf /etc/redis/6380/redis.conf /etc/redis/6381/redis.conf

#redis 6379 配置文件
port 6379
daemonize yes
pidfile /etc/redis/6379/redis.pid
loglevel notice
logfile /etc/redis/6379/redis.log
dbfilename dump.rdb
dir /etc/redis/6379
bind 10.0.0.51
protected-mode no

#redis 6380 配置文件
port 6380
daemonize yes
pidfile /etc/redis/6380/redis.pid
loglevel notice
logfile /etc/redis/6380/redis.log
dbfilename dump.rdb
dir /etc/redis/6380
bind 10.0.0.51
protected-mode no

#redis 6381 配置文件
port 6381
daemonize yes
pidfile /etc/redis/6381/redis.pid
loglevel notice
logfile /etc/redis/6381/redis.log
dbfilename dump.rdb
dir /etc/redis/6381
bind 10.0.0.51
protected-mode no

#启动redis多实例
[root@db01 ~]# redis-server /etc/redis/6379/redis.conf
[root@db01 ~]# redis-server /etc/redis/6380/redis.conf
[root@db01 ~]# redis-server /etc/redis/6381/redis.conf

#查看进程
[root@db01 ~]# ps -ef|grep redis
root 3570 1 0 22:44 ? 00:00:00 redis-server 127.0.0.1:6379
root 3574 1 0 22:44 ? 00:00:00 redis-server 127.0.0.1:6380
root 3578 1 0 22:44 ? 00:00:00 redis-server 127.0.0.1:6381

主从复制功能

1)使用异步复制。 2)一个主服务器可以有多个从服务器。 3)从服务器也可以有自己的从服务器。 4)复制功能不会阻塞主服务器。 5)可以通过复制功能来让主服务器免于执行持久化操作,由从服务器去执行持久化操作即可。

详解

1)Redis 使用异步复制。从 Redis2.8开始,从服务器会以每秒一次的频率向主服务器报告复制流 (replication stream)的处理进度。 2)一个主服务器可以有多个从服务器。 3)不仅主服务器可以有从服务器,从服务器也可以有自己的从服务器,多个从服务器之间可以构成一 个图状结构。 4)复制功能不会阻塞主服务器:即使有一个或多个从服务器正在进行初次同步, 主服务器也可以继续 处理命令请求。 5)复制功能也不会阻塞从服务器:只要在 redis.conf 文件中进行了相应的设置, 即使从服务器正在进 行初次同步, 服务器也可以使用旧版本的数据集来处理命令查询。 6)在从服务器删除旧版本数据集并载入新版本数据集的那段时间内,连接请求会被阻塞。 7)还可以配置从服务器,让它在与主服务器之间的连接断开时,向客户端发送一个错误。 8)复制功能可以单纯地用于数据冗余(data redundancy),也可以通过让多个从服务器处理只读命 令请求来提升扩展性(scalability): 比如说,繁重的SORT命令可以交给附属节点去运行。 9)可以通过复制功能来让主服务器免于执行持久化操作:只要关闭主服务器的持久化功能,然后由从 服务器去执行持久化操作即可。

Redis主从复制_Redis多实例

关闭主服务器上的持久化数据安全如何保证

1.当配置Redis复制功能时,强烈建议打开主服务器的持久化功能。 否则的话,由于延迟等问题,部署 的服务应该要避免自动拉起。 2.为了帮助理解主服务器关闭持久化时自动拉起的危险性,参考一下以下会导致主从服务器数据全部丢 失的例子: 1)假设节点A为主服务器,并且关闭了持久化。并且节点B和节点C从节点A复制数据 2)节点A崩溃,然后由自动拉起服务重启了节点A. 由于节点A的持久化被关闭了,所以重启之后没有 任何数据 3)节点B和节点C将从节点A复制数据,但是A的数据是空的,于是就把自身保存的数据副本删除。 结论: 1)在关闭主服务器上的持久化,并同时开启自动拉起进程的情况下,即便使用Sentinel来实现Redis的 高可用性,也是非常危险的。因为主服务器可能拉起得非常快,以至于Sentinel在配置的心跳时间间隔 内没有检测到主服务器已被重启,然后还是会执行上面的数据丢失的流程。 2)无论何时,数据安全都是极其重要的,所以应该禁止主服务器关闭持久化的同时自动拉起。

主从复制原理

Redis主从复制_Redis断线重连_02

1)从服务器向主服务器发送 SYNC 命令。 2)接到 SYNC 命令的主服务器会调用BGSAVE 命令,创建一个 RDB 文件,并使用缓冲区记录接下来执 行的所有写命令。 3)当主服务器执行完 BGSAVE 命令时,它会向从服务器发送 RDB 文件,而从服务器则会接收并载入 这个文件。 4)主服务器将缓冲区储存的所有写命令发送给从服务器执行。

Redis主从复制_Redis多实例_03

在主从服务器完成同步之后,主服务器每执行一个写命令,它都会将被执行的写命令发送给从服务器 执行,这个操作被称为“命令传播”(command propagate)。

Redis主从复制_Redis断线重连_04

命令传播是一个持续的过程:只要复制仍在继续,命令传播就会一直进行,使得主从服务器的状态可以一直保持一致。

Redis的断线重连

从库宕机后,重新连接主库时,如何保证数据集的完整性?

SYNC

Redis主从复制_主从复制_05

1)在 Redis2.8版本之前,断线之后重连的从服务器总要执行一次完整重同步(fullresynchronization) 操作。 2)从 Redis2.8开始,Redis使用PSYNC命令代替SYNC命令。 3)PSYNC比起SYNC的最大改进在于PSYNC实现了部分重同步(partial resync)特性: 在主从服务器断线并且重新连接的时候,只要条件允许,PSYNC可以让主服务器只向从服务器同步断 线期间缺失的数据,而不用重新向从服务器同步整个数据库。 注: PSYNC这个特性需要主服务器为被发送的复制流创建一个内存缓冲区(in-memory backlog), 并且 主服务器和所有从服务器之间都记录一个复制偏移量(replication offset)和一个主服务器 ID(master run id),当出现网络连接断开时,从服务器会重新连接,并且向主服务器请求继续执行原来的复制进 程: 1)如果从服务器记录的主服务器ID和当前要连接的主服务器的ID相同,并且从服务器记录的偏移量所 指定的数据仍然保存在主服务器的复制流缓冲区里面,那么主服务器会向从服务器发送断线时缺失的 那部分数据,然后复制工作可以继续执行。 2)否则的话,从服务器就要执行完整重同步操作。 如果我们仔细地观察整个断线并重连的过程,就会发现: 从服务器在断线之前已经拥有主服务器的绝大部分数据,要让主从服务器重新回到一致状态,从服务 器真正需要的是 k10087、k10088和k10089这三个键的数据,而不是主服务器整个数据库的数据。 SYNC 命令在处理断线并重连时的做法——将主服务器的整个数据库重新同步给从服务器,是极度浪费 的!

PSYNC

Redis主从复制_Redis多实例_06

1)PSYNC只会将从服务器断线期间缺失的数据发送给从服务器。两个例子的情况是相同的,但SYNC 需要发送包含整个数据库的 RDB 文件,而PSYNC 只需要发送三个命令。 2)如果主从服务器所处的网络环境并不那么好的话(经常断线),那么请尽量使用 Redis 2.8 或以上 版本:通过使用 PSYNC 而不是 SYNC 来处理断线重连接,可以避免因为重复创建和传输 RDB文件而浪 费大量的网络资源、计算资源和内存资源。

主从复制数据一致性问题

Redis主从复制_Redis断线重连_07

1)在读写分离环境下,客户端向主服务器发送写命令 SET k10086 v10086,主服务器在执行这个写命 令之后,向客户端返回回复,并将这个写命令传播给从服务器。 2)接到回复的客户端继续向从服务器发送读命令 GET k10086 ,并且因为网络状态的原因,客户端的 GET命令比主服务器传播的 SET 命令更快到达了从服务器。 3)因为从服务器键k10086的值还未被更新,所以客户端在从服务器读取到的将是一个错误(过期)的 k10086值。

如何保证数据的安全性

1)主服务器只在有至少N个从服务器的情况下,才执行写操作 2)从Redis 2.8开始,为了保证数据的安全性,可以通过配置,让主服务器只在有至少N个当前已连接 从服务器的情况下,才执行写命令。 3)不过,因为 Redis 使用异步复制,所以主服务器发送的写数据并不一定会被从服务器接收到,因 此, 数据丢失的可能性仍然是存在的。 4)通过以下两个参数保证数据的安全:

#执行写操作所需的至少从服务器数量
min-slaves-to-write <number of slaves>
#指定网络延迟的最大值
min-slaves-max-lag <number of seconds>
min-slaves-to-write 1
min-slaves-max-lag 30

这个特性的运作原理: 1)从服务器以每秒一次的频率 PING 主服务器一次, 并报告复制流的处理情况。主服务器会记录各个 从服务器最后一次向它发送 PING 的时间。用户可以通过配置, 指定网络延迟的最大值 min-slavesmax-lag , 以及执行写操作所需的至少从服务器数量 min-slaves-to-write 。 2)如果至少有 min-slaves-to-write 个从服务器, 并且这些服务器的延迟值都少于 min-slaves-maxlag 秒, 那么主服务器就会执行客户端请求的写操作。你可以将这个特性看作 CAP 理论中的 C 的条件 放宽版本: 尽管不能保证写操作的持久性, 但起码丢失数据的窗口会被严格限制在指定的秒数中。 3)另一方面, 如果条件达不到 min-slaves-to-write 和 min-slaves-max-lag 所指定的条件, 那么写操 作就不会被执行, 主服务器会向请求执行写操作的客户端返回一个错误。

主从切换(手动)

当主库宕机了,主从是如何切换的?

[root@db01 6380]# systemctl stop redis
127.0.0.1:6380> slaveof no one
OK
127.0.0.1:6380> slaveof 172.16.1.51 6380
OK
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:172.16.1.51
master_port:6380
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_read_repl_offset:7462
slave_repl_offset:7462
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:95c2a415d0200ced2e2029a7afe37adad7676f75
master_replid2:b452962e762b8c18ec4b893feee86434eba2b12a
master_repl_offset:7462
second_repl_offset:7463
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2969
repl_backlog_histlen:4494