一、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 # slaveofslaveof 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级联级复制!
不足之处,请多多指出!