Redis专题(六)——Redis高可用(复制篇)

Redis专题(六) ——Redis高可用(复制篇)

(原创内容,转载请注明来源,谢谢)

一、单台服务器

单台redis服务器,会出现单点故障,且需要承受所有的负载。另外,所有的内容都存在单个服务器上,该服务器会成为瓶颈。

使用多台服务器作为redis服务器,需要考虑集群管理,如数据一致性、增加节点、故障恢复等问题。redis对处理这些问题有一套方案。

二、复制

redis的持久化功能保证了数据的持久性,但是如果服务器故障,数据还是可能会丢失,因此需要将数据备份到其他服务器。当一台服务器内容更新,会通知其他服务器进行备份。

多台服务器使用redis时,有主数据库、从数据库的概念。通常主数据库是读写(或只有写操作),从数据库都是只读。主数据库数据的变化会通知从库,让从库进行更新。

1、命令

1)redis配置从数据库,只需要在从数据库配置文件中加入命令:slave of 主库ip 主库端口。该命令可以在开启数据库的时候使用,也可以在运行期间使用。

2)主数据库无需任何配置。

3)查看数据库的从库/主库命令:INFOreplication,该命令返回当前库的角色(master/slave),对于主库还可以看到从库的数量、每个从库的ip与端口、当前连接开启的从库数量,对于从库可以看到主库的ip和端口。

2、注意事项

如果当前数据库已经是某个数据库的从库,再输入slave of 新主库,则会断开和当前主库的连接,并成为新主库的从库,且同步新主库的数据(如果现有数据新的主库也有,会被覆盖)。

运行期间输入slaveof no one命令,使当前数据库与主库断开连接,并且自己成为主库。

3、原理

a. 复制初始化:

1)从数据库启动后,给主库发送sync命令。

2)主库接到命令后,会开始对当前数据保存快照(RDB持久化),且对保存期间客户端发送的写命令进行缓存。保存完毕后,将保存文件和缓存的写命令一起发给从数据库。

3)从数据库收到后,会还原快照,并且执行缓存命令。

复制初始化后,主数据库每当收到写命令,都会发送给从数据库。

断开连接后重连时,2.8之前的redis版本会重新进行一遍复制初始化;2.8开始的版本可以进行增量初始化,加快初始化速度。

b. 协议角度分析复制初始化:

1)从库使用命令连接主库,如果需要输入密码则还要和主库发送auth验证。

2)从库使用replconflistening-port 端口号告诉主库当前监听的端口号。

3)向主库发送sync命令开始同步。主库发送回快照文件和缓存命令,从库收到后写入硬盘的临时文件中。

4)写入完成后,从库会使用该rdb文件替换当前rdb文件。

5)在同步过程中,从库不会阻塞,可以接收客户端的命令。默认情况下,同步还没完成时,会用同步前的数据响应客户端。也可以通过配置文件slave-server-stable-data=no,强制要求同步完成后才可以提供服务,则此时同步期间收到客户端的请求会报错。

6)复制完成后,主数据库的任何写操作,从数据库都会收到异步的命令,并且去执行。

c. 乐观复制

redis采用乐观复制的策略,容忍一定时间内的数据差异,最终数据是一致的。

当主库收到写命令,会立即写完并反馈给客户端,再异步地向从数据库发送命令告知同步,因此存在差异的时间端口。可以配置从库至少连接几个时,主库才可写,通过配置文件的命令min-slaves-to-write。

4、图结构

从数据库不仅可以作为主库的从库,也可以作为其他从数据库的主库。

上图中A变化会同步给B和C,B变化会同步给D和E,但不会同步给A和C。

5、读写分离优势

正常的业务场景中,都是大量的读操作(远大于写操作),甚至带上计算(如sort)等场景,单个服务器很难应付,这是多个数据库的优势,保证主库仅进行写操作和同步数据,从库进行读操作,可以把工作量平均分配给从数据库。

6、从库持久化

持久化比较耗时,当有主从结构时,通常设置主库禁止持久化,由从库进行持久化操作。当主库奔溃时,使用以下方式进行还原:

1)将进行持久化的某台从库服务器,执行slave of no one,使其变成主库。

2)将重新恢复正常后的原主库,执行slave of 步骤1的从库,使其变成原从库的从库。

3)注意事项

主库设置关闭持久化后,一定要同时关闭自动重启功能。因为其没有持久化数据,关闭(无论正常还是异常关闭)后数据全部清空,如果此时自动重启,则所有的从库会同步数据,所有的数据都被清空。

7、无硬盘复制

使用rdb复制,简化逻辑,代码易复用,但是有以下缺点:

1)无法确定主库恢复数据的时间,因为快照的复制时间不确定。

2)复制初始化要在硬盘创建文件,如果硬盘性能差则会很慢(如网络硬盘)。

因此,redis2.8开始的版本,允许主库通过配置文件开启无硬盘复制,即对从库进行复制初始化时,直接通过网络传输给从库,而不是在主库的本地先生成rdb文件,再传输rdb。命令是repl-diskless-sync yes

8、增量复制

a. 当从库断开重连,如果要全量复制,速度较慢。从redis2.8开始,支持增量复制。增量复制如下步骤:

1)从库存储主库的运行id(run id),每个redis实例有唯一运行id,重启后id会变。

2)复制过程中,主库把命令传给从库,并把命令存到挤压队列(backlog)中,记录当前挤压队列存放命令的偏移量。

3)从库接收到主库的命令后,会记录偏移量。

4)从库准备就绪后,从redis2.8开始,不再发送sync,而是发送psync 主库运行id断开前最新偏移量。

b. 主库收到psync后,会进行以下判断确定是否进行增量复制;

1)首先判断运行id是否正确,例如主库重启过则id会是新的。如果运行id不正确,则进行全量复制。

2)判断从库最后同步成功的命令是否在挤压队列中,在的话则可以进行增量复制,否则全量复制。

c. 挤压队列:

挤压队列本质是固定长度序列,大小为1MB,挤压队列越大,则允许断开的时间越长。通过repl-backlog-size设置挤压队列大小,通过repl-backlog-ttl设置全部从库断开连接后挤压队列释放的时间。

——written by linhxx 2017.08.11

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-08-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android干货

LeanCloud数据存储相关问题

2748
来自专栏Play & Scala 技术分享

PlayScala 2.5.x - 关闭X-Forwarded-For解析

2484
来自专栏性能与架构

Redis过期key的删除策略

key的过期时间都保存在过期字典中,如果一个键过期了,那么redis什么时候会被删除呢? 删除策略 (1)惰性删除 对key进行操作时才进行过期检查,对CPU最...

3747
来自专栏北京马哥教育

CentOS 7下安装Logstash ELK Stack 日志管理系统(下)

修改防火墙,对外开放tcp/5601 [root@elk elk]# firewall-cmd --permanent --add-port=5601/tcp ...

2624
来自专栏Huramkin的归档库

解决macOS下ssh空闲一段时间自动断开的问题

使用ssh登录linux服务器后,在后台放置一段时间,会发现会自动断开或者卡死无法输入

261
来自专栏ionic3+

【技巧】Ionic3多文件上传

文件上传,我们一般需要和本地文件打交道,先安装file插件(全称cordova-plugin-file),

794
来自专栏黄长富的专栏

【腾讯云的1001种玩法】利用 Docker 快速搭建 git 仓库 Gitlab 与代码审阅 Gerrit 平台

大多数程序猿都用过全球最大的git托管平台Github,上面有丰富的开源项目。在Github上托管开源项目是免费的,但是私有项目需要收取管理费。对于拥有云服务器...

2.4K0
来自专栏Java技术

简要分析ZooKeeper基本原理及安装部署

Zookeeper官网地址: http://zookeeper.apache.org/

723
来自专栏行者悟空

Nginx 启用upstream模块后,location块中的相关参数说明

492
来自专栏python学习指南

Elasticsearch--数据索引

前言 Elasticsearch可以支持全文检索,那么ES是以什么机制来支持的,这里索引就是一个重要的步骤,经过索引之后的文档才可以被分析存储、建立倒排索引。本...

2166

扫描关注云+社区