本文轉(zhuǎn)自互聯(lián)網(wǎng)
專業(yè)領(lǐng)域包括成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、商城建設(shè)、微信營(yíng)銷、系統(tǒng)平臺(tái)開(kāi)發(fā), 與其他網(wǎng)站設(shè)計(jì)及系統(tǒng)開(kāi)發(fā)公司不同,成都創(chuàng)新互聯(lián)的整合解決方案結(jié)合了幫做網(wǎng)絡(luò)品牌建設(shè)經(jīng)驗(yàn)和互聯(lián)網(wǎng)整合營(yíng)銷的理念,并將策略和執(zhí)行緊密結(jié)合,為客戶提供全網(wǎng)互聯(lián)網(wǎng)整合方案。
本系列文章將整理到我在GitHub上的《Java面試指南》倉(cāng)庫(kù),更多精彩內(nèi)容請(qǐng)到我的倉(cāng)庫(kù)里查看
https://github.com/h3pl/Java-Tutorial
喜歡的話麻煩點(diǎn)下Star哈
文章首發(fā)于我的個(gè)人博客:
www.how2playlife.com
本文是微信公眾號(hào)【Java技術(shù)江湖】的《探索redis設(shè)計(jì)與實(shí)現(xiàn)》其中一篇,本文部分內(nèi)容來(lái)源于網(wǎng)絡(luò),為了把本文主題講得清晰透徹,也整合了很多我認(rèn)為不錯(cuò)的技術(shù)博客內(nèi)容,引用其中了一些比較好的博客文章,如有侵權(quán),請(qǐng)聯(lián)系作者。
該系列博文會(huì)告訴你如何從入門到進(jìn)階,Redis基本的使用方法,Redis的基本數(shù)據(jù)結(jié)構(gòu),以及一些進(jìn)階的使用方法,同時(shí)也需要進(jìn)一步了解Redis的底層數(shù)據(jù)結(jié)構(gòu),再接著,還會(huì)帶來(lái)Redis主從復(fù)制、集群、分布式鎖等方面的相關(guān)內(nèi)容,以及作為緩存的一些使用方法和注意事項(xiàng),以便讓你更完整地了解整個(gè)Redis相關(guān)的技術(shù)體系,形成自己的知識(shí)框架。
如果對(duì)本系列文章有什么建議,或者是有什么疑問(wèn)的話,也可以關(guān)注公眾號(hào)【Java技術(shù)江湖】聯(lián)系作者,歡迎你參與本系列博文的創(chuàng)作和修訂。
轉(zhuǎn)自網(wǎng)絡(luò),侵刪
早期的RDBMS被設(shè)計(jì)為運(yùn)行在單個(gè)CPU之上,讀寫操作都由經(jīng)單個(gè)數(shù)據(jù)庫(kù)實(shí)例完成,復(fù)制技術(shù)使得數(shù)據(jù)庫(kù)的讀寫操作可以分散在運(yùn)行于不同CPU之上的獨(dú)立服務(wù)器上,Redis作為一個(gè)開(kāi)源的、優(yōu)秀的key-value緩存及持久化存儲(chǔ)解決方案,也提供了復(fù)制功能,本文主要介紹Redis的復(fù)制原理及特性。
數(shù)據(jù)庫(kù)復(fù)制指的是發(fā)生在不同數(shù)據(jù)庫(kù)實(shí)例之間,單向的信息傳播的行為,通常由被復(fù)制方和復(fù)制方組成,被復(fù)制方和復(fù)制方之間建立網(wǎng)絡(luò)連接,復(fù)制方式通常為被復(fù)制方主動(dòng)將數(shù)據(jù)發(fā)送到復(fù)制方,復(fù)制方接收到數(shù)據(jù)存儲(chǔ)在當(dāng)前實(shí)例,最終目的是為了保證雙方的數(shù)據(jù)一致、同步。
復(fù)制示意圖
Redis的復(fù)制方式有兩種,一種是主(master)-從(slave)模式,一種是從(slave)-從(slave)模式,因此Redis的復(fù)制拓?fù)鋱D會(huì)豐富一些,可以像星型拓?fù)洌部梢韵駛€(gè)有向無(wú)環(huán):
Redis集群復(fù)制結(jié)構(gòu)圖
通過(guò)配置多個(gè)Redis實(shí)例獨(dú)立運(yùn)行、定向復(fù)制,形成Redis集群,master負(fù)責(zé)寫、slave負(fù)責(zé)讀。
通過(guò)配置多個(gè)Redis實(shí)例,數(shù)據(jù)備份在不同的實(shí)例上,主庫(kù)專注寫請(qǐng)求,從庫(kù)負(fù)責(zé)讀請(qǐng)求,這樣的好處主要體現(xiàn)在下面幾個(gè)方面:
在一個(gè)Redis集群中,如果master宕機(jī),slave可以介入并取代master的位置,因此對(duì)于整個(gè)Redis服務(wù)來(lái)說(shuō)不至于提供不了服務(wù),這樣使得整個(gè)Redis服務(wù)足夠安全。
在一個(gè)Redis集群中,master負(fù)責(zé)寫請(qǐng)求,slave負(fù)責(zé)讀請(qǐng)求,這么做一方面通過(guò)將讀請(qǐng)求分散到其他機(jī)器從而大大減少了master服務(wù)器的壓力,另一方面slave專注于提供讀服務(wù)從而提高了響應(yīng)和讀取速度。
通過(guò)增加slave機(jī)器可以橫向(水平)擴(kuò)展Redis服務(wù)的整個(gè)查詢服務(wù)的能力。
復(fù)制提供了高可用性的解決方案,但同時(shí)引入了分布式計(jì)算的復(fù)雜度問(wèn)題,認(rèn)為有兩個(gè)核心問(wèn)題:
上面兩個(gè)問(wèn)題,尤其是第一個(gè)問(wèn)題是Redis服務(wù)實(shí)現(xiàn)一直在演變,致力于解決的一個(gè)問(wèn)題。
Redis提供了提高數(shù)據(jù)一致性的解決方案,本文后面會(huì)進(jìn)行介紹,一致性程度的增加雖然使得我能夠更信任數(shù)據(jù),但是更好的一致性方案通常伴隨著性能的損失,從而減少了吞吐量和服務(wù)能力。然而我們希望系統(tǒng)的性能達(dá)到最優(yōu),則必須要犧牲一致性的程度,因此Redis的復(fù)制實(shí)時(shí)性和數(shù)據(jù)一致性是存在矛盾的。
舉個(gè)例子,我們有四臺(tái)redis實(shí)例,M1,R1、R2、R3,其中M1為master,R1、R2、R3分別為三臺(tái)slave redis實(shí)例。在M1啟動(dòng)如下:
./redis-server ../redis8000.conf --port 8000
下面分別為R1、R2、R3的啟動(dòng)命令:
./redis-server ../redis8001.conf --port 8001 --slaveof 127.0.0.1 8000 ./redis-server ../redis8002.conf --port 8002 --slaveof 127.0.0.1 8000 ./redis-server ../redis8003.conf --port 8003 --slaveof 127.0.0.1 8000
這樣,我們就成功的啟動(dòng)了四臺(tái)Redis實(shí)例,master實(shí)例的服務(wù)端口為8000,R1、R2、R3的服務(wù)端口分別為8001、8002、8003,集群圖如下:
Redis集群復(fù)制拓?fù)?/p>
上面的命令在slave啟動(dòng)的時(shí)候就指定了master機(jī)器,我們也可以在slave運(yùn)行的時(shí)候通過(guò)slaveof命令來(lái)指定master機(jī)器。
Redis復(fù)制主要由SYNC命令實(shí)現(xiàn),復(fù)制過(guò)程如下圖:
Redis復(fù)制過(guò)程
上圖為Redis復(fù)制工作過(guò)程:
值得注意的是,當(dāng)slave跟master的連接斷開(kāi)時(shí),slave可以自動(dòng)的重新連接master,在redis2.8版本之前,每當(dāng)slave進(jìn)程掛掉重新連接master的時(shí)候都會(huì)開(kāi)始新的一輪全量復(fù)制。如果master同時(shí)接收到多個(gè)slave的同步請(qǐng)求,則master只需要備份一次RDB文件。
上面復(fù)制過(guò)程介紹的最后提到,slave和master斷開(kāi)了、當(dāng)slave和master重新連接上之后需要全量復(fù)制,這個(gè)策略是很不友好的,從Redis2.8開(kāi)始,Redis提供了增量復(fù)制的機(jī)制:
增量復(fù)制機(jī)制
master除了備份RDB文件之外還會(huì)維護(hù)者一個(gè)環(huán)形隊(duì)列,以及環(huán)形隊(duì)列的寫索引和slave同步的全局offset,環(huán)形隊(duì)列用于存儲(chǔ)最新的操作數(shù)據(jù),當(dāng)slave和maste斷開(kāi)重連之后,會(huì)把slave維護(hù)的offset,也就是上一次同步到哪里的這個(gè)值告訴master,同時(shí)會(huì)告訴master上次和當(dāng)前slave連接的master的runid,滿足下面兩個(gè)條件,Redis不會(huì)全量復(fù)制:
滿足上面兩個(gè)條件,Redis就不會(huì)全量復(fù)制,這樣的好處是大大的提高的性能,不做無(wú)效的功。
增量復(fù)制是由psync命令實(shí)現(xiàn)的,slave可以通過(guò)psync命令來(lái)讓Redis進(jìn)行增量復(fù)制,當(dāng)然最終是否能夠增量復(fù)制取決于環(huán)形隊(duì)列的大小和slave的斷線時(shí)間長(zhǎng)短和重連的這個(gè)master是否是之前的master。
環(huán)形隊(duì)列大小配置參數(shù):
repl-backlog-size 1mb
Redis同時(shí)也提供了當(dāng)沒(méi)有slave需要同步的時(shí)候,多久可以釋放環(huán)形隊(duì)列:
repl-backlog-ttl 3600
免持久化機(jī)制官方叫做Diskless Replication,前面基于RDB文件寫磁盤的方式可以看出,Redis必須要先將RDB文件寫入磁盤,才進(jìn)行網(wǎng)絡(luò)傳輸,那么為什么不能直接通過(guò)網(wǎng)絡(luò)把RDB文件傳送給slave呢?免持久化復(fù)制就是做這個(gè)事情的,而且在Redis2.8.18版本開(kāi)始支持,當(dāng)然目前還是實(shí)驗(yàn)階段。
值得注意的是,一旦基于Diskless Replication的復(fù)制傳送開(kāi)始,新的slave請(qǐng)求需要等待這次傳輸完畢才能夠得到服務(wù)。
是否開(kāi)啟Diskless Replication的開(kāi)關(guān)配置為:
repo-diskless-sync no
為了讓后續(xù)的slave能夠盡量趕上本次復(fù)制,Redis提供了一個(gè)參數(shù)配置指定復(fù)制開(kāi)始的時(shí)間延遲:
repl-diskless-sync-delay 5
自從Redis2.6版本開(kāi)始,支持對(duì)slave的只讀模式的配置,默認(rèn)對(duì)slave的配置也是只讀。只讀模式的slave將會(huì)拒絕客戶端的寫請(qǐng)求,從而避免因?yàn)閺膕lave寫入而導(dǎo)致的數(shù)據(jù)不一致問(wèn)題。
和MySQL復(fù)制策略有點(diǎn)類似,Redis復(fù)制本身是異步的,但也提供了半同步的復(fù)制策略,半同步復(fù)制策略在Redis復(fù)制中的語(yǔ)義是這樣的:
允許用戶給出這樣的配置:在maste接受寫操作的時(shí)候,只有當(dāng)一定時(shí)間間隔內(nèi),至少有N臺(tái)slave在線,否則寫入無(wú)效。
上面功能的實(shí)現(xiàn)基于Redis下面特性:
我們可以通過(guò)下面配置來(lái)指定時(shí)間間隔和N這個(gè)值:
min-slaves-to-write <number of slaves>min-slaves-max-lag <number of seconds>
當(dāng)配置了上面兩個(gè)參數(shù)之后,一旦對(duì)于一個(gè)寫操作沒(méi)有滿足上面的兩個(gè)條件,則master會(huì)報(bào)錯(cuò),并且將本次寫操作視為無(wú)效。這有點(diǎn)像CAP理論中的“C”,即一致性實(shí)現(xiàn),雖然半同步策略不能夠完全保證master和slave的數(shù)據(jù)一致性,但是相對(duì)減少了不一致性的窗口期。
本文在理解Redis復(fù)制概念和復(fù)制的優(yōu)缺點(diǎn)的基礎(chǔ)之上介紹了當(dāng)前Redis復(fù)制工作原理以及主要特性,希望能夠幫助大家。
文章題目:探索Redis設(shè)計(jì)與實(shí)現(xiàn)10:Redis的事件驅(qū)動(dòng)模型與命令執(zhí)行過(guò)程
URL網(wǎng)址:http://vcdvsql.cn/article30/pdpipo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營(yíng)銷型網(wǎng)站建設(shè)、做網(wǎng)站、企業(yè)網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)、響應(yīng)式網(wǎng)站、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)