Redis的主從複製
redis的主從複製解決的是讀取分離的問題。或者說解決的是數據備份的問題。node
redis主從複製經常使用方式redis
- 一僕二主。一個主機有兩個從機
- 薪火相傳。從機也能夠有從機
- 反客爲主。使當前數據庫中止和主機的同步,並由從機轉爲主機(從機執行
SLAVEOF no one
命令後,會從slave
轉爲master
)
介紹
運行redis的主機掛了,迅速將redis的數據複製到從機上。這樣就有修主機的時間了shell
只有主機能修改數據,從機只能讀數據,不能改數據數據庫
從機使用主機的.rdb
文件覆蓋本身的文件從而作到和主機數據保持一致服務器
搭建流程:併發
主機不須要修改,正常運行便可ui
從機須要修改配置文件redis.conf
,指定主機的ip和端口。一旦主機的redis掛掉,從機立刻補上3d
單機啓動多個Redis
- 建立多個
redis.conf
配置文件 - 使用不一樣的
redis.conf
文件(這些配置文件中配置的端口號必須不一樣)啓動Redis
- 在
slave
從機中指定master
完成上述步驟便可完成單機集羣日誌
-
複製多個
redis.conf
code修改port,修改日誌文件(logfile)的名字爲「redis_port.log」,修改生成的rdb文件的名字(dbfile)修改pidfile文件名
-
使用不一樣的配置文件啓動redis
$ redis-server ./redis6379.conf $ redis-server ./redis6380.conf $ redis-server ./redis6381.conf
-
啓動多個
redis-cli
鏈接不一樣的redis-server
$ redis-cli -p 6379 $ redis-cli -p 6380 $ redis-cli -p 6381
-
查看redis的集羣狀態,如下命令會打印當前redis的身份,主從機的地址和端口號
> info replication
# Replication role:master connected_slaves:0 master_replid:9dbcba9b7769c48547860bda99e9464b717a0ef3 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0
可見,三個
redis-server
均爲master
-
在兩個
redis-server
中執行命令,指定主機地址(ip+端口)> SLAVEOF 127.0.0.1 6379
此後這兩個
redis-server
均變爲slave
,且所存數據和master
一致
即,slave
的原數據所有丟棄,數據和master
同步
單機啓動多個Redis遇到的問題
-
主機的
redis-server
執行SHUTDOWN
關閉了服務。從機會怎麼辦?主機重啓後,從機又怎麼辦?主機關閉後,從機仍是從機(不會上位變主機),從機中數據也不會丟失。主機啓動後,主機依舊能存數據,從機依舊能複製主機數據
-
從機關閉了服務。會發生什麼?從機從新啓動後又會發生什麼?
其餘從機正常工做。從機啓動後,若是沒有指定主機,這個從機將再也不是從機,而是一個獨立的
redis-server
。須要從新在redis-cli
中指定主機或在配置文件中就指定主機
哨兵模式
反客爲主的自動版,原反客爲主是要手動令從機轉爲主機
哨兵監控主機狀態,若是主機掛掉,哨兵將選舉新的主機
場景:A(master),B(slave),C(slave),D(哨兵)
A掛掉,B轉爲master。A從新啓動,哨兵監控到A上線,A變爲從機
實現步驟:
- 寫哨兵的配置文件
sentinel.conf
(配置文件的內容只須要下述一行配置便可) - 啓動哨兵
redis-sentinel ./sentinel.conf
哨兵的配置文件的內容
# sentinel monitor 被監控數據庫名字(本身起名字) 127.0.0.1 6379 1 sentinel monitor iammaster 127.0.0.1 6379 1
上面最後一個數字1,表示主機掛掉後salve投票看讓誰接替成爲主機,得票數多少後成爲主機
sentinel.conf
的其餘可配置項在這裏
# Example sentinel.conf # 哨兵sentinel實例運行的端口 默認26379 port 26379 # 哨兵sentinel的工做目錄 dir /tmp # 哨兵sentinel監控的redis主節點的 ip port # master-name 能夠本身命名的主節點名字 只能由字母A-z、數字0-9 、這三個字符".-_"組成。 # quorum 當這些quorum個數sentinel哨兵認爲master主節點失聯 那麼這時 客觀上認爲主節點失聯了 # sentinel monitor <master-name> <ip> <redis-port> <quorum> sentinel monitor mymaster 127.0.0.1 6379 2 # 當在Redis實例中開啓了requirepass foobared 受權密碼 這樣全部鏈接Redis實例的客戶端都要提供密碼 # 設置哨兵sentinel 鏈接主從的密碼 注意必須爲主從設置同樣的驗證密碼 # sentinel auth-pass <master-name> <password> sentinel auth-pass mymaster MySUPER--secret-0123passw0rd # 指定多少毫秒以後 主節點沒有應答哨兵sentinel 此時 哨兵主觀上認爲主節點下線 默認30秒 # sentinel down-after-milliseconds <master-name> <milliseconds> sentinel down-after-milliseconds mymaster 30000 # 這個配置項指定了在發生failover主備切換時最多能夠有多少個slave同時對新的master進行 同步, 這個數字越小,完成failover所需的時間就越長, 可是若是這個數字越大,就意味着越 多的slave由於replication而不可用。 能夠經過將這個值設爲 1 來保證每次只有一個slave 處於不能處理命令請求的狀態。 # sentinel parallel-syncs <master-name> <numslaves> sentinel parallel-syncs mymaster 1 # 故障轉移的超時時間 failover-timeout 能夠用在如下這些方面: #1. 同一個sentinel對同一個master兩次failover之間的間隔時間。 #2. 當一個slave從一個錯誤的master那裏同步數據開始計算時間。直到slave被糾正爲向正確的master那裏同步數據時。 #3.當想要取消一個正在進行的failover所須要的時間。 #4.當進行failover時,配置全部slaves指向新的master所需的最大時間。不過,即便過了這個超時,slaves依然會被正確配置爲指向master,可是就不按parallel-syncs所配置的規則來了 # 默認三分鐘 # sentinel failover-timeout <master-name> <milliseconds> sentinel failover-timeout mymaster 180000 # SCRIPTS EXECUTION #配置當某一事件發生時所須要執行的腳本,能夠經過腳原本通知管理員,例如當系統運行不正常時發郵件通知相關人員。 #對於腳本的運行結果有如下規則: #若腳本執行後返回1,那麼該腳本稍後將會被再次執行,重複次數目前默認爲10 #若腳本執行後返回2,或者比2更高的一個返回值,腳本將不會重複執行。 #若是腳本在執行過程當中因爲收到系統中斷信號被終止了,則同返回值爲1時的行爲相同。 #一個腳本的最大執行時間爲60s,若是超過這個時間,腳本將會被一個SIGKILL信號終止,以後從新執行。 #通知型腳本:當sentinel有任何警告級別的事件發生時(好比說redis實例的主觀失效和客觀失效等等),將會去調用這個腳本, 這時這個腳本應該經過郵件,SMS等方式去通知系統管理員關於系統不正常運行的信息。調用該腳本時,將傳給腳本兩個參數, 一個是事件的類型, 一個是事件的描述。 若是sentinel.conf配置文件中配置了這個腳本路徑,那麼必須保證這個腳本存在於這個路徑,而且是可執行的,不然sentinel沒法正常啓動成功。 #通知腳本 # sentinel notification-script <master-name> <script-path> sentinel notification-script mymaster /var/redis/notify.sh # 客戶端從新配置主節點參數腳本 # 當一個master因爲failover而發生改變時,這個腳本將會被調用,通知相關的客戶端關於master地址已經發生改變的信息。 # 如下參數將會在調用腳本時傳給腳本: # <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port> # 目前<state>老是「failover」, # <role>是「leader」或者「observer」中的一個。 # 參數 from-ip, from-port, to-ip, to-port是用來和舊的master和新的master(即舊的slave)通訊的 # 這個腳本應該是通用的,能被屢次調用,不是針對性的。 # sentinel client-reconfig-script <master-name> <script-path> sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
Redis集羣
相對於Redis的主從複製。Redis解決的是內存問題。將使用者對Redis的操做分攤到各個節點中
Redis集羣解決內存不夠和承受併發壓力的問題
下面實現的是單機建立的集羣
介紹
由上圖可知,redis-cli
操做的是集羣。當redis-cli
向集羣中插入一對新的鍵值對時,數據具體存放到哪臺服務器中由集羣決定。因此使用者只須要像操做單個Redis
服務同樣,操做集羣就能夠了。
搭建集羣流程
-
修改配置文件,開啓集羣
-
啓動一堆redis
-
使用redis的集羣命令,將redis鏈接起來造成集羣
-
使用
redis-cli
實操 -
修改配置文件。主機的配置文件須要開啓集羣,從機不須要開啓集羣,可是須要指定主機的地址
port 6379 daemonize yes pidfile /var/run/redis_6379.pid # 主機須要開啓集羣 cluster-enabled yes cluster-node-timeout 15000 cluster-config-file nodes-6379.conf
port 6389 daemonize yes pidfile /var/run/redis_6389.pid # 從機須要指定主機地址,並關閉集羣 cluster-enabled no slaveof 127.0.0.1 6379
配置
redis
集羣須要至少三個節點,每一個節點再配置一個從機。若是配置集羣的話須要在啓動redis
前刪除全部.rdb
文件 -
啓動一堆redis。這裏啓動的前三個是主機,後三個是從機。
$ redis-server redis6379.conf $ redis-server redis6380.conf $ redis-server redis6381.conf $ redis-server redis6389.conf $ redis-server redis6390.conf $ redis-server redis6391.conf $ ps -ef | grep redis
-
使用命令將多個
redis
服務合併爲集羣# 主從節點的地址全都寫上 $ redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6389 127.0.0.1:6390 127.0.0.1:6391
-
使用
redis-cli
實操$ redis-cli -c -p 6379
-c
選項表示使用集羣啓動,若是沒有此選項,如下操做均不可實現在
6379
端口下的redis-cli
使用命令存入數據時,由於集羣的緣由,數據可能存到不一樣的節點。成功存入數據的同時當前終端也會自動跳轉到存入數據的節點的redis-cli
可是,正因如此。
redis-cli
沒法執行批量操做。由於存取數據時,可能不一樣數據會存入不一樣節點或從不一樣的節點取數據。因此在一個節點下的redis-cli
沒法執行批量操做
插槽
在執行以下命令時,會打印一些集羣的信息
$ redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381
Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 M: 5df2139bfae322a623dfeaa7e31f8663548a9fb2 127.0.0.1:6379 slots:[0-5460] (5461 slots) master M: 4f358a2baf74f490e14093cdcf6422f17b95b67e 127.0.0.1:6380 slots:[5461-10922] (5462 slots) master M: 4efd186e801cfb226fd29215f98c1927eb035a01 127.0.0.1:6381 slots:[10923-16383] (5461 slots) master
其中有關鍵字==slots==(插槽)
上述打印信息顯示,集羣的插槽範圍爲0~16383。,每一個插槽能夠存放一對鍵值對
前三行顯示了,每一個節點管理的插槽範圍
關於集羣的經常使用命令
查看節點列表
127.0.0.1:6379> cluster nodes
還有不少redis客戶端執行的cluster
命令,例如:查全部節點中鍵值對總數,插槽總數等,查詢key所在的插槽,這裏不贅述
添加主機節點
$ redis-cli --cluster add-node 127.0.0.1:6385 127.0.0.1:6379
添加從機節點
$ redis-cli --cluster add-node 127.0.0.1:6386 127.0.0.1:6379 --cluster-slave --cluster-master-id 22e8a8e97d6f7cc7d627e577a986384d4d181a4f
爲新節點分配插槽
$ redis-cli --cluster reshard 127.0.0.1:6385
刪除節點
$ redis-cli --cluster del-node 127.0.0.1:6386