單機有什么問題函似?
單機即在一臺機器上部署一個redis節(jié)點版扩,主要會存在以下問題:
1. 機器故障
如果發(fā)生機器故障,例如磁盤損壞,主板損壞等绍撞,未能在短時間內修復好正勒,客戶端將無法連接redis。
當然如果僅僅是redis節(jié)點掛掉了傻铣,可以進行問題排查然后重啟章贞,姑且不考慮這段時間對外服務的可用性,那還是可以接受的非洲。
而發(fā)生機器故障鸭限,基本是無濟于事。除非把redis遷移到另一臺機器上两踏,并且還要考慮數(shù)據(jù)同步的問題败京。
2. 容量瓶頸
假如一臺機器是16G內存,redis使用了12G內存缆瓣,而其他應用還需要使用內存喧枷,假設我們總共需要60G內存要如何去做呢,是否有必要購買64G內存的機器弓坞?
3. QPS瓶頸
redis官方數(shù)據(jù)顯示可以達到10w的QPS隧甚,如果業(yè)務需要100w的QPS怎么去做呢?
關于容量瓶頸和QPS瓶頸是redis分布式需要解決的問題渡冻,而機器故障就是高可用的問題了戚扳。
主從復制的作用
一主一從
如圖所示左邊是Master節(jié)點,右邊是slave節(jié)點族吻,即主節(jié)點和從節(jié)點帽借。從節(jié)點也是可以對外提供服務的,主節(jié)點是有數(shù)據(jù)的超歌,從節(jié)點可以通過復制操作將主節(jié)點的數(shù)據(jù)同步過來砍艾,并且隨著主節(jié)點數(shù)據(jù)不斷寫入,從節(jié)點數(shù)據(jù)也會做同步的更新巍举。
整體起到的就是數(shù)據(jù)備份的效果脆荷。
一主多從
除了一主一從模型之外,redis還提供了一主多從的模型懊悯,也就是一個master可以有多個slave蜓谋,也就相當于有了多份的數(shù)據(jù)副本。
這樣可以做一個更加高可用的選擇炭分,例如一個master和一個slave掛掉了桃焕,還能有其他的slave數(shù)據(jù)備份。
讀寫分離
除了作為數(shù)據(jù)備份捧毛,主從模型還能做另外一個功能观堂,就是讀寫分離让网。
讓master節(jié)點負責提供寫服務,而將數(shù)據(jù)讀取的壓力進行分流和負載师痕,分攤給所有的從節(jié)點寂祥。
主從復制的作用
- 數(shù)據(jù)副本(備份)
- 擴展讀性能(讀寫分離)
簡單總結
- 一個master可以有多個slave
- 一個slave只能有一個master
- 數(shù)據(jù)流向是單向的,master到slave
主從復制的配置
1. slaveof命令
如圖七兜,想讓6380節(jié)點成為6379的從節(jié)點,只需要執(zhí)行 slaveof
命令即可福扬,此復制命令是異步進行的腕铸,redis會自動進行后續(xù)數(shù)據(jù)復制的操作。
注:一般生產環(huán)境不允許主從節(jié)點都在一臺機器上铛碑,因為沒有任何的價值狠裹。
取消復制
如果6380節(jié)點不希望成為6379的從節(jié)點,可以執(zhí)行 slave of on one
命令汽烦,取消后6380節(jié)點的數(shù)據(jù)不會被清除涛菠,只是說后續(xù)6379節(jié)點新寫入的數(shù)據(jù)不會再同步到該節(jié)點了。
注意:如果取消復制后想slave一個新的主節(jié)點撇吞,新的主節(jié)點在同步給slave節(jié)點數(shù)據(jù)時俗冻,會先將從節(jié)點的數(shù)據(jù)全部清除
2. 修改配置
# 配置主節(jié)點的IP和端口號
slaveof ip port
# 從節(jié)點只做讀的操作,保證主從數(shù)據(jù)的一致性
slave-read-only yes
對比
runid和復制偏移量
redis每次啟動的時候都會有一個隨機的ID牍颈,作為一個標識迄薄,這個ID就是runid
,當然重啟之后值就改變了煮岁。
查看runid:redis-cli -p 6379 info | grep run
假如端口為6380的redis去復制6379讥蔽,知道runid
后,在6380上做一個標識画机,如果runid
改變了冶伞,說明主可能重啟了或者發(fā)生了其它變化,這時候就可以做一個全量復制把數(shù)據(jù)同步過來步氏∠烨荩或者第一次啟動時根本不知道6379的runid
,也會進行全量復制
偏移量:數(shù)據(jù)寫入量的字節(jié)
比如主執(zhí)行set hello world戳护,就會有一個偏移量金抡,然后從同步數(shù)據(jù),也會記錄一個偏移量
當兩個偏移量達到一致時候腌且,實際上數(shù)據(jù)就是完全同步的狀態(tài)梗肝。
啟動主從redis,并在寫入命令執(zhí)行前后查看主偏移量:
redis-cli -p 6379 info replication | grep master_repl
從節(jié)點會向主節(jié)點做一個上報铺董,把從節(jié)點的狀態(tài)同步給主節(jié)點巫击,這樣主節(jié)點就知道了從節(jié)點的偏移量
生產環(huán)境我們一般不關心這個值禀晓,有時候做監(jiān)控的時候會比對一下這兩個值的差,如果差的太多坝锰,說明主從是有問題的粹懒。
全量復制
全量復制主節(jié)點會將RDB文件也就是當前狀態(tài)去同步給slave,在此期間主新寫入的命令會單獨記錄起來顷级,然后當RDB文件加載完畢之后凫乖,會通過偏移量對比將這個期間產生的寫入值同步給slave,這樣就能達到數(shù)據(jù)完全同步的效果
全量復制過程
- 在其內部有一條命令
psync
弓颈,是做同步的命令帽芽,它可以完成全量復制和部分復制的功能,當啟動slave節(jié)點時翔冀,它會發(fā)送psync
命令給主節(jié)點导街,需要傳遞兩個參數(shù),runid
和offset
(偏移量)纤子,也就是從向主傳遞主節(jié)點的runid以及自己的偏移量搬瑰,對于第一次復制而言,就直接傳遞控硼?和 -1泽论,當然這個參數(shù)是由slave內部傳的。 - master接收到命令后知道從希望做全量復制卡乾,主就會將自己的runid和offset傳遞給從
- slave節(jié)點保存master的基本信息
- master執(zhí)行
bgsave
生成RDB文件佩厚,并且在此期間新產生的寫入命令會被記錄到repl_back_buffer
(復制緩沖區(qū)) - 主向從傳輸RDB文件
- 主向從發(fā)送復制緩沖區(qū)內容
- 清空從節(jié)點舊的數(shù)據(jù)
- 從節(jié)點加載RDB文件到內存中,同時加載緩沖區(qū)數(shù)據(jù)
全量復制的開銷
實際上全量復制的開銷是非常大的说订,主要體現(xiàn)在如下方面
- bgsave時間(對cpu抄瓦、 內存、硬盤都會有一定的開銷)
- RDB文件網(wǎng)絡傳輸時間(網(wǎng)絡帶寬)
- 從節(jié)點清空數(shù)據(jù)時間(根據(jù)從節(jié)點的數(shù)據(jù)規(guī)模)
- 從節(jié)點加載RDB的時間
- 可能的AOF重寫時間(在最后從加載完RDB之后如果開啟了AOF陶冷,會做AOF重寫)
全量復制除了上述開銷之外钙姊,還會有個問題:
假如master和slave網(wǎng)絡發(fā)生了抖動,那一段時間內這些數(shù)據(jù)就會丟失埂伦,對于slave來說這段時間master更新的數(shù)據(jù)是不知道的煞额。最簡單的方式就是再做一次全量復制,從而獲取到最新的數(shù)據(jù)沾谜,在redis2.8之前是這么做的膊毁。
部分復制
部分復制,redis2.8之后提供基跑。如果發(fā)生類似抖動時候婚温,可以有一種機制將這種損失降低到最低,如何實現(xiàn)的媳否?
- 如果發(fā)生了抖動栅螟,相當于連接斷開了
- 主會將寫命令記錄到緩沖區(qū)荆秦,repl_back_buffer
- 當slave再次去連接master時候,就是說網(wǎng)絡抖動結束之后力图,會觸發(fā)增量復制
- 從會執(zhí)行pysnc命令步绸,將當前自己的offset和主的runid傳遞給master
- 如果發(fā)現(xiàn)傳輸?shù)膐ffset偏移量是在buffer內的,不在期間內就證明你已經(jīng)錯過了很多數(shù)據(jù)吃媒,buffer也是有限的瓤介,默認是1M,會將offset開始到隊列結束的數(shù)據(jù)同步給從赘那。這樣master和slave就達到了一致惑朦。
通過部分復制(增量復制)有效的降低了全量復制的開銷。
復制的相關配置
無磁盤化復制
# 開啟無磁盤化復制
repl-diskless-sync yes
# 當收到第一個復制請求時漓概,等待 5s 后再開始復制,因為要等更多 slave 一起連接過來
repl-diskless-sync-delay 5
復制的限制
如果在復制期間病梢,rdb復制時間超過60秒胃珍,內存緩沖區(qū)持續(xù)消耗超過64MB,或者一次性超過256MB蜓陌,那么將會停止復制(失敗)
配置項:client-output-buffer-limit slave 256MB 64MB 60
`