redis客戶端實(shí)現(xiàn)高可用讀寫分離的方式詳解
背景
(1) redis單機(jī)的讀寫性能輕松上大幾萬,不過線上環(huán)境不會只部署光禿禿的一個(gè)節(jié)點(diǎn),還是會配合 sentinel 再部署一個(gè) slave作為高可用節(jié)點(diǎn)的;
但是standby的slave節(jié)點(diǎn)是不對外提供服務(wù)端的,一定程度上造成了浪費(fèi)資源
(2) 當(dāng)業(yè)務(wù)不斷發(fā)展,原來單節(jié)點(diǎn)緩存的數(shù)據(jù)(如,商品信息緩存、配置信息等)的查詢qps不斷升高(寫qps增長不多),突破十幾萬、幾十萬的的時(shí)候,此時(shí)一個(gè)節(jié)點(diǎn)就扛不住了,我們就需要增加幾個(gè)redis slaves節(jié)點(diǎn)來分擔(dān)這些查詢的壓力 也就是讀寫分離
但是,常用的 redis 客戶端jedis并不支持讀寫分離能力
實(shí)現(xiàn)方式
(1) 從配置中心獲取 master 和 slaves 的連接信息,分別初始化好一個(gè)連接master的寫連接池和一組slave的讀連接池
(2) 將命令進(jìn)行分類:執(zhí)行寫命令則從 master的連接池取連接然后執(zhí)行,如果是讀命令則從slave的連接池中取出連接執(zhí)行
可能有多個(gè)slave節(jié)點(diǎn),可以按照一定的策略進(jìn)行負(fù)載均衡(權(quán)重、隨機(jī)、輪詢...etc) 從其中一個(gè) slave節(jié)點(diǎn)的連接池獲取連接
大概長這樣:
高可用版本
前面的實(shí)現(xiàn)方式正常情況下是可以的
但是:
(1) 如果運(yùn)行期間 master掛了怎么辦? 如何自動 failover 切換?
(2) 如果流量突增,需要動態(tài)擴(kuò)容一個(gè)或多個(gè) slave節(jié)點(diǎn),如何動態(tài)生效?
那就不能從配置文件取master和slaves的 ip+port 了,得從redis ha的組件去動態(tài)獲取 當(dāng)前master 和可用slave列表的節(jié)點(diǎn)信息 => sentinel
1.初始化
向 sentinel 發(fā)送命令獲取master和slaves的節(jié)點(diǎn)信息
//獲取當(dāng)前masterName標(biāo)識的當(dāng)前master節(jié)點(diǎn)信息,哨兵可監(jiān)控多個(gè) mater ha,所以要用<masterName>區(qū)分 SENTINEL get-master-addr-by-name <masterName> //獲取可用的slaves列表信息 SENTINEL slaves <masterName>
拿到連接后,繼續(xù)用開頭的方式去創(chuàng)建連接池就行了
2. 動態(tài)failover、擴(kuò)容
初始化完畢后,在運(yùn)行期間master節(jié)點(diǎn),和slaves還是可能變化的, 如
(1) master故障、網(wǎng)絡(luò)分區(qū),sentinel 提升一個(gè)slave為新的master
(2) 新增slave節(jié)點(diǎn)應(yīng)對突增流量
我們?nèi)绾文懿恢貑⒖蛻舳说那闆r下,動態(tài)切換?
sentinel 在進(jìn)行master切換、slave變更等操作的時(shí)候都會向?qū)?yīng)的 channel 發(fā)布事件,我們可以基于這些事件感知到相應(yīng)的變化
參考: https://redis.io/topics/sentinel
2.1 failover切換 master
當(dāng) sentinel 進(jìn)行master failover切換的時(shí)候,它會向channel: switch-master 發(fā)送通知,我們在客戶端訂閱這個(gè)channel,收到事件后,重新進(jìn)行初始化的步驟即可
2.2 擴(kuò)容slave
當(dāng)新的 slave 節(jié)點(diǎn)加入, sentinel 感知到則會向channel: +slave 發(fā)布事件,我們監(jiān)聽到后,重新獲取slaves節(jié)點(diǎn)信息重建slaves的連接池就可以了(這邊不涉及master的變化)
總結(jié)
基于 sentienl 獲取和動態(tài)感知 master、slaves節(jié)點(diǎn)信息的變化,我們的讀寫分離客戶端就能具備高可用+動態(tài)擴(kuò)容感知能力了;
到此這篇關(guān)于redis客戶端實(shí)現(xiàn)高可用讀寫分離的文章就介紹到這了,更多相關(guān)redis讀寫分離內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何保證Redis與數(shù)據(jù)庫的數(shù)據(jù)一致性
這篇文章主要介紹了如何保證Redis與數(shù)據(jù)庫的數(shù)據(jù)一致性,文中舉了兩個(gè)場景例子介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05Redis高級數(shù)據(jù)類型Hyperloglog、Bitmap的使用
很多小伙伴在面試中都會被問道 Redis的常用數(shù)據(jù)結(jié)構(gòu)有哪些?可能很大一部分回答都是 string、hash、list、set、zset,但其實(shí)還有Hyperloglog和Bitmap,本文就來介紹一下2021-05-05Redis緩存數(shù)據(jù)庫表(列單獨(dú)緩存)的示例代碼
在Redis中緩存數(shù)據(jù)庫表數(shù)據(jù),而不使用JSON結(jié)構(gòu)來表示value,通常意味著我們會將數(shù)據(jù)庫表的每一行數(shù)據(jù)映射為Redis中的一個(gè)或多個(gè)鍵值對,這篇文章主要介紹了Redis緩存數(shù)據(jù)庫表(列單獨(dú)緩存),需要的朋友可以參考下2024-03-03redis內(nèi)部數(shù)據(jù)結(jié)構(gòu)之SDS簡單動態(tài)字符串詳解
SDS是Redis中實(shí)現(xiàn)的一種數(shù)據(jù)結(jié)構(gòu),用來存儲字符串,最近學(xué)習(xí)中正好學(xué)習(xí)到了這里,所以下面這篇文章主要給大家介紹了redis內(nèi)部數(shù)據(jù)結(jié)構(gòu)之SDS簡單動態(tài)字符串的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。2017-11-11Redis數(shù)據(jù)庫分布式設(shè)計(jì)方案介紹
大家好,本篇文章主要講的是Redis數(shù)據(jù)庫分布式設(shè)計(jì)方案介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下2022-01-01利用Redis進(jìn)行數(shù)據(jù)緩存的項(xiàng)目實(shí)踐
在實(shí)際的業(yè)務(wù)場景中,Redis 一般和其他數(shù)據(jù)庫搭配使用,用來減輕后端數(shù)據(jù)庫的壓力,本文就介紹了利用Redis進(jìn)行數(shù)據(jù)緩存的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2022-06-06利用redisson快速實(shí)現(xiàn)自定義限流注解(接口防刷)
利用redis的有序集合即Sorted?Set數(shù)據(jù)結(jié)構(gòu),構(gòu)造一個(gè)令牌桶來實(shí)施限流,而redisson已經(jīng)幫我們封裝成了RRateLimiter,通過redisson,即可快速實(shí)現(xiàn)我們的目標(biāo),這篇文章主要介紹了利用redisson快速實(shí)現(xiàn)自定義限流注解,需要的朋友可以參考下2024-07-07