Master:主 Slaves:从
一、Redis的Replication:
下面的列表清楚的解释了Redis Replication的特点和优势。
1). 同一个Master可以同步多个Slaves。
2). Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。因此我们可以将Redis的Replication架构视为图结构。
3). Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求。
4). Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据。
5). 为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成。即便如此,系统的伸缩性还是得到了很大的提高。
6). Master可以将数据保存操作交给Slaves完成,从而避免了在Master中要有独立的进程来完成此操作。
二、Replication的工作原理:
在Slave启动并连接到Master之后,它将主动发送一个SYNC命令。此后Master将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Slave,以完成一次完全同步。而Slave服务器在接收到数据库文件数据之后将其存盘并加载到内存中。此后,Master继续将所有已经收集到的修改命令,和新的修改命令依次传送给Slaves,Slave将在本次执行这些数据修改命令,从而达到最终的数据同步。
如果Master和Slave之间的链接出现断连现象,Slave可以自动重连Master,但是在连接成功之后,一次完全同步将被自动执行。
三、如何配置Replication:
见如下步骤:
1). 同时启动两个Redis服务器,可以考虑在同一台机器上启动两个Redis服务器,分别监听不同的端口,如6379和6380。
2). 在Slave服务器上执行一下命令:
/> redis-cli -p 6380 #这里我们假设Slave的端口号是6380
redis 127.0.0.1:6380> slaveof 127.0.0.1 6379 #我们假设Master和Slave在同一台主机,Master的端口为6379
OK
上面的方式只是保证了在执行slaveof命令之后,redis_6380成为了redis_6379的slave,一旦服务(redis_6380)重新启动之后,他们之间的复制关系将终止。
如果希望长期保证这两个服务器之间的Replication关系,可以在redis_6380的配置文件中做如下修改:
/> cd /etc/redis #切换Redis服务器配置文件所在的目录。
/> ls
6379.conf 6380.conf
/> vi 6380.conf
将
# slaveof <masterip> <masterport>
改为
slaveof 127.0.0.1 6379
保存退出。
这样就可以保证Redis_6380服务程序在每次启动后都会主动建立与Redis_6379的Replication连接了。
四、应用示例:
这里我们假设Master-Slave已经建立。
主服务器:
#启动master服务器。 [root@Stephen-PC redis]# redis-cli -p 6379 redis 127.0.0.1:6379> #情况Master当前数据库中的所有Keys。 redis 127.0.0.1:6379> flushdb OK #在Master中创建新的Keys作为测试数据。 redis 127.0.0.1:6379> set mykey hello OK redis 127.0.0.1:6379> set mykey2 world OK #查看Master中存在哪些Keys。 redis 127.0.0.1:6379> keys * 1) "mykey" 2) "mykey2"
从服务器:
#启动slave服务器。 [root@Stephen-PC redis]# redis-cli -p 6380 #查看Slave中的Keys是否和Master中一致,从结果看,他们是相等的。 redis 127.0.0.1:6380> keys * 1) "mykey" 2) "mykey2"
主服务器:
#在Master中删除其中一个测试Key,并查看删除后的结果。 redis 127.0.0.1:6379> del mykey2 (integer) 1 redis 127.0.0.1:6379> keys * 1) "mykey"
从服务器:
#在Slave中查看是否mykey2也已经在Slave中被删除。 redis 127.0.0.1:6380> keys * 1) "mykey"
-----------主从服务配置过程------------------
主服务器只接收数据,持久化操作在从服务器进行。可以减小主服务器的压力。
1.复制一个配置文件作为另一个从服务器
root@qiaozhi:/usr/local/redis# cp redis.conf redis6380.conf root@qiaozhi:/usr/local/redis# ll total 132 drwxr-xr-x 3 root root 4096 Nov 7 09:38 ./ drwxr-xr-x 12 root root 4096 Nov 4 03:28 ../ drwxr-xr-x 2 root root 4096 Nov 4 03:28 bin/ -rw-r--r-- 1 root root 57772 Nov 7 09:38 redis6380.conf -rw-r--r-- 1 root root 57772 Nov 7 07:52 redis.conf
2.修改redis6380.conf配置文件:(从服务器配置)
(0).从服务器的启动端口
(1)打开主从复制开关:
(2)如果主服务器有密码需要配置密码:
(3)从服务器是否只读
3.修改主服务器的配置文件(redis.conf),将RDB和AOF持久化关掉:(主服务器配置)
(1)关掉RDB持久化(注释掉保存方式)
(2)关掉AOF持久化:
4.开启主服务器与从服务器
root@qiaozhi:/usr/local/redis# ./bin/redis-server redis.conf 4714:C 07 Nov 09:50:45.518 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 4714:C 07 Nov 09:50:45.518 # Redis version=4.0.2, bits=32, commit=00000000, modified=0, pid=4714, just started 4714:C 07 Nov 09:50:45.518 # Configuration loaded root@qiaozhi:/usr/local/redis# ./bin/redis-server redis6380.conf 4720:C 07 Nov 09:50:50.924 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 4720:C 07 Nov 09:50:50.924 # Redis version=4.0.2, bits=32, commit=00000000, modified=0, pid=4720, just started 4720:C 07 Nov 09:50:50.925 # Configuration loaded root@qiaozhi:/usr/local/redis# ps -ef | grep redis root 4715 1 0 09:50 ? 00:00:00 ./bin/redis-server 127.0.0.1:6379 root 4721 1 0 09:50 ? 00:00:00 ./bin/redis-server 127.0.0.1:6380 root 4730 3763 0 09:51 pts/0 00:00:00 grep --color=auto redis root@qiaozhi:/usr/local/redis#
5.测试主从复制
(1)连接主服务器并且添加数据:
root@qiaozhi:/usr/local/redis# ./bin/redis-cli -p 6379 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> set str1 hello OK 127.0.0.1:6379> set str2 world OK 127.0.0.1:6379> keys * 1) "str1" 2) "str2"
(2)从服务器连接并获取主服务器上的值:
root@qiaozhi:~# cd /usr/local/redis root@qiaozhi:/usr/local/redis# ./bin/redis-cli -p 6380 127.0.0.1:6380> keys * 1) "str2" 2) "str1" 127.0.0.1:6380> get str1 "hello" 127.0.0.1:6380> get str2 "world" 127.0.0.1:6380>
(3)主服务器上删除一个值并重新添加一个:
127.0.0.1:6379> del str1 (integer) 1 127.0.0.1:6379> set str3 test3 OK 127.0.0.1:6379> keys * 1) "str3" 2) "str2" 127.0.0.1:6379>
(4)从服务器上获取数据;
127.0.0.1:6380> keys * 1) "str3" 2) "str2" 127.0.0.1:6380> get str3 "test3" 127.0.0.1:6380>
(5)在一个只读的从服务器上写数据会报错:
127.0.0.1:6380> set test3 eee (error) READONLY You can't write against a read only slave. 127.0.0.1:6380>
(6)验证是否搭建成功也可以通过info命令查看服务信息:
# Replication模块显示的是主从服务器的信息
127.0.0.1:6380> info # Server redis_version:4.0.2 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:33f2ebc265a685ff redis_mode:standalone os:Linux 3.11.0-12-generic i686 arch_bits:32 multiplexing_api:epoll atomicvar_api:atomic-builtin gcc_version:4.8.1 process_id:2718 run_id:79a305359f89298847959bb64f5e55735f0b4600 tcp_port:6380 uptime_in_seconds:1231 uptime_in_days:0 hz:10 lru_clock:121176 executable:/usr/local/redis/./bin/redis-server config_file:/usr/local/redis/redis6380.conf # Clients connected_clients:2 client_longest_output_list:0 client_biggest_input_buf:0 blocked_clients:0 # Memory used_memory:1720672 used_memory_human:1.64M used_memory_rss:2383872 used_memory_rss_human:2.27M used_memory_peak:1760576 used_memory_peak_human:1.68M used_memory_peak_perc:97.73% used_memory_overhead:1703768 used_memory_startup:588880 used_memory_dataset:16904 used_memory_dataset_perc:1.49% total_system_memory:1050468352 total_system_memory_human:1001.80M used_memory_lua:25600 used_memory_lua_human:25.00K maxmemory:3221225472 maxmemory_human:3.00G maxmemory_policy:noeviction mem_fragmentation_ratio:1.39 mem_allocator:jemalloc-4.0.3 active_defrag_running:0 lazyfree_pending_objects:0 # Persistence loading:0 rdb_changes_since_last_save:0 rdb_bgsave_in_progress:0 rdb_last_save_time:1510069822 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:0 rdb_current_bgsave_time_sec:-1 rdb_last_cow_size:270336 aof_enabled:1 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:0 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok aof_last_cow_size:147456 aof_current_size:370 aof_base_size:136 aof_pending_rewrite:0 aof_buffer_length:0 aof_rewrite_buffer_length:0 aof_pending_bio_fsync:0 aof_delayed_fsync:0 # Stats total_connections_received:1 total_commands_processed:133 instantaneous_ops_per_sec:0 total_net_input_bytes:2305 total_net_output_bytes:53816 instantaneous_input_kbps:0.00 instantaneous_output_kbps:0.04 rejected_connections:0 sync_full:0 sync_partial_ok:0 sync_partial_err:0 expired_keys:0 evicted_keys:0 keyspace_hits:3 keyspace_misses:0 pubsub_channels:0 pubsub_patterns:0 latest_fork_usec:524 migrate_cached_sockets:0 slave_expires_tracked_keys:0 active_defrag_hits:0 active_defrag_misses:0 active_defrag_key_hits:0 active_defrag_key_misses:0 # Replication role:slave master_host:localhost master_port:6379 master_link_status:up master_last_io_seconds_ago:10 master_sync_in_progress:0 slave_repl_offset:1900 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:8975dc3026cea391919b1e5bb4bc8842252e21ac master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1900 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:1900 # CPU used_cpu_sys:2.73 used_cpu_user:1.00 used_cpu_sys_children:0.01 used_cpu_user_children:0.00 # Cluster cluster_enabled:0 # Keyspace db0:keys=2,expires=0,avg_ttl=0
总结:
从服务器:打开从服务器(设置主服务器地址与端口,设置连接主服务器密码,设置主服务器只读,设置持久化的地址与方式)
主服务器:关闭持久化操作即可