日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

小米的redis使用規(guī)模很大,現(xiàn)在有數(shù)萬個實例,并且每天有百萬億次的訪問頻率,支撐了幾乎所有的產品線和生態(tài)鏈公司。之前所有的Redis都部署在物理機上,也沒有做資源隔離,給管理治理帶來了很大的困難。我們的運維人員工作壓力很大,機器宕機網絡抖動導致的Redis節(jié)點下線都經常需要人工介入處理。由于沒有做CPU的資源隔離,slave節(jié)點打RDB或者由于流量突增導致節(jié)點QPS升高造成的節(jié)點CPU使用率升高,都可能對本集群或其他集群的節(jié)點造成影響,導致無法預測的時延增加。

Redis分片方式采用社區(qū)的Redis Cluster協(xié)議,集群自主分片。Redis Cluster帶來了一定的易用性的同時,也提高了應用開發(fā)的門檻,應用開發(fā)人員需要一定程度上了解Redis Cluster,同時需要使用智能客戶端訪問Redis Cluster。這些智能客戶端配置參數(shù)繁多,應用開發(fā)人員并無法完全掌握并設置這些參數(shù),踩了很多坑。同時,由于智能客戶端需要做分片計算,給應用端的機器也帶來了一定的負載。

小米Redis的K8s容器化部署實踐

 

Why K8S

資源隔離

當前的Redis Cluster部署在物理機集群上,為了提高資源利用率節(jié)約成本,多業(yè)務線的Redis集群都是混布的。由于沒有做CPU的資源隔離,經常出現(xiàn)某Redis節(jié)點CPU使用率過高導致其他Redis集群的節(jié)點爭搶不到CPU資源引起時延抖動。因為不同的集群混布,這類問題很難快速定位,影響運維效率。K8s容器化部署可以指定 CPU request 和 CPU limit ,在提高資源利用率的同時避免了資源爭搶。

自動化部署

自動化部署。當前Redis Cluster在物理機上的部署過程十分繁瑣,需要通過查看元信息數(shù)據(jù)庫查找有空余資源的機器,手動修改很多配置文件再逐個部署節(jié)點,最后使用redis_trib工具創(chuàng)建集群,新集群的初始化工作經常需要一兩個小時。

K8s通過StatefulSet部署Redis集群,使用configmap管理配置文件,新集群部署時間只需要幾分鐘,大大提高了運維效率。

How K8S

客戶端通過LVS的VIP統(tǒng)一接入,通過Redis Proxy轉發(fā)服務請求到Redis Cluster集群。這里我們引入了Redis Proxy來轉發(fā)請求。

小米Redis的K8s容器化部署實踐

 

Redis Cluster部署方式

Redis部署為StatefulSet,作為有狀態(tài)的服務,選擇StatefulSet最為合理,可以將節(jié)點的RDB/AOF持久化到分布式存儲中。當節(jié)點重啟漂移到其他機器上時,可通過掛載的PVC(PersistentVolumeClaim)拿到原來的RDB/AOF來同步數(shù)據(jù)。我們選擇的持久化存儲PV(PersistentVolume)是Ceph Block Service。Ceph的讀寫性能低于本地磁盤,會帶來100~200ms的讀寫時延。但由于Redis的RDB/AOF的寫出都是異步的,分布式存儲帶來的讀寫延遲對服務并沒有影響。

小米Redis的K8s容器化部署實踐

 

Proxy選型

開源的Redis Proxy有很多,常見的開源Redis Proxy如下:

小米Redis的K8s容器化部署實踐

 

我們希望能夠繼續(xù)使用Redis Cluster來管理Redis集群,所以Codis和Twemproxy不再考慮。redis-cluster-proxy是Redis官方在6.0版本推出的支持Redis Cluster協(xié)議的Proxy,但是目前還沒有穩(wěn)定版,暫時也無法大規(guī)模應用。

備選就只有Cerberus和Predixy兩種。我們在K8s環(huán)境上對Cerberus和Predixy進行了性能測試,結果如下:

測試環(huán)境

測試工具: redis-benchmark

Proxy CPU: 2 core

Client CPU: 2 core

Redis Cluster: 3 master nodes, 1 CPU per node

測試結果

小米Redis的K8s容器化部署實踐

 


小米Redis的K8s容器化部署實踐

 

在相同workload和配置下,Predixy的最高QPS要優(yōu)于Cerberus,時延也比較接近。綜合來看,Predixy比Cerberus的性能要高33%~60%,并且數(shù)據(jù)的key/value越大,Predixy優(yōu)勢越明顯,所以最后我們選擇了Predixy。

為了適應業(yè)務和K8s環(huán)境,在上線前我們對Predixy做了大量的改動,增加了很多新的功能,比如動態(tài)切換后端Redis Cluster、黑白名單、異常操作審計等。

Proxy部署方式

Proxy作為deployment部署,無狀態(tài)輕量化,通過LB對外提供服務,很容易做到動態(tài)擴縮容。同時,我們?yōu)镻roxy開發(fā)了動態(tài)切換后端Redis Cluster的功能,可實現(xiàn)在線添加和切換Redis Cluster。

Proxy自動擴縮容方式

我們使用K8s原生的HPA(Horizontal Pod Autoscaler)來實現(xiàn)Proxy的動態(tài)擴縮容。當Proxy所有pod的平均CPU使用率超過一定閾值時,會自動觸發(fā)擴容,HPA會將Proxy的replica數(shù)加1,之后LVS就會探測到新的Proxy pod并將一部分流量切過去。如果擴容后CPU使用率仍然超過規(guī)定的閾值,會繼續(xù)觸發(fā)擴容邏輯。但是在擴容成功5分鐘內,不論CPU使用率降到多低,都不會觸發(fā)縮容邏輯,這樣就避免了頻繁的擴縮容給集群穩(wěn)定性帶來的影響。

HPA可配置集群的最少(MINPODS)和最多(MAXPODS)pod數(shù)量,集群負載再低也不會縮容到MINPODS以下數(shù)量的pods。建議客戶可以根據(jù)自己的實際業(yè)務情況來決定MINPODS和MAXPODS的值。

Why Proxy

Redis pod重啟可導致IP變化

使用Redis Cluster的Redis客戶端,都需要配置集群的部分IP和Port,用于客戶端重啟時查找Redis Cluster的入口。對于物理機集群部署的Redis節(jié)點,即便遇到實例重啟或者機器重啟,IP和Port都可以保持不變,客戶端依然能夠找到Redis Cluster的拓撲。但是部署在K8s上的Redis Cluster,pod重啟是不保證IP不變的(即便是重啟在原來的K8s node上),這樣客戶端重啟時,就可能會找不到Redis Cluster的入口。

通過在客戶端和Redis Cluster之間加上Proxy,就對客戶端屏蔽了Redis Cluster的信息,Proxy可以動態(tài)感知Redis Cluster的拓撲變化,客戶端只需要將LVS的IP:Port作為入口,請求轉發(fā)到Proxy上,即可以像使用單機版Redis一樣使用Redis Cluster集群,而不需要Redis智能客戶端。

Redis處理連接負載高

在6.0版本之前,Redis都是單線程處理大部分任務的。當Redis節(jié)點的連接較高時,Redis需要消耗大量的CPU資源處理這些連接,導致時延升高。有了Proxy之后,大量連接都在Proxy上,而Proxy跟Redis實例之間只保持很少的連接,這樣降低了Redis的負擔,避免了因為連接增加而導致的Redis時延升高。

集群遷移切換需要應用重啟

在使用過程中,隨著業(yè)務的增長,Redis集群的數(shù)據(jù)量會持續(xù)增加,當每個節(jié)點的數(shù)據(jù)量過高時,BGSAVE的時間會大大延長,降低集群的可用度。同時QPS的增加也會導致每個節(jié)點的CPU使用率增高。這都需要增加擴容集群來解決。目前Redis Cluster的橫向擴展能力不是很好,原生的slots搬移方案效率很低。新增節(jié)點后,有些客戶端比如Lettuce,會因為安全機制無法識別新節(jié)點。另外遷移時間也完全無法預估,遷移過程中遇到問題也無法回退。

當前物理機集群的擴容方案是:

  1. 按需創(chuàng)建新集群
  2. 使用同步工具將數(shù)據(jù)從老集群同步到新集群
  3. 確認數(shù)據(jù)無誤后,跟業(yè)務溝通,重啟服務切換到新集群

整個過程繁瑣而且風險較大,還需要業(yè)務重啟服務。

有了Proxy層,可以將后端的創(chuàng)建、同步和切換集群對客戶端屏蔽掉。新老集群同步完成之后,向Proxy發(fā)送命令就可以將連接換到新集群,可以實現(xiàn)對客戶端完全無感知的集群擴縮容。

數(shù)據(jù)安全風險

Redis是通過AUTH來實現(xiàn)鑒權操作,客戶端直連Redis,密碼還是需要在客戶端保存。而使用Proxy,客戶端只需要通過Proxy的密碼來訪問Proxy,不需要知道Redis的密碼。Proxy還限制了FLUSHDB、CONFIG SET等操作,避免了客戶誤操作清空數(shù)據(jù)或修改Redis配置,大大提高了系統(tǒng)的安全性。

同時,Redis并沒有提供審計功能。我們在Proxy上增加了高危操作的日志保存功能,可以在不影響整體性能的前提下提供審計能力。

Proxy 帶來的問題

多一跳帶來的時延

Proxy在客戶端和Redis實例之間,客戶端訪問Redis數(shù)據(jù)需要先訪問Proxy再訪問Redis節(jié)點,多了一跳,會導致時延增加。經測試,多一跳會增加0.2~0.3ms的時延,不過通常這對業(yè)務來說是可以接受的。

Pod漂移造成IP變化

Proxy在K8s上是通過deployment部署的,一樣會有節(jié)點重啟導致IP變化的問題。我們K8s的LB方案可以感知到Proxy的IP變化,動態(tài)的將LVS的流量切到重啟后的Proxy上。

LVS帶來的時延

LVS也會帶來時延,如下表中的測試,不同的數(shù)據(jù)長度get/set操作,LVS引入的時延小于0.1ms。

小米Redis的K8s容器化部署實踐

 

K8S 帶來的好處

部署方便

通過運維平臺調用K8s API部署集群,大大提高了運維效率。

解決端口管理問題

目前小米在物理機上部署Redis實例是通過端口來區(qū)分的,并且下線的端口不能復用,也就是說整個公司每個Redis實例都有唯一的端口號。目前65535個端口已經用到了40000多,按現(xiàn)在的業(yè)務發(fā)展速度,將在兩年內耗盡端口資源。而通過K8s部署,每一個Redis實例對應的K8s pod都有獨立的IP,不存在端口耗盡問題和復雜的管理問題。

降低客戶使用門檻

對應用來說,只需要使用單機版的非智能客戶端連接VIP,降低了使用門檻,避免了繁瑣復雜的參數(shù)設置。同時由于VIP和端口是固定不變的,應用程序不再需要自己管理Redis Cluster的拓撲。

提高客戶端性能

使用非智能客戶端還可以降低客戶端的負載,因為智能客戶端需要在客戶端對key進行hash以確定將請求發(fā)送到哪個Redis節(jié)點,在QPS比較高的情況下會消耗客戶端機器的CPU資源。當然,為了降低客戶端應用遷移的難度,我們讓Proxy也支持了智能客戶端協(xié)議。

動態(tài)升級和擴縮容

Proxy支持動態(tài)添加切換Redis Cluster的功能,這樣Redis Cluster的集群升級和擴容切換過程可以做到對業(yè)務端完全無感知。例如,業(yè)務方使用30個節(jié)點的Redis Cluster集群,由于業(yè)務量的增加,數(shù)據(jù)量和QPS都增長的很快,需要將集群規(guī)模擴容兩倍。如果在原有的物理機上擴容,需要以下過程:

  1. 協(xié)調資源,部署60個節(jié)點的新集群
  2. 手動配置遷移工具,將當前集群的數(shù)據(jù)遷移到新集群
  3. 驗證數(shù)據(jù)無誤后,通知業(yè)務方修改Redis Cluster連接池拓撲,重啟服務

雖然Redis Cluster支持在線擴容,但是擴容過程中slots搬移會對線上業(yè)務造成影響,同時遷移時間不可控,所以現(xiàn)階段很少采用這種方式,只有在資源嚴重不足時才會偶爾使用。

在新的K8s架構下,遷移過程如下:

  1. 通過API接口一鍵創(chuàng)建60個節(jié)點的新集群
  2. 同樣通過API接口一鍵創(chuàng)建集群同步工具,將數(shù)據(jù)遷移到新集群
  3. 驗證數(shù)據(jù)無誤后,向Proxy發(fā)送命令添加新集群信息并完成切換

整個過程對業(yè)務端完全無感知。

集群升級也很方便:如果業(yè)務方能接受一定的延遲毛刺,可以在低峰時通過StatefulSet滾動升級的方式來實現(xiàn);如果業(yè)務對延遲有要求,可以通過創(chuàng)建新集群遷移數(shù)據(jù)的方式來實現(xiàn)。

提高服務穩(wěn)定性和資源利用率

通過K8s自帶的資源隔離能力,實現(xiàn)和其他不同類型應用混部,在提高資源利用率的同時,也能保證服務穩(wěn)定性。

遇到的問題

Pod重啟導致數(shù)據(jù)丟失

K8s的pod碰到問題重啟時,由于重啟速度過快,會在Redis Cluster集群發(fā)現(xiàn)并切主前將pod重啟。如果pod上的Redis是slave,不會造成什么影響。但如果Redis是master,并且沒有AOF,重啟后原先內存的數(shù)據(jù)都被清空,Redis會reload之前存儲的RDB文件,但是RDB文件并不是實時的數(shù)據(jù)。之后slave也會跟著把自己的數(shù)據(jù)同步成之前的RDB文件中的數(shù)據(jù)鏡像,會造成部分數(shù)據(jù)丟失。

StatefulSet是有狀態(tài)服務,部署的pod名是固定格式(StatefulSet名+編號)。我們在初始化Redis Cluster時,將相鄰編號的pod設置為主從關系。在重啟pod時,通過pod名確定它的slave,在重啟pod前向從節(jié)點發(fā)送cluster failover命令,強制將活著的從節(jié)點切主。這樣在重啟后,該節(jié)點會自動以從節(jié)點方式加入集群。

LVS映射時延

Proxy的pod是通過LVS實現(xiàn)負載均衡的,LVS對后端IP:Port的映射生效有一定的時延,Proxy節(jié)點突然下線會導致部分連接丟失。為減少Proxy運維對業(yè)務造成影響,我們在Proxy的deployment模板中增加了如下選項:

  lifecycle:    preStop:      exec:        command:        - sleep        - "171"

對于正常的Proxy pod下線,例如集群縮容、滾動更新Proxy版本以及其它K8s可控的pod下線,在pod下線前會發(fā)消息給LVS并等待171秒,這段時間足夠LVS將這個pod的流量逐漸切到其他pod上,對業(yè)務無感知。

K8s StatefulSet無法滿足Redis Cluster部署要求

K8s原生的StatefulSet不能完全滿足Redis Cluster部署的要求:

  1. Redis Cluster不允許同為主備關系的節(jié)點部署在同一臺機器上。這個很好理解,如果該機器宕機,會導致這個數(shù)據(jù)分片不可用。
  2. Redis Cluster不允許集群超過一半的主節(jié)點失效,因為如果超過一半主節(jié)點失效,就無法有足夠的節(jié)點投票來滿足gossip協(xié)議的要求。因為Redis Cluster的主備是可能隨時切換的,我們無法避免同一個機器上的所有節(jié)點都是主節(jié)點這種情況,所以在部署時不能允許集群中超過1/4的節(jié)點部署在同一臺機器上。

為了滿足上面的要求,原生StatefulSet可以通過 anti-affinity 功能來保證相同集群在同一臺機器上只部署一個節(jié)點,但是這樣機器利用率很低。

因此我們開發(fā)了基于StatefulSet的CRD:RedisStatefulSet,會采用多種策略部署Redis節(jié)點。同時,還在RedisStatefulSet中加入了一些Redis管理功能。這些我們將會在其他文章中來繼續(xù)詳細探討。

總結

目前集團內部已經有多個業(yè)務的數(shù)十個Redis集群部署到了K8s上并運行了半年多。得益于K8s的快速部署和故障遷移能力,這些集群的運維工作量比物理機上的Redis集群低很多,穩(wěn)定性也得到了充分的驗證。

在運維過程中我們也遇到了不少問題,文章中提到的很多功能都是根據(jù)實際需求提煉出來的。目前還是有很多問題需要在后續(xù)逐步解決,以進一步提高資源利用率和服務質量。

混布 Vs. 獨立部署

物理機的Redis實例是獨立部署的,單臺物理機上部署的都是Redis實例,這樣有利于管理,但是資源利用率并不高。Redis實例使用了CPU、內存和網絡IO,但存儲空間基本都是浪費的。在K8s上部署Redis實例,其所在的機器上可能也會部署其他任意類型的服務,這樣雖然可以提高機器的利用率,但是對于Redis這樣的可用性和時延要求都很高的服務來說,如果因為機器內存不足而被驅逐,是不能接受的。這就需要運維人員監(jiān)控所有部署了Redis實例的機器內存,一旦內存不足,就切主和遷移節(jié)點,但這樣又增加運維的工作量。

同時,如果混部的其他服務是網絡吞吐很高的應用,也可能對Redis服務造成影響。雖然K8s的 anti-affinity 功能可以將Redis實例有選擇地部署到沒有這類應用的機器上,但是在機器資源緊張時,還是無法避免這種情況。

Redis Cluster管理

Redis Cluster是一個P2P無中心節(jié)點的集群架構,依靠gossip協(xié)議傳播協(xié)同自動化修復集群的狀態(tài),節(jié)點上下線和網絡問題都可能導致Redis Cluster的部分節(jié)點狀態(tài)出現(xiàn)問題,例如會在集群拓撲中出現(xiàn)failed或者handshake狀態(tài)的節(jié)點,甚至腦裂。對這種異常狀態(tài),我們可以在Redis CRD上增加更多的功能來逐步解決,進一步提高運維效率。

審計與安全

Redis本身只提供了Auth密碼認證保護功能,沒有權限管理,安全性較差。通過Proxy,我們可以通過密碼區(qū)分客戶端類型,管理員和普通用戶使用不同的密碼登錄,可執(zhí)行的操作權限也不同,這樣就可以實現(xiàn)權限管理和操作審計等功能。

支持多Redis Cluster

單個Redis Cluster由于gossip協(xié)議的限制,橫向擴展能力有限,集群規(guī)模在300個節(jié)點時,節(jié)點選主這類拓撲變更的效率就明顯降低。同時,由于單個Redis實例的容量不宜過高,單個Redis Cluster也很難支持TB以上的數(shù)據(jù)規(guī)模。通過Proxy,我們可以對key做邏輯分片,這樣單個Proxy就可以接入多個Redis Cluster,從客戶端的視角來看,就相當于接入了一個能夠支持更大數(shù)據(jù)規(guī)模的Redis集群。

最后,像Redis這種有狀態(tài)服務的容器化部署在國內大廠都還沒有非常成熟的經驗,小米云平臺也是在摸索中逐步完善。目前我們新增集群已經大部分部署在K8s上,更計劃在一到兩年內將集團內大部分的物理機Redis集群都遷移到K8s上。這樣就可以有效地降低運維人員的負擔,在不顯著增加運維人員的同時維護更多的Redis集群。

分享到:
標簽:小米 Redis
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定