前言
現(xiàn)在遇到高并發(fā)場(chǎng)景時(shí),緩存技術(shù)應(yīng)該算是性能優(yōu)化的第一步,緩解數(shù)據(jù)庫(kù)壓力的同時(shí)還能提高訪問效率钓瞭,而Redis應(yīng)該是絕大多數(shù)應(yīng)用場(chǎng)景的首選。但是盡快Redis性能再優(yōu)秀淫奔,在當(dāng)今高并發(fā)場(chǎng)景下山涡,一臺(tái)服務(wù)器負(fù)責(zé)讀寫,機(jī)器的性能和內(nèi)存的瓶頸肯定避免不了唆迁,到這肯定有小伙伴會(huì)想到集群佳鳖, 對(duì)的,思路沒錯(cuò)媒惕,只是在集群之前,主從復(fù)制模式的優(yōu)化策略能解決很多問題来庭,如果主從模式還抗不住高并發(fā)妒蔚,那再來集群也不晚;這里先來說說Redis的主從復(fù)制。
為了更好的演示肴盏,搞了一臺(tái)云服務(wù)器科盛,Linux環(huán)境; 方便的同時(shí)菜皂,也能更符合實(shí)際應(yīng)用場(chǎng)景贞绵;
正文
主從復(fù)制:主從指有多臺(tái)Redis服務(wù)器,其中一臺(tái)為主服務(wù)器恍飘,其他為從服務(wù)器榨崩,可以通過命令或配置實(shí)現(xiàn)主從關(guān)系;復(fù)制指將主服務(wù)器的數(shù)據(jù)同步到從服務(wù)器章母,數(shù)據(jù)只能從主服務(wù)器向從服務(wù)器單向同步母蛛;其作用如下:
- 讀寫分離:主服務(wù)器復(fù)制寫,各從服務(wù)器負(fù)責(zé)讀乳怎;根據(jù)二八原則彩郊,80%的操作都是讀,只有20%進(jìn)行寫蚪缀,所以在一定程度上也解決了單機(jī)瓶頸問題秫逝;
- 數(shù)據(jù)持久化更加安全:主從多臺(tái)服務(wù)器進(jìn)行持久化操作,任意一臺(tái)服務(wù)宕機(jī)也不會(huì)影響數(shù)據(jù)恢復(fù)询枚,避免了單點(diǎn)故障問題违帆;
- 其他:主從復(fù)制是實(shí)現(xiàn)哨兵模式和Redis集群的前提,這個(gè)后續(xù)會(huì)說到哩盲。
好啦前方,老規(guī)矩,了解其作用之后廉油,接下來就先實(shí)操再總結(jié)惠险。
實(shí)現(xiàn)主從復(fù)制
每一臺(tái)Redis服務(wù)器啟動(dòng)時(shí),默認(rèn)都是主服務(wù)器(Master)抒线,可以通過命令info replication
查看,如下圖所示:
開始實(shí)操搭建一主二從的環(huán)境抱慌,如下:
1. 配置文件修改
由于是在同一臺(tái)機(jī)器上模擬眨猎,所以將redis配置文件拷貝三份出來,主要修改項(xiàng)如下:
- 配置文件名稱:分別為redis.conf睡陪、redis6388.conf匿情、redis6399.conf信殊;
- port:端口,三個(gè)配置文件分別修改為6379涡拘、6388、6399鳄乏,這是為了避免同一臺(tái)機(jī)器演示端口沖突跷车;
- pidfile:修改此文件名,避免文件沖突汞窗,改文件名即可姓赤,分別修改為redis.pid、redis6388.pid仲吏、redis6399.pid不铆;
- dbfilename:持久化文件名,避免持久化文件沖突裹唆,分別修改為dump.rdb誓斥、dump6388.rdb、dump6399.rdb许帐;
2. 啟動(dòng)redis服務(wù)器
然后分別指定配置文件啟動(dòng)redis-server劳坑,在redis中bin目錄下執(zhí)行./redis-server redis.conf
、./redis-server redis6388.conf
成畦、./redis-server redis6399.conf
命令即可距芬,可以通過命令ps -ef | grep redis
查看啟動(dòng)redis效果,如下:
3.1 使用命令實(shí)現(xiàn)主從關(guān)系
默認(rèn)情況下循帐,啟動(dòng)的三臺(tái)服務(wù)器默認(rèn)都是主服務(wù)器框仔,現(xiàn)在可以通過簡(jiǎn)單的命令實(shí)現(xiàn)一主二從的關(guān)系,這里以6379這臺(tái)服務(wù)器為主拄养,6388和6399兩臺(tái)服務(wù)器為從离斩,配置主從關(guān)系只針對(duì)從節(jié)點(diǎn)服務(wù)器配置即可,如下:
-
分別連上6388和6399兩臺(tái)服務(wù)器瘪匿,執(zhí)行
slaveof masterip masterport
即可: -
從節(jié)點(diǎn)顯示沒問題跛梗,看看主節(jié)點(diǎn)狀態(tài)信息,連上6379這臺(tái)看看棋弥,如下:
-
主從關(guān)系維護(hù)好了核偿,接下來看看數(shù)據(jù)復(fù)制,通常主節(jié)點(diǎn)負(fù)責(zé)寫顽染,將數(shù)據(jù)同步到從節(jié)點(diǎn)宪祥,從節(jié)點(diǎn)負(fù)責(zé)讀蝗羊; 現(xiàn)在三臺(tái)服務(wù)器都沒數(shù)據(jù)耀找,接下來往主節(jié)點(diǎn)中寫入點(diǎn)數(shù)據(jù)野芒,看看是否能同步到從節(jié)點(diǎn):
注:如果通過命令方式實(shí)現(xiàn)主從關(guān)系狞悲,那當(dāng)從服務(wù)器重啟時(shí)摇锋,主從關(guān)系就丟了荸恕,還得手動(dòng)再執(zhí)行命令融求,所以推薦配置文件的形式進(jìn)行配置生宛;
3.2 通過配置文件實(shí)現(xiàn)主從配置
還是很簡(jiǎn)單的陷舅,主服務(wù)器不用動(dòng)蔑赘,僅修改從服務(wù)器配置文件缩赛,然后重啟即可酥馍,根據(jù)前面章節(jié)的學(xué)習(xí)經(jīng)驗(yàn)阅酪,打開配置文件,直接找到REPLICATION模塊進(jìn)行如下配置修改:
-
replicaof <masterip> <masterport>
:指定主節(jié)點(diǎn)ip和端口即可施无,如:replicaof 127.0.0.1 6379
; -
masterauth <master-password>
:指定主節(jié)點(diǎn)密碼猾骡,如果主節(jié)點(diǎn)配置密碼兴想,直接通過這配置就行赡勘;
修改完這兩項(xiàng)闸与,重啟服務(wù)器即可几迄,和命令行一樣簡(jiǎn)單映胁,只是通過配置文件搭建的主從關(guān)系不會(huì)因?yàn)殛P(guān)閉服務(wù)器而丟失解孙;這里配置文件的演示就不截圖了弛姜,只是實(shí)現(xiàn)方式不一樣廷臼,其他都是和命令行一致;
小總結(jié)
配從不配主寂恬,即只針對(duì)從服務(wù)器配置即可初肉,主服務(wù)器無需配置牙咏;
-
一個(gè)主節(jié)點(diǎn)有多個(gè)從節(jié)點(diǎn)妄壶,從節(jié)點(diǎn)只能有一個(gè)主節(jié)點(diǎn);從節(jié)點(diǎn)也可以作為其他從節(jié)點(diǎn)的主節(jié)點(diǎn)盒发,如下:
這種方式的演示截圖就不提供了,小伙伴實(shí)操一把奢浑,這里說明一下雀彼,雖然6388是6399的主節(jié)點(diǎn)徊哑,但扮演的角色還是6379的從節(jié)點(diǎn)莺丑,只是它下面連接了其他從節(jié)點(diǎn)而已梢莽;
如果用命令方式實(shí)現(xiàn)主從昏名,主服務(wù)器斷開后轻局,重新連接仑扑,主從關(guān)系還在颂斜;從服務(wù)器斷開之后重連關(guān)系消失沃疮,需要手動(dòng)執(zhí)行命令重新指定主節(jié)點(diǎn);
如果希望斷開重連主從關(guān)系還在姨蝴,推薦配置文件方式實(shí)現(xiàn)左医;
實(shí)現(xiàn)主從復(fù)制的搭建是不是很簡(jiǎn)單同木,不管是命令還是配置文件的方式彤路,都很輕松實(shí)現(xiàn)洲尊;但小伙伴是不是也有疑問: 主從節(jié)點(diǎn)之間的數(shù)據(jù)是如何同步的坞嘀?關(guān)于主從復(fù)制的其他參數(shù)有什么用丽涩?
主從復(fù)制原理
通過上面實(shí)操,在主服務(wù)器中寫入的數(shù)據(jù)检眯,在無感知的情況下就同步到各個(gè)從服務(wù)器锰瘸,中間到底經(jīng)歷了什么呢避凝? 接下來簡(jiǎn)單的了解一下管削;
在Redis2.8之前同步方式都以全量方式同步含思,之后為了提高效率含潘,數(shù)據(jù)復(fù)制方式分為兩種遏弱,一種為全量復(fù)制漱逸,一種為部分復(fù)制:
- 全量復(fù)制:即將主服務(wù)器中的數(shù)據(jù)饰抒,全部同步到從服務(wù)器袋坑;一般是在從服務(wù)器啟動(dòng)初始化數(shù)據(jù)的時(shí)候進(jìn)行全量同步咒彤;
- 部分復(fù)制:即將未同步的增量數(shù)據(jù)镶柱,同步到從服務(wù)器歇拆,無需全部再同步一遍故觅;一般用于因網(wǎng)絡(luò)中斷等無法同步數(shù)據(jù)的情況输吏,待恢復(fù)正常之后贯溅,將中斷期間數(shù)據(jù)進(jìn)行部分同步它浅;
為了方便查看日志分析镣煮,使用兩臺(tái)redis服務(wù)器進(jìn)行搭建主從, 將之前搭建的關(guān)系去除胯府,通過修改配置文件重啟即可盟劫;
這里以6388作為主節(jié)點(diǎn)(Master)侣签,6399作為從節(jié)點(diǎn)(Slave)影所,當(dāng)連接6399執(zhí)行命令slaveof 127.0.0.1 6388
配置主從關(guān)系時(shí)猴娩,主從節(jié)點(diǎn)分別打印日志如下:
上圖是剛開始建立主從關(guān)系時(shí)卷中,進(jìn)行了全量復(fù)制蟆豫,大概流程如下:
簡(jiǎn)要說明:
- 從節(jié)點(diǎn)與主節(jié)點(diǎn)建立連接十减,然后發(fā)送同步請(qǐng)求psync帮辟;
- 主節(jié)點(diǎn)給從節(jié)點(diǎn)發(fā)送信息玩焰,replid和offset震捣,這兩個(gè)參數(shù)后續(xù)是判斷是否部分復(fù)制的關(guān)鍵數(shù)據(jù)蒿赢;
- 主節(jié)點(diǎn)fork子進(jìn)程將全部數(shù)據(jù)生成RDB文件;
- 主節(jié)點(diǎn)期間接收到的寫命令存入到復(fù)制緩沖區(qū)中壹若;
- 當(dāng)主節(jié)點(diǎn)RDB文件完成之后發(fā)送給從節(jié)點(diǎn)店展;
- 從節(jié)點(diǎn)接收到文件赂蕴,先清空老數(shù)據(jù);
- 從節(jié)點(diǎn)清空數(shù)據(jù)后碧注,加載接收到的數(shù)據(jù)到內(nèi)存中萍丐;
- 主節(jié)點(diǎn)發(fā)送復(fù)制緩沖區(qū)中的數(shù)據(jù)到從節(jié)點(diǎn)逝变;
- 從節(jié)點(diǎn)接收到命令并執(zhí)行壳影,最終同步到最新數(shù)據(jù)态贤;
主從關(guān)系是通過網(wǎng)絡(luò)進(jìn)行通訊醋火,可能出現(xiàn)網(wǎng)絡(luò)中斷或網(wǎng)絡(luò)抖動(dòng)情況芥驳,導(dǎo)致短時(shí)間的數(shù)據(jù)不能及時(shí)同步到從節(jié)點(diǎn)上兆旬,理想情況下丽猬,當(dāng)連接恢復(fù)的時(shí)候脚祟,希望只同步中斷期間的數(shù)據(jù)由桌,從而提高同步效率行您,流程大概如下:
簡(jiǎn)要說明:
- 當(dāng)主從之間由于網(wǎng)絡(luò)中斷時(shí)娃循,從節(jié)點(diǎn)會(huì)嘗試重連主節(jié)點(diǎn)捌斧;
- 在此期間,主節(jié)點(diǎn)接收到的寫命令會(huì)記錄到復(fù)制緩沖區(qū)中经瓷;
- 當(dāng)網(wǎng)絡(luò)恢復(fù)舆吮,從節(jié)點(diǎn)連上主節(jié)點(diǎn)队贱,會(huì)請(qǐng)求發(fā)布同步請(qǐng)求psync柱嫌,并帶上之前主節(jié)點(diǎn)發(fā)送過來的replid和offset;
- 主節(jié)點(diǎn)接收到從節(jié)點(diǎn)的請(qǐng)求与学,會(huì)驗(yàn)證接收的replid與主節(jié)點(diǎn)replid是否匹配索守,不匹配會(huì)進(jìn)行全量復(fù)制卵佛;還會(huì)驗(yàn)證offset數(shù)據(jù)偏移量是否在合法范圍內(nèi)截汪,如果中斷期間數(shù)據(jù)量過大衙解,導(dǎo)致復(fù)制緩沖區(qū)的數(shù)據(jù)超出丢郊,主從節(jié)點(diǎn)的offset數(shù)據(jù)偏移量不一致枫匾,也會(huì)進(jìn)行全復(fù)制干茉;
- 當(dāng)從節(jié)點(diǎn)傳遞過來的replid和offset驗(yàn)證通過時(shí),則進(jìn)行部分復(fù)制沾谓,并記錄最新的offset均驶;
這里就不模擬演示部分復(fù)制流程了,留給小伙伴操作隶债。演示流程如下:已經(jīng)搭建主從關(guān)系的兩臺(tái)機(jī)器死讹,手動(dòng)模擬網(wǎng)絡(luò)斷開,斷開期間在主服務(wù)器寫入數(shù)據(jù)妓忍,一會(huì)之后恢復(fù)網(wǎng)絡(luò),查看主從服務(wù)器日志打印情況忘瓦;
主從復(fù)制的相關(guān)配置參數(shù)
以上演示在配置文件中只是配置了部分參數(shù)耕皮,還有其他參數(shù)的配置可以輕松實(shí)現(xiàn)功能凌停,這里結(jié)合主從復(fù)制的內(nèi)容可以回顧一下相關(guān)配置參數(shù)的意義罚拟,如下:
- slaveof:設(shè)置本機(jī)為從機(jī)赐俗,指定主機(jī)的IP和端口阻逮;
- masterauth:如果主機(jī)需要密碼叔扼,通過這設(shè)置;
- slave-serve-stale-data:從機(jī)如果與主機(jī)斷開或數(shù)據(jù)正在同步鳍咱,獲取數(shù)據(jù)是否繼續(xù)谤辜,如果設(shè)置為yes每辟,還可以正常讀取數(shù)據(jù)干旧,設(shè)置為no渠欺,獲取數(shù)據(jù)返回錯(cuò)誤提示;
- slave-read-only:配置從主機(jī)為只讀模式椎眯,默認(rèn)為yes挠将,也強(qiáng)烈建議為只讀模式;
- repl-diskless-sync:是否采用無磁盤方式進(jìn)行主從傳遞數(shù)據(jù)编整,即采用Socket方式舔稀,默認(rèn)沒采用,如果機(jī)器磁盤性能不好掌测,而網(wǎng)絡(luò)環(huán)境良好内贮,可以嘗試使用這種模式;
- repl-diskless-sync-delay:當(dāng)使用無磁盤方式傳遞數(shù)據(jù)時(shí),服務(wù)器開始傳遞數(shù)據(jù)前等待指定時(shí)間,等待從服務(wù)器進(jìn)入傳輸隊(duì)列事富,提高數(shù)據(jù)傳輸效率,默認(rèn)為5秒;
- repl-ping-slave-period:設(shè)置從機(jī)向主機(jī)發(fā)送ping消息間隔,即理解為心跳檢測(cè);
- repl-timeout:設(shè)置超時(shí)時(shí)間恰画,主從機(jī)傳遞數(shù)據(jù)的時(shí)間片林,如果超過指定時(shí)間弓摘,從機(jī)會(huì)重連研叫。一般主從復(fù)制數(shù)據(jù)比較大時(shí)渤昌,可以將其改大迈窟,默認(rèn)為60s 湖员;
- repl-disable-tcp-nodelay:主從復(fù)制數(shù)據(jù)是否采用TCP_NODELAY唤反,默認(rèn)為no,代表不啟用,標(biāo)識(shí)主機(jī)立即同步數(shù)據(jù),保證數(shù)據(jù)一致性失效;如果設(shè)置為yes蒋腮,合并較小的TCP包一并發(fā)送作彤,延遲高浙踢,但可以提升帶寬性能蹬挤,但推薦不啟用蓝翰;
- repl-backlog-size:用于設(shè)置復(fù)制緩沖區(qū)的大小爆雹,此緩沖區(qū)用于從機(jī)斷開重連之后同步的增量數(shù)據(jù)册倒,在一定時(shí)間內(nèi)不用全量復(fù)制崇呵,提升同步效率犹褒;默認(rèn)為1mb付材,可以根據(jù)需求進(jìn)行修改;
- repl-backlog-ttl:設(shè)置從機(jī)斷開后沒有連接主機(jī)的間隔時(shí)間恤左,超過此時(shí)間蹄皱,設(shè)置的backlog緩沖區(qū)就會(huì)釋放署拟,默認(rèn)為3600s;
- slave-priority:用于哨兵模式選擇炉爆,即當(dāng)主機(jī)掛掉時(shí)波附,選擇優(yōu)先級(jí)較高的從機(jī)代替掛掉的主機(jī)盏求,快速恢復(fù)竟趾;默認(rèn)值為100账蓉;
- min-slaves-to-write 3:指可用從服務(wù)器少于3個(gè)時(shí)波丰,主服務(wù)器只能讀先馆,不能寫徙歼,一般和min-slaves-max-lag搭配用辣苏,默認(rèn)不使用档玻,根據(jù)需要進(jìn)行配置纤怒;
- min-slaves-max-lag 10:指從服務(wù)器的延遲超過10秒時(shí),主服務(wù)器也只能讀龟劲,不能寫蚕愤,一般和min-slaves-to-write搭配用,默認(rèn)不使用,根據(jù)需要進(jìn)行配置;
主從復(fù)制有哪些問題
主從復(fù)制緩解了單節(jié)點(diǎn)性能和存儲(chǔ)的瓶頸,那又帶來什么問題呢软免?
- 主從復(fù)制架構(gòu)會(huì)有延時(shí)曹锨,盡快很快,也有凤壁,特別數(shù)據(jù)量和并發(fā)大的時(shí)候吩屹;目前的主從架構(gòu)沒有好的方法處理延時(shí),MySql拧抖、SqlServer也是如此煤搜;
- 過期Key數(shù)據(jù)在早期版本不能及時(shí)將從服務(wù)器數(shù)據(jù)失效,可以升級(jí)到redis3.2之后解決唧席,因?yàn)榧尤肓诉^期判斷擦盾;
- 主節(jié)點(diǎn)宕機(jī)之后,只能手動(dòng)重新配置主從關(guān)系淌哟,從服務(wù)器可以執(zhí)行
slaveof no one
命令重寫回到主服務(wù)器角色迹卢,然后重新配置主從關(guān)系; - 如果從節(jié)點(diǎn)過多徒仓,當(dāng)剛開始初始化數(shù)據(jù)全量同步或多個(gè)從節(jié)點(diǎn)斷開重連時(shí)腐碱,就會(huì)導(dǎo)致主節(jié)點(diǎn)的IO劇增;
總結(jié)
主從復(fù)制演練看似簡(jiǎn)單掉弛,但還需要不斷在實(shí)踐中獲取經(jīng)驗(yàn)症见,搭配相關(guān)配置參數(shù),從而使得更加適合應(yīng)用場(chǎng)景殃饿;配置沒有固定都一樣谋作,而是應(yīng)用場(chǎng)景是否適合。隨著主節(jié)點(diǎn)宕機(jī)不能自動(dòng)選舉的問題乎芳,下次在此基礎(chǔ)上說說哨兵模式遵蚜,讓自動(dòng)選舉不是問題;
一個(gè)被程序搞丑的帥小伙奈惑,關(guān)注"Code綜藝圈"谬晕,跟我一起學(xué)~~~