Redis(三):Redis replication/主从架构和读写分离原理

目录

写在前面

1、图解redis replication基本原理

2、redis replication的核心机制

3、master持久化对于主从架构的安全保障的意义

3.1、master必须持久化

3.2、master备份

4、主从架构的核心原理

5、主从复制的断点续传

6、无磁盘化复制

7、过期key处理

8、复制的完整流程

9、数据同步相关的核心机制

10、全量复制

11、增量复制

12、heartbeat

13、异步复制

14、redis读写分离架构

14.1、启用复制,部署slave node

14.2、强制读写分离

14.3、集群安全认证

14.4、读写分离架构的测试

15、公司集群配置


写在前面

1、图解redis replication基本原理

2、redis replication的核心机制

3、master持久化对于主从架构的安全保障的意义

redis replication -> 主从架构 -> 读写分离 -> 水平扩容支撑读高并发

1、图解redis replication基本原理

Redis(三):Redis replication/主从架构和读写分离原理_第1张图片

2、redis replication的核心机制

  • redis采用异步方式复制数据到slave节点,不过redis 2.8开始,slave node会周期性地确认自己每次复制的数据量。 
  • 一个master node是可以配置多个slave node的。
  • slave node也可以连接其他的slave node。
  • slave node做复制的时候,是不会block master node的正常工作的。
  • slave node在做复制的时候,也不会block对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了。
  • slave node主要用来进行横向扩容,做读写分离,扩容的slave node可以提高读的吞吐量
  • slave与高可用性,有很大的关系。

3、master持久化对于主从架构的安全保障的意义

3.1、master必须持久化

如果采用了主从架构,那么建议必须开启master node的持久化

不建议用slave node作为master node的数据热备,因为那样的话,如果你关掉master的持久化,可能在master宕机重启的时候数据是空的,然后可能一经过复制,salve node数据也丢了。

过程分析:master -> RDB和AOF都关闭了 -> 全部在内存中。当master宕机重启,是没有本地数据可以恢复的,然后就会直接认为自己的数据是空的,然后master就会将空的数据集同步到slave上去,所有slave的数据全部清空。100%的数据丢失。

3.2、master备份

        master的各种备份方案,要不要做,万一说本地的所有文件丢失了; 从备份中挑选一份rdb去恢复master; 这样才能确保master启动的时候,是有数据的。即使采用了后续讲解的高可用机制,slave node可以自动接管master node,但是也可能sentinal还没有检测到master failure,master node就自动重启了,还是可能导致上面的所有slave node数据清空故障。

4、主从架构的核心原理

Redis(三):Redis replication/主从架构和读写分离原理_第2张图片

        客户端发送请求给master,master写成功后返回ok。然后master异步给slave。  

        当启动一个slave node的时候,它会发送一个PSYNC命令给master node,如果这是slave node重新连接master node,那么master node仅仅会复制给slave部分缺少的数据; 否则如果是slave node第一次连接master node,那么会触发一次full resynchronization。

        开始full resynchronization的时候,master会启动一个后台线程,开始生成一份内存全量RDB快照文件,同时还会将从客户端收到的所有写命令缓存在内存中。RDB文件生成完毕之后,master会将这个RDB发送给slave,slave会先写入本地磁盘,然后再从本地磁盘加载到内存中。然后master会将内存中缓存的写命令发送给slave,slave也会同步这些数据。

        slave node如果跟master node有网络故障,断开了连接,会自动重连。master如果发现有多个slave node都来重新连接,仅仅会启动一个rdb save操作,用一份数据服务所有slave node。

5、主从复制的断点续传

        从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份。

        master node会在内存中创建一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制。但是如果没有找到对应的offset,那么就会执行一次resynchronization。

6、无磁盘化复制

master在内存中直接创建rdb,然后发送给slave,master不会将rdb在自己本地落地磁盘了

repl-diskless-sync no

repl-diskless-sync-delay 5,等待一定时长再开始复制,因为要等更多slave重新连接过来

7、过期key处理

slave不会过期key,只会等待master过期key。如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给slave。

8、复制的完整流程

Redis(三):Redis replication/主从架构和读写分离原理_第3张图片

  1. slave node启动,仅仅保存master node的信息,包括master node的host和ip,但是复制流程没开始。master host和ip是从哪儿来的,redis.conf里面的slaveof配置的。
  2. slave node内部有个定时任务,每秒检查是否有新的master node要连接和复制,如果发现,就跟master node建立socket网络连接。
  3. slave node发送ping命令给master node。
  4. 口令认证,如果master设置了requirepass,那么salve node必须发送masterauth的口令过去进行认证。
  5. master node第一次执行全量复制,将所有数据同步发给slave node。
  6. master node后续持续将写命令,异步复制给slave node

9、数据同步相关的核心机制

数据同步:第一次slave连接msater的时候,执行的全量复制,那个过程里面你的一些细节的机制

(1)master和slave都会维护一个offset

master会在自身不断累加offset,slave也会在自身不断累加offset,slave每秒都会上报自己的offset给master,同时master也会保存每个slave的offset,这个倒不是说特定就用在全量复制的,主要是master和slave都要知道各自的数据的offset,才能知道互相之间的数据不一致的情况

(2)backlog

master node有一个backlog,默认是1MB大小。master node给slave node复制数据时,也会将数据在backlog中同步写一份。backlog主要是用来做全量复制中断后的增量复制的。

(3)master run_id

Redis(三):Redis replication/主从架构和读写分离原理_第4张图片

 在info server文件里可以看到master run id,即run_id:cdon4535onoi4n5n3o63j6j3jt。

        根据host+ip定位master node是不靠谱的,如果master node重启或者数据出现了变化,那么slave node应该根据不同的run id区分,run id不同就做全量复制。如果需要不更改run id重启redis,可以使用redis-cli debug reload命令。

        开始master同步给slave100w条数据,然后master发现20w数据错误,则master从备份中取出一份备份数据到master中,此时master中数据变了而且run_id也变了。则slave发现run_id变了就触发全量复制,因为offset和master不一致了。

(4)psync

从节点使用psync从master node进行复制,psync runid offset

master node会根据自身的情况返回响应信息,可能是fullresync runid offset触发全量复制,可能是continue触发增量复制。

10、全量复制

  1. master执行bgsave,在本地生成一份rdb快照文件
  2. master node将rdb快照文件发送给salve node,如果rdb复制时间超过60秒(repl-timeout),那么slave node就会认为复制失败,可以适当调节大这个参数。
  3. 对于千兆网卡的机器,一般每秒传输100MB,6G文件,很可能超过60s。
  4. master node在生成rdb时,会将所有新的写命令缓存在内存中,在salve node保存了rdb之后,再将新的写命令复制给salve node。
  5. client-output-buffer-limit slave 256MB 64MB 60,如果在复制期间,内存缓冲区持续消耗超过64MB,或者一次性超过256MB,那么停止复制,复制失败。
  6. slave node接收到rdb之后,清空自己的旧数据,然后重新加载rdb到自己的内存中,同时基于旧的数据版本对外提供服务。
  7. 如果slave node开启了AOF,那么会立即执行bgrewriteaof,重写AOF,rdb生成、rdb通过网络拷贝、slave旧数据的清理、slave aof rewrite,很耗费时间。如果复制的数据量在4G~6G之间,那么很可能全量复制时间消耗到1分半到2分钟

11、增量复制

  1. 如果全量复制过程中,master-slave网络连接断掉,那么salve重新连接master时,会触发增量复制
  2. master直接从自己的backlog中获取部分丢失的数据,发送给slave node,默认backlog就是1MB
  3. msater就是根据slave发送的psync中的offset来从backlog中获取数据的。

12、heartbeat

主从节点互相都会发送heartbeat信息。

master默认每隔10秒发送一次heartbeat,salve node每隔1秒发送一个heartbeat

13、异步复制

master每次接收到写命令之后,现在内部写入数据,然后异步发送给slave node

14、redis读写分离架构

一主一从,往主节点去写,在从节点去读,可以读到,主从架构就搭建成功。

14.1、启用复制,部署slave node

wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz

tar -xzvf tcl8.6.1-src.tar.gz

cd  /usr/local/tcl8.6.1/unix/

./configure  

make && make install

使用redis-3.2.8.tar.gz(截止2017年4月的最新稳定版)

tar -zxvf redis-3.2.8.tar.gz

cd redis-3.2.8

make && make test && make install

(1)redis utils目录下,有个redis_init_script脚本

(2)将redis_init_script脚本拷贝到linux的/etc/init.d目录中,将redis_init_script重命名为redis_6379,6379是我们希望这个redis实例监听的端口号

(3)修改redis_6379脚本的第6行的REDISPORT,设置为相同的端口号(默认就是6379)

(4)创建两个目录:/etc/redis(存放redis的配置文件),/var/redis/6379(存放redis的持久化文件)

(5)修改redis配置文件(默认在根目录下,redis.conf),拷贝到/etc/redis目录中,修改名称为6379.conf

(6)修改redis.conf中的部分配置为生产环境

daemonize yes 让redis以daemon进程运行

pidfile /var/run/redis_6379.pid 设置redis的pid文件位置

port 6379 设置redis的监听端口号

dir /var/redis/6379 设置持久化文件的存储位置

(7)让redis跟随系统启动自动启动

在redis_6379脚本中,最上面,加入两行注释

# chkconfig:   2345 90 10

# description:  Redis is a persistent key-value database

chkconfig redis_6379 on

在slave node上配置:slaveof 192.168.1.1 6379,即可

也可以使用slaveof命令

14.2、强制读写分离

基于主从复制架构,实现读写分离

redis slave node只读,默认开启,slave-read-only

开启了只读的redis slave node,会拒绝所有的写操作,这样可以强制搭建成读写分离的架构。

14.3、集群安全认证

master上启用安全认证,requirepass

master连接口令,masterauth

14.4、读写分离架构的测试

先启动主节点,eshop-cache01上的redis实例

再启动从节点,eshop-cache02上的redis实例

刚才我调试了一下,redis slave node一直说没法连接到主节点的6379的端口

在搭建生产环境的集群的时候,不要忘记修改一个配置,bind

bind 127.0.0.1 -> 本地的开发调试的模式,就只能127.0.0.1本地才能访问到6379的端口

每个redis.conf中的bind 127.0.0.1 -> bind自己的ip地址

在每个节点上都: iptables -A INPUT -ptcp --dport  6379 -j ACCEPT

redis-cli -h ipaddr

info replication

在主上写(set k1 v1),在从上读(get k1)

15、公司集群配置

 1、很多公司里,给一些低配置的服务器,操作复杂度。大公司里,都是公司会提供统一的云平台,比如京东、腾讯、BAT、其他的一些、小米、美团,虚拟机,低配。搭建一些集群,专门为某个项目,搭建的专用集群,4核4G内存,比较复杂的操作,数据比较大,几万,单机做到,差不多了

redis提供的高并发,至少到上万,没问题,几万~十几万/二十万不等

QPS,自己不同公司,不同服务器,自己去测试,跟生产环境还有区别

生产环境,大量的网络请求的调用,网络本身就有开销,你的redis的吞吐量就不一定那么高

QPS的两个杀手:一个是复杂操作,lrange,挺多的; value很大,2 byte,我之前用redis做大规模的缓存。做商品详情页的cache,可能是需要把大串数据,拼接在一起,作为一个json串,大小可能都几k,几个byte。

2、水平扩容redis读节点,提升度吞吐量

就按照上一节课讲解的,再在其他服务器上搭建redis从节点,单个从节点读请QPS在5万左右,两个redis从节点,所有的读请求打到两台机器上去,承载整个集群读QPS在10万+。

16、什么是99.99%高可用?

16.1、系统不可用含义

Redis(三):Redis replication/主从架构和读写分离原理_第5张图片

16.2、架构上,高可用性,99.99%的高可用性

Redis(三):Redis replication/主从架构和读写分离原理_第6张图片

高可用:出现问题时瞬间恢复,或者过几分钟就恢复。

99.99%:系统可用的时间 / 系统故障的时间,365天,在365天 * 99.99%的时间内,你的系统都是可以哗哗对外提供服务的,那就是高可用性,99.99%

系统可用的时间 / 总的时间 = 高可用性。 

16.3、redis不可用是什么?单实例不可用?主从架构不可用?不可用的后果是什么? 

当一个slave挂掉了,不用影响可用性,因为还有其他slave在提供相同数据下的相同对外的查询服务。

redis不可用:master node死掉了即不可用。则缓存不可用,高并发高性能缓存不可用,则大量流量超过mysql最大承载能力的大并发大流量涌入mysql,导致mysql宕机。则系统不可用。

16.4、redis基于哨兵的高可用

你可能感兴趣的:(Redis,java)