目录
写在前面
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 -> 主从架构 -> 读写分离 -> 水平扩容支撑读高并发
如果采用了主从架构,那么建议必须开启master node的持久化!
不建议用slave node作为master node的数据热备,因为那样的话,如果你关掉master的持久化,可能在master宕机重启的时候数据是空的,然后可能一经过复制,salve node数据也丢了。
过程分析:master -> RDB和AOF都关闭了 -> 全部在内存中。当master宕机重启,是没有本地数据可以恢复的,然后就会直接认为自己的数据是空的,然后master就会将空的数据集同步到slave上去,所有slave的数据全部清空。100%的数据丢失。
master的各种备份方案,要不要做,万一说本地的所有文件丢失了; 从备份中挑选一份rdb去恢复master; 这样才能确保master启动的时候,是有数据的。即使采用了后续讲解的高可用机制,slave node可以自动接管master node,但是也可能sentinal还没有检测到master failure,master node就自动重启了,还是可能导致上面的所有slave node数据清空故障。
客户端发送请求给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。
从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份。
master node会在内存中创建一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制。但是如果没有找到对应的offset,那么就会执行一次resynchronization。
master在内存中直接创建rdb,然后发送给slave,master不会将rdb在自己本地落地磁盘了。
repl-diskless-sync no
repl-diskless-sync-delay 5,等待一定时长再开始复制,因为要等更多slave重新连接过来
slave不会过期key,只会等待master过期key。如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给slave。
数据同步:第一次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
在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触发增量复制。
主从节点互相都会发送heartbeat信息。
master默认每隔10秒发送一次heartbeat,salve node每隔1秒发送一个heartbeat
master每次接收到写命令之后,现在内部写入数据,然后异步发送给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命令
基于主从复制架构,实现读写分离
redis slave node只读,默认开启,slave-read-only
开启了只读的redis slave node,会拒绝所有的写操作,这样可以强制搭建成读写分离的架构。
master上启用安全认证,requirepass
master连接口令,masterauth
先启动主节点,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)
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万+。
高可用:出现问题时瞬间恢复,或者过几分钟就恢复。
99.99%:系统可用的时间 / 系统故障的时间,365天,在365天 * 99.99%的时间内,你的系统都是可以哗哗对外提供服务的,那就是高可用性,99.99%
系统可用的时间 / 总的时间 = 高可用性。
当一个slave挂掉了,不用影响可用性,因为还有其他slave在提供相同数据下的相同对外的查询服务。
redis不可用:master node死掉了即不可用。则缓存不可用,高并发高性能缓存不可用,则大量流量超过mysql最大承载能力的大并发大流量涌入mysql,导致mysql宕机。则系统不可用。