作者|張云楊
在 Kube.NETes 大行其道的今天,數(shù)據(jù)庫容器化對于云原生團隊而言是一個極具吸引力,但往往不知道從何下手的挑戰(zhàn)。
開源 MySQL、PostgreSQL 誕生于 PC Server 時代,往往被用于存儲業(yè)務的重要數(shù)據(jù),放到 Kubernetes 里面也許需要更多的投入和勇氣;但是對于 redis 這種跟容器技術(shù)誕生于同一個時代,而且大多只用作緩存用途的數(shù)據(jù)庫,容器化是否就更加容易呢?很多云原生團隊確實是這樣想的,但是真正實踐后才發(fā)現(xiàn) Redis 這個“軟柿子”并不是那么好捏。
太容易了吧,只是...
Redis 容器化的起步非常容易,通過 Redis 官方提供的 Docker 鏡像幾秒鐘就可以拉起 Redis 服務。將應用與 Redis 部署在同一個 Kubernetes 極大簡化了上手難度,只有兩個小小的問題:
Redis 服務并不是高可用的
只要 Redis 容器發(fā)生調(diào)度,Redis 容器的 IP 就會變化,應用側(cè)的連接池配置也會隨之失效。為了適應容器環(huán)境的起伏,Redis 容器的 IP 不能直接暴露給應用,需要增加 VIP 或 DNS 域名來提供固定的連接地址。
Redis 服務并不是高可靠的
只要 Redis 容器所在的宿主機發(fā)生宕機,Redis 容器的持久化卷就可能發(fā)生損壞,應用數(shù)據(jù)也會隨之丟失。雖然有大量開發(fā)者將 Redis 當作易失的內(nèi)存數(shù)據(jù)庫來使用,但是也有不少開發(fā)者將 Redis 用作鍵值數(shù)據(jù)的持久化存儲,所以 Redis 容器化不可避免地涉及到分布式塊存儲或本地盤同步方案,只有這樣才能具備數(shù)據(jù)持久化能力。
不出意外的話,
就要出意外了
通常,雄心勃勃的云原生團隊當然不能滿足于提供玩具級別的 Redis 服務,對多個 Redis 容器進行編排的進階方案自然而然地被提上議程。在進階方案里面,Redis 服務將具有多個分布于不同宿主機的 Redis 容器(副本),可以應對一到多個 Redis 容器的故障,能夠提供持續(xù)可靠的服務。
Redis 內(nèi)核并不具備分布式能力,需要引入外部組件來完成 Redis 容器的角色判斷和復制關(guān)系配置。Sentinel(哨兵)組件在這方面久經(jīng)考驗,社區(qū)也提供了相應的容器編排方案。用 Bitnami 提供的 Redis Helm Chart 就可以很容易部署出含有 Sentinel 組件的 Redis 主備集群。只要正確配置副本數(shù)、規(guī)格參數(shù)并對內(nèi)核參數(shù)做少量調(diào)整,Redis 服務的質(zhì)量立即就能抬升一個檔次。如果應用負載較為穩(wěn)定,這個方案的效果會很不錯。但是一旦涉及到故障或擴縮容場景,馬上會遇到幾個不那么容易解決的問題:
Redis 服務能力存在永久受損的風險
云原生團隊往往沒有現(xiàn)成的分布式塊存儲,本地盤資源相對比較常見。當 Redis 容器被分配到本地盤宿主機后,容器就會變相被“固定”到該宿主機上。遇到硬件故障時,如果宿主機能迅速恢復,那么上面的 Redis 容器也能隨之快速恢復;反之,Redis 容器將會一直處于 Pending 狀態(tài),無法被調(diào)度到其它健康的宿主機上。雖然 Redis 服務依舊是可靠可用的,但是服務能力會受到永久損傷,而 Pending 的容器狀態(tài)也能順帶逼死患有強迫癥的工程師。
Redis 服務能力的天花板較低
在本地盤宿主機場景下,Redis 服務能力的天花板也是比較低的。被“固定”到宿主機上后,Redis 容器的內(nèi)存使用上限也被限制在了該宿主機上。宿主機上面運行的容器越多,Redis 容器能使用的內(nèi)存就越少。相同的問題也會發(fā)生在 Redis 容器能使用的存儲容量上。因為被“固定”在宿主機上,Redis 容器能使用的存儲容量上限就是其它容器用剩的宿主機本地盤余量。CPU 資源的問題倒是沒那么明顯,Redis 用不了多核,云淡風輕。
Redis 服務的擴縮容問題
在遇到業(yè)務高峰的時候,難免需要對 Redis 服務進行擴容。根據(jù)遇到的容量挑戰(zhàn),擴容手段又分為垂直擴容和橫向擴容兩個大類。如果業(yè)務整體數(shù)據(jù)量沒變,只是需要緩存的熱點數(shù)據(jù)變多了,那么垂直擴容一下 Redis 容器的內(nèi)存就可以了;但是一旦業(yè)務的整體數(shù)據(jù)量變大了,需要垂直擴容存儲容量,云原生團隊就無法通過 helm 修改 StatefulSet 配置實現(xiàn)變配,只能切換到手工模式劫持底層 PVC 才能實現(xiàn)。劫持的代價會在以后需要進行橫向擴容的時候暴露出來,新增的 Redis 容器會采用老的配置,原本同構(gòu)、自動化的 Redis 服務,變成了異構(gòu)、手工的縫合怪。
還有隱藏關(guān)卡!
高可用、高可靠方面的問題,從架構(gòu)設計和拓撲圖上一眼就能看出來,一般在 Day 1 就會被云原生團隊關(guān)注和解決;而服務能力在特定場景下的挑戰(zhàn)是比較微妙的,取決于真實的業(yè)務場景和云原生團隊的經(jīng)驗,往往在 Day 2 才會被察覺。審慎的云原生團隊不應該在生產(chǎn)環(huán)境使用原生的 Kubernetes 工作負載來運行容器化的數(shù)據(jù)庫,這就像坐著用紙糊的船出海一樣危險。
Kubernetes 提供的自定義資源能夠更好地聚合存儲、計算和網(wǎng)絡資源,通過 API 的方式提供“聲明式”的數(shù)據(jù)庫服務。目前市面上有幾個知名的 Redis Operator 提供了更進一步的方案,幫助云原生團隊解決 Day 2 的常見問題,比如:
- Redis Enterprise Operator by RedisLabs
- KubeDB by AppsCode
- KubeBlocks by ApeCloud
- Redis Operator by Spotahome
- Redis Operator by OpsTree
RedisLabs、AppsCode 和 ApeCloud 提供的 Operator 功能是企業(yè)級的,在能力方面更完整;而 Spotahome 和 OpsTree 提供的 Redis Operator 則是完全開源的,功能雖然少但勝在簡單易懂。通過 Release Notes 和 Changelog 可知,Spotahome 最后一次發(fā)布版本的時間是 2022.1.19 而 OpsTree 則是 2022.11.10,對問題的響應速度上面恐怕會差點意思,這一點需要特別注意。
無論選了哪一款 Redis Operator,云原生團隊都要有這樣一個預期:真實業(yè)務場景下的網(wǎng)絡環(huán)境非常復雜,有可能會對 Redis 服務支持的網(wǎng)絡方案帶來挑戰(zhàn)。這個挑戰(zhàn)往往會發(fā)生在跨 Kubernetes 部署的新應用需要讀寫存量 Redis 集群的時候。如果沒有規(guī)劃好應對措施,很有可能會阻礙業(yè)務的上線效率。考慮到業(yè)務側(cè)存在多種 SDK 的使用方法,Redis 服務需要支持如下的部署模式才能滿足長遠的要求:
- 單節(jié)點(客戶端只訪問主庫)
- Redis Server 通過 Nodeport 暴露主庫的地址
- Redis Server 通過 LoadBalancer 暴露主庫的地址
- 雙節(jié)點(客戶端只訪問主庫)
- Redis Server 通過 Nodeport 暴露主庫的地址
- Redis Server 通過 LoadBalancer 暴露主庫的地址
- 雙節(jié)點或多節(jié)點(客戶端訪問 Sentinel 實現(xiàn)讀寫分離)
- Redis Server 和 Sentinel 組件通過 HostNetwork 暴露 Redis、Sentinel 的副本地址
- Redis Server 和 Sentinel 組件通過 Nodeport 暴露 Redis、Sentinel 的副本地址
- Redis Server 和 Sentinel 組件通過 LoadBalancer 暴露 Redis、Sentinel 的副本地址
- Sharding
- Redis Server 通過 HostNetwork 暴露副本地址
- Sharding + Proxy
- Proxy Server 通過 Nodeport 暴露連接地址
- Proxy Server 通過 LoadBalancer 暴露連接地址
咦,為什么 Redis Sharding 跟其它的形態(tài)不一樣,只能使用 HostNetwork?這涉及到 Redis 官方跟云廠商的各種博弈。簡而言之,就是官方想把 Sharding 形態(tài)作為收費功能,而代碼的 License 又是 BSD 協(xié)議的。為了不讓云廠商薅到羊毛,Redis 官方故意沒有實現(xiàn) announce-ip 的功能,使得原生的 Redis Sharding 形態(tài)無法運行在云廠商的網(wǎng)絡環(huán)境。然而,云廠商也不甘示弱,“幫”Redis 官方把 announce-ip 功能的坑給填上了,付出了一點點代價就能繼續(xù)大賣特賣。討厭的是,Redis 官方和云廠商的拉鋸,導致 Redis Sharding 形態(tài)在容器環(huán)境里只能使用 HostNetwork 暴露地址,為云原生團隊帶來了額外的阻力。這些商業(yè)利益的糾葛,也是 Redis 容器化過程中需要不斷被關(guān)注到的。
^_^ 我還是要捏~
是不是覺得 Redis 容器化并不是那么好上手,公有云全托管服務收些溢價也情有可原?
這個感覺沒錯,但是別急著放棄。公有云廠商最重要的數(shù)據(jù)庫技術(shù)方向之一就是容器化,而容器化的挑戰(zhàn)起點就是保障彈性能力以及支持多種網(wǎng)絡方案。在塊存儲、對象存儲、VPC 網(wǎng)絡以及四層負載均衡等支撐性產(chǎn)品的加持下,公有云廠商實現(xiàn)數(shù)據(jù)庫容器化會更加容易,技術(shù)方案上面也會更加花哨(比如固定容器 IP、升級 Kuberntes 不重啟等等)。而大部分云原生團隊沒有軟件定義存儲(SDS)和軟件定義網(wǎng)絡(SDN)的支持,實現(xiàn)數(shù)據(jù)庫容器化就會更有挑戰(zhàn)。
幸運的是,大部分云原生團隊需要支持的業(yè)務場景也不像公有云廠商所面臨的那么復雜,如果能夠選對方向、收斂需求,循序漸進地積累生產(chǎn)經(jīng)驗,數(shù)據(jù)庫容器化的考驗就不會呼嘯而來。業(yè)界也不乏 Redis 容器化的實踐分享,有的大幅降低了成本,有的讓業(yè)務團隊實現(xiàn)了 self-serving。
沖著提升資源利用率和研發(fā)效能的收益,這個柿子就算有點硬,也值得一捏。
作者信息:
張云楊,前阿里云數(shù)據(jù)庫產(chǎn)品負責人,2016-2019 年任阿里云數(shù)據(jù)庫產(chǎn)品總監(jiān),負責 RDS、PolarDB、Redis、MongoDB 等核心產(chǎn)品。目前作者就職于云猿生數(shù)據(jù),是容器化數(shù)據(jù)庫管控 KubeBlocks 和 Serverless MySQL 的產(chǎn)品負責人。
逃離 windows!德國又宣布遷移到 linux,涉及數(shù)萬系統(tǒng)、3 萬余人,官員吐苦水:Windows 對硬件要求太高了
李彥宏:大模型開源意義不大;騰訊云后臺崩了;離開百度7年后,吳恩達官宣加入亞馬遜董事會 | Q資訊
走進 AI 高薪族:小而美團隊成主流,博士生招聘需求飆升 430%!
用 100 年前的架構(gòu)和淘汰的軟盤技術(shù),美國列車系統(tǒng)升不了級:要花費十年、上百億美元,“風險太大!”