Redis搭建主從複製和集羣

Redis的主從複製

redis的主從複製解決的是讀取分離的問題。或者說解決的是數據備份的問題。node

redis主從複製經常使用方式redis

  • 一僕二主。一個主機有兩個從機
  • 薪火相傳。從機也能夠有從機
  • 反客爲主。使當前數據庫中止和主機的同步,並由從機轉爲主機(從機執行SLAVEOF no one命令後,會從slave轉爲master

介紹

運行redis的主機掛了,迅速將redis的數據複製到從機上。這樣就有修主機的時間了shell

只有主機能修改數據,從機只能讀數據,不能改數據數據庫

從機使用主機的.rdb文件覆蓋本身的文件從而作到和主機數據保持一致服務器

搭建流程:併發

主機不須要修改,正常運行便可ui

從機須要修改配置文件redis.conf,指定主機的ip和端口。一旦主機的redis掛掉,從機立刻補上3d

單機啓動多個Redis

  1. 建立多個redis.conf配置文件
  2. 使用不一樣的redis.conf文件(這些配置文件中配置的端口號必須不一樣)啓動Redis
  3. slave從機中指定master

完成上述步驟便可完成單機集羣日誌

  1. 複製多個redis.confcode

    修改port,修改日誌文件(logfile)的名字爲「redis_port.log」,修改生成的rdb文件的名字(dbfile)修改pidfile文件名

  2. 使用不一樣的配置文件啓動redis

    $ redis-server ./redis6379.conf
    $ redis-server ./redis6380.conf
    $ redis-server ./redis6381.conf
  3. 啓動多個redis-cli鏈接不一樣的redis-server

    $ redis-cli -p 6379
    $ redis-cli -p 6380
    $ redis-cli -p 6381
  4. 查看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

  5. 在兩個redis-server中執行命令,指定主機地址(ip+端口)

    > SLAVEOF 127.0.0.1 6379

    此後這兩個redis-server均變爲slave,且所存數據和master一致

即,slave的原數據所有丟棄,數據和master同步

單機啓動多個Redis遇到的問題

  1. 主機的redis-server執行SHUTDOWN關閉了服務。從機會怎麼辦?主機重啓後,從機又怎麼辦?

    主機關閉後,從機仍是從機(不會上位變主機),從機中數據也不會丟失。主機啓動後,主機依舊能存數據,從機依舊能複製主機數據

  2. 從機關閉了服務。會發生什麼?從機從新啓動後又會發生什麼?

    其餘從機正常工做。從機啓動後,若是沒有指定主機,這個從機將再也不是從機,而是一個獨立的redis-server。須要從新在redis-cli中指定主機或在配置文件中就指定主機

哨兵模式

反客爲主的自動版,原反客爲主是要手動令從機轉爲主機

哨兵監控主機狀態,若是主機掛掉,哨兵將選舉新的主機

場景:A(master),B(slave),C(slave),D(哨兵)

A掛掉,B轉爲master。A從新啓動,哨兵監控到A上線,A變爲從機

實現步驟:

  1. 寫哨兵的配置文件sentinel.conf(配置文件的內容只須要下述一行配置便可)
  2. 啓動哨兵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服務同樣,操做集羣就能夠了。

搭建集羣流程

  1. 修改配置文件,開啓集羣

  2. 啓動一堆redis

  3. 使用redis的集羣命令,將redis鏈接起來造成集羣

  4. 使用redis-cli實操

  5. 修改配置文件。主機的配置文件須要開啓集羣,從機不須要開啓集羣,可是須要指定主機的地址

    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文件

  6. 啓動一堆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
  7. 使用命令將多個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
  8. 使用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
相關文章
相關標籤/搜索