偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

從Memcache轉(zhuǎn)戰(zhàn)Redis,聊聊緩存使用填過的“坑”

原創(chuàng)
開發(fā) 架構(gòu) Redis
在高并發(fā)場景下,很多人都把 Cache(高速緩沖存儲(chǔ)器)當(dāng)做可以“續(xù)命”的靈丹妙藥,哪里高并發(fā)壓力大,哪里就上傳 Cache 來解決并發(fā)問題。

【51CTO.com原創(chuàng)稿件】在高并發(fā)場景下,很多人都把 Cache(高速緩沖存儲(chǔ)器)當(dāng)做可以“續(xù)命”的靈丹妙藥,哪里高并發(fā)壓力大,哪里就上傳 Cache 來解決并發(fā)問題。

但有時(shí)候,即使使用了 Cache,卻發(fā)現(xiàn)系統(tǒng)依然卡頓宕機(jī),是因?yàn)?Cache 技術(shù)不好嗎?非也,其實(shí)這是緩存的治理工作沒有做好。

2018 年 5 月 18-19 日,由 51CTO 主辦的全球軟件與運(yùn)維技術(shù)峰會(huì)在北京召開。

在 19 日下午“高并發(fā)與實(shí)時(shí)處理”分會(huì)場,同程藝龍機(jī)票事業(yè)群 CTO 王曉波帶來了《高并發(fā)場景的緩存治理》的主題演講。

他針對(duì)如何讓緩存更適合高并發(fā)使用、如何正確使用緩存、如何通過治理化解緩存問題等熱點(diǎn)展開了闡述。

對(duì)于我們來說,我們是 OTA 的角色,所以有大量的數(shù)據(jù)要計(jì)算處理變?yōu)榭墒圪u商品,總的來說是“商品搬運(yùn)工,而非生產(chǎn)商”。

所以面對(duì)各種大數(shù)據(jù)并發(fā)運(yùn)行的應(yīng)用場景,我們需要通過各種緩存技術(shù)來提升服務(wù)的質(zhì)量。

想必大家都聽說過服務(wù)的治理和數(shù)據(jù)的治理,那么是否聽說過緩存的治理呢?誠然,在許多場景下,Cache 成了應(yīng)對(duì)各處出現(xiàn)高并發(fā)問題的一顆“銀彈”。

但是它并非是放之四海皆準(zhǔn)的,有時(shí)它反而成了一顆導(dǎo)致系統(tǒng)“掛掉”的自殺子彈。有時(shí)候這種原因的出現(xiàn)并非 Cache 本身的技術(shù)不好,而是我們沒有做好治理。

下面,我們將從三個(gè)方面來具體討論緩存的治理:

  • 緩存使用中的一些痛點(diǎn)
  • 如何用好緩存,用正確緩存
  • 如何通過治理讓緩存的問題化為無形

緩存使用中的一些痛點(diǎn)

我們同程的業(yè)務(wù)特點(diǎn)是:OTA 類商品,沒有任何一個(gè)價(jià)格是固定的。像酒店,客戶今天訂、明天訂、連續(xù)訂三天、訂兩天,是否跨周末,他們最后得出的價(jià)格都是不一樣的。

價(jià)格隨著時(shí)間的變化而波動(dòng)的。這些波動(dòng)會(huì)引發(fā)大量的計(jì)算,進(jìn)而帶來性能上的損耗。

要解決性能的損耗問題,我們勢必要插入各種 Cache,包括:價(jià)格的 Cache、時(shí)間段的 Cache、庫存的 Cache。而且這些 Cache 的寫入數(shù)據(jù)量遠(yuǎn)大于整個(gè)外部的請求數(shù)據(jù)量,即:寫多于讀。

下面介紹同程緩存使用的歷史:

  • 一開始,我們僅使用一臺(tái) Memcache 來提供緩存服務(wù)。
  • 后來,我們發(fā)現(xiàn) Memcache 存在著支持并發(fā)性不好、可運(yùn)維性欠佳、原子性操作不夠、在誤操作時(shí)產(chǎn)生數(shù)據(jù)不一致等問題。
  • 因此,我們轉(zhuǎn)為使用 Redis,以單線程保證原子性操作,而且它的數(shù)據(jù)類型也比較多。當(dāng)有一批新的業(yè)務(wù)邏輯被寫到 Redis 中時(shí),我們就把它當(dāng)作一個(gè)累加計(jì)數(shù)器。

當(dāng)然,更有甚者把它當(dāng)作數(shù)據(jù)庫。由于數(shù)據(jù)庫比較慢,他們就讓數(shù)據(jù)線先寫到 Redis,再落盤到數(shù)據(jù)庫中。

  • 隨后,我們發(fā)現(xiàn)在單機(jī) Redis 的情況下,Cache 成了系統(tǒng)的“命門”。哪怕上層的計(jì)算尚屬良好、哪怕流量并不大,我們的服務(wù)也會(huì)“掛掉”。于是我們引入了集群 Redis。
  • 同時(shí),我們用 Java 語言自研了 Redis 的客戶端。我們也在客戶端里實(shí)現(xiàn)了二級(jí) Cache。不過,我們發(fā)現(xiàn)還是會(huì)偶爾出現(xiàn)錯(cuò)亂的問題。
  • 后來,我們還嘗試了分布式 Cache,以及將 Redis 部署到 Docker 里面。

最終,我們發(fā)現(xiàn)這些問題都是跟場景相關(guān)。如果你所構(gòu)建的場景較為紊亂,則直接會(huì)導(dǎo)致底層無法提供服務(wù)。

下面我們來看看有哪些需要治理的場景,通俗地說就是有哪些“坑”需要“填”。

早期在單機(jī)部署 Redis 服務(wù)的時(shí)代,我們針對(duì)業(yè)務(wù)系統(tǒng)部署了一套使用腳本運(yùn)維的平臺(tái)。

當(dāng)時(shí)在一臺(tái)虛機(jī)上能跑六萬左右的并發(fā)數(shù)據(jù),這些對(duì)于 Redis 服務(wù)器來說基本夠用了。

但是當(dāng)大量部署,并達(dá)到了數(shù)百多臺(tái)時(shí),我們碰到了兩個(gè)問題:

  • 面對(duì)高并發(fā)的性能需求,我們無法單靠腳本進(jìn)行運(yùn)維。一旦運(yùn)維操作出現(xiàn)失誤或失控,就可能導(dǎo)致 Redis 的主從切換失敗,甚至引起服務(wù)宕機(jī),從而直接對(duì)整個(gè)業(yè)務(wù)端產(chǎn)生影響。
  • 應(yīng)用調(diào)用的凌亂。在采用微服務(wù)化之前,我們面對(duì)的往往是一個(gè)擁有各種模塊的大系統(tǒng)。

而在使用場景中,我們常把 Redis 看成數(shù)據(jù)庫、存有各種工程的數(shù)據(jù)源。同時(shí)我們將 Cache 視為一個(gè)黑盒子,將各種應(yīng)用數(shù)據(jù)都放入其中。

例如,對(duì)于一個(gè)訂單交易系統(tǒng),你可能會(huì)把訂單積分、訂單說明、訂單數(shù)量等信息放入其中,這樣就導(dǎo)致了大量的業(yè)務(wù)模塊被耦合于此,同時(shí)所有的業(yè)務(wù)邏輯數(shù)據(jù)塊也集中在了 Redis 處。

那么就算我們?nèi)ゲ鸱治⒎?wù)、做代碼解耦,可是多數(shù)情況下緩存池中的大數(shù)據(jù)并沒有得到解耦,多個(gè)服務(wù)端仍然通過 Redis 去共享和調(diào)用數(shù)據(jù)。

一旦出現(xiàn)宕機(jī),就算你能對(duì)服務(wù)進(jìn)行降級(jí),也無法對(duì)數(shù)據(jù)本身采取降級(jí),從而還是會(huì)導(dǎo)致整體業(yè)務(wù)的“掛掉”。

脆弱的數(shù)據(jù)消失了。由于大家都習(xí)慣把 Redit 當(dāng)作數(shù)據(jù)庫使用(雖然大家都知道在工程中不應(yīng)該如此),畢竟它不是數(shù)據(jù)庫,沒有持久性,所以一旦數(shù)據(jù)丟失就會(huì)出現(xiàn)大的麻煩。

為了防止單臺(tái)掛掉,我們可以采用多臺(tái) Redis。此時(shí)運(yùn)維和應(yīng)用分別有兩種方案:

  • 運(yùn)維認(rèn)為:可以做“主從”,并提供一個(gè)浮動(dòng)的虛擬 IP(VIP)地址。在一個(gè)節(jié)點(diǎn)出現(xiàn)問題時(shí),VIP 地址不用變更,直接連到下一個(gè)節(jié)點(diǎn)便可。
  • 應(yīng)用認(rèn)為:可以在應(yīng)用客戶端里寫入兩個(gè)地址,并采取“哨兵”監(jiān)控,來實(shí)現(xiàn)自動(dòng)切換。

這兩個(gè)方案看似沒有問題,但是架不住 Redis 的濫用。我們曾經(jīng)碰到過一個(gè)現(xiàn)實(shí)的案例:如上圖右下角所示,兩個(gè) Redis 根據(jù)主從關(guān)系可以互相切換。

按照需求,存有 20G 數(shù)據(jù)的主 Redis 開始對(duì)從 Redis 進(jìn)行同步。此時(shí)網(wǎng)絡(luò)出現(xiàn)卡頓,而應(yīng)用正好發(fā)現(xiàn)自己的請求也相應(yīng)變慢了,因此上層應(yīng)用根據(jù)網(wǎng)絡(luò)故障采取主從切換。

然而此時(shí)由于主從 Redis 正好處于同步狀態(tài),資源消耗殆盡,那么在上次應(yīng)用看來此時(shí)主從 Redis 都是不可達(dá)的。

我們經(jīng)過深入排查,最終發(fā)現(xiàn)是在 Cache 中某個(gè)表的一個(gè) Key 中,被存放了 20G 的數(shù)據(jù)。

而在程序?qū)用嫔?,他們并沒有控制好該 Key 的消失時(shí)間(如一周),因而造成了該 Key 被持續(xù)追加增大的狀況。

由上可見,就算我們對(duì) Redis 進(jìn)行了拆分,這個(gè)巨大的 Key 仍會(huì)存在于某一個(gè)“片”上。

如上圖所示,仍以 Redis 為例,我們能夠監(jiān)控的方面包括:

  • 當(dāng)前客戶端的連接數(shù)
  • 客戶端的輸出與輸入情況
  • 是否出現(xiàn)堵塞
  • 被分配的整個(gè)內(nèi)存總量
  • 主從復(fù)制時(shí)的狀態(tài)信息
  • 集群的情況
  • 各服務(wù)器每秒執(zhí)行的命令數(shù)量

可以說,這些監(jiān)控的方面并不能及時(shí)地發(fā)現(xiàn)上述 20 個(gè) G 的 Key 數(shù)據(jù)。再比如:通常系統(tǒng)是在客戶下訂單之后,才增加會(huì)員積分。

但是在應(yīng)用設(shè)計(jì)上卻將核心訂單里的核心 Key,與本該滯后增加的積分輔助進(jìn)程,放在了同一個(gè)實(shí)例之中。

由于我們能夠監(jiān)控到的都是些延遲信息,因此這種將級(jí)別高的數(shù)據(jù)與級(jí)別低的數(shù)據(jù)混淆的情況,是無法被監(jiān)控到的。

上面是一段運(yùn)維與開發(fā)的真實(shí)對(duì)話,曾發(fā)生在我們公司內(nèi)部的 IM 上,它反映了在 DevOps 推進(jìn)之前,運(yùn)維與開發(fā)之間的矛盾。

開發(fā)問:Redis 為什么不能訪問?

運(yùn)維答:剛才服務(wù)器因內(nèi)存故障自動(dòng)重啟了。其背后的原因是:一個(gè) Cache 的故障導(dǎo)致了某個(gè)業(yè)務(wù)的故障。業(yè)務(wù)認(rèn)為自己的代碼沒有問題,原因在于運(yùn)維的 Cache 上。

開發(fā)問:為什么我的 Cache 的延遲這么大?

運(yùn)維答:發(fā)現(xiàn)開發(fā)在此處放了幾萬條數(shù)據(jù),從而影響了插入排序。

開發(fā)問:我寫進(jìn)去的 Key 找不到?肯定是 Cache 出錯(cuò)了。這其實(shí)是運(yùn)維 Cache 與使用 Cache 之間的最大矛盾。

運(yùn)維答:你的 Redis 超過最大限制了,根本就沒寫成功,或者寫進(jìn)去就直接被淘汰了。這就是大家都把它當(dāng)成黑盒所帶來的問題。

開發(fā)問:剛剛為何讀取全部失???

運(yùn)維答:網(wǎng)絡(luò)臨時(shí)中斷,在全同步完成之前,從機(jī)的讀取全部失敗了。這是一個(gè)非常經(jīng)典的問題,當(dāng)時(shí)運(yùn)維為了簡化起見,將主從代替了集群模式。

開發(fā)問:我的系統(tǒng)需要 800G 的 Redis,何時(shí)能準(zhǔn)備好?

運(yùn)維答:我們線上的服務(wù)器最大只有 256 G。

開發(fā)問:為什么 Redis 慢得像驢一樣,是否服務(wù)器出了故障?

運(yùn)維答:對(duì)千萬級(jí)的 Key,使用 Keys*,肯定會(huì)慢。

由上可見這些問題既有來自運(yùn)維的,也有來自開發(fā)的,同時(shí)還有當(dāng)前技術(shù)所限制的。

我們在應(yīng)對(duì)并發(fā)查詢時(shí),只注重它給我們帶來的“快”這一性能特點(diǎn),卻忽略了對(duì) Cache 的使用規(guī)范,以及在設(shè)計(jì)時(shí)需要考慮到的各種本身缺點(diǎn)。

如何用好緩存,用正確緩存?

因此在某次重大故障發(fā)生之后,我們總結(jié)出:沒想到初始狀態(tài)下只有 30000 行代碼的小小 Redis 竟然能帶來如此神奇的功能。

以至于它在程序員手中變成了一把“見到釘子就想錘的錘子”,即:他們看見任何的需求都想用緩存去解決。

于是他們相繼開發(fā)出來了基于緩存的日志搜集器、倒計(jì)時(shí)、計(jì)數(shù)器、訂單系統(tǒng)等,卻忘記了它本身只是一個(gè) Cache。一旦出現(xiàn)了故障,它們將如何去保證其本身呢?

下面我們來看看緩存故障的具體因素有哪些?

過度依賴

即:明明不需要設(shè)置緩存之處,卻非要用緩存。程序員們常認(rèn)為某處可能會(huì)在將來出現(xiàn)大的并發(fā)量,故放置了緩存,卻忘記了對(duì)數(shù)據(jù)進(jìn)行隔離,以及使用的方式是否正確。

例如:在某些代碼中,一個(gè)函數(shù)會(huì)執(zhí)行一到兩百次 Cache 的讀取,通過反復(fù)的 get 操作,對(duì)同一個(gè) Key 進(jìn)行連續(xù)的讀取。

試想,一次并發(fā)會(huì)帶給 Redis 多少次操作呢?這些對(duì)于 Redis 來說負(fù)載是相當(dāng)巨大的。

數(shù)據(jù)落盤

這是一個(gè)高頻次出現(xiàn)的問題。由于大家確實(shí)需要一個(gè)高速的 KV 存儲(chǔ),來實(shí)現(xiàn)數(shù)據(jù)落盤需求。

因此他們都會(huì)把整個(gè) Cache 當(dāng)作數(shù)據(jù)庫去使用,將任何不允許丟失的數(shù)據(jù)都放在 Cache 之中。

即使公司有各種使用規(guī)范,此現(xiàn)象仍是無法杜絕。最終我們在 Cache 平臺(tái)上真正做了一個(gè) KV 數(shù)據(jù)庫供程序員們使用,并且要求他們在使用的時(shí)候,必須聲明用的是 KV 數(shù)據(jù)庫還是 Cache。

超大容量

由于大家都知道“放到內(nèi)存里是最快的”,因此他們對(duì)于內(nèi)存的需求是無窮盡的。更有甚者,有人曾向我提出 10 個(gè) T 容量的需求,而根本不去考慮營收上的成本。

雪崩效應(yīng)

由于我們使用的是大量依賴于緩存的數(shù)據(jù),來為并發(fā)提供支撐,一旦緩存出現(xiàn)問題,就會(huì)產(chǎn)生雪崩效應(yīng)。

即:外面的流量還在,你卻不得不重啟整個(gè)緩存服務(wù)器,進(jìn)而會(huì)造成 Cache 被清空的情況。

由于斷絕了數(shù)據(jù)的來源,這將導(dǎo)致后端的服務(wù)連片“掛掉”。為了防止雪崩的出現(xiàn),我們會(huì)多寫一份數(shù)據(jù)到特定磁盤上。

其數(shù)據(jù)“新鮮度”可能不夠,但是當(dāng)雪崩發(fā)生時(shí),它會(huì)被加載到內(nèi)存中,以防止雪崩的下一波沖擊,從而能夠順利地過渡到我們重新將“新鮮”的數(shù)據(jù)灌進(jìn)來為止。

我們對(duì)上面提到的“坑”總結(jié)一下:

  • 最厲害的是:使用者亂用、濫用和懶用。如前例所說,我們平時(shí)對(duì)于緩存到底在哪里用、怎么用、防止什么等方面考慮得實(shí)在太少。
  • 運(yùn)維數(shù)千臺(tái)毫無使用規(guī)則的緩存服務(wù)器。我們常說 DevOps 的做法是讓應(yīng)用與運(yùn)維靠得更近,但是針對(duì)緩存進(jìn)行運(yùn)維時(shí),由于應(yīng)用開發(fā)都不關(guān)心里面的數(shù)據(jù),又何談相互靠近呢?
  • 運(yùn)維不懂開發(fā),開發(fā)不懂運(yùn)維。這導(dǎo)致了緩存系統(tǒng)上各自為政,無法真正地應(yīng)用好 Cache。
  • 緩存在無設(shè)計(jì)、無控制的情況下被使用。一般情況下 JVM 都能監(jiān)控到內(nèi)存的爆漲,并考慮是否需要回收。但是如前例所示,在出現(xiàn)了一個(gè) Key 居然有 20G 大小時(shí)、我們卻往往忽視了一個(gè) Key 在緩存服務(wù)器上的爆漲。
  • 開發(fā)人員能力的不同。由于不可能要求所有的開發(fā)人員都是前端工程師,那么當(dāng)你這個(gè)團(tuán)隊(duì)里面有不同經(jīng)驗(yàn)的人員時(shí),如何讓他們能寫出同樣規(guī)范的代碼呢?
  • 畢竟我們做的是工程,需要更多的人能夠保證寫出來的代碼不會(huì)發(fā)生上述的問題。
  • 太多的服務(wù)器資源被浪費(fèi)。特別是 Cache 的整體浪費(fèi)是非常巨大的。無論并發(fā)量高或低,是否真正需要,大家都在使用它的內(nèi)存。
  • 例如:在我們的幾千臺(tái) Cache Server 中,最高浪費(fèi)量可達(dá) 60%。一些只有幾百或幾千 KPS 要求的系統(tǒng)或數(shù)據(jù)也被設(shè)計(jì)運(yùn)行在了 Cache 昂貴的內(nèi)存中。
  • 而實(shí)際上它們可能僅僅是為了應(yīng)對(duì)一月一次、或一年一次促銷活動(dòng)的 Cache 高峰需求。
  • 懶人心理,應(yīng)對(duì)變化不夠快。應(yīng)對(duì)高并發(fā)量,十個(gè)程序員有五個(gè)會(huì)說:為數(shù)據(jù)層添加 Cache,而不會(huì)真正去為架構(gòu)做長遠(yuǎn)的規(guī)劃。

如何通過治理讓緩存的問題化為無形

那么到底緩存應(yīng)當(dāng)如何被治理呢?從真正的開發(fā)哲學(xué)角度上說,我們想要的是一個(gè)百變的魔術(shù)箱,它能夠快速地自我變化與處理,而不需要開發(fā)和運(yùn)維人員擔(dān)心濫用的問題。

另外,其他需要應(yīng)對(duì)的方面還包括:應(yīng)用對(duì)緩存大小的需求就像貪吃蛇一般,一堆孤島般的單機(jī)服務(wù)器,緩存服務(wù)運(yùn)維則像一個(gè)迷宮。

因此,我們希望構(gòu)建的是一種能適用各種應(yīng)用場景的緩存服務(wù),而不是冷冰冰的 Cache Server。

起初我們嘗試了各種現(xiàn)成的開源方案,但是后來發(fā)現(xiàn)它們或多或少存在著一些問題。

例如:

  • Cachecloud,對(duì)于部署和運(yùn)維方面欠佳。
  • Codis,本身做了一個(gè)很大的集群,但是我們考慮到當(dāng)這么一個(gè)超大池出現(xiàn)問題時(shí),整個(gè)團(tuán)隊(duì)在應(yīng)對(duì)上會(huì)失去靈活性。
  • 例如:我們會(huì)擔(dān)心業(yè)務(wù)數(shù)據(jù)塊可能未做隔離,就被放到了池中,那么當(dāng)一個(gè)實(shí)例“掛掉”時(shí),所有的數(shù)據(jù)塊都會(huì)受到影響。
  • Pika,雖然可以使用硬盤,但是部署方式很少。
  • Twemproxy,只是代理見長,其他的能力欠佳。

后來,我們選擇自己動(dòng)手,做了一個(gè) phoenix 的方案。整個(gè)系統(tǒng)包含了客戶端、運(yùn)維平臺(tái)、以及存儲(chǔ)擴(kuò)容等方面。

在最初期的架構(gòu)設(shè)計(jì)上,我們只讓應(yīng)用端通過簡單的 SDK 去使用該系統(tǒng)。

為了避免服務(wù)端延續(xù)查找 Cache Server 的模式,我們要求應(yīng)用事先聲明其項(xiàng)目和數(shù)據(jù)場景,然后給系統(tǒng)分配一個(gè) Key。SDK 籍此為應(yīng)用分配一個(gè)新的或既有的緩存?zhèn)}庫。

如上圖所示,為了加快速度,我們將緩存區(qū)分出多個(gè)虛擬的邏輯池,它們對(duì)于上層調(diào)度系統(tǒng)來說就是一個(gè)個(gè)的場景。

那么應(yīng)用就可以籍此申請包含需要存放何種數(shù)據(jù)的場景,最后根據(jù)所分配到的 Key 進(jìn)行調(diào)用。

此處,底層是各種數(shù)據(jù)的復(fù)制和遷移,而兩邊則是相應(yīng)的監(jiān)控和運(yùn)維。

但是在系統(tǒng)真正“跑起來”的時(shí)候,我們發(fā)現(xiàn)很難對(duì)其進(jìn)行部署和擴(kuò)容,因此在改造時(shí),我們做重了整個(gè)緩存客戶端 SDK,并引入了場景的配置。

我們通過進(jìn)行本地緩存的管理,添加過濾條件,以保證客戶端讀取緩存時(shí),能夠知道具體的數(shù)據(jù)源和基本的協(xié)議,從而判斷出要訪問的是 Redis、還是 MemCache、或是其他類型的存儲(chǔ)。

在 Cache 客戶端做好之后,我們又碰到了新的問題:由于同程使用了包括 Java、.Net、Go,Node.js 等多種語言的開發(fā)模式,如果為每一種語言都準(zhǔn)備和維護(hù)一套 Cache 的客戶端的話,顯然非常耗費(fèi)人力。

同時(shí),對(duì)于維護(hù)來說:只要是程序就會(huì)有 Bug,只要有 Bug 就需要升級(jí)。一旦所有事業(yè)部的所有應(yīng)用都要升級(jí) SDK,那么對(duì)于所有嵌套應(yīng)用的中間件來說,都要進(jìn)行升級(jí)測試,這將會(huì)牽扯到巨大的回歸量。

可以說這樣的反復(fù)測試幾乎是不現(xiàn)實(shí)的。于是我們需要做出一個(gè)代理層,通過把協(xié)議、過濾、場景等內(nèi)容下沉到 Proxy 中,以實(shí)現(xiàn)SDK的整體輕量化。

與此同時(shí),我們在部署時(shí)也引入了容器,將整個(gè) Redis 都運(yùn)行在容器之中,并讓容器去完成整個(gè)應(yīng)用的部署。

通過容器化的部署,集群的建立變得極其簡單,我們也大幅豐富了集群的方案。

我們實(shí)現(xiàn)了為每個(gè)應(yīng)用場景都能配有一個(gè)(或一種)Key,并且被一個(gè)(或一種)集群來服務(wù)。

眾所周知,Redis 雖然實(shí)現(xiàn)了遷移擴(kuò)容,但是其操作較為復(fù)雜。因此我們自行研發(fā)了一套遷移調(diào)度系統(tǒng),自動(dòng)化地實(shí)現(xiàn)了從流量擴(kuò)容到數(shù)據(jù)擴(kuò)容、以及從縱向到橫向的擴(kuò)容。

如前所述,我們有著 Redis 和 Memcache 兩種客戶端,它們是使用不同的協(xié)議進(jìn)行訪問。因此,我們通過統(tǒng)一的 Proxy 來實(shí)現(xiàn)良好的支持。

如今在我們的緩存平臺(tái)上,運(yùn)維人員唯一需要做的就是:往該緩存平臺(tái)里添加一臺(tái)物理服務(wù)器、插上網(wǎng)線、然后系統(tǒng)就能夠自動(dòng)發(fā)現(xiàn)新的服務(wù)器的加入,進(jìn)而開啟 Redis。

而對(duì)于單場景下的 Redis 實(shí)例,我們也能夠通過控制臺(tái),以獲取包括 Top10 的 Key、當(dāng)前訪問最多的 Key、Key 的屬主、最后由誰執(zhí)行了寫入或修改等多個(gè)監(jiān)控項(xiàng)。

可見,由于上下層都是自建的,因此我們擴(kuò)展了原來 Redis 里沒有的監(jiān)控項(xiàng)。

上圖是 Topkey 使用情況的一個(gè)示例,就像程序在故障時(shí)經(jīng)常用到的 Dump 文件一樣,它能夠反映出后續(xù)的各種編排。

王曉波,同程藝龍機(jī)票事業(yè)群 CTO,專注于高并發(fā)互聯(lián)網(wǎng)架構(gòu)設(shè)計(jì)、分布式電子商務(wù)交易平臺(tái)設(shè)計(jì)、大數(shù)據(jù)分析平臺(tái)設(shè)計(jì)、高可用性系統(tǒng)設(shè)計(jì)。 設(shè)計(jì)過多個(gè)并發(fā)百萬以上平臺(tái)。 擁有十多年豐富的技術(shù)架構(gòu)、技術(shù)咨詢經(jīng)驗(yàn),深刻理解電商系統(tǒng)對(duì)技術(shù)選擇的重要性。

【51CTO原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請注明原文作者和出處為51CTO.com】

責(zé)任編輯:武曉燕 來源: 51CTO技術(shù)棧
相關(guān)推薦

2020-02-15 15:02:44

產(chǎn)品技術(shù)設(shè)計(jì)團(tuán)隊(duì)

2019-04-23 08:42:42

EhcacheMemcacheRedis

2019-07-21 09:17:11

數(shù)據(jù)緩存架構(gòu)

2018-11-15 12:12:31

Memcache緩存系統(tǒng)

2021-09-26 09:16:45

RedisGeo 類型數(shù)據(jù)類型

2020-11-03 13:50:31

Redis緩存數(shù)據(jù)庫

2024-05-06 00:00:00

緩存高并發(fā)數(shù)據(jù)

2022-10-20 18:00:00

MyBatis緩存類型

2023-02-24 16:46:25

Glide緩存機(jī)制

2024-06-24 00:30:00

2021-08-14 09:48:02

ReentrantLock多線編程

2021-11-05 07:59:25

HashMapJava知識(shí)總結(jié)

2022-03-09 09:43:20

并發(fā)編程Java

2017-11-08 12:51:12

2023-06-26 08:31:59

哈希緩存系統(tǒng)

2018-09-12 19:46:53

數(shù)據(jù)庫MySQLRedis

2020-11-09 15:49:38

PHPMemcache網(wǎng)絡(luò)安全

2024-07-25 08:39:48

2023-05-12 11:52:21

緩存場景性能

2021-06-08 06:13:16

React開發(fā)開發(fā)技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)