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

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

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

redis 簡介

Redis 是大家日常工作中使用較多的典型 KV 存儲,常年位居 DB-Engines Key-Value 存儲第一。Redis 是基于內存的存儲,提供了豐富的數據結構,支持字符串類型、哈希/列表/集合類型以及 stream 結構。Redis 內置了很多特性,其中比較重要的有:

 

  • 復制:Redis 支持異步的全量和增量同步,可以把數據從 Master 復制到 Slave, 實現 Redis 數據的高可用。
  • 持久化:支持數據的持久化,可以通過 RDB 和 AOF 機制實現數據落盤。
  • 支持哨兵工具:哨兵工具的主要工作模式是監控 Master 節點的健康狀況。當發現 Master 節點不可用時,會主動執行 Failover, 把 Slave 節點提升成 Master,保證 Redis 服務的高可用。
  • 提供集群模式:單體 Redis 實例受限于物理機內存,當需要很大的 Redis 集群容量時,可以使用 Redis 集群模式。Redis 集群模式的原理是把保存在其中的數據做了分片,每一部分數據由不同的 Redis 實例承擔。

 

Redis 的典型應用場景有以下 3 種:

  • 緩存:因為 Redis 是基于內存的存儲,它的讀寫請求會在內存執行,請求響應的延遲很低,所以很多場景下會把 Redis 當做緩存使用。
  • 數據庫:Redis 支持持久化,可以把它當做 KV 數據庫使用。
  • 消息隊列:Redis 支持 stream 數據,在 stream 數據結構基礎上封裝了 pub-sub 命令,實現了數據的發布和訂閱,即提供了消息隊列的基本功能。

 

Redis 協議是二進制安全的文本協議。它很簡單,可以通過 telnet 連接到一個 Redis server 實例上執行 get 和 set 操作。

K8s 簡介

K8s 是一個容器編排系統,可以自動化容器應用的部署、擴展和管理。K8s 提供了一些基礎特性:

  • 自動裝箱:可指定 K8s 里 Pod 所需資源的最小值和最大值,即 limit 和 request 的值。K8s 可以根據 request 的值做 Pod 調度,在一個節點上拉起 Pod。
  • 服務發現與負載均衡:K8s 提供基于 DNS 的服務發現機制,同時也提供基于 service 的負載均衡。
  • 自動化上線和回滾:這里會涉及到 K8s 的工作負載資源。K8s 提供幾種不同的工作負載資源對應不同的業務場景。這些不同的工作負載資源可以實現服務的配置變更,例如更新 image、升級 binary、進行副本的擴縮容等。
  • 支持 Deployment/DaemonSet
  • 支持 StatefulSet
  • 支持 CronJob/Job
  • 水平擴縮容:K8s 天然支持水平擴縮容,可以基于 Pod 的 CPU 利用率、內存利用率以及第三方自定義 metrics 對 Pod 進行水平動態擴縮容。
  • 存儲編排:K8s 支持基于 PV 和 PVC 的存儲供應模式,可以通過 PV 和 PVC 在 Pod 內部使用存儲。
  • 自我修復:舉一個例子就是副本保持。比如用 Deployment 來托管一個服務,如果 Deployment 下的一個 Pod 所在的宿主機出現了不可用的情況, K8s 會在可用的節點上重新拉起一個新的 Pod 來提供服務。

 

現實工作中遇到的服務根據是否需要數據持久化可分為有狀態服務和無狀態服務。不需要數據持久化的服務被認為是無狀態的,包含以下幾種類型:

  • API 類服務:可在任意節點上執行。如果要在 K8s 上部署這類服務,可使用 K8s Deployment。
  • Agent 或 Deamon 類服務:需要部署在每一臺機器上,而且每臺機器上最多部署一個進程。在 K8s 上可選擇 DaemonSet 來完成對應的部署。
  • 還有一類無狀態服務對固定的唯一標識有需求。要滿足這些需求,可使用 K8s 的 StatefulSet 來滿足。雖然 StatefulSet 是用來部署有狀態服務的,但它可提供固定的唯一標識,也可用來托管無狀態服務。

 

有狀態服務需要穩定的持久化存儲。除此之外,可能還會有一些其它的特性要求:

  • 穩定的唯一標識
  • 有序、優雅地部署和縮放
  • 有序的自動滾動更新

在 K8s 上,我們一般會用 StatefulSet resource 來托管有狀態服務。

Redis 云原生實踐

下面將介紹火山引擎 Redis 云原生實踐。首先我們會明確 Redis 云原生的目標,主要有以下幾個:

  • 資源的抽象和交付由 K8s 來完成,無需再關注具體機型。在物理機時代我們需要根據不同機型上的 CPU 和內存配置來決定每個機型的機器上可以部署的 Redis 實例的數量。通過 Redis 云原生,我們只需要跟 K8s 聲明需要的 CPU 和內存的大小,剩下的調度、資源供給、機器篩選由 K8s 來完成。
  • 節點的調度由 K8s 來完成。在實際部署一個 Redis 集群時,為了保證高可用,需要讓 Redis 集群的一些組件滿足一定的放置策略。要滿足放置策略,在物理機時代需要運維系統負責完成機器的篩選以及計算的邏輯,這個邏輯相對比較復雜。K8s 本身提供了豐富的調度能力,可以輕松實現這些放置策略,從而降低運維系統的負擔。
  • 節點的管理和狀態保持由 K8s 完成。在物理機時代,如果某臺物理機掛了,需要運維系統介入了解其上部署的服務和組件,然后在另外一些可用的機器節點上重新拉起新的節點,填補因為機器宕機而缺少的節點。如果由 K8s 來完成節點的管理和狀態的保持,就可以降低運維系統的復雜度。
  • 標準化 Redis 的部署和運維的模式。盡量減少人工介入,提升運維自動化能力,這是最重要的一點。

 

Redis 集群架構

下面介紹一下我們的 Redis 集群架構。集群里有三個組件:Server、Proxy 和 Configserver,分別完成不同的功能。

  • Server:存儲數據的組件,即 Redis Server,其后端部署模型是一個多分片的模型。分片之間的 Server Pod 沒有通信,為 share-nothing 的架構。分片內部為一主多從的模式,可以一主一從、一主兩從,甚至更多。
  • Proxy:承接 client 發來的請求,同時根據讀寫拓撲,把請求轉發給后端的 Server 分片。
  • Configserver:配置管理組件,本身是無狀態的,所有的狀態信息都存儲在 etcd。集群生命周期里 Server 所有的分片信息都保存在 Configserver 里。Configserver 會對每一個分片的 Master 節點進行定期探活,如果發現某一個分片的 Master 節點不可用,就會執行 Failover,把分片內可用的 Slave 提成新的 Master,保證分片可繼續對外提供服務。同時,Configserver 也會定期根據 Failover 或其他一些實例信息的變更來更新自己的讀寫拓撲關系,保證 Proxy 可以從 Configserver 拉取新的正確的配置。
火山引擎 Redis 云原生實踐

 

結合以上介紹的 Redis 架構以及 K8s 的特性,我們抽象了一個 Redis 集群在 K8s 集群上部署的基本形態:

  • 使用 Deployment 將無狀態的 Configserver 部署在 K8s 上。因為 Configserver 可被所有 Redis 集群共用,為了簡化運維復雜度,我們規定所有的 Redis 集群共用一個 Configserver。
  • Proxy 也是無狀態的組件,也用 Deployment 來部署。
  • 因為我們有多分片,而且 Server 是有狀態的,所以每一個分片用 StatefulSet 進行托管。在新建集群時,我們默認分片內的 0 號 Pod 為 Master Pod,其余所有的 Pod 是 Slave。這是一個初始狀態,后續可能會跟隨 Failover 或其他異常發生變更,但是 Configserver 里會實時記錄最新的狀態信息。

 

Redis Server 啟動的時候需要一些配置文件,里面涉及到一些用戶名和密碼,我們是用 Secret 來存儲的。在 Server Pod 運行的時候通過 volume 機制掛載到 Server Pod 內部。

對于 Proxy,通過 HPA,基于 Proxy 的 CPU 利用率,支持 Proxy 服務的動態擴縮容。

火山引擎 Redis 云原生實踐

 

放置策略

對于一個 Redis 集群涉及到的 Server 和 Proxy 組件,我們有一些放置策略的要求,比如:

  • 同一個 Server 分片下的節點不能在同一臺機器上,即,一個分片內的主從節點不能在同一臺機器上。轉換成 K8s 里面的模型,即我們希望一個 StatefulSet 下所有的 Pod 部署在不同的機器上。我們會利用 Pod-AntiAffinity 下面的 required 語義,來保證 StatefulSet 下所有的 Pod 都部署在不同的機器上。
  • 一個集群下的 Proxy Pod 需要盡可能分布在不同的機器上,可通過 Pod-AntiAffinity 下的 preferred 語義加上拓撲分布約束來滿足。preferred 語義只能保證 Pod 盡可能分布在不同的機器上,為了避免極端情況下所有 Pod 都在同一臺機器上的情況,我們會使用拓撲分布約束。

 

存儲

存儲使用的是 PVC 加 PV 再加上具有動態供給能力的 StorageClass。使用 StorageClass 是為了抽象不同的存儲后端,可支持本地磁盤和分布式存儲。可以通過 StorageClass 的配置直接申請對應的存儲,不用了解具體后端的實現。

 

另外,我們使用的是支持動態供給的 StorageClass,可自動按需創建不同大小的 PV。如果使用靜態供給,就無法提前預知所有 Redis 實例的規格,也無法把它們對應的指定數量的 PV 都創建出來。

Redis 云原生功能介紹

Redis 云原生化以后,Operator 組件是基于 Operator Pattern 實現的一個 custom controller,主要用于編排 Redis Cluster resource,管理 Redis 集群的一些變更。Configserver 也部署在 K8s 上,所有跟 Redis 相關的組件都是云原生化的

新建集群

火山引擎 Redis 云原生實踐

 

  1. 對于常見的新建集群的請求,會先發給 ApiServer。ApiServer 接收到請求之后,會通過 client go 的 watch 機制讓 Operator 感知到。
  2. 隨后 Operator 會請求 ApiServer 創建對應 Server 的 StatefulSet。
  3. K8s 把所有 Server 的 StatefulSet 創建成功之后,等所有的 Pod 都處于 ready 狀態,這時所有分片內的 Server Pod 之間是沒有主從關系的。
  4. Operator 感知到所有的 StatefulSet 都已經處于 ready 的狀態之后,會獲取所有 Server Pod 信息,并注冊到 Configserver。
  5. Configserver 接下來會連接到所有分片內的 Slave 節點,執行實際的 SLAVEOF 命令,保證建立真正的主從關系。
  6. Operator 會定期查詢 Configserver 里建立主從關系的進度。等所有分片的主從關系建立成功之后, Operator 會請求 ApiServer 把對應的 Proxy 創建出來。
  7. Proxy 創建出來之后,會去 Configserver 拉取最新的拓撲,保證對外提供服務的時候可以把請求打給后端正常的分片。

 

分片擴容

火山引擎 Redis 云原生實踐

 

在實際使用的過程中如果遇到容量不足的情況,需要進行水平擴容。分片擴容的請求也是類似的:

  1. 請求發給 ApiServer。
  2. ApiServer 把請求推送給 Operator。
  3. Operator 感知到之后,會先給 ApiServer 發請求,把新的分片對應的 StatefulSet 創建出來。
  4. K8s 會把新分片的 StatefulSet 創建好,在處于 ready 狀態之后,一個 StatefulSet 下的每個 Pod 也都是獨立的狀態,沒有建立真正的主從關系。
  5. Operator 獲知新創建的 Server StatefulSet 分片已經處于 ready 狀態之后,會把新的 Server 分片的實例地址注冊到 Configserver。Configserver 現在會有兩個階段:
  6. 第一步:指導新分片內真實主從關系的建立。即連到所有的新分片的 Slave 上,執行 SLAVEOF 的命令;
  7. 第二步:指導數據從老分片遷移到新分片。這樣新的分片才能發揮作用,這一步很重要。
  8. Operator 會一直檢查數據遷移或者 rebalance 的進度。等進度結束之后,Operator 會更新 Redis Cluster 里 status 的字段,反映出來當前的分片擴容的操作已經結束了。

 

分片縮容

火山引擎 Redis 云原生實踐

 

分片縮容的流程和分片擴容類似:請求先發送給 ApiServer,Operator 會感知到請求,然后把縮容分片的請求發送給 Configserver。

Configserver 此時做的事情是:

 

  1. 先指導數據遷移??紤]到后邊的一些分片下線,需要把分片上的數據先遷移到其他可用分片上,保證數據不丟。
  2. Operator 會一直查詢 Configserver 指導的數據 rebalance 的進度。等縮容操作在 Configserver 完成之后,Operator 會請求 ApiServer 執行真正的 Server StatefulSet 刪除,這時才是安全的刪除操作。

 

組件升級

火山引擎 Redis 云原生實踐

 

一個 Redis 集群會涉及到兩個組件:Proxy 和 Server。

 

無狀態的 Proxy 用 Deployment 托管,如果要進行組件升級,直接升級對應的 image 即可。

 

Server 是一個有狀態的組件,它的升級流程相對來說復雜一點。為了簡化流程,我們以 Server 只有 1 分片的 Redis 集群為例,介紹升級過程。

  1. Server 組件的升級請求發送給 ApiServer,ApiServer 接收到這個請求之后會把它推送給 Operator。
  2. Operator 首先會按照分片內 Pod 編號從大到小的順序選擇要升級的 Pod。
  3. 選定 Pod 之后,會把它從 Configserver 的讀拓撲里摘掉。(如果要摘除的這個 Pod 在集群拓撲里是 Master,我們會先調用 Configserver 的 API,執行 Failover,把它變成 Slave,然后再把它從讀的拓撲里邊給摘除掉。)
  4. 之后,Operator 等待 30 秒。這個機制的出發點是:
  5. 首先,Proxy 去 Configserver 拉取配置是異步過程,可能需要經過至少一輪的數據同步才能正常拿到數據。等待 30 秒主要是為了保證所有的 Proxy 都已經拿到了最新的讀拓撲,新的讀請求不會再發送到要升級的 Server 節點上。
  6. 另外,我們要保證等待 30 秒的時間,讓已經被要升級的 Server Pod 接收的這些請求都成功地被處理,并且返回之后,才能把要升級的 Server Pod kill 掉。
  7. 30 秒之后請求 ApiServer 執行實際的 Pod 刪除操作。刪除之后 K8s 會重新調度一個新的 Pod 起來,這時新創建的 Server Pod 也是一個獨立的 Server 的狀態,沒有跟任何節點建立主從關系。Operator 感知到新的 Server Pod 已經處于 ready 的狀態,會把它注冊到 Configserver。
  8. Configserver 連到新的 Server Pod 上,根據它所處的分片跟所在分片的 Master 節點建立主從關系,同時進行數據同步。
  9. Operator 會定期檢查新的 Server 分片在 Configserver 是否已經完成數據同步。如果是,Operator 才會認為一個 Server Pod 完成了升級。該分片內其他所有 Server pod 的升級流程都是類似的,直到該分片內所有 Server Pod 都升級完,才認為這個分片升級完成。最后 Operator 會更新自己 Redis Cluster 的 CRD 里對應的 Status 狀態信息,反映當前組件升級的流程和變更操作已經結束了。

總結展望

本次分享的以 Redis 為例,介紹了有狀態服務部署到 K8s 的抽象流程,并介紹了火山引擎在 Redis 云原生方向的一些探索和實踐。目前火山引擎對于 Redis 云原生已經完成了基本功能的構建,未來會在動態擴縮容、異?;謴?、細粒度的資源分配和管理方面,結合 K8s 的特性,進行更多深層次的思考和實踐,期望通過云原生化的方式,進一步提升運維自動化能力和資源的利用率。

 

Q&A

Q1:沒用 Cluster 的模式嗎?

A:沒有,最早也使用過 Cluster 模式,后來業務體量變大,發現 Cluster 有集群規模上限,不能滿足業務的需求。

Q2:Redis 的 Proxy 會計算 Key 在哪個分片嗎?

A:會的,Proxy 會參考類似 Redis Cluster 的 Key Hash 算法對 Key 進行 hash,之后分布到不同的 Server 分片上。

Q3:如何界定 Slave 可以提升為 Master?切換步驟是怎樣的?

A:Configserver 會定期給 Master 發送 health check 請求進行探活。只有連續多次對一個 Master 的探活都失敗時,才會認為 Master 不可用。這時 Configserver 會從分片內所有 Slave 中選擇可用的提升成新的 Master(不是所有的 Slave 都可用,可能某一個 Slave 也掛了,或者主從數據同步的延遲比較高)。

Q4:Proxy 是每個 Redis 集群獨有還是所有集群共享的?

A:Proxy 不是每個 Redis 集群獨占的。首先,所有集群共享一個 Proxy 集群,有隔離性的問題。另外,Proxy 支持動態擴縮容,可以做到彈性資源擴縮容,所以不會導致資源浪費。

Q5:系統的穩定性如何,主從切換耗時怎樣?

A:穩定性挺好。主從切換的耗時是一個策略問題,需要做一些 tradeoff。如果判斷策略太激進,可能會因為臨時的網絡抖動等因素頻繁觸發主從切換。實際使用中我們的主從切換耗時在 10s 左右。

Q6:Redis 在什么規模等級下的 K8s 部署會需要修改較多默認配置或者直接更改源碼? 在動態擴容的基礎上建立 Redis 集群是否會加大困難?有什么方式可以讓 Redis 集群無限擴容嗎?最多到多少?

A:Redis 目前部署的 K8s 集群規??蛇x,根據需要的 Redis 集群容量來選擇 K8s 規模就可以。適配云原生會需要調整一些組件之間的服務發現方式,但是不需要太多源碼的修改。我們目前只支持 Proxy 的動態擴縮容,Server 是有狀態的服務,還不太好接入 HPA(因為可能會涉及到一些數據的遷移),雖然 HPA 也支持對 Statefulset 服務的自動化擴縮容。我們的 Redis 架構理論上集群的規??梢院艽螅F在 CRD 的限制是一個 Redis 集群最多 1024 個分片。

關于火山引擎

火山引擎是字節跳動旗下的數字服務與智能科技品牌,基于公司服務數億用戶的大數據、人工智能和基礎服務等技術能力,為企業提供系統化的全鏈路解決方案,助力企業務實地創新,給企業帶來持續、快速增長。

分享到:
標簽:火山 引擎
用戶無頭像

網友整理

注冊時間:

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

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

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

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

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

運動步數有氧達人2018-06-03

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

每日養生app2018-06-03

每日養生,天天健康

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

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