(03)Redis集群技術(shù)及Codis實(shí)踐

2018-02-24 15:45 更新

原文出處:http://www.infoq.com/cn/articles/effective-ops-part-03
作者:蕭田國(guó)

前言

誠(chéng)如開篇文章所言,高效運(yùn)維包括管理的專業(yè)化和技術(shù)的專業(yè)化。前兩篇我們主要在說(shuō)些管理相關(guān)的內(nèi)容,本篇說(shuō)一下技術(shù)專業(yè)化。希望讀者朋友們能適應(yīng)這個(gè)轉(zhuǎn)換,謝謝。

互聯(lián)網(wǎng)早在幾年前就已進(jìn)入Web 2.0時(shí)代,對(duì)后臺(tái)支撐能力的要求,提高了幾十倍甚至幾百倍。在這個(gè)演化過(guò)程中,緩存系統(tǒng)扮演了舉足輕重的角色。

運(yùn)維進(jìn)化到今天,已經(jīng)不是重復(fù)造輪子的時(shí)代。所以,我們?cè)诩軜?gòu)優(yōu)化和自動(dòng)化運(yùn)維中,可以盡可能地選用優(yōu)秀的開源產(chǎn)品,而不是自己完全從頭再來(lái)(各種技術(shù)geek除外)。

本文主要討論Redis集群相關(guān)技術(shù)及新發(fā)展,關(guān)于Redis運(yùn)維等內(nèi)容,以后另開主題討論。

本文重點(diǎn)推薦Codis——豌豆莢開源的Redis分布式中間件(該項(xiàng)目于4個(gè)月前在GitHub開源,目前star已超過(guò)2100)。其和Twemproxy相比,有諸多激動(dòng)人心的新特性,并支持從Twemproxy無(wú)縫遷移至Codis。

本文主要目錄如下,對(duì)Redis比較了解的朋友,可跳過(guò)前兩部分,直接欣賞Codis相關(guān)內(nèi)容。

好吧我們正式開始。

1. Redis常見集群技術(shù)

長(zhǎng)期以來(lái),Redis本身僅支持單實(shí)例,內(nèi)存一般最多10~20GB。這無(wú)法支撐大型線上業(yè)務(wù)系統(tǒng)的需求。而且也造成資源的利用率過(guò)低——畢竟現(xiàn)在服務(wù)器內(nèi)存動(dòng)輒100~200GB。

為解決單機(jī)承載能力不足的問題,各大互聯(lián)網(wǎng)企業(yè)紛紛出手,“自助式”地實(shí)現(xiàn)了集群機(jī)制。在這些非官方集群解決方案中,物理上把數(shù)據(jù)“分片”(sharding)存儲(chǔ)在多個(gè)Redis實(shí)例,一般情況下,每一“片”是一個(gè)Redis實(shí)例。

包括官方近期推出的Redis Cluster,Redis集群有三種實(shí)現(xiàn)機(jī)制,分別介紹如下,希望對(duì)大家選型有所幫助。

1.1 客戶端分片

這種方案將分片工作放在業(yè)務(wù)程序端,程序代碼根據(jù)預(yù)先設(shè)置的路由規(guī)則,直接對(duì)多個(gè)Redis實(shí)例進(jìn)行分布式訪問。這樣的好處是,不依賴于第三方分布式中間件,實(shí)現(xiàn)方法和代碼都自己掌控,可隨時(shí)調(diào)整,不用擔(dān)心踩到坑。

這實(shí)際上是一種靜態(tài)分片技術(shù)。Redis實(shí)例的增減,都得手工調(diào)整分片程序?;诖朔制瑱C(jī)制的開源產(chǎn)品,現(xiàn)在仍不多見。

這種分片機(jī)制的性能比代理式更好(少了一個(gè)中間分發(fā)環(huán)節(jié))。但缺點(diǎn)是升級(jí)麻煩,對(duì)研發(fā)人員的個(gè)人依賴性強(qiáng)——需要有較強(qiáng)的程序開發(fā)能力做后盾。如果主力程序員離職,可能新的負(fù)責(zé)人,會(huì)選擇重寫一遍。

所以,這種方式下,可運(yùn)維性較差。出現(xiàn)故障,定位和解決都得研發(fā)和運(yùn)維配合著解決,故障時(shí)間變長(zhǎng)。

這種方案,難以進(jìn)行標(biāo)準(zhǔn)化運(yùn)維,不太適合中小公司(除非有足夠的DevOPS)。

1.2 代理分片

這種方案,將分片工作交給專門的代理程序來(lái)做。代理程序接收到來(lái)自業(yè)務(wù)程序的數(shù)據(jù)請(qǐng)求,根據(jù)路由規(guī)則,將這些請(qǐng)求分發(fā)給正確的Redis實(shí)例并返回給業(yè)務(wù)程序。

這種機(jī)制下,一般會(huì)選用第三方代理程序(而不是自己研發(fā)),因?yàn)楹蠖擞卸鄠€(gè)Redis實(shí)例,所以這類程序又稱為分布式中間件。

這樣的好處是,業(yè)務(wù)程序不用關(guān)心后端Redis實(shí)例,運(yùn)維起來(lái)也方便。雖然會(huì)因此帶來(lái)些性能損耗,但對(duì)于Redis這種內(nèi)存讀寫型應(yīng)用,相對(duì)而言是能容忍的。

這是我們推薦的集群實(shí)現(xiàn)方案。像基于該機(jī)制的開源產(chǎn)品Twemproxy,便是其中代表之一,應(yīng)用非常廣泛。

1.3 Redis Cluster

在這種機(jī)制下,沒有中心節(jié)點(diǎn)(和代理模式的重要不同之處)。所以,一切開心和不開心的事情,都將基于此而展開。

Redis Cluster將所有Key映射到16384個(gè)Slot中,集群中每個(gè)Redis實(shí)例負(fù)責(zé)一部分,業(yè)務(wù)程序通過(guò)集成的Redis Cluster客戶端進(jìn)行操作??蛻舳丝梢韵蛉我粚?shí)例發(fā)出請(qǐng)求,如果所需數(shù)據(jù)不在該實(shí)例中,則該實(shí)例引導(dǎo)客戶端自動(dòng)去對(duì)應(yīng)實(shí)例讀寫數(shù)據(jù)。

Redis Cluster的成員管理(節(jié)點(diǎn)名稱、IP、端口、狀態(tài)、角色)等,都通過(guò)節(jié)點(diǎn)之間兩兩通訊,定期交換并更新。

由此可見,這是一種非?!爸亍钡姆桨?。已經(jīng)不是Redis單實(shí)例的“簡(jiǎn)單、可依賴”了??赡苓@也是延期多年之后,才近期發(fā)布的原因之一。

這令人想起一段歷史。因?yàn)镸emcache不支持持久化,所以有人寫了一個(gè)Membase,后來(lái)改名叫Couchbase,說(shuō)是支持Auto Rebalance,好幾年了,至今都沒多少家公司在使用。

這是個(gè)令人憂心忡忡的方案。為解決仲裁等集群管理的問題,Oracle RAC還會(huì)使用存儲(chǔ)設(shè)備的一塊空間。而Redis Cluster,是一種完全的去中心化……

本方案目前不推薦使用,從了解的情況來(lái)看,線上業(yè)務(wù)的實(shí)際應(yīng)用也并不多見。

2. Twemproxy及不足之處

Twemproxy是一種代理分片機(jī)制,由Twitter開源。Twemproxy作為代理,可接受來(lái)自多個(gè)程序的訪問,按照路由規(guī)則,轉(zhuǎn)發(fā)給后臺(tái)的各個(gè)Redis服務(wù)器,再原路返回。

這個(gè)方案順理成章地解決了單個(gè)Redis實(shí)例承載能力的問題。當(dāng)然,Twemproxy本身也是單點(diǎn),需要用Keepalived做高可用方案。

我想很多人都應(yīng)該感謝Twemproxy,這么些年來(lái),應(yīng)用范圍最廣、穩(wěn)定性最高、最久經(jīng)考驗(yàn)的分布式中間件,應(yīng)該就是它了。只是,他還有諸多不方便之處。

Twemproxy最大的痛點(diǎn)在于,無(wú)法平滑地?cái)U(kuò)容/縮容。

這樣導(dǎo)致運(yùn)維同學(xué)非常痛苦:業(yè)務(wù)量突增,需增加Redis服務(wù)器;業(yè)務(wù)量萎縮,需要減少Redis服務(wù)器。但對(duì)Twemproxy而言,基本上都很難操作(那是一種錐心的、糾結(jié)的痛……)。

或者說(shuō),Twemproxy更加像服務(wù)器端靜態(tài)sharding。有時(shí)為了規(guī)避業(yè)務(wù)量突增導(dǎo)致的擴(kuò)容需求,甚至被迫新開一個(gè)基于Twemproxy的Redis集群。

Twemproxy另一個(gè)痛點(diǎn)是,運(yùn)維不友好,甚至沒有控制面板。

Codis剛好擊中Twemproxy的這兩大痛點(diǎn),并且提供諸多其他令人激賞的特性。

3. Codis實(shí)踐

Codis由豌豆莢于2014年11月開源,基于Go和C開發(fā),是近期涌現(xiàn)的、國(guó)人開發(fā)的優(yōu)秀開源軟件之一?,F(xiàn)已廣泛用于豌豆莢的各種Redis業(yè)務(wù)場(chǎng)景(已得到豌豆莢@劉奇同學(xué)的確認(rèn),呵呵)。

從3個(gè)月的各種壓力測(cè)試來(lái)看,穩(wěn)定性符合高效運(yùn)維的要求。性能更是改善很多,最初比Twemproxy慢20%;現(xiàn)在比Twemproxy快近100%(條件:多實(shí)例,一般Value長(zhǎng)度)。

3.1 體系架構(gòu)

Codis引入了Group的概念,每個(gè)Group包括1個(gè)Redis Master及至少1個(gè)Redis Slave,這是和Twemproxy的區(qū)別之一。這樣做的好處是,如果當(dāng)前Master有問題,則運(yùn)維人員可通過(guò)Dashboard“自助式”切換到Slave,而不需要小心翼翼地修改程序配置文件。

為支持?jǐn)?shù)據(jù)熱遷移(Auto Rebalance),出品方修改了Redis Server源碼,并稱之為Codis Server。

Codis采用預(yù)先分片(Pre-Sharding)機(jī)制,事先規(guī)定好了,分成1024個(gè)slots(也就是說(shuō),最多能支持后端1024個(gè)Codis Server),這些路由信息保存在ZooKeeper中。

ZooKeeper還維護(hù)Codis Server Group信息,并提供分布式鎖等服務(wù)。

3.2 性能對(duì)比測(cè)試

Codis目前仍被精益求精地改進(jìn)中。其性能,從最初的比Twemproxy慢20%(雖然這對(duì)于內(nèi)存型應(yīng)用而言,并不明顯),到現(xiàn)在遠(yuǎn)遠(yuǎn)超過(guò)Twemproxy性能(一定條件下)。

我們進(jìn)行了長(zhǎng)達(dá)3個(gè)月的測(cè)試。測(cè)試基于redis-benchmark,分別針對(duì)Codis和Twemproxy,測(cè)試Value長(zhǎng)度從16B~10MB時(shí)的性能和穩(wěn)定性,并進(jìn)行多輪測(cè)試。

一共有4臺(tái)物理服務(wù)器參與測(cè)試,其中一臺(tái)分別部署codis和twemproxy,另外三臺(tái)分別部署codis server和redis server,以形成兩個(gè)集群。

從測(cè)試結(jié)果來(lái)看,就Set操作而言,在Value長(zhǎng)度<888B時(shí),Codis性能優(yōu)越優(yōu)于Twemproxy(這在一般業(yè)務(wù)的Value長(zhǎng)度范圍之內(nèi))。

就Get操作而言,Codis性能一直優(yōu)于Twemproxy。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)