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
總結:
從服務器:打開從服務器(設置主服務器地址與端口,設置連接主服務器密碼,設置主服務器只讀,設置持久化的地址與方式)
主服務器:關閉持久化操作即可