關於redis中的Replication

来源:http://www.cnblogs.com/chenpingzhao/archive/2016/01/28/5167784.html
-Advertisement-
Play Games

一、簡介 Redis的replication機制允許slave從master那裡通過網路傳輸拷貝到完整的數據備份。具有以下特點: 非同步複製 可以配置一主多從 可以配置從伺服器可以級聯從伺服器,既 M->S->S M replication時是非阻塞的(在replication期間,M依然能夠處理客戶


一、簡介

Redis的replication機制允許slave從master那裡通過網路傳輸拷貝到完整的數據備份。具有以下特點:

  • 非同步複製

  • 可以配置一主多從

  • 可以配置從伺服器可以級聯從伺服器,既 M->S->S

  • M replication時是非阻塞的(在replication期間,M依然能夠處理客戶端的請求)

  • S replication期間也是非阻塞的(也可以接受來自客戶端的請求,但是它用的是之前的舊數據)可以通過配置來決定S是否在進行replication時用舊數據響應客戶端的請求,如果配置為否,那麼slave將會返回一個錯誤消息給客戶端。不過當新的數據接收完全後,必須將新數據與舊數據替換,即刪除舊數據,在替換數據的這個時間視窗內,slave將會拒絕客戶端的請求和連接

  • 能夠通過replication來避免master每次持久化時都將整個數據集持久化到硬碟中。只需把master配置為不進行save操作,然後連接上一個slave,這個slave則被配置為不時地進行save操作的。不過需要註意的是,在這個用例中,必須確保master不會自動啟動

二、Master持久化功能關閉時Replication的安全性

當有需要使用到replication機制時,一般都會強烈建議把master的持久化開關打開。即使為了避免持久化帶來的延遲影響,不把持久化開關打開,那麼也應該把master配置為不會自動啟動的

為了更好地理解當一個不進行持久化的master如果允許自動啟動所帶來的危險性。可以看看下麵這種失敗情形:

假設我們有一個redis節點A,設置為master,並且關閉持久化功能,另外兩個節點B和C是它的slave,並從A複製數據。

  • 如果A節點崩潰了導致所有的數據都丟失了,它會有重啟系統來重啟進程。但是由於持久化功能被關閉了,所以即使它重啟了,它的數據集是空的。而B和C依然會通過replication機制從A複製數據,所以B和C會從A那裡複製到一份空的數據集,並用這份空的數據集將自己本身的非空的數據集替換掉。於是就相當於丟失了所有的數據

  • 即使使用一些HA工具,比如說sentinel來監控master-slaves集群,也會發生上述的情形,因為master可能崩潰後迅速恢復。速度太快而導致sentinel無法察覺到一個failure的發生

  • 數據的安全很重要、持久化開關被關閉並且有replication發生的時候,應該禁止實例的自啟動

三、M/S replication的工作原理

  • 當master和slave啟動時,不管這個slave是否是第一次連接上Master,它都會發送一個SYNC命令給master請求複製數據

  • master收到SYNC命令後,會在後臺進行數據持久化,持久化期間,master會繼續接收客戶端的請求,它會把這些可能修改數據集的請求緩存在記憶體中。當持久化進行完畢以後,master會把這份數據集發送給slave,slave會把接收到的數據進行持久化,然後再載入到記憶體中。然後,master再將之前緩存在記憶體中的命令發送給slave

  • 當master與slave之間的連接由於某些原因而斷開時,slave能夠自動重連Master,如果master收到了多個slave併發連接請求,它只會進行一次持久化,然後再把這一份持久化的數據發送給多個併發連接的slave

  • 當master和slave斷開重連後,一般都會對整份數據進行複製。但從redis2.8版本開始,支持部分複製

數據部分複製

從2.8版本開始,slave與master能夠在網路連接斷開重連後只進行部分數據複製。

master會在其記憶體中創建一個複製流的等待隊列,master和它所有的slave都維護了複製的數據下標和master的進程id,因此,當網路連接斷開後,slave會請求master繼續進行未完成的複製,從所記錄的數據下標開始。如果進程id變化了,或者數據下標不可用,那麼將會進行一次全部數據的複製。支持部分數據複製的命令是PSYNC

不需硬碟參與的Replication

一般情況下,一次複製需要將記憶體的數據寫到硬碟中,再將數據從硬碟讀進記憶體,再發送給slave。對於速度比較慢的硬碟,這個操作會給master帶來性能上的損失。Redis2.8版本開始,實驗性地加上了無硬碟複製的功能。這個功能能將數據從記憶體中直接發送到slave,而不用經過硬碟的存儲。不過這個功能目前處於實驗階段,還未正式發佈

四、配置M/S

slaveof <masterip> <masterport>
slave實例需要配置該項,指向master的(ip, port)

masterauth <master-password>
如果master實例啟用了密碼保護,則該配置項需填master的啟動密碼;若master未啟用密碼,該配置項需要註釋掉

slave-serve-stale-data
指定slave與master連接中斷時的動作。預設為yes,表明slave會繼續應答來自client的請求,但這些數據可能已經過期(因為連接中斷導致無法從master同步)
若配置為no,則slave除正常應答"INFO"和"SLAVEOF"命令外,其餘來自客戶端的請求命令均會得到"SYNC with master in progress"的應答,
直到該slave與master的連接重建成功或該slave被提升為master。

slave-read-only
指定slave是否只讀,預設為yes。若配置為no,這表示slave是可寫的,但寫的內容在主從同步完成後會被刪掉

repl-ping-slave-period
Redis部署為Replication模式後,slave會以預定周期(預設10s)發PING包給master,該配置可以更改這個預設周期

repl-timeout
有2種情況的超時均由該配置指定:1) Bulk transfer I/O timeout; 2) master data or ping response timeout
需要特別註意的是:若修改預設值,則用戶輸入的值必須大於repl-ping-slave-period的配置值,否則在主從鏈路延時較高時,會頻繁timeout

repl-disable-tcp-nodelay
指定向slave同步數據時,是否禁用socket的NO_DELAY選項。
若配置為yes,則禁用NO_DELAY,則TCP協議棧會合併小包統一發送,這樣可以減少主從節點間的包數量並節省帶寬,但會增加數據同步到slave的時間
若配置為no,表明啟用NO_DELAY,則TCP協議棧不會延遲小包的發送時機,這樣數據同步的延時會減少,但需要更大的帶寬
通常情況下,應該配置為no以降低同步延時,但在主從節點間網路負載已經很高的情況下,可以配置為yes
備註:socket的NO_DELAY選項涉及到TCP協議棧的擁塞控制演算法—Nagle's Algorithm

slave-priority
指定slave的優先順序。在不只1個slave存在的部署環境下,當master宕機時,Redis Sentinel會將priority值最小的slave提升為master
需要註意的是,若該配置項為0,則對應的slave永遠不會被Redis Sentinel自動提升為master

replication相關的配置比較簡單,只需要把下麵一行加到slave的配置文件中

slaveof 192.168.1.1 6379

你也可以通過客戶端發送SLAVEOF命令給slave。無硬碟複製功能可以通過repl-diskless-sync來配置,另外一個配置項repl-diskless-sync-delay用來配置當收到第一個請求時,等待多個slave一起來請求之間的間隔時間

1、同時啟動兩個Redis伺服器,可以考慮在同一臺機器上啟動兩個Redis伺服器,分別監聽不同的埠,如6379和6380

2、配置文件為6379.conf 6380.conf

3、啟動並配置

./src/redis-server  6380.conf 
./src/redis-server  6379.conf 

4、測試

[root@localhost redis]# ./src/redis-cli  -p 6379
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set aa 1
OK
127.0.0.1:6379> set bb 2
OK
127.0.0.1:6379> set cc 3
OK
127.0.0.1:6379> exit
[root@localhost redis]# ./src/redis-cli  -p 6380
127.0.0.1:6380> keys *
1) "bb"
2) "aa"
3) "cc"
127.0.0.1:6380> get aa 
"1"
127.0.0.1:6380> get bb 
"2"

五、only read slave

從redis2.6版本開始,slave支持只讀模式,而且是預設的。可以通過配置項slave-read-only來進行配置,並且支持客戶端使用CONFIG SET命令來動態修改配置

只讀的slave會拒絕所有的寫請求,只讀的slave並不是為了防範不可信的客戶端,畢竟一些管理命令例如DEBUGCONFIG在只讀模式下還是可以使用的。如果確實要確保全全性,那麼可以在配置文件中將一些命令重新命名。也許你會感到很奇怪,為什麼能夠將一個只讀模式的slave恢復為可寫的呢,儘管可寫,但是只要slave一同步master的數據,就會丟失那些寫在slave的數據。不過還是有一些合法的應用場景需要存儲瞬時數據會用到這個特性。不過,之後可能會考慮廢除掉這個特性。Setting a slave to authenticate to a master

如果master通過requirepass配置項設置了密碼,slave每次同步操作都需要驗證密碼,可以通過在slave的配置文件中添加以下配置項:

masterauth <password>

也可以通過客戶端在運行時發送以下命令:

config set masterauth <password>

六、至少N個slave才允許向master寫數據

從redis2.8版本開始,master可以被配置為只有當master當前有至少N個slave連接著的時候才接受寫數據的請求;由於redis是非同步複製的,所以它並不能保證slave會收到一個寫請求,所以總有一個數據丟失的時間視窗存在

這個機制的工作原理如下所示:

  • slave每秒發送ping心跳給master,詢問當前複製了多少數據

  • master會記錄下它上次收到某個slave的ping心跳是什麼時候

  • 使用者可以配置一個時間,來指定ping心跳的發送不應超過的一個超時時間

如果master有至少N個slave,並且ping心跳的超時不超過M秒,那麼它就會接收寫請求。也許你會認為這情形好似CAP理論中弱化版的C(consistency),因為寫請求並不能保證數據的一致性,但這樣做,至少數據丟失被限制在了限定的時間內,即M秒

如果N和M的條件都無法達到,那麼master會回覆一個錯誤信息。寫請求也不會被處理

有兩個配置項用來配置上文中提到的N和M:

min-slaves-to-write <number of slaves>
min-slaves-max-lag <number of seconds>

 

參考文章

https://support.pivotal.io/hc/en-us/articles/205309278-How-to-setup-Redis-Master-and-Salve-replication


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.網上代碼托管有好多我選了開源中國的git 2.開源中國鏈接:http://git.oschina.net 3.在git上創建一個新的項目 4.打開終端全局設置名字和郵箱 tanqihongdeiMac:~ tanqihong$ git config --global user.name "幻想無
  • 代碼在評論中。 JNI: 為什麼需要JNI: 因為android是由【JAVA & C/C++】組成。Java運行在Dalvik虛擬機中。 沒有辦法直接訪問底層硬體。底層HW相關目前技術一般都用C語言,不會用java,C速度也比較快。 怎麼從JAVA語言傳送數據到C語言中: 1. java中會調用n
  • //自動調節輸入文本框的高度 - (void)textViewDidChange:(UITableView *)textView{ float height; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { CGRe
  • 一、//觸摸空白處隱藏鍵盤 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [_feedBackTextView resignFirstResponder]; [_telTextField resignFirstRe
  • srand(seed)用來將隨機序列的起始點設為seed srand((int)time(0))表示以當前時間對應的int值為隨機序列起點,這樣每次運行程式,由於起點不同才可以得到不同的隨機數 time函數給出從1970年1月1日00:00:00至今的秒數,它必須帶一個參數,用來存儲這個秒數,tim
  • 第一篇,寫的比較詳細,新手可以看得懂: http://www.360doc.com/content/16/0128/08/30422106_531162539.shtml
  • 相比看一下枯燥乏味的對於block的講解,為什麼不從大神的代碼中領路它的使用方法呢,瞭解一下大神是如何使用block的呢,見識它的強大。https://github.com/zwaldowski/BlocksKit該項目對iOS的一些常用類進行了擴展,你可以學習到block的精髓。
  • 本文介紹一些流行的iOS的開源項目庫 1.AFNetworking 更新頻率高的輕量級的第三方網路庫,基於NSURL和NSOperation,支持iOS和OSX。https://github.com/AFNetworking/AFNetworking 2.GPUImage 圖像處理庫,基於OpenG
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...