免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Redis復(fù)制與可擴(kuò)展集群搭建

Redis復(fù)制流程概述

Redis的復(fù)制功能是完全建立在之前我們討論過的基于內(nèi)存快照的持久化策略基礎(chǔ)上的,也就是說無論你的持久化策略選擇的是什么,只要用到了Redis的復(fù)制功能,就一定會有內(nèi)存快照發(fā)生,那么首先要注意你的系統(tǒng)內(nèi)存容量規(guī)劃,原因可以參考我上一篇文章中提到的Redis磁盤IO問題。

Redis復(fù)制流程在Slave和Master端各自是一套狀態(tài)機(jī)流轉(zhuǎn),涉及的狀態(tài)信息是:

Slave 端:

REDIS_REPL_NONEREDIS_REPL_CONNECTREDIS_REPL_CONNECTED 

Master端:

REDIS_REPL_WAIT_BGSAVE_STARTREDIS_REPL_WAIT_BGSAVE_ENDREDIS_REPL_SEND_BULKREDIS_REPL_ONLINE

整個(gè)狀態(tài)機(jī)流程過程如下:

  1. Slave端在配置文件中添加了slave of指令,于是Slave啟動時(shí)讀取配置文件,初始狀態(tài)為REDIS_REPL_CONNECT。
  2. Slave端在定時(shí)任務(wù)serverCron(Redis內(nèi)部的定時(shí)器觸發(fā)事件)中連接Master,發(fā)送sync命令,然后阻塞等待master發(fā)送回其內(nèi)存快照文件(最新版的Redis已經(jīng)不需要讓Slave阻塞)。
  3. Master端收到sync命令簡單判斷是否有正在進(jìn)行的內(nèi)存快照子進(jìn)程,沒有則立即開始內(nèi)存快照,有則等待其結(jié)束,當(dāng)快照完成后會將該文件發(fā)送給Slave端。
  4. Slave端接收Master發(fā)來的內(nèi)存快照文件,保存到本地,待接收完成后,清空內(nèi)存表,重新讀取Master發(fā)來的內(nèi)存快照文件,重建整個(gè)內(nèi)存表數(shù)據(jù)結(jié)構(gòu),并最終狀態(tài)置位為 REDIS_REPL_CONNECTED狀態(tài),Slave狀態(tài)機(jī)流轉(zhuǎn)完成。
  5. Master端在發(fā)送快照文件過程中,接收的任何會改變數(shù)據(jù)集的命令都會暫時(shí)先保存在Slave網(wǎng)絡(luò)連接的發(fā)送緩存隊(duì)列里(list數(shù)據(jù)結(jié)構(gòu)),待快照完成后,依次發(fā)給Slave,之后收到的命令相同處理,并將狀態(tài)置位為 REDIS_REPL_ONLINE。

整個(gè)復(fù)制過程完成,流程如下圖所示:

Redis復(fù)制機(jī)制的缺陷

從上面的流程可以看出,Slave從庫在連接Master主庫時(shí),Master會進(jìn)行內(nèi)存快照,然后把整個(gè)快照文件發(fā)給Slave,也就是沒有象MySQL那樣有復(fù)制位置的概念,即無增量復(fù)制,這會給整個(gè)集群搭建帶來非常多的問題。

比如一臺線上正在運(yùn)行的Master主庫配置了一臺從庫進(jìn)行簡單讀寫分離,這時(shí)Slave由于網(wǎng)絡(luò)或者其它原因與Master斷開了連接,那么當(dāng)Slave進(jìn)行重新連接時(shí),需要重新獲取整個(gè)Master的內(nèi)存快照,Slave所有數(shù)據(jù)跟著全部清除,然后重新建立整個(gè)內(nèi)存表,一方面Slave恢復(fù)的時(shí)間會非常慢,另一方面也會給主庫帶來壓力。

所以基于上述原因,如果你的Redis集群需要主從復(fù)制,那么最好事先配置好所有的從庫,避免中途再去增加從庫。

Cache還是Storage

在我們分析過了Redis的復(fù)制與持久化功能后,我們不難得出一個(gè)結(jié)論,實(shí)際上Redis目前發(fā)布的版本還都是一個(gè)單機(jī)版的思路,主要的問題集中在,持久化方式不夠成熟,復(fù)制機(jī)制存在比較大的缺陷,這時(shí)我們又開始重新思考Redis的定位:Cache還是Storage?

如果作為Cache的話,似乎除了有些非常特殊的業(yè)務(wù)場景,必須要使用Redis的某種數(shù)據(jù)結(jié)構(gòu)之外,我們使用Memcached可能更合適,畢竟Memcached無論客戶端包和服務(wù)器本身更久經(jīng)考驗(yàn)。

如果是作為存儲Storage的話,我們面臨的最大的問題是無論是持久化還是復(fù)制都沒有辦法解決Redis單點(diǎn)問題,即一臺Redis掛掉了,沒有太好的辦法能夠快速的恢復(fù),通常幾十G的持久化數(shù)據(jù),Redis重啟加載需要幾個(gè)小時(shí)的時(shí)間,而復(fù)制又有缺陷,如何解決呢?

Redis可擴(kuò)展集群搭建

1. 主動復(fù)制避開Redis復(fù)制缺陷。

既然Redis的復(fù)制功能有缺陷,那么我們不妨放棄Redis本身提供的復(fù)制功能,我們可以采用主動復(fù)制的方式來搭建我們的集群環(huán)境。

所謂主動復(fù)制是指由業(yè)務(wù)端或者通過代理中間件對Redis存儲的數(shù)據(jù)進(jìn)行雙寫或多寫,通過數(shù)據(jù)的多份存儲來達(dá)到與復(fù)制相同的目的,主動復(fù)制不僅限于用在Redis集群上,目前很多公司采用主動復(fù)制的技術(shù)來解決MySQL主從之間復(fù)制的延遲問題,比如Twitter還專門開發(fā)了用于復(fù)制和分區(qū)的中間件gizzard(https://github.com/twitter/gizzard) 。

主動復(fù)制雖然解決了被動復(fù)制的延遲問題,但也帶來了新的問題,就是數(shù)據(jù)的一致性問題,數(shù)據(jù)寫2次或多次,如何保證多份數(shù)據(jù)的一致性呢?如果你的應(yīng)用對數(shù)據(jù)一致性要求不高,允許最終一致性的話,那么通常簡單的解決方案是可以通過時(shí)間戳或者vector clock等方式,讓客戶端同時(shí)取到多份數(shù)據(jù)并進(jìn)行校驗(yàn),如果你的應(yīng)用對數(shù)據(jù)一致性要求非常高,那么就需要引入一些復(fù)雜的一致性算法比如Paxos來保證數(shù)據(jù)的一致性,但是寫入性能也會相應(yīng)下降很多。

通過主動復(fù)制,數(shù)據(jù)多份存儲我們也就不再擔(dān)心Redis單點(diǎn)故障的問題了,如果一組Redis集群掛掉,我們可以讓業(yè)務(wù)快速切換到另一組Redis上,降低業(yè)務(wù)風(fēng)險(xiǎn)。

2. 通過presharding進(jìn)行Redis在線擴(kuò)容。

通過主動復(fù)制我們解決了Redis單點(diǎn)故障問題,那么還有一個(gè)重要的問題需要解決:容量規(guī)劃與在線擴(kuò)容問題。

我們前面分析過Redis的適用場景是全部數(shù)據(jù)存儲在內(nèi)存中,而內(nèi)存容量有限,那么首先需要根據(jù)業(yè)務(wù)數(shù)據(jù)量進(jìn)行初步的容量規(guī)劃,比如你的業(yè)務(wù)數(shù)據(jù)需要100G存儲空間,假設(shè)服務(wù)器內(nèi)存是48G,那么根據(jù)上一篇我們討論的Redis磁盤IO的問題,我們大約需要3~4臺服務(wù)器來存儲。這個(gè)實(shí)際是對現(xiàn)有業(yè)務(wù)情況所做的一個(gè)容量規(guī)劃,假如業(yè)務(wù)增長很快,很快就會發(fā)現(xiàn)當(dāng)前的容量已經(jīng)不夠了,Redis里面存儲的數(shù)據(jù)很快就會超過物理內(nèi)存大小,那么如何進(jìn)行Redis的在線擴(kuò)容呢?

Redis的作者提出了一種叫做presharding的方案來解決動態(tài)擴(kuò)容和數(shù)據(jù)分區(qū)的問題,實(shí)際就是在同一臺機(jī)器上部署多個(gè)Redis實(shí)例的方式,當(dāng)容量不夠時(shí)將多個(gè)實(shí)例拆分到不同的機(jī)器上,這樣實(shí)際就達(dá)到了擴(kuò)容的效果。

拆分過程如下:

  1. 在新機(jī)器上啟動好對應(yīng)端口的Redis實(shí)例。
  2. 配置新端口為待遷移端口的從庫。
  3. 待復(fù)制完成,與主庫完成同步后,切換所有客戶端配置到新的從庫的端口。
  4. 配置從庫為新的主庫。
  5. 移除老的端口實(shí)例。
  6. 重復(fù)上述過程遷移好所有的端口到指定服務(wù)器上。

以上拆分流程是Redis作者提出的一個(gè)平滑遷移的過程,不過該拆分方法還是很依賴Redis本身的復(fù)制功能的,如果主庫快照數(shù)據(jù)文件過大,這個(gè)復(fù)制的過程也會很久,同時(shí)會給主庫帶來壓力。所以做這個(gè)拆分的過程最好選擇為業(yè)務(wù)訪問低峰時(shí)段進(jìn)行。

Redis復(fù)制的改進(jìn)思路

我們線上的系統(tǒng)使用了我們自己改進(jìn)版的Redis,主要解決了Redis沒有增量復(fù)制的缺陷,能夠完成類似Mysql Binlog那樣可以通過從庫請求日志位置進(jìn)行增量復(fù)制。

我們的持久化方案是首先寫Redis的AOF文件,并對這個(gè)AOF文件按文件大小進(jìn)行自動分割滾動,同時(shí)關(guān)閉Redis的Rewrite命令,然后會在業(yè)務(wù)低峰時(shí)間進(jìn)行內(nèi)存快照存儲,并把當(dāng)前的AOF文件位置一起寫入到快照文件中,這樣我們可以使快照文件與AOF文件的位置保持一致性,這樣我們得到了系統(tǒng)某一時(shí)刻的內(nèi)存快照,并且同時(shí)也能知道這一時(shí)刻對應(yīng)的AOF文件的位置,那么當(dāng)從庫發(fā)送同步命令時(shí),我們首先會把快照文件發(fā)送給從庫,然后從庫會取出該快照文件中存儲的AOF文件位置,并將該位置發(fā)給主庫,主庫會隨后發(fā)送該位置之后的所有命令,以后的復(fù)制就都是這個(gè)位置之后的增量信息了。

Redis與MySQL的結(jié)合

目前大部分互聯(lián)網(wǎng)公司使用MySQL作為數(shù)據(jù)的主要持久化存儲,那么如何讓Redis與MySQL很好的結(jié)合在一起呢?我們主要使用了一種基于MySQL作為主庫,Redis作為高速數(shù)據(jù)查詢從庫的異構(gòu)讀寫分離的方案。

為此我們專門開發(fā)了自己的MySQL復(fù)制工具,可以方便的實(shí)時(shí)同步MySQL中的數(shù)據(jù)到Redis上。

(MySQL-Redis 異構(gòu)讀寫分離)

總結(jié):

  1. Redis的復(fù)制功能沒有增量復(fù)制,每次重連都會把主庫整個(gè)內(nèi)存快照發(fā)給從庫,所以需要避免向在線服務(wù)的壓力較大的主庫上增加從庫。
  2. Redis的復(fù)制由于會使用快照持久化方式,所以如果你的Redis持久化方式選擇的是日志追加方式(aof),那么系統(tǒng)有可能在同一時(shí)刻既做aof日志文件的同步刷寫磁盤,又做快照寫磁盤操作,這個(gè)時(shí)候Redis的響應(yīng)能力會受到影響。所以如果選用aof持久化,則加從庫需要更加謹(jǐn)慎。
  3. 可以使用主動復(fù)制和presharding方法進(jìn)行Redis集群搭建與在線擴(kuò)容。

本文加上之前的2篇文章基本將Redis的最常用功能和使用場景與優(yōu)化進(jìn)行了分析和討論,實(shí)際Redis還有很多其它輔助的一些功能,Redis的作者也在不斷嘗試新的思路,這里就不一一列舉了,有興趣的朋友可以研究下,也很歡迎一起討論,我的微博(http://weibo.com/bachmozart ) @搖擺巴赫。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
一文帶你揭開Redis復(fù)制原理的神秘面紗
redis主從復(fù)制和集群實(shí)現(xiàn)原理
redis介紹
一文掌握Redis的三種集群方案
NoSQL初探之人人都愛Redis:(4)Redis主從復(fù)制架構(gòu)初步探索
redis 面試總結(jié)篇
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服