緩存服務(wù)器有哪些端緩存(緩存服務(wù)器有哪些作用) DATE: 2026-05-05 07:01:18
人生??不過(guò)如此,緩存且行且珍惜。服務(wù)自己永遠是端緩自己的主角,不要總在別人的存緩存服戲劇里充當著(zhù)配角。
我以林語(yǔ)堂的有作用《人生不過(guò)如此》中一句話(huà)來(lái)開(kāi)篇。
背景
在互聯(lián)網(wǎng)高速發(fā)展、緩存快速演化的服務(wù)時(shí)代,想必在你的端緩系統架構設計中,緩存服務(wù)是存緩存服不是已經(jīng)成為必不可少的一層,豐富的有作用數據結構、高性能的緩存讀寫(xiě)、簡(jiǎn)單的服務(wù)協(xié)議,讓緩存數據庫很好的端緩承擔起關(guān)系型數據庫的上層。暢途網(wǎng)為了(′?`*)解決節假日或高峰期的存緩存??服車(chē)次查詢(xún)、搶票等大數據量的有作用訪(fǎng)問(wèn)請求,很早以前就引進(jìn)了 Redis,來(lái)作為數據庫的上游緩存層,緩解底層數據庫的讀寫(xiě)壓力。
REDIS HA 架構
世界上唯一可以不勞而獲的就是貧窮,唯一可以無(wú)中生有的是夢(mèng)想。沒(méi)有哪件事,不動(dòng)手就可以實(shí)現。世界雖然殘酷,但只(zhi)要(?????)你愿意走,總會(huì )有路;看不到美好,是因為你沒(méi)有堅持走下去。人(′?`)生貴在行動(dòng),遲疑不決時(shí),不妨先邁出小小一步。(╯°□°)╯前進(jìn)不必遺憾,若是美好,叫做精彩;若是糟糕,叫做經(jīng)歷。(′ω`*)**——林語(yǔ)堂《人生不過(guò)如此》
2014 年 10 月,為了避免單點(diǎn)故障,我們嘗試在生產(chǎn)環(huán)境的 Redis 主從架構中,引入了 Redis Sentinel,實(shí)現了 Redis 服務(wù)的 failover。當 Redis-Master 主機異常宕機或 Redis-Master 服務(wù)異常崩潰時(shí),原有的 Redis-Slave 自動(dòng)升級為 master 角色,當原有 Redis-Master 恢復后,自動(dòng)恢復為 slave 角色(′▽?zhuān)?。
由于 Redi??s Sentinel 只能做到 Redis 服務(wù)級別的切換,無(wú)法做到 IP 地址的切換,無(wú)法完全滿(mǎn)??足現網(wǎng)系統架構的需要,我們又嘗試在 HA 架構中加入了(°□°)負載均衡器設備,引用了浮動(dòng) IP,所有應用程序訪(fǎng)問(wèn)浮動(dòng) IP,IP 地址的切換操作(°ロ°) !由負載均衡器設備來(lái)實(shí)現。
Redis Sentinel 配置文件
測試小結:
主 Redis 服務(wù)器:redis-sent-0-17
從 Redis 服務(wù)器:??redis-sent-0-18
redis-sent.cache.changtu.p??vt
- 重啟 redis-sent-0-17 節點(diǎn),60 秒后,redis-sent-0-18 節點(diǎn)成為 master,用戶(hù)訪(fǎng)問(wèn) redis-seヽ(′?`)ノnt.cache.changtu.pvt 域名 re(⊙_⊙)dis 服務(wù)恢復正常,2 分鐘后,redis-se??nt-0-17 節點(diǎn)重啟完成,自動(dòng)成為 slave;(?⊿?)
- 重啟?? redis-sent-0-18 節點(diǎn),60 秒后,redis-sent-0-17 節點(diǎn)成為 master,用戶(hù)訪(fǎng)問(wèn) redis-sent.cache.changtu.pvt 域名 redis 服務(wù)恢復正常,2 分鐘后,red(′;ω;`)is-sent-?0-(⊙_⊙)1ヽ(′?`)ノ8 節點(diǎn)重啟??完成,自動(dòng)成為 slave。
對應用程序的要求
- 緩存應用服務(wù)(′?`*)統一通過(guò)域名訪(fǎng)問(wèn)。
- 緩存應用服務(wù)對 Redis 域名的訪(fǎng)問(wèn)有斷點(diǎn)重連的功能。
2015 年新增 2 臺 Redis Senヾ(′ω`)?tinel 服務(wù)器,負責平臺所??有 Redis 服務(wù)器集群管理。并對平臺現有 Redis 服務(wù)進(jìn)行改造??,逐步升級為 Redis HA 架構。
CODIS 分布式集群
你可以一輩子不登山,但你心中一定要有座山。它使你總往高處爬,它使你總有個(gè)奮斗的方(fang)向,它使你任何一刻抬起頭,都能看??到自(zi)己的希望?!终Z(yǔ)堂《人生不過(guò)(guo)如此》
在 Codis 發(fā)布之前,業(yè)界只有 Twemproxy,??Twemproxy 本身是(shi)一個(gè)靜態(tài)的分布式 Redis 方案,進(jìn)行擴容、縮容對運維要求非常高,而且很難做到平滑的擴縮容。Codis 的目標就是盡量兼容 Twe(′?ω?`)mproxy,并且加上數據遷移的功能以實(shí)現(xian)擴容和縮容,最終替換 Twemproxy。本文省略了對 Twemproxy 的介紹。
與 Codis 同時(shí)期發(fā)布的官方 redis-cluster,采用 P2P 的模式,完全去中心化架??構, 其實(shí)我們花了大精力研究測試過(guò),由于當時(shí)對 failover 判斷方式提出懷疑,高耦合的模塊設計思想、(′_`)客戶(hù)端問(wèn)題、不太??友??好的維護等(deng)方面, 我司目前沒(méi)有投入生產(chǎn),沒(méi)有了(le)實(shí)際的生產(chǎn)維護經(jīng)驗,我先不發(fā)表看法。抱拳,我知道在緩存數據庫里最不應該缺少的就是 Redis-cluster 了,以后有機會(huì )單獨介紹吧!
容我感嘆一下,別指望所有的人都能懂你,因為蘿卜白菜,各有所愛(ài)。你做了蘿卜,自然就做不成青菜。
核心組件說(shuō)明
1. ZooKeeper:
用來(lái)存放(′?`*)數據路由表和 Codis-proxy 節點(diǎn)的元信息,Codis-config 發(fā)起的命令都(dou)會(huì )通過(guò) ZooKeeper 同步到各個(gè)存活的 Codis??-proxy 中。
2. Codis-Proxy :
是客戶(hù)端連接的 Redis 代理服務(wù),本身是??沒(méi)狀態(tài)的,Codis-proxy 實(shí)現了 Redis 協(xié)議,對于一個(gè)業(yè)務(wù)來(lái)說(shuō),可以部署多個(gè) Codis-proxy, 提供??連(lian)接集群 Redis 服務(wù)的入(ru)口。
3. Codis-Config :
是 Cod???is 的集成管理工具,支持添加 / 刪除 Redis 節點(diǎn)、添加 / 刪除 Proxy 節點(diǎn)、以及發(fā)起數據遷移等(deng)操作,Codis-config 還自帶了 http server,會(huì )??啟動(dòng) dashboard,用戶(hù)可以在 WEB 上監控 Codis 集群的狀態(tài)。
4. Codis┐(′ー`)┌-ヽ(′▽?zhuān)?/Server:
是 Codiヽ(′▽?zhuān)?ノs 項目維護的一個(gè)(′?_?`) Redis 分支,基于 redis??-2.8.21 分支開(kāi)發(fā),增加了額外的數據結??構,以支持 slot 有關(guān)的操作以及數據遷移指令。
5.??Pre-Sharding 技術(shù)
Codis 采用 Pre-Shardi??ng 的技術(shù)來(lái)實(shí)現數據的分片, 默認分成 1024 個(gè) slots (0-1023), 對于每個(gè) key 來(lái)說(shuō),(′▽?zhuān)?) 通過(guò)以下公式確定所屬的 Slot Id : SlotId = crc32(key) % 1024,每一個(gè) slot 都會(huì )有一個(gè)特定的 server(⊙_⊙) group id 來(lái)表??(biao)示這個(gè) slot 的數據由哪個(gè) server gr??oup 來(lái)提供。
在 2016 年 6 月左右,我們引進(jìn)了 Codis(當時(shí)版本是 3.0,并沒(méi)有 Redis-Sentinel、Codis-fe 等組件,1 年后,才升級到 3.??2 的,文章主要以 3.0 版本為背景),首先介紹一下基礎環(huán)境。
系統架構
在公司硬件資源有限條件下,我們計劃用 6 臺服務(wù)器部署 Codis,簡(jiǎn)單分了兩層,Codis-Proxy 層和 Codis-Server 層。
- Codis-Proxy 層用了三臺配置相對較低服務(wù)器,部署了 Zoo(╯°□°)╯︵ ┻━┻Keeper、Cod(???)is-Proxy、Keepalived、LVS 等 ,3 個(gè)節點(diǎn)都做了負載均衡。
- Codis-Server 層用來(lái)三臺配置相對較高的服務(wù)器,并用 SSD,3 個(gè) Codis-group,每個(gè) group 有一主一從,交叉部署,每個(gè)主從分配 30G 內存。
我們分別通過(guò) jredis 編寫(xiě)測試程序和使用 redis-benchmark 工具模擬壓力測試(請求量:1000 萬(wàn)~1 億,并發(fā)(fa)數:1000~50000,長(cháng)度??:固定 / 可變):
- 在性能方面:基本上能達到我們的預期,理想情況 Codis 性能值能達到 50~60K OP/S,各個(gè) codis-group 中 master-slave 實(shí)例數據能實(shí)時(shí)同步,詳情可以參考《Codis?? 高可用集群性能測試報告 _20160315》。
- 數據一ヽ(′▽?zhuān)?/致性(xing)問(wèn)題:一方面,Codis 的 HA 并不能保證數據完全不丟失,由于 M-S 是異步復制,當 master 節點(diǎn)異?;虮罎?,將 slave 切換成?? master 后,剛剛沒(méi)來(lái)得及同步的數據就會(huì )丟失。另一方面,Codis 支持的 mg??et??/??mse??t 命令是無(wú)法保證單點(diǎn)時(shí)的原子語(yǔ)義的,如果 mset 指定 KEY 分布在不同 slot 上,從而導致 KEY 在不同機器上,造成要不一起成功,不要一起失敗。所以對于分布式事務(wù)的問(wèn)題,這是一個(gè)痛點(diǎn)。在實(shí)際場(chǎng)(′?`)景中,也有人使用了 lua 腳本以擴展 Redis 的功能,雖然 Codis 支持,但?????是并不保證你的腳本操作(zuo)的數據是否在正確的節點(diǎn)執行,僅僅起到一個(gè)轉發(fā)功能。如果(guo)你并不能保證 lua 操作的 KEY 是否??在同一個(gè)機器上,Codis 只能將這個(gè)腳本分配到參數列表中的第一個(gè) key 的機器上執行。
- 不支持命令列表,參考
- https://github.com/CodisLabs/codis/blob/release3??.2/doc/unsupported_cmds.md
- Redis 修改部(°o°)分(增加(jia)若干指令),參考
- https://github.com/CodisLabs/codis/blob/release3.2/doc/redis_change_zh.md
倔強的青銅
于是組織研??發(fā)同事進(jìn)行多次分析討論,并提?出了對??緩存服務(wù)進(jìn)行接口改造,經(jīng)過(guò) 2 個(gè)多月的辛勞,取得了很大進(jìn)展,讓我們 Codis 項目順利上線(xiàn)邁開(kāi)了重要一步,打??斷一下,容我在此特別感謝一下同事王慧,在他的主導下,完成公司???絕大部分緩存服務(wù)接口改造工作。
幾點(diǎn)改造思路
1. 緩存服務(wù)分類(lèi)。
- 針對業(yè)務(wù)緩存服務(wù)ヽ(′ー`)ノ不容許數據丟失,在現有的邏輯中,Codis 和數據庫都會(huì )保留,優(yōu)先從 Codis 讀取,如讀取不到時(shí),會(huì )從后端數據庫里讀取。
- 針對車(chē)次、合作方緩存服務(wù),由于數據量大,拉取頻率高的數據,只會(huì )從 Codis 里讀取。
2. 對緩存服務(wù)進(jìn)行接口改造,新增基礎緩存服務(wù)層,將生產(chǎn)的 Re(′_ゝ`)dis/Codis 相關(guān)的服務(wù)納入基礎緩存服務(wù)進(jìn)行統一管理。
- 制定一套標準 KEY 命名、管理規范,包括數據類(lèi)型的選擇、長(cháng)??度、過(guò)期時(shí)間等。我們會(huì )統一在后??臺管理系統公示,限定新數據的規則,限制一切不合規范的行為。
- 在基礎緩存服務(wù)層(//ω//),對部分 Codis 不支持的命令進(jìn)(jin)行改寫(xiě),規范 Redis/Codis 日常操作。
- 統計熱點(diǎn)數據,維護熱點(diǎn)數據,在基礎緩存服務(wù)層上假設二級緩存,作為熱點(diǎn)數據的快速通道。
3.SLOT 的分配
哈希算法(fa)
key 值重定向分配
比如你有一個(gè)腳本是操作某個(gè)用戶(hù)的多個(gè)信息,如 uid1age,uid1sex,uid1??name 形如此類(lèi)的 key,如果??你不用 hashtag 的話(huà),這些 key 可能會(huì )分(?_?;)散在不同的機器上,如果使用了 hashtag(用花括號擴住計算 hash 的區域):{ uid1}age,{ uid1}sex,{ uid1}name,這樣就保證這些 key 分布在同一個(gè)機器上。這個(gè)是 twemproxy 引入的一個(gè)語(yǔ)法,我們這邊也支持了。
以 pub_cty 為例,通過(guò) crc32hash 算法得出,key 存放在 237 slot 中(zhong),類(lèi)似測試了{ pub_cty}_ct01,{ pub_cty}_ct02…{ pub_cty}_ctnn 都存放在 237 slot 中。第一,有了 hashtag 算法支持,我們可以對特定需求的 key 做一些特需的規劃,將這些特殊的 key 有序的存放在 codis slot 中,保證 mget/mset, 以及 lua 腳本正常執行。我們目前大概管理 200 多個(gè) redis 鍵,統一鎖定到一個(gè) codis-server(slot)中。第二,在某些極端情況(不希望發(fā)生(sheng)),如某 codis-group 中的 master 異?;虮罎r(shí),我們從程序設計角度,盡可能對出現的無(wú)法(′▽?zhuān)?進(jìn)行操作?? KEY 的行為做一些 " 某種意義上 " 保護。譬如,當某 codis-??group 的 maser(╬?益?) 宕機(???)時(shí),對 codis?? 進(jìn)行寫(xiě)操作,如果對應的 key 落到宕機的主機上,會(huì )得到異?;蛘??錯誤,可以通過(guò)捕獲異常信息,將異常的 key 通過(guò)改變 key 名的規則將其存放到其他 codis-group 上。同理(′ω`),如果是讀取宕機主機上的 key 數據時(shí)??,將其引導到調整后的 key 上,在一定程度上保障 codis 的完整性(不保障數據不丟失,只保證業(yè)務(wù)系統操作緩存數據完整性)。
有點(diǎn)意思的整改
熱點(diǎn)數據
統計緩存熱點(diǎn)數據,在基礎緩存服務(wù)層上假設二級緩存,作為熱點(diǎn)數據的快速通道,具備可動(dòng)態(tài)獲取,最快訪(fǎng)問(wèn),少變化的特點(diǎn) 。
根據緩存服務(wù)各主、子鍵關(guān)系,使用 index_{ 主鍵}的方式來(lái)作為管理主子鍵關(guān)系的 SortedSet 集合,統計數據的使(O_O)用頻率,抽取 Top100 的數??據,作為熱點(diǎn)數據。對這批數據進(jìn)行分析,結合數據的改動(dòng)頻率,制定這批數據??緩存在內存中的時(shí)長(cháng)。
二級緩存設計
緩存數據列表生成與維護
內存緩存數據的?? key 列表由緩存服務(wù)生成和維護,Key 列表包括后臺手動(dòng)配置(如,10 個(gè))和系統根據使??用熱度生成(如,20 個(gè))共同組成,其中 cache-manager 的 jar 包只負責對該數據使用,通過(guò)定時(shí)任務(wù)獲取 codis 中的前 20 位和(he)后臺手動(dòng)配置的相關(guān)數據,期間要保證獲取(qu)到數據的有效性。
維護本地內存中的數據
自然統計內存緩存:用?? sortedSet 集(ji)合,統計各主鍵下的所有鍵 Get 的次數??,匯總(′▽?zhuān)?成 score_{ 主鍵}方式的集合。利用 ZIncrby 命令統計對應的子鍵的次數,最終匯總每個(gè)主鍵,統計出 Top10??0 的 key,利用 zunionstore 命令將信息統計匯總作為內存緩存(cun)的基礎,此集合內數據均從內(nei)存中獲取。
管理類(lèi)內存緩存:分析和統計項目主流程的關(guān)鍵的基礎緩存數據保存到內存中, 保障對應區域的數據獲取與緩存(cun)時(shí)間,在離開(kāi)數據源后能夠最大程度的展現暢途網(wǎng)的功能。
在發(fā)生??手動(dòng)更新時(shí),對內存中對應的主鍵進(jìn)行更新
在發(fā)生更新時(shí),由(you)后臺發(fā)起,在(zai)緩存服務(wù)向 codis 中置入標志(zhi)位,各客戶(hù)端在定時(shí)任(ren)務(wù)中獲取標志位,如果標志位(cache_memory_update_flag)為 Y,則清空內存和 Key 規則表,等到下一個(gè)更新周期來(lái)臨重新獲取數據。
總結??
多年后,再回想年少時(shí)的迷茫和執著(zhù),或許原因都記不得了。青春就是讓(????)你張揚的笑,也給你莫名??的痛?!终Z(yǔ)堂《人生不過(guò)如此》經(jīng)過(guò)大??半年的時(shí)間測ˉ\_(ツ)_/ˉ試、緩存服務(wù)接口改造,在 20??16 年 9 月份,趕在國慶前,我們的 Codis3.0 上線(xiàn)了,在車(chē)次查詢(xún)等方面,有了質(zhì)的飛越,尤其節假日或高峰期(qi)期間,平滑的擴縮容、數據遷移、高可用等方面展示出巨大優(yōu)勢。
三個(gè) codis_proxy 節點(diǎn)的均衡情況:
1 年后,2018 年 8~9 月份,我們將 Codis 升級到 3.2 的,由之前 6 臺服務(wù)器,擴展到 7 臺,實(shí)際上多一臺 Codis-web 節點(diǎn),獨立承擔 Codis-fe、Codis-dashboard 等組件。對于 Redis-Sent??inel、Codis-fe 等組件的引進(jìn),解決了運維人員很??多問(wèn)題,在ヾ(′▽?zhuān)??此不再描述,有興趣的可以參考。
https://githu???b.com/CodisLabs/codis/blob/3.2.2/doc/tutorial_zh.md
目前 Codis 作為暢途網(wǎng)最為核心ヽ(′ー`)ノ的緩存層,一如既往的穩定輸出,肩負起它的神圣使命!
版權聲明:本文內容由互聯(lián)網(wǎng)用戶(hù)自發(fā)貢獻,該ヾ(′▽?zhuān)??文觀(guān)點(diǎn)僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權,不承擔相關(guān)法律責任。如發(fā)現本站有涉嫌抄襲侵權/(′?_?`)違法違規的內容, 請發(fā)送郵件至 [email protected]??m 舉報(′▽?zhuān)?,一經(jīng)查實(shí),本站將立刻刪除。

