Redis的複製特性

對於有擴展平臺以適應更高負載經驗的工程師和管理員來講,複製(replication)是不可或缺的。複製可讓其餘服務器擁有一個不斷更新的數據副本,從而使得擁有數據副本的服務器能夠用於處理客戶端發送的讀請求。關係數據庫一般會使用一個主服務器(master)向多個從服務器(slave)發送更新,並使用從服務器來處理全部讀請求。Redis也採用了一樣的方法來實現本身的複製特性,並將其用做擴展性能的一種手段。本節將對Redis的複製配置選項進行討論,並說明Redis在進行復制時的各個步驟。html

儘管Redis的性能很是優秀,但它也會趕上沒辦法快速處理請求的狀況,特別是在對集合和有序集合進行操做的時候,涉及的元素可能會有上萬個甚至上百萬個,在這種狀況下,執行操做所花費的時間可能須要以秒來進行計算,而不是毫秒或者微秒。但即便一個命令只須要花費10毫秒就能完成,單個Redis實例(instance)1秒也只能處理100個命令。node

SUNIONSTORE命令的性能做爲對Redis性能的一個參考,在主頻爲2.4GHz的英特爾酷睿2處理器上,對兩個分別包含10000個元素的集合執行SUNIONSTORE命令併產生一個包含20000個元素的結果集合,須要花費Redis七八毫秒的時間。數據庫

在須要擴展讀請求的時候,或者在須要寫入臨時數據的時候,用戶能夠經過設置額外的Redis從服務器來保存數據集的副本。在接收到主服務器發送的數據初始副本(initialcopyofthedata)以後,客戶端每次向主服務器進行寫入時,從服務器都會實時地獲得更新。在部署好主從服務器以後,客戶端就能夠向任意一個從服務器發送讀請求了,而沒必要再像以前同樣,老是把每一個讀請求都發送給主服務器(客戶端一般會隨機地選擇使用哪一個從服務器,從而將負載平均分配到各個從服務器上)。服務器

接下來的一節將介紹配置Redis主從服務器的方法,並說明Redis在整個複製過程當中所作的各項操做。網絡

對Redis的複製相關選項進行配置

當從服務器鏈接主服務器的時候,主服務器會執行BGSAVE操做。所以爲了正確地使用複製特性,用戶須要保證主服務器已經正確地設置了dir選項和dbfilename選項,而且這兩個選項所指示的路徑和文件對於Redis進程來講都是可寫的(writable)。app

儘管有多個不一樣的選項能夠控制從服務器自身的行爲,但開啓從服務器所必須的選項只有slaveof一個。若是用戶在啓動Redis服務器的時候,指定了一個包含slaveofhostport選項的配置文件,那麼Redis服務器將根據該選項給定的IP地址和端口號來鏈接主服務器。對於一個正在運行的Redis服務器,用戶能夠經過發送SLAVEOFnoone命令來讓服務器終止複製操做,再也不接受主服務器的數據更新;也能夠經過發送SLAVEOF host port命令來讓服務器開始複製一個新的主服務器。性能

開啓Redis的主從複製特性並不須要進行太多的配置,但瞭解Redis服務器是如何變成主服務器或者從服務器的,對於咱們來講將是很是有用的和有趣的過程。spa

Redis複製的啓動過程

本章前面曾經說過,從服務器在鏈接一個主服務器的時候,主服務器會建立一個快照文件並將其發送至從服務器,但這只是主從複製執行過程的其中一步。表4-2完整地列出了當從服務器鏈接主服務器時,主從服務器執行的全部操做。htm

經過使用表4-2所示的辦法,Redis在複製進行期間也會盡量地處理接收到的命令請求,可是,若是主從服務器之間的網絡帶寬不足,或者主服務器沒有足夠的內存來建立子進程和建立記錄寫命令的緩衝區,那麼Redis處理命令請求的效率就會受到影響。所以,儘管這並非必須的,但在實際中最好仍是讓主服務器只使用50%~65%的內存,留下30%~45%的內存用於執行BGSAVE命令和建立記錄寫命令的緩衝區。blog

設置從服務器的步驟很是簡單,用戶既能夠經過配置選項SLAVEOFhostport來將一個Redis服務器設置爲從服務器,又能夠經過向運行中的Redis服務器發送SLAVEOF命令來將其設置爲從服務器。若是用戶使用的是SLAVEOF配置選項,那麼Redis在啓動時首先會載入當前可用的任何快照文件或者AOF文件,而後鏈接主服務器並執行表4-2所示的複製過程。若是用戶使用的是SLAVEOF命令,那麼Redis會當即嘗試鏈接主服務器,並在鏈接成功以後,開始表4-2所示的複製過程。

從服務器在進行同步時,會清空本身的全部數據。由於有些用戶在第一次使用從服務器時會忘記這件事,因此這裏要特別提醒一下:從服務器在與主服務器進行初始鏈接時,數據庫中原有的全部數據都將丟失,並被替換成主服務器發來的數據。

警告:Redis不支持主主複製(master-masterreplication)由於Redis容許用戶在服務器啓動以後使用SLAVEOF命令來設置從服務器選項(slavingoptions),因此可能會有讀者誤覺得能夠經過將兩個Redis實例互相設置爲對方的主服務器來實現多主複製(multi-masterreplication)(甚至可能會在一個循環裏面將多個實例互相設置爲主服務器)。遺憾的是,這種作法是行不通的:被互相設置爲主服務器的兩個Redis實例只會持續地佔用大量處理器資源而且接二連三地嘗試與對方進行通訊,根據客戶端鏈接的服務器的不一樣,客戶端的請求可能會獲得不一致的數據,或者徹底得不到數據。

當多個從服務器嘗試鏈接同一個主服務器的時候,就會出現表4-3所示的兩種狀況中的其中一種。

在大部分狀況下,Redis都會盡量地減小複製所需的工做,然而,若是從服務器鏈接主服務器的時間並不湊巧,那麼主服務器就須要多作一些額外的工做。另外一方面,當多個從服務器同時鏈接主服務器的時候,同步多個從服務器所佔用的帶寬可能會使得其餘命令請求難以傳遞給主服務器,與主服務器位於同一網絡中的其餘硬件的網速可能也會所以而下降。

主從鏈

有些用戶發現,建立多個從服務器可能會形成網絡不可用——當複製須要經過互聯網進行或者須要在不一樣數據中心之間進行時,尤其如此。由於Redis的主服務器和從服務器並無特別不一樣的地方,因此從服務器也能夠擁有本身的從服務器,並由此造成主從鏈(master/slavechaining)。

從服務器對從服務器進行復制在操做上和從服務器對主服務器進行復制的惟一區別在於,若是從服務器X擁有從服務器Y,那麼當從服務器X在執行表4-2中的步驟4時,它將斷開與從服務器Y的鏈接,致使從服務器Y須要從新鏈接並從新同步(resync)。

當讀請求的重要性明顯高於寫請求的重要性,而且讀請求的數量遠遠超出一臺Redis服務器能夠處理的範圍時,用戶就須要添加新的從服務器來處理讀請求。隨着負載不斷上升,主服務器可能會沒法快速地更新全部從服務器,或者由於從新鏈接和從新同步從服務器而致使系統超載。爲了緩解這個問題,用戶能夠建立一個由Redis主從節點(master/slavenode)組成的中間層來分擔主服務器的複製工做,如圖4-1所示。

 

儘管主從服務器之間並不必定要像圖4-1那樣組成一個樹狀結構,但記住並理解這種樹狀結構對於Redis複製來講是可行的(possible)而且是合理的(reasonable),將有助於讀者理解以後的內容。AOF持久化(參考:Redis數據持久化)的同步選項能夠控制數據丟失的時間長度:經過將每一個寫命令同步到硬盤裏面,用戶幾乎能夠不損失任何數據(除非系統崩潰或者硬盤驅動器損壞),但這種作法會對服務器的性能形成影響;另外一方面,若是用戶將同步的頻率設置爲每秒一次,那麼服務器的性能將回到正常水平,但故障可能會形成1秒的數據丟失。經過同時使用複製和AOF持久化,咱們能夠將數據持久化到多臺機器上面。

爲了將數據保存到多臺機器上面,用戶首先須要爲主服務器設置多個從服務器,而後對每一個從服務器設置appendonly yes選項和appendfsync everysec選項(若是有須要的話,也能夠對主服務器進行相同的設置),這樣的話,用戶就可讓多臺服務器以每秒一次的頻率將數據同步到硬盤上了。但這還只是第一步:由於用戶還必須等待主服務器發送的寫命令到達從服務器,而且在執行後續操做以前,檢查數據是否已經被同步到了硬盤裏面。

參考資料

黃健宏:<Redis實戰>

相關文章
相關標籤/搜索