redis
redis是單線程的怀各,但是一般的作為緩存使用的話舍悯,redis足夠了,因?yàn)樗淖x寫速度太快了虹菲。
官方的一個(gè)簡(jiǎn)單測(cè)試:
測(cè)試完成了50個(gè)并發(fā)執(zhí)行100000個(gè)請(qǐng)求跛锌。
設(shè)置和獲取的值是一個(gè)256字節(jié)字符串。
結(jié)果:讀的速度是110000次/s,寫的速度是81000次/s
但對(duì)于訪問量特別大的服務(wù)來說届惋,還是稍有不足髓帽。那么,如何提升redis的性能呢脑豹?搭建集群郑藏。
redis主要提供三種集群策略:
- 主從復(fù)制
- 集群
- 哨兵
一、主從復(fù)制
在主從復(fù)制中瘩欺,數(shù)據(jù)庫(kù)分為倆類必盖,主數(shù)據(jù)庫(kù)(master)和從數(shù)據(jù)庫(kù)(slave)。
1.1 主從復(fù)制有如下特點(diǎn):
- 主數(shù)據(jù)庫(kù)可以進(jìn)行讀寫操作俱饿,當(dāng)讀寫操作導(dǎo)致數(shù)據(jù)變化時(shí)會(huì)自動(dòng)將數(shù)據(jù)同步給從數(shù)據(jù)庫(kù)
- 從數(shù)據(jù)庫(kù)一般都是只讀的歌粥,并且接收主數(shù)據(jù)庫(kù)同步過來的數(shù)據(jù)
- 一個(gè)master可以擁有多個(gè)slave,但是一個(gè)slave只能對(duì)應(yīng)一個(gè)master
1.2 工作機(jī)制
slave從節(jié)點(diǎn)服務(wù)啟動(dòng)并連接到Master之后拍埠,它將主動(dòng)發(fā)送一個(gè)SYNC命令失驶。Master服務(wù)主節(jié)點(diǎn)收到同步命令后將啟動(dòng)后臺(tái)存盤進(jìn)程,同時(shí)收集所有接收到的用于修改數(shù)據(jù)集的命令枣购,在后臺(tái)進(jìn)程執(zhí)行完畢后嬉探,Master將傳送整個(gè)數(shù)據(jù)庫(kù)文件到Slave,以完成一次完全同步棉圈。而Slave從節(jié)點(diǎn)服務(wù)在接收到數(shù)據(jù)庫(kù)文件數(shù)據(jù)之后將其存盤并加載到內(nèi)存中涩堤。此后,Master主節(jié)點(diǎn)繼續(xù)將所有已經(jīng)收集到的修改命令分瘾,和新的修改命令依次傳送給Slaves胎围,Slave將在本次執(zhí)行這些數(shù)據(jù)修改命令,從而達(dá)到最終的數(shù)據(jù)同步德召。
復(fù)制初始化后白魂,master每次接收到的寫命令都會(huì)同步發(fā)送給slave,保證主從數(shù)據(jù)一致性氏捞。
如果Master和Slave之間的鏈接出現(xiàn)斷連現(xiàn)象碧聪,Slave可以自動(dòng)重連Master,但是在連接成功之后液茎,一次完全同步將被自動(dòng)執(zhí)行逞姿。
1.3 主從配置
redis默認(rèn)是主數(shù)據(jù)辞嗡,所以master無需配置,我們只需要修改slave的配置即可滞造。
設(shè)置需要連接的master的ip端口:
slaveof 192.168.0.107 6379
如果master設(shè)置了密碼续室。需要配置:
masterauth master-password
連接成功進(jìn)入命令行后,可以通過以下命令行查看連接該數(shù)據(jù)庫(kù)的其他庫(kù)信息:
info replication
1.3 優(yōu)點(diǎn)
同一個(gè)Master可以同步多個(gè)Slaves谒养。
Slave同樣可以接受其它Slaves的連接和同步請(qǐng)求挺狰,這樣可以有效的分載Master的同步壓力。因此我們可以將Redis的Replication架構(gòu)視為圖結(jié)構(gòu)买窟。
Master Server是以非阻塞的方式為Slaves提供服務(wù)丰泊。所以在Master-Slave同步期間,客戶端仍然可以提交查詢或修改請(qǐng)求始绍。
Slave Server同樣是以非阻塞的方式完成數(shù)據(jù)同步瞳购。在同步期間,如果有客戶端提交查詢請(qǐng)求亏推,Redis則返回同步之前的數(shù)據(jù)
為了分載Master的讀操作壓力学赛,Slave服務(wù)器可以為客戶端提供只讀操作的服務(wù),寫服務(wù)仍然必須由Master來完成吞杭。即便如此盏浇,系統(tǒng)的伸縮性還是得到了很大的提高。
Master可以將數(shù)據(jù)保存操作交給Slaves完成芽狗,從而避免了在Master中要有獨(dú)立的進(jìn)程來完成此操作绢掰。
支持主從復(fù)制,主機(jī)會(huì)自動(dòng)將數(shù)據(jù)同步到從機(jī)译蒂,可以進(jìn)行讀寫分離曼月。
1.4 缺點(diǎn)
Redis不具備自動(dòng)容錯(cuò)和恢復(fù)功能谊却,主機(jī)從機(jī)的宕機(jī)都會(huì)導(dǎo)致前端部分讀寫請(qǐng)求失敗柔昼,需要等待機(jī)器重啟或者手動(dòng)切換前端的IP才能恢復(fù)。
主機(jī)宕機(jī)炎辨,宕機(jī)前有部分?jǐn)?shù)據(jù)未能及時(shí)同步到從機(jī)捕透,切換IP后還會(huì)引入數(shù)據(jù)不一致的問題,降低了系統(tǒng)的可用性碴萧。
Redis的主從復(fù)制采用全量復(fù)制乙嘀,復(fù)制過程中主機(jī)會(huì)fork出一個(gè)子進(jìn)程對(duì)內(nèi)存做一份快照,并將子進(jìn)程的內(nèi)存快照保存為文件發(fā)送給從機(jī)破喻,這一過程需要確保主機(jī)有足夠多的空余內(nèi)存虎谢。若快照文件較大,對(duì)集群的服務(wù)能力會(huì)產(chǎn)生較大的影響曹质,而且復(fù)制過程是在從機(jī)新加入集群或者從機(jī)和主機(jī)網(wǎng)絡(luò)斷開重連時(shí)都會(huì)進(jìn)行婴噩,也就是網(wǎng)絡(luò)波動(dòng)都會(huì)造成主機(jī)和從機(jī)間的一次全量的數(shù)據(jù)復(fù)制擎场,這對(duì)實(shí)際的系統(tǒng)運(yùn)營(yíng)造成了不小的麻煩。
Redis較難支持在線擴(kuò)容几莽,在集群容量達(dá)到上限時(shí)在線擴(kuò)容會(huì)變得很復(fù)雜迅办。為避免這一問題,運(yùn)維人員在系統(tǒng)上線時(shí)必須確保有足夠的空間章蚣,這對(duì)資源造成了很大的浪費(fèi)站欺。
其實(shí)redis的主從模式很簡(jiǎn)單,在實(shí)際的生產(chǎn)環(huán)境中是很少使用的纤垂,我也不建議在實(shí)際的生產(chǎn)環(huán)境中使用主從模式來提供系統(tǒng)的高可用性矾策,之所以不建議使用都是由它的缺點(diǎn)造成的,在數(shù)據(jù)量非常大的情況峭沦,或者對(duì)系統(tǒng)的高可用性要求很高的情況下蝴韭,主從模式也是不穩(wěn)定的。
二熙侍、哨兵
該模式是從Redis的2.6版本開始提供的榄鉴,但是當(dāng)時(shí)這個(gè)版本的模式是不穩(wěn)定的,直到Redis的2.8版本以后蛉抓,這個(gè)哨兵模式才穩(wěn)定下來庆尘,無論是主從模式,還是哨兵模式巷送,這兩個(gè)模式都有一個(gè)問題驶忌,不能水平擴(kuò)容,并且這兩個(gè)模式的高可用特性都會(huì)受到Master主節(jié)點(diǎn)內(nèi)存的限制笑跛。
2.1 哨兵的作用是監(jiān)控 redis系統(tǒng)的運(yùn)行狀況付魔,功能如下
監(jiān)控主從數(shù)據(jù)庫(kù)是否正常運(yùn)行。
master出現(xiàn)故障時(shí)飞蹂,自動(dòng)將它的其中一個(gè)slave轉(zhuǎn)化為master几苍。
master和slave服務(wù)器切換后,master的redis.conf陈哑、slave的redis.conf和sentinel.conf的配置文件的內(nèi)容都會(huì)發(fā)生相應(yīng)的改變妻坝,即恬砂,saster主服務(wù)器的redis.conf配置文件中會(huì)多一行slaveof的配置叔扼,sentinel.conf的監(jiān)控目標(biāo)會(huì)隨之調(diào)換。
當(dāng)被監(jiān)控的某個(gè)Redis節(jié)點(diǎn)出現(xiàn)問題時(shí), 哨兵(sentinel) 可以通過 API 向管理員或者其他應(yīng)用程序發(fā)送通知诚卸。
多哨兵配置的時(shí)候界酒,哨兵之間也會(huì)自動(dòng)監(jiān)控圣拄。
多個(gè)哨兵可以監(jiān)控同一個(gè)redis。
2.2 哨兵工作機(jī)制
哨兵進(jìn)程啟動(dòng)時(shí)會(huì)讀取配置文件的內(nèi)容毁欣,通過sentinel monitor master-name ip port quorum查找到master的ip端口庇谆。一個(gè)哨兵可以監(jiān)控多個(gè)master數(shù)據(jù)庫(kù)赁遗,只需要提供多個(gè)該配置項(xiàng)即可。
配置文件還定義了與監(jiān)控相關(guān)的參數(shù)族铆,比如master多長(zhǎng)時(shí)間無響應(yīng)即即判定位為下線岩四。
哨兵啟動(dòng)后,會(huì)與要監(jiān)控的master建立倆條連接:
3.1 一條連接用來訂閱master的sentinel:hello頻道哥攘,并獲取其他監(jiān)控該master的哨兵節(jié)點(diǎn)信息
3.2 另一條連接定期向master發(fā)送INFO等命令獲取master本身的信息與master建立連接后剖煌,哨兵會(huì)執(zhí)行三個(gè)操作,這三個(gè)操作的發(fā)送頻率都可以在配置文件中配置:
4.1 定期向master和slave發(fā)送INFO命令
4.2 定期向master和slave的sentinel:hello頻道發(fā)送自己的信息
4.3 定期向master逝淹、slave和其他哨兵發(fā)送PING命令
這三個(gè)操作的意義非常重大耕姊,發(fā)送INFO命令可以獲取當(dāng)前數(shù)據(jù)庫(kù)的相關(guān)信息從而實(shí)現(xiàn)新節(jié)點(diǎn)的自動(dòng)發(fā)現(xiàn)。所以說哨兵只需要配置master數(shù)據(jù)庫(kù)信息就可以自動(dòng)發(fā)現(xiàn)其slave信息栅葡。獲取到slave信息后茉兰,哨兵也會(huì)與slave建立倆條連接執(zhí)行監(jiān)控。通過INFO命令欣簇,哨兵可以獲取主從數(shù)據(jù)庫(kù)的最新信息规脸,并進(jìn)行相應(yīng)的操作,比如角色變更等熊咽。
接下來哨兵向主從數(shù)據(jù)庫(kù)的sentinel:hello頻道發(fā)送信息莫鸭,并與同樣監(jiān)控這些數(shù)據(jù)庫(kù)的哨兵共享自己的信息,發(fā)送內(nèi)容為哨兵的ip端口横殴、運(yùn)行id被因、配置版本、master名字衫仑、master的ip端口還有master的配置版本梨与。這些信息有以下用處:
5.1 其他哨兵可以通過該信息判斷發(fā)送者是否是新發(fā)現(xiàn)的哨兵,如果是的話會(huì)創(chuàng)建一個(gè)到該哨兵的連接用于發(fā)送ping命令文狱。
5.2 其他哨兵通過該信息可以判斷master的版本粥鞋,如果該版本高于直接記錄的版本,將會(huì)更新當(dāng)實(shí)現(xiàn)了自動(dòng)發(fā)現(xiàn)slave和其他哨兵節(jié)點(diǎn)后如贷,哨兵就可以通過定期發(fā)送ping命令定時(shí)監(jiān)控這些數(shù)據(jù)庫(kù)和節(jié)點(diǎn)有沒有停止服務(wù)陷虎。發(fā)送頻率可以配置,但是最長(zhǎng)間隔時(shí)間為1s杠袱,可以通過sentinel down-after-milliseconds mymaster 600設(shè)置。
如果被ping的數(shù)據(jù)庫(kù)或者節(jié)點(diǎn)超時(shí)未回復(fù)窝稿,哨兵認(rèn)為其主觀下線楣富。如果下線的是master,哨兵會(huì)向其他哨兵點(diǎn)發(fā)送命令詢問他們是否也認(rèn)為該master主觀下線伴榔。如果一個(gè)master主服務(wù)器被標(biāo)記為主觀下線(SDOWN)纹蝴,則正在監(jiān)視這個(gè)Master主服務(wù)器的所有 Sentinel(哨兵)進(jìn)程要以每秒一次的頻率確認(rèn)Master主服務(wù)器的確進(jìn)入了主觀下線狀態(tài)庄萎。如果達(dá)到一定數(shù)目(即配置文件中的quorum)投票,哨兵會(huì)認(rèn)為該master已經(jīng)客觀下線(ODOWN)塘安,并選舉領(lǐng)頭的哨兵節(jié)點(diǎn)對(duì)主從系統(tǒng)發(fā)起故障恢復(fù)糠涛。
如上文所說,哨兵認(rèn)為master客觀下線后兼犯,故障恢復(fù)的操作需要由選舉的領(lǐng)頭哨兵執(zhí)行忍捡,選舉采用Raft算法:
8.1 發(fā)現(xiàn)master下線的哨兵節(jié)點(diǎn)(我們稱他為A)向每個(gè)哨兵發(fā)送命令,要求對(duì)方選自己為領(lǐng)頭哨兵
8.2 如果目標(biāo)哨兵節(jié)點(diǎn)沒有選過其他人切黔,則會(huì)同意選舉A為領(lǐng)頭哨兵
8.3 如果有超過一半的哨兵同意選舉A為領(lǐng)頭砸脊,則A當(dāng)選
8.4 如果有多個(gè)哨兵節(jié)點(diǎn)同時(shí)參選領(lǐng)頭,此時(shí)有可能存在一輪投票無競(jìng)選者勝出纬霞,此時(shí)每個(gè)參選的節(jié)點(diǎn)等待一個(gè)隨機(jī)時(shí)間后再次發(fā)起參選請(qǐng)求凌埂,進(jìn)行下一輪投票精選,直至選舉出領(lǐng)頭哨兵
8.5 選出領(lǐng)頭哨兵后诗芜,領(lǐng)頭者開始對(duì)進(jìn)行故障恢復(fù)瞳抓,從出現(xiàn)故障的master的從數(shù)據(jù)庫(kù)slave中挑選一個(gè)來當(dāng)選新的master,選擇規(guī)則如下:
8.5.1 所有在線的slave中選擇優(yōu)先級(jí)最高的,優(yōu)先級(jí)可以通過slave-priority配置
8.5.2 如果有多個(gè)最高優(yōu)先級(jí)的slave伏恐,則選取復(fù)制偏移量最大(即復(fù)制越完整)的當(dāng)選
8.5.3 如果以上條件都一樣挨下,選取id最小的slave挑選出需要繼任的slaver后,領(lǐng)頭哨兵向該數(shù)據(jù)庫(kù)發(fā)送命令使其升格為master脐湾,然后再向其他slave發(fā)送命令接受新的master臭笆,最后更新數(shù)據(jù)。將已經(jīng)停止的舊的master更新為新的master的從數(shù)據(jù)庫(kù)秤掌,使其恢復(fù)服務(wù)后以slave的身份繼續(xù)運(yùn)行愁铺。
2.3 哨兵配置
哨兵配置的配置文件為sentinel.conf,設(shè)置主機(jī)名稱闻鉴,地址茵乱,端口,以及選舉票數(shù)即恢復(fù)時(shí)最少需要幾個(gè)哨兵節(jié)點(diǎn)同意孟岛。只要配置需要監(jiān)控的master就可以了瓶竭,哨兵會(huì)監(jiān)控連接該master的slave。
sentinel monitor mymaster 192.168.0.107 6379 1
啟動(dòng)哨兵節(jié)點(diǎn):
redis-server sentinel.conf --sentinel &
出現(xiàn)以下類似信息即啟動(dòng)哨兵成功
3072:X 12 Apr 22:40:02.554 ### Sentinel runid is e510bd95d4deba3261de72272130322b2ba650e7
3072:X 12 Apr 22:40:02.554 ### +monitor master mymaster 192.168.0.107 6379 quorum 1
3072:X 12 Apr 22:40:03.516 * +slave slave 192.168.0.108:6379 192.168.0.108 6379 @ mymaster 192.168.0.107 6379
3072:X 12 Apr 22:40:03.516 * +slave slave 192.168.0.109:6379 192.168.0.109 6379 @ mymaster 192.168.0.107 6379
可以在任何一臺(tái)服務(wù)器上查看指定哨兵節(jié)點(diǎn)信息:
bin/redis-cli -h 192.168.0.110 -p 26379 info Sentinel
控制臺(tái)輸出哨兵信息
redis-cli -h 192.168.0.110 -p 26379 info Sentinel
### Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=192.168.0.107:6379,slaves=2,sentinels=1
三渠羞、集群
3.1 特點(diǎn)
3.0版本之前的redis是不支持集群的斤贰,我們的徐子睿老師說,那個(gè)時(shí)候次询,我們的redis如果想要集群的話荧恍,就需要一個(gè)中間件,然后這個(gè)中間件負(fù)責(zé)將我們需要存入redis中的數(shù)據(jù)的key通過一套算法計(jì)算得出一個(gè)值。然后根據(jù)這個(gè)值找到對(duì)應(yīng)的redis節(jié)點(diǎn)送巡,將這些數(shù)據(jù)存在這個(gè)redis的節(jié)點(diǎn)中摹菠。在取值的時(shí)候,同樣先將key進(jìn)行計(jì)算骗爆,得到對(duì)應(yīng)的值次氨,然后就去找對(duì)應(yīng)的redis節(jié)點(diǎn),從對(duì)應(yīng)的節(jié)點(diǎn)中取出對(duì)應(yīng)的值摘投。這樣做有很多不好的地方煮寡,比如說我們的這些計(jì)算都需要在系統(tǒng)中去進(jìn)行,所以會(huì)增加系統(tǒng)的負(fù)擔(dān)谷朝。還有就是這種集群模式下洲押,某個(gè)節(jié)點(diǎn)掛掉,其他的節(jié)點(diǎn)無法知道圆凰。而且也不容易對(duì)每個(gè)節(jié)點(diǎn)進(jìn)行負(fù)載均衡杈帐。
從redis 3.0版本開始支持redis-cluster集群,redis-cluster采用無中心結(jié)構(gòu)专钉,每一個(gè)節(jié)點(diǎn)都保存有這個(gè)集群所有主節(jié)點(diǎn)以及從節(jié)點(diǎn)的信息挑童,及集群狀態(tài),每個(gè)節(jié)點(diǎn)都和其他節(jié)點(diǎn)連接跃须。所以redis-cluster是一種服務(wù)端分片技術(shù)站叼。
每個(gè)節(jié)點(diǎn)都和n-1個(gè)節(jié)點(diǎn)通信,這被稱為集群總線(cluster bus)菇民。它們使用特殊的端口號(hào)尽楔,即對(duì)外服務(wù)端口號(hào)加10000。所以要維護(hù)好這個(gè)集群的每個(gè)節(jié)點(diǎn)信息第练,不然會(huì)導(dǎo)致整個(gè)集群不可用阔馋,其內(nèi)部采用特殊的二進(jìn)制協(xié)議優(yōu)化傳輸速度和帶寬。
redis-cluster把所有的物理節(jié)點(diǎn)映射到[0,16383]slot(槽)上娇掏,cluster負(fù)責(zé)維護(hù)node--slot--value呕寝。
集群預(yù)先給所有節(jié)點(diǎn)分好16384個(gè)桶,每個(gè)節(jié)點(diǎn)得到部分桶婴梧,當(dāng)需要在redis集群中插入數(shù)據(jù)時(shí)下梢,根據(jù)CRC16(KEY) mod 16384的值,決定將一個(gè)key放到哪個(gè)桶中塞蹭。
客戶端與redis節(jié)點(diǎn)直連孽江,不需要連接集群所有的節(jié)點(diǎn),連接集群中任何一個(gè)可用節(jié)點(diǎn)即可浮还。整個(gè)cluster被看做是一個(gè)整體竟坛,客戶端可連接任意一個(gè)節(jié)點(diǎn)進(jìn)行操作,當(dāng)客戶端操作的key沒有分配在該節(jié)點(diǎn)上時(shí)钧舌,redis會(huì)返回轉(zhuǎn)向指令担汤,指向正確的節(jié)點(diǎn)。
redis-trib.rb腳本(rub語(yǔ)言)為集群的管理工具洼冻,比如自動(dòng)添加節(jié)點(diǎn)崭歧,規(guī)劃槽位,遷移數(shù)據(jù)等一系列操作撞牢。
節(jié)點(diǎn)的fail是通過集群中超過半數(shù)的節(jié)點(diǎn)檢測(cè)失效時(shí)才生效率碾。集群節(jié)點(diǎn)之間通過互相的ping-pong判斷是否可以連接上。如果有一半以上的節(jié)點(diǎn)去ping一個(gè)節(jié)點(diǎn)的時(shí)候沒有回應(yīng)屋彪,集群就認(rèn)為這個(gè)節(jié)點(diǎn)宕機(jī)了所宰,然后去連接它的備用節(jié)點(diǎn)。如果某個(gè)節(jié)點(diǎn)和所有從節(jié)點(diǎn)全部掛掉畜挥,集群就進(jìn)入fail狀態(tài)仔粥,也可以理解成集群的slot映射[0-16383]不完整時(shí)進(jìn)入fail狀態(tài)。如果有一半以上的主節(jié)點(diǎn)宕機(jī)蟹但,那么無論這些節(jié)點(diǎn)有沒有從節(jié)點(diǎn)躯泰,集群同樣進(jìn)入fail狀態(tài)。這就是redis的投票機(jī)制华糖。
為了增加集群的可訪問性麦向,官方推薦的方案是將node配置成主從結(jié)構(gòu),即一個(gè)master主節(jié)點(diǎn)客叉,掛n個(gè)slave從節(jié)點(diǎn)诵竭。如果主節(jié)點(diǎn)失效,redis cluster會(huì)根據(jù)選舉算法從slave節(jié)點(diǎn)中選擇一個(gè)上升為master節(jié)點(diǎn)兼搏,整個(gè)集群繼續(xù)對(duì)外提供服務(wù)卵慰。
3.2 配置
1.redis集群依賴ruby,需安裝ruby環(huán)境向族,ruby版本需高于2.2
yum install ruby
yum install rubygems
gem install redis
2.修改配置文件
bind 192.168.0.107
### 配置端口
port 6380
### 配置快照保存路徑呵燕,6個(gè)節(jié)點(diǎn)配置不同路徑
dir /usr/local/redis-cluster/6380/
### 開啟集群
cluster-enabled yes
### 為節(jié)點(diǎn)設(shè)置不同的工作目錄,6個(gè)節(jié)點(diǎn)配置不同目錄
cluster-config-file nodes-6380.conf
### 集群失效時(shí)間
cluster-node-timeout 15000
3.開啟集群中的所有節(jié)點(diǎn)
redis-service …/6380/redis.conf
redis-service …/6381/redis.conf
redis-service …/6382/redis.conf
redis-service …/6383/redis.conf
redis-service …/6384/redis.conf
redis-service …/6385/redis.conf
4.將節(jié)點(diǎn)加入集群中件相,中途需要輸入yes確定創(chuàng)建集群
redis-trib.rb create --replicas 1 192.168.0.107:6380 192.168.0.107:6381 192.168.0.107:6382 192.168.0.107:6383 192.168.0.107:6384 192.168.0.107:6385
5.進(jìn)入集群中任何一個(gè)節(jié)點(diǎn)
redis-cli -c -h 192.168.0.107 -p 6381
6.查看集群中的節(jié)點(diǎn)
cluster nodes
[root@buke107 src]### redis-cli -c -h 192.168.0.107 -p 6381
192.168.0.107:6381> cluster nodes
868456121fa4e6c8e7abe235a88b51d354a944b5 192.168.0.107:6382 master - 0 1523609792598 3 connected 10923-16383
d6d01fd8f1e5b9f8fc0c748e08248a358da3638d 192.168.0.107:6385 slave 868456121fa4e6c8e7abe235a88b51d354a944b5 0 1523609795616 6 connected
5cd3ed3a84ead41a765abd3781b98950d452c958 192.168.0.107:6380 master - 0 1523609794610 1 connected 0-5460
b8e047aeacb9398c3f58f96d0602efbbea2078e2 192.168.0.107:6383 slave 5cd3ed3a84ead41a765abd3781b98950d452c958 0 1523609797629 1 connected
68cf66359318b26df16ebf95ba0c00d9f6b2c63e 192.168.0.107:6384 slave 90b4b326d579f9b5e181e3df95578bceba29b204 0 1523609796622 5 connected
90b4b326d579f9b5e181e3df95578bceba29b204 192.168.0.107:6381 myself,master - 0 0 2 connected 5461-10922
如上所示再扭,三主三從節(jié)點(diǎn)已創(chuàng)建成功
7.增加集群節(jié)點(diǎn)
cluster meet ip port
其他集群實(shí)現(xiàn)方式
中間件
一、twemproxy
twemproxy又稱nutcracker夜矗,起源于推特系統(tǒng)中redis泛范、memcached集群的輕量級(jí)代理。
Redis代理中間件twemproxy是一種利用中間件做分片的技術(shù)紊撕。twemproxy處于客戶端和服務(wù)器的中間罢荡,將客戶端發(fā)來的請(qǐng)求,進(jìn)行一定的處理后(sharding),再轉(zhuǎn)發(fā)給后端真正的redis服務(wù)器区赵。也就是說惭缰,客戶端不直接訪問redis服務(wù)器,而是通過twemproxy代理中間件間接訪問笼才。降低了客戶端直連后端服務(wù)器的連接數(shù)量漱受,并且支持服務(wù)器集群水平擴(kuò)展。
twemproxy中間件的內(nèi)部處理是無狀態(tài)的骡送,它本身可以很輕松地集群昂羡,這樣可以避免單點(diǎn)壓力或故障。
從下面架構(gòu)圖看到twemproxy是一個(gè)單點(diǎn)摔踱,很容易對(duì)其造成很大的壓力虐先,所以通常會(huì)結(jié)合keepalived來實(shí)現(xiàn)twemproy的高可用。這時(shí)派敷,通常只有一臺(tái)twemproxy在工作蛹批,另外一臺(tái)處于備機(jī),當(dāng)一臺(tái)掛掉以后膀息,vip自動(dòng)漂移般眉,備機(jī)接替工作。關(guān)于keepalived的用法可自行網(wǎng)上查閱資料潜支。
二甸赃、codis
codis是一個(gè)分布式的Redis解決方案,由豌豆莢開源冗酿,對(duì)于上層的應(yīng)用來說埠对,連接codis proxy和連接原生的redis server沒什么明顯的區(qū)別,上層應(yīng)用可以像使用單機(jī)的redis一樣使用裁替,codis底層會(huì)處理請(qǐng)求的轉(zhuǎn)發(fā)项玛,不停機(jī)的數(shù)據(jù)遷移等工作,所有后邊的事情弱判,對(duì)于前面的客戶端來說是透明的襟沮,可以簡(jiǎn)單的認(rèn)為后邊連接的是一個(gè)內(nèi)存無限大的redis服務(wù)。
客戶端分片
分區(qū)的邏輯在客戶端實(shí)現(xiàn)昌腰,由客戶端自己選擇請(qǐng)求到哪個(gè)節(jié)點(diǎn)开伏。方案可參考一致性哈希,這種方案通常適用于用戶對(duì)客戶端的行為有完全控制能力的場(chǎng)景遭商。
一固灵、Jedis sharding集群
Redis Sharding可以說是在Redis cluster出來之前業(yè)界普遍的采用方式,其主要思想是采用hash算法將存儲(chǔ)數(shù)據(jù)的key進(jìn)行hash散列劫流,這樣特定的key會(huì)被定為到特定的節(jié)點(diǎn)上巫玻。
慶幸的是丛忆,Java Redis客戶端驅(qū)動(dòng)Jedis已支持Redis Sharding功能,即ShardedJedis以及結(jié)合緩存池的ShardedJedisPool
Jedis的Redis Sharding實(shí)現(xiàn)具有如下特點(diǎn):
采用一致性哈希算法仍秤,將key和節(jié)點(diǎn)name同時(shí)hashing熄诡,然后進(jìn)行映射匹配,采用的算法是MURMUR_HASH徒扶。采用一致性哈希而不是采用簡(jiǎn)單類似哈希求模映射的主要原因是當(dāng)增加或減少節(jié)點(diǎn)時(shí)粮彤,不會(huì)產(chǎn)生由于重新匹配造成的rehashing根穷。一致性哈希只影響相鄰節(jié)點(diǎn)key分配姜骡,影響量小。
為了避免一致性哈希只影響相鄰節(jié)點(diǎn)造成節(jié)點(diǎn)分配壓力屿良,ShardedJedis會(huì)對(duì)每個(gè)Redis節(jié)點(diǎn)根據(jù)名字(沒有圈澈,Jedis會(huì)賦予缺省名字)會(huì)虛擬化出160個(gè)虛擬節(jié)點(diǎn)進(jìn)行散列。根據(jù)權(quán)重weight尘惧,也可虛擬化出160倍數(shù)的虛擬節(jié)點(diǎn)康栈。用虛擬節(jié)點(diǎn)做映射匹配,可以在增加或減少Redis節(jié)點(diǎn)時(shí)喷橙,key在各Redis節(jié)點(diǎn)移動(dòng)再分配更均勻啥么,而不是只有相鄰節(jié)點(diǎn)受影響。
ShardedJedis支持keyTagPattern模式贰逾,即抽取key的一部分keyTag做sharding悬荣,這樣通過合理命名key,可以將一組相關(guān)聯(lián)的key放入同一個(gè)Redis節(jié)點(diǎn)疙剑,這在避免跨節(jié)點(diǎn)訪問相關(guān)數(shù)據(jù)時(shí)很重要氯迂。
當(dāng)然,Redis Sharding這種輕量靈活方式必然在集群其它能力方面做出妥協(xié)言缤。比如擴(kuò)容嚼蚀,當(dāng)想要增加Redis節(jié)點(diǎn)時(shí),盡管采用一致性哈希管挟,畢竟還是會(huì)有key匹配不到而丟失轿曙,這時(shí)需要鍵值遷移。
作為輕量級(jí)客戶端sharding僻孝,處理Redis鍵值遷移是不現(xiàn)實(shí)的导帝,這就要求應(yīng)用層面允許Redis中數(shù)據(jù)丟失或從后端數(shù)據(jù)庫(kù)重新加載數(shù)據(jù)。但有些時(shí)候皮璧,擊穿緩存層舟扎,直接訪問數(shù)據(jù)庫(kù)層,會(huì)對(duì)系統(tǒng)訪問造成很大壓力悴务。