一、redis 主从复制安装配置

1、主从复制介绍

主从复制,当用户往Master端写入数据时,通过Redis Sync机制将数据文件发送至Slave,Slave也会执行相同的操作确保数据一致;且实现Redis的主从复制非常简单,但是redis的主从复制是异步的。

2、redis主从复制特点

同一个Master可以拥有多个Slaves。

Master下的Slave还可以接受同一架构中其它slave的链接与同步请求,实现数据的级联复制,即Master->Slave->Slave模式;

Master以非阻塞的方式同步数据至slave,这将意味着Master会继续处理一个或多个slave的读写请求;

Slave端同步数据也可以修改为非阻塞式的方式,当slave在执行新的同步时,它仍可以用旧的数据信息来提供查询;否则,当slave与master失去联系时,slave会返回一个错误给客户端;

主从复制具有可扩展性,即多个slave专门提供只读查询与数据的冗余,Master端专门提供写操作;

通过配置禁用Master数据持久化机制,将其数据持久化操作交给Slaves完成,避免在Master中要有独立的进程来完成此操作。

3、主从复制原理

当启动一个Slave进程后,它会向Master发送一个SYNC Command,请求同步连接。无论是第一次连接还是重新连接,Master都会启动一个后台进程,将数据快照保存到数据文件中,

同时Master会记录所有修改数据的命令并缓存在数据文件中。后台进程完成缓存操作后,Master就发送数据文件给Slave,Slave端将数据文件保存到硬盘上,然后将其在加载到

内存中,接着Master就会将所有修改数据的操作,将其发送给Slave端。若Slave出现故障导致宕机,恢复正常后会自动重新连接,Master收到Slave的连接后,将其完整的数据

文件发送给Slave,如果Mater同时收到多个Slave发来的同步请求,Master只会在后台启动一个进程保存数据文件,然后将其发送给所有的Slave,确保Slave正常。

4、主从架构介绍

Centos 6.6 x86_64  redis 3.0.7
master   IP:  10.0.18.145    redis port 6379
slave1   IP:  10.0.18.146    redis port 6379

配置主从之前先编译安装redis,优化内核参数,参数如下:

#vi /etc/sysctl.conf    #添加如下到文件末尾
vm.overcommit_memory = 1
net.core.somaxconn = 511
vm.swappiness = 0
net.ipv4.neigh.default.gc_stale_time=120
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.all.arp_announce=2
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 1024 
net.ipv4.tcp_synack_retries = 2
net.ipv4.conf.lo.arp_announce=2
##修改以下参数为never
#echo never > /sys/kernel/mm/transparent_hugepage/enabled
修改打开最大文件数
#vim /etc/security/limits.conf 
* soft nofile 65535
* hard nofile 65535
* soft    nproc     10240         
* hard    nproc     10240

5、开始配置主从

为master端提供redis配置文件:

#cp /root/redis-3.0.7/redis.conf /usr/local/redis/conf/
#cat redis.conf | egrep -v "^#|^$"  #注释都是修改的,其他默认,如果有其他需求可以根据情况修改
daemonize yes            #以daemon后台模式运行
pidfile "/var/run/redis.pid"
port 6379
tcp-backlog 511
bind 10.0.18.145         #绑定master的地址
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/usr/local/redis/log/redis.log"  #redis日志路径
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error no #修改为no,如果对数据要求比较高,不允许服务器出任何错误,保持默认yes。
rdbcompression yes
rdbchecksum yes
dbfilename "dump.rdb"
dir "/usr/local/redis"      #rdb文件存放目录
masterauth "abcd123"        #master验证密码
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 80           #slave优先级别,数字越小优先级别越高,当master宕机时优先选取slave,如果单纯是主从,可以不配置此项
                            #我这里配置了,是为了后面配置redisHA做准备!
requirepass "abcd123"       #redis的认证密码,如果设置进入redis必须通过密码认证才可以操作
appendonly yes              #改为yes,aof持久化,增量写disk,比aof慢,但更可靠.企业的默认选择,有的会两者均开启
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes

为slave1提供redis配置文件:

#cp /root/redis-3.0.7/redis.conf /usr/local/redis/conf/
#cat redis.conf    #slave1的配置文件参数其他都和master端的一样,只有下面几项需要修改:
bind 10.0.18.146         #绑定slave1的地址
slaveof 10.0.18.146 6379 #此选项是主从配置的关键,指向master的ip和redis端口
slave-priority 90        #slave1服务器的优先级
然后启动主从端的redis服务!
#nohup /usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf &  #在后台运行
补充:这里之所以从redis源码目录中拷贝redis.conf文件,而不直接建redis.conf并且写入参数是因为遇到了一个坑,后面会描述详情!

6、日志查看

在master上查看日志,如下:

#tail -f redis.log
……………………
10370:M 12 Oct 11:02:25.148 # Server started, Redis version 3.0.7
10370:M 12 Oct 11:02:25.148 * DB loaded from append only file: 0.000 seconds
10370:M 12 Oct 11:02:25.148 * The server is now ready to accept connections on port 6379
10370:M 12 Oct 11:02:45.243 * Slave 10.0.18.146:6379 asks for synchronization
10370:M 12 Oct 11:02:45.243 * Full resync requested by slave 10.0.18.146:6379
10370:M 12 Oct 11:02:45.243 * Starting BGSAVE for SYNC with target: disk
10370:M 12 Oct 11:02:45.244 * Background saving started by pid 10384
10384:C 12 Oct 11:02:45.254 * DB saved on disk
10384:C 12 Oct 11:02:45.255 * RDB: 0 MB of memory used by copy-on-write
10370:M 12 Oct 11:02:45.303 * Background saving terminated with success
10370:M 12 Oct 11:02:45.303 * Synchronization with slave 10.0.18.146:6379 succeeded
在slave 上查看日志,如下:
#tail -f redis.log
………………
20825:S 12 Oct 11:02:44.278 * DB loaded from append only file: 0.000 seconds
20825:S 12 Oct 11:02:44.278 * The server is now ready to accept connections on port 6379
20825:S 12 Oct 11:02:45.278 * Connecting to MASTER 10.0.18.145:6379
20825:S 12 Oct 11:02:45.278 * MASTER <-> SLAVE sync started
20825:S 12 Oct 11:02:45.279 * Non blocking connect for SYNC fired the event.
20825:S 12 Oct 11:02:45.280 * Master replied to PING, replication can continue...
20825:S 12 Oct 11:02:45.282 * Partial resynchronization not possible (no cached master)
20825:S 12 Oct 11:02:45.284 * Full resync from master: 80508d50892115ab7d158c643c6ee68cb9282c76:1
20825:S 12 Oct 11:02:45.343 * MASTER <-> SLAVE sync: receiving 46 bytes from master
20825:S 12 Oct 11:02:45.344 * MASTER <-> SLAVE sync: Flushing old data
20825:S 12 Oct 11:02:45.344 * MASTER <-> SLAVE sync: Loading DB in memory
20825:S 12 Oct 11:02:45.344 * MASTER <-> SLAVE sync: Finished with success
20825:S 12 Oct 11:02:45.345 * Background append only file rewriting started by pid 20828
20825:S 12 Oct 11:02:45.370 * AOF rewrite child asks to stop sending diffs.
20828:C 12 Oct 11:02:45.370 * Parent agreed to stop sending diffs. Finalizing AOF...
20828:C 12 Oct 11:02:45.370 * Concatenating 0.00 MB of AOF diff received from parent.
20828:C 12 Oct 11:02:45.371 * SYNC append only file rewrite performed
20828:C 12 Oct 11:02:45.371 * AOF rewrite: 0 MB of memory used by copy-on-write
20825:S 12 Oct 11:02:45.379 * Background AOF rewrite terminated with success
20825:S 12 Oct 11:02:45.379 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
20825:S 12 Oct 11:02:45.379 * Background AOF rewrite finished successfully
如果都可以正常启动,测试数据可以复制,表示主从复制就配置OK了!
注意:进入redis之后,需要认证后才能进去操作
#./redis-cli -h 10.0.18.145
10.0.18.145:6379> info
NOAUTH Authentication required.
10.0.18.145:6379> auth  abcd123    #输入密码
ok

7、查看复制信息

在master查看:

#./redis-cli -h 10.0.18.145
10.0.18.145:6379> auth abcd123
OK
10.0.18.145:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.18.146,port=6379,state=online,offset=14967,lag=0
master_repl_offset:14967
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:742

在slave查看

#./redis-cli -h 10.0.18.146
10.0.18.146:6379> auth abcd123
OK
10.0.18.146:6379> info replication
# Replication
role:slave
master_host:10.0.18.145
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:14967
slave_priority:90
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

注意:如果主从复制正常运行master_repl_offset:14967和slave_repl_offset:14967值是相同的,master_last_io_seconds_ago:的值小于等于10秒!

主从复制配置好之后,写操作是在master实现的,然后复制到slave服务器,所以是不能再slave上进行写操作的,或报错,如下:

10.0.18.146:6379> set class num1
(error) READONLY You can't write against a read only slave.

如果从服务器宕机, 将自动从主服务器的主从关系中解除;但是如果是主服务器宕机了,从服务器无法工作也不能自动切换!!!

8、主从复制的健康检查

Slave按照repl-ping-slave-period的间隔(默认10秒),向Master发送ping。

如果主从间的链接中断后,再次连接的时候,2.8以前按照full sync再同期。2.8以后,因为有backlog的设定,backlog存在master的内存里,重新连接之前,如果redis没有重启,并且offset在backlog保存的范围内,可以实现从断开地方同期,不符合这个条件,还是full sync。

用monitor命令,可以看到slave在发送ping

10.0.18.146:6379> monitor
OK
1476252338.841551 [0 10.0.18.145:6379] "PING"
1476252348.871064 [0 10.0.18.145:6379] "PING"
1476252358.896442 [0 10.0.18.145:6379] "PING"
1476252368.923831 [0 10.0.18.145:6379] "PING"
……………………

到此,主从复制配置完成,其实挺简单!

二、redis的级联复制

所谓级联级复制是master-slave1-slave2,对于slave1来说,master是主;对于slave2来说,slave1就是主,具体方式如下:

假如ip地址如下:
master  192.168.8.7
slave1  192.168.8.8
slave2  192.168.8.9
在slave1上操作
#vim  redis.conf
# slaveof 
slaveof 192.168.8.7 6379       --指定master的IP和端口
在slave2上操作
#vim  redis.conf
# slaveof 
slaveof 192.168.8.8 6379       --指定slave1的IP和端口
然后启动redis-server进程
#nohup /usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf &
以上就实现了redis级联级复制!

不足之处,请多多指出!