redis全量複製的原理是,首先將master自己的RDB文件同步給slave,而在同步期間,master寫入的命令也會記錄下來(master內部有一個複製緩衝區,會記錄同步時master新增的寫入),當slave將RDB加載完後,會經過偏移量的對比將這期間master寫入的值同步給slave。redis
來看一張完整的複製流程圖:緩存
1. slave內部首先會發送一個psync的命令給master 這個命令第一個參數是runId,第二個參數是偏移量,而因爲是第一次複製,slave不知道master的runId,也不知道本身偏移量,這時候會傳一個問號和-1,告訴master節點是第一次同步。網絡
2. 當master接受到psync ? -1 時,就知道slave是要全量複製,就會將本身的runID和offset告知slavespa
3.slave會將master信息保存隊列
4.master這時會作一個RDB的生成(bgsave)進程
5.將RDB發送給slave內存
6.將複製緩衝區記錄的操做也發送給slave同步
7.slave清空本身的全部老數據ast
8.slave這時就會加載RDB文件以及複製緩衝區數據,完成同步。原理
1.bgsave的開銷,每次bgsave須要fork子進程,對內存和CPU的開銷很大
2.RDB文件網絡傳輸的時間(網絡帶寬)
3.從節點清空數據的時間
4.從節點加載RDB的時間
5.可能的AOF重寫時間(若是咱們的從節點開啓了AOF,則加載完RDB後會對AOF進行一個重寫,保證AOF是最新的)
爲何要部分複製? 在redis2.8版本以前,若是master和slave之間的網絡發生了抖動鏈接斷開,就會致使slave徹底不知道master的動做,同步就會出問題,而爲了保證數據一致,等網絡恢復後進行一次全量複製。而全量複製的開銷是很大的,redis2.8版本就提個了一個部分複製的功能。
部分複製的實現原理:
當master和slave斷開鏈接時,master會將期間所作的操做記錄到複製緩存區當中(能夠當作是一個隊列,其大小默認1M)。待slave重連後,slave會向master發送psync命令並傳入offset和runId,這時候,若是master發現slave傳輸的偏移量的值,在緩存區隊列範圍中,就會將從offset開始到隊列結束的數據傳給slave,從而達到同步,下降了使用全量複製的開銷。