墨墨导读:本文在依托Redis主从环境下,针对访问的数据一致性进行分析,解开Redis复制原理的神秘面纱。 Redis作为一个非结构化的内存数据库,在某些应用场景具备相应优势,在实际的场景设计中也得到广泛的关注和使用。但是,大部分企业的Redis数据库架构为单机运行,没有设计容灾复制,这样对于Redis的容错特性没有发挥出来,而且无持久化情况下,数据存在丢失风险。 [redis@albert redis-5.0.4]$ cp redis.conf redis.conf6380 ################################# REPLICATION ################################# # Master-Replica replication. Use replicaof to make a Redis instance a copy of # another Redis server. A few things to understand ASAP about Redis replication. # # +------------------+ +---------------+ # | Master | ---> | Replica | # | (receive writes) | | (exact copy) | # +------------------+ +---------------+ # # 1) Redis replication is asynchronous, but you can configure a master to # stop accepting writes if it appears to be not connected with at least # a given number of replicas. # 2) Redis replicas are able to perform a partial resynchronization with the # master if the replication link is lost for a relatively small amount of # time. You may want to configure the replication backlog size (see the next # sections of this file) with a sensible value depending on your needs. # 3) Replication is automatic and does not need user intervention. After a # network partition replicas automatically try to reconnect to masters # and resynchronize with them. # # replicaof <masterip> <masterport> # slaveof <masterip> <masterport> slaveof 127.0.0.1 6379 [redis@albert src]$ ./redis-server redis.conf6380 18828:C 04 Aug 2019 10:52:27.743 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 18828:C 04 Aug 2019 10:52:27.744 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=18828, just started 18828:C 04 Aug 2019 10:52:27.744 # Configuration loaded _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 5.0.4 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6380 | `-._ `._ / _.-' | PID: 18828 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http:// `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 18828:S 04 Aug 2019 10:52:27.746 # Server initialized 18828:S 04 Aug 2019 10:52:27.746 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. 18828:S 04 Aug 2019 10:52:27.746 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. 18828:S 04 Aug 2019 10:52:27.746 * Ready to accept connections 18828:S 04 Aug 2019 10:52:27.746 * Connecting to MASTER 127.0.0.1:6379 18828:S 04 Aug 2019 10:52:27.746 * MASTER <-> REPLICA sync started 18828:S 04 Aug 2019 10:52:27.746 * Non blocking connect for SYNC fired the event. 18828:S 04 Aug 2019 10:52:27.746 * Master replied to PING, replication can continue... 18828:S 04 Aug 2019 10:52:27.747 * Partial resynchronization not possible (no cached master) 18828:S 04 Aug 2019 10:52:27.748 * Full resync from master: fc71b19242e8145254ba7751d346a8f4bb4c53c6:0 18828:S 04 Aug 2019 10:52:27.788 * MASTER <-> REPLICA sync: receiving 175 bytes from master 18828:S 04 Aug 2019 10:52:27.788 * MASTER <-> REPLICA sync: Flushing old data 18828:S 04 Aug 2019 10:52:27.788 * MASTER <-> REPLICA sync: Loading DB in memory 18828:S 04 Aug 2019 10:52:27.788 * MASTER <-> REPLICA sync: Finished with success 18661:M 04 Aug 2019 10:52:27.747 * Replica 127.0.0.1:6380 asks for synchronization 18661:M 04 Aug 2019 10:52:27.747 * Full resync requested by replica 127.0.0.1:6380 18661:M 04 Aug 2019 10:52:27.747 * Starting BGSAVE for SYNC with target: disk 18661:M 04 Aug 2019 10:52:27.747 * Background saving started by pid 18832 18832:C 04 Aug 2019 10:52:27.757 * DB saved on disk 18832:C 04 Aug 2019 10:52:27.757 * RDB: 4 MB of memory used by copy-on-write 18661:M 04 Aug 2019 10:52:27.788 * Background saving terminated with success 18661:M 04 Aug 2019 10:52:27.788 * Synchronization with replica 127.0.0.1:6380 succeeded [redis@albert src]$ ./redis-cli -p 6380 127.0.0.1:6380> 127.0.0.1:6380> 127.0.0.1:6380> INFO replication # Replication role:slave master_host:127.0.0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:6 master_sync_in_progress:0 slave_repl_offset:252 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:fc71b19242e8145254ba7751d346a8f4bb4c53c6 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:252 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:252 [redis@albert src]$ ./redis-cli -p 6379 127.0.0.1:6379> INFO replication # Replication role:master connected_slaves:1 slave0:ip=127.0.0.1,port=6380,state=online,offset=364,lag=0 master_replid:fc71b19242e8145254ba7751d346a8f4bb4c53c6 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:364 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:364 127.0.0.1:6379> set kebo 24 OK 127.0.0.1:6380> get kebo "24" 33570:S 26 Aug 2019 11:54:48.918 * Ready to accept connections 33570:S 26 Aug 2019 11:54:48.918 * Connecting to MASTER 127.0.0.1:6379 33570:S 26 Aug 2019 11:54:48.918 * MASTER <-> REPLICA sync started 33570:S 26 Aug 2019 11:54:48.918 * Non blocking connect for SYNC fired the event. 33570:S 26 Aug 2019 11:54:48.918 * Master replied to PING, replication can continue... 33570:S 26 Aug 2019 11:54:48.918 * Trying a partial resynchronization (request fc71b19242e8145254ba7751d346a8f4bb4c53c6:2533). 33570:S 26 Aug 2019 11:54:48.920 * Full resync from master: b9e0f41a523e078a6a88ae274f204777775ab4dc:0 33570:S 26 Aug 2019 11:54:48.920 * Discarding previously cached master state. 33570:S 26 Aug 2019 11:54:49.003 * MASTER <-> REPLICA sync: receiving 188 bytes from master 33570:S 26 Aug 2019 11:54:49.003 * MASTER <-> REPLICA sync: Flushing old data 33570:S 26 Aug 2019 11:54:49.003 * MASTER <-> REPLICA sync: Loading DB in memory 33570:S 26 Aug 2019 11:54:49.004 * MASTER <-> REPLICA sync: Finished with success 33565:M 26 Aug 2019 11:54:48.918 * Replica 127.0.0.1:6380 asks for synchronization 33565:M 26 Aug 2019 11:54:48.918 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for 'fc71b19242e8145254ba7751d346a8f4bb4c53c6', my replication IDs are '1e531f295fc2dcf986a18889e8f8c3b6e6fdc7b6' and '0000000000000000000000000000000000000000') 33565:M 26 Aug 2019 11:54:48.918 * Starting BGSAVE for SYNC with target: disk 33565:M 26 Aug 2019 11:54:48.919 * Background saving started by pid 33574 33574:C 26 Aug 2019 11:54:48.929 * DB saved on disk 33574:C 26 Aug 2019 11:54:48.929 * RDB: 4 MB of memory used by copy-on-write 33565:M 26 Aug 2019 11:54:49.002 * Background saving terminated with success 33565:M 26 Aug 2019 11:54:49.003 * Synchronization with replica 127.0.0.1:6380 succeeded [redis@albert src]$ ps -ef | grep redis redis 33565 33500 0 11:54 pts/4 00:00:01 ./redis-server *:6379 redis 33570 33476 0 11:54 pts/5 00:00:01 ./redis-server 127.0.0.1:6380 redis 33744 33688 0 12:03 pts/0 00:00:00 ./redis-server 127.0.0.1:6382 [redis@albert src]$ [redis@albert src]$ kill -9 33744 33565:M 26 Aug 2019 12:03:17.736 * Replica 127.0.0.1:6382 asks for synchronization 33565:M 26 Aug 2019 12:03:17.736 * Partial resynchronization request from 127.0.0.1:6382 accepted. Sending 714 bytes of backlog starting from offset 1. 33565:M 26 Aug 2019 12:13:43.494 # Connection with replica 127.0.0.1:6382 lost. 3)根据偏移量进行同步 33565:M 26 Aug 2019 12:14:12.019 * Replica 127.0.0.1:6382 asks for synchronization 33565:M 26 Aug 2019 12:14:12.019 * Partial resynchronization request from 127.0.0.1:6382 accepted. Sending 436 bytes of backlog starting from offset 1315. role:master connected_slaves:2 slave0:ip=127.0.0.1,port=6380,state=online,offset=3724,lag=1 slave1:ip=127.0.0.1,port=6382,state=online,offset=3724,lag=1 master_replid:b9e0f41a523e078a6a88ae274f204777775ab4dc master_replid2:0000000000000000000000000000000000000000 master_repl_offset:3724 second_repl_offset:-1 repl_backlog_active:1 role:slave master_host:127.0.0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:7 master_sync_in_progress:0 slave_repl_offset:3752 slave_priority:100 slave_read_only:1 [redis@albert src]$ cp redis.conf6380 redis.conf6382 [redis@albert src]$ ./redis-server redis.conf6382 33744:C 26 Aug 2019 12:03:17.731 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 33744:C 26 Aug 2019 12:03:17.731 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=33744, just started 33744:C 26 Aug 2019 12:03:17.731 # Configuration loaded _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 5.0.4 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6382 | `-._ `._ / _.-' | PID: 33744 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http:// `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 33744:S 26 Aug 2019 12:03:17.734 # Server initialized 33744:S 26 Aug 2019 12:03:17.734 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. 33744:S 26 Aug 2019 12:03:17.734 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. 33744:S 26 Aug 2019 12:03:17.734 * DB loaded from disk: 0.000 seconds 33744:S 26 Aug 2019 12:03:17.734 * Before turning into a replica, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer. 33744:S 26 Aug 2019 12:03:17.734 * Ready to accept connections 33744:S 26 Aug 2019 12:03:17.735 * Connecting to MASTER 127.0.0.1:6379 33744:S 26 Aug 2019 12:03:17.735 * MASTER <-> REPLICA sync started 33744:S 26 Aug 2019 12:03:17.735 * Non blocking connect for SYNC fired the event. 33744:S 26 Aug 2019 12:03:17.735 * Master replied to PING, replication can continue... 33744:S 26 Aug 2019 12:03:17.736 * Trying a partial resynchronization (request b9e0f41a523e078a6a88ae274f204777775ab4dc:1). 33744:S 26 Aug 2019 12:03:17.736 * Successful partial resynchronization with master. 33744:S 26 Aug 2019 12:03:17.736 * MASTER <-> REPLICA sync: Master accepted a Partial Resynchronization. # Replication role:master connected_slaves:2 slave0:ip=127.0.0.1,port=6380,state=online,offset=6986,lag=1 slave1:ip=127.0.0.1,port=6382,state=online,offset=6986,lag=0 127.0.0.1:6379> mset a 1 b 2 c 3 d 4 OK mget a b c d 1) "1" 2) "2" 3) "3" 4) "4" mget a b c d 1) "1" 2) "2" 3) "3" 4) "4" 127.0.0.1:6379> shutdown 33570:S 26 Aug 2019 13:23:41.429 * Connecting to MASTER 127.0.0.1:6379 33570:S 26 Aug 2019 13:23:41.429 * MASTER <-> REPLICA sync started 33570:S 26 Aug 2019 13:23:41.429 # Error condition on socket for SYNC: Connection refused 33570:S 26 Aug 2019 13:23:42.441 * Connecting to MASTER 127.0.0.1:6379 33570:S 26 Aug 2019 13:23:42.442 * MASTER <-> REPLICA sync started 33570:S 26 Aug 2019 13:23:42.442 # Error condition on socket for SYNC: Connection refused 33570:S 26 Aug 2019 13:23:43.455 * Connecting to MASTER 127.0.0.1:6379 33570:S 26 Aug 2019 13:23:43.456 * MASTER <-> REPLICA sync started 33570:S 26 Aug 2019 13:23:43.456 # Error condition on socket for SYNC: Connection refused 33570:S 26 Aug 2019 13:23:44.466 * Connecting to MASTER 127.0.0.1:6379 33570:S 26 Aug 2019 13:23:44.466 * MASTER <-> REPLICA sync started 33570:S 26 Aug 2019 13:23:44.466 # Error condition on socket for SYNC: Connection refused 33570:S 26 Aug 2019 13:23:45.470 * Connecting to MASTER 127.0.0.1:6379 33570:S 26 Aug 2019 13:23:45.471 * MASTER <-> REPLICA sync started 33570:S 26 Aug 2019 13:23:45.471 # Error condition on socket for SYNC: Connection refused 33570:S 26 Aug 2019 13:23:46.474 * Connecting to MASTER 127.0.0.1:6379 33570:S 26 Aug 2019 13:23:46.475 * MASTER <-> REPLICA sync started 33570:S 26 Aug 2019 13:23:46.475 # Error condition on socket for SYNC: Connection refused 33570:S 26 Aug 2019 13:23:47.478 * Connecting to MASTER 127.0.0.1:6379 33570:S 26 Aug 2019 13:23:47.478 * MASTER <-> REPLICA sync started 33570:S 26 Aug 2019 13:23:47.478 # Error condition on socket for SYNC: Connection refused 33570:S 26 Aug 2019 13:23:48.481 * Connecting to MASTER 127.0.0.1:6379 33570:S 26 Aug 2019 13:23:48.481 * MASTER <-> REPLICA sync started 33570:S 26 Aug 2019 13:23:48.481 # Error condition on socket for SYNC: Connection refused 33570:S 26 Aug 2019 13:23:49.485 * Connecting to MASTER 127.0.0.1:6379 33570:S 26 Aug 2019 13:23:49.485 * MASTER <-> REPLICA sync started 33570:S 26 Aug 2019 13:23:49.485 # Error condition on socket for SYNC: Connection refused 33570:S 26 Aug 2019 13:23:50.488 * Connecting to MASTER 127.0.0.1:6379 从库开始检测主库的连接,发送sync请求 34781:M 26 Aug 2019 13:24:05.899 * DB loaded from disk: 0.000 seconds 34781:M 26 Aug 2019 13:24:05.899 * Ready to accept connections 34781:M 26 Aug 2019 13:24:06.544 * Replica 127.0.0.1:6380 asks for synchronization 34781:M 26 Aug 2019 13:24:06.544 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for 'b9e0f41a523e078a6a88ae274f204777775ab4dc', my replication IDs are 'aac4a31754592820422c3ba7c8244f31c39f067f' and '0000000000000000000000000000000000000000') 34781:M 26 Aug 2019 13:24:06.544 * Starting BGSAVE for SYNC with target: disk 34781:M 26 Aug 2019 13:24:06.545 * Background saving started by pid 34785 34785:C 26 Aug 2019 13:24:06.555 * DB saved on disk 34785:C 26 Aug 2019 13:24:06.555 * RDB: 4 MB of memory used by copy-on-write 34781:M 26 Aug 2019 13:24:06.601 * Background saving terminated with success 34781:M 26 Aug 2019 13:24:06.602 * Synchronization with replica 127.0.0.1:6380 succeeded 34781:M 26 Aug 2019 13:24:06.642 * Replica 127.0.0.1:6382 asks for synchronization 34781:M 26 Aug 2019 13:24:06.642 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for 'b9e0f41a523e078a6a88ae274f204777775ab4dc', my replication IDs are 'd41f950be7593a93620b1fd872b7552668f0b355' and '0000000000000000000000000000000000000000') 34781:M 26 Aug 2019 13:24:06.642 * Starting BGSAVE for SYNC with target: disk 34781:M 26 Aug 2019 13:24:06.643 * Background saving started by pid 34786 34786:C 26 Aug 2019 13:24:06.644 * DB saved on disk 34786:C 26 Aug 2019 13:24:06.644 * RDB: 4 MB of memory used by copy-on-write 34781:M 26 Aug 2019 13:24:06.701 * Background saving terminated with success 34781:M 26 Aug 2019 13:24:06.701 * Synchronization with replica 127.0.0.1:6382 succeeded 33570:S 26 Aug 2019 13:24:06.544 * Master replied to PING, replication can continue...33570:S 26 Aug 2019 13:24:06.544 * Master replied to PING, replication can continue... 33570:S 26 Aug 2019 13:24:06.544 * Trying a partial resynchronization (request b9e0f41a523e078a6a88ae274f204777775ab4dc:7603). 33570:S 26 Aug 2019 13:24:06.545 * Full resync from master: d41f950be7593a93620b1fd872b7552668f0b355:0 33570:S 26 Aug 2019 13:24:06.545 * Discarding previously cached master state. 33570:S 26 Aug 2019 13:24:06.601 * MASTER <-> REPLICA sync: receiving 240 bytes from master 33570:S 26 Aug 2019 13:24:06.601 * MASTER <-> REPLICA sync: Flushing old data 33570:S 26 Aug 2019 13:24:06.601 * MASTER <-> REPLICA sync: Loading DB in memory 33570:S 26 Aug 2019 13:24:06.601 * MASTER <-> REPLICA sync: Finished with success 127.0.0.1:6382> shutdown not connected> 34781:M 26 Aug 2019 13:24:06.701 * Synchronization with replica 127.0.0.1:6382 succeeded 34781:M 26 Aug 2019 13:29:45.037 # Connection with replica 127.0.0.1:6382 lost. # Replication role:master connected_slaves:1 slave0:ip=127.0.0.1,port=6380,state=online,offset=546,lag=1 可以在主库看出,目前存活的从数据库只有一个 127.0.0.1:6379> set slavetest 0851 OK keys * 1) "test02" 2) "c" 3) "d" 4) "a" 5) "test" 6) "kebo" 7) "slavetest" 8) "b" 9) "redisfast" get slavetest "0851" 34855:S 26 Aug 2019 13:34:39.561 * DB loaded from disk: 0.000 seconds 34855:S 26 Aug 2019 13:34:39.561 * Before turning into a replica, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer. 34855:S 26 Aug 2019 13:34:39.561 * Ready to accept connections 34855:S 26 Aug 2019 13:34:39.561 * Connecting to MASTER 127.0.0.1:6379 34855:S 26 Aug 2019 13:34:39.561 * MASTER <-> REPLICA sync started 34855:S 26 Aug 2019 13:34:39.561 * Non blocking connect for SYNC fired the event. 34855:S 26 Aug 2019 13:34:39.561 * Master replied to PING, replication can continue... 34855:S 26 Aug 2019 13:34:39.562 * Trying a partial resynchronization (request d41f950be7593a93620b1fd872b7552668f0b355:888). 34855:S 26 Aug 2019 13:34:39.562 * Successful partial resynchronization with master. 34855:S 26 Aug 2019 13:34:39.562 * MASTER <-> REPLICA sync: Master accepted a Partial Resynchronization. 34781:M 26 Aug 2019 13:24:06.701 * Synchronization with replica 127.0.0.1:6382 succeeded 34781:M 26 Aug 2019 13:29:45.037 # Connection with replica 127.0.0.1:6382 lost. 34781:M 26 Aug 2019 13:34:39.562 * Replica 127.0.0.1:6382 asks for synchronization 34781:M 26 Aug 2019 13:34:39.562 * Partial resynchronization request from 127.0.0.1:6382 accepted. Sending 56 bytes of backlog starting from offset 888. 127.0.0.1:6379> info replication # Replication role:master connected_slaves:2 slave0:ip=127.0.0.1,port=6380,state=online,offset=1139,lag=1 slave1:ip=127.0.0.1,port=6382,state=online,offset=1139,lag=1 master_replid:d41f950be7593a93620b1fd872b7552668f0b355 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1139 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:1139 出处:墨天轮(https://www./db/6415,复制到网页中打开或者点击“阅读原文”) |
|