<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jinfeng_wang

    G-G-S,D-D-U!

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
    http://www.open-open.com/lib/view/open1469933226345.html

    吳建超,優酷土豆廣告基礎平臺開發工程師,對互聯網基礎產品及大數據產品有興趣。

    在優酷,我們使用 Redis Cluster 構建了一套內存存儲系統,項目代號為藍鯨。藍鯨的設計目標是高效讀寫,所有數據都在內存中。藍鯨的主要應用場景是 cookie 和大數據團隊計算的數據,都具有較強的時效性,因此所有的數據都有過期時間。更準確的說藍鯨是一個全內存的臨時存儲系統。

    到目前為止集群規模逐漸增長到 700+ 節點,即將達到 作者建議的最大集群規模 1,000 節點 。我們發現隨著集群規模的擴大,帶寬壓力不斷突出,并且響應時間 RT 方面也會略微升高。與一致性哈希構建的 Redis 集群不一樣,Redis Cluster 不能做成超大規模的集群,它比較適合作為中等規模集群的解決方案。

    運維期間, 吞吐量與 RT 一直作為衡量集群穩定性的重要指標 ,這里在本文中,我們碰到的影響集群吞吐量與 RT 的一些問題與探索記錄下來,希望對大家有所幫助。

    Redis Cluster 工作原理

    Redis 采用單進程模型,除去 bgsave 與 aof rewrite 會另外新建進程外,所有的請求與操作都在主進程內完成。其中比較重量級的請求與操作類型有:

    • 客戶端請求

    • 集群通訊

    • 從節同步

    • AOF 文件

    • 其它定時任務

    Redis 服務端采用 Reactor 設計模式,它是一種基于事件的編程模型,主要思想是將請求的處理流程劃分成有序的事件序列,比如對于網絡請求通常劃分為:Accept new connections、Read input to buffer、Process request、 Response 等幾個事件。并在一個無限循環的 EventLoop 中不斷的處理這些事件。更多關于Reactor,請參考 https://en.wikipedia.org/wiki/Reactor 。

    比較特別的是,Redis 中還存在一種時間事件,它其實是定時任務,與請求事件一樣,它同樣在 EventLoop 中處理。Redis 主線程的主要處理流程如下圖:

     

    Redis main process playload overview

    理解了 Redis 的單進程模型與主要負載情況,很容易明白,想要增加 Redis 吞吐量,只需要盡量降低其它任務的負載量就行了,所以提高 Redis 集群吞吐量的方式主要有:

    提高 Redis 集群吞吐的方法

    1. 適當調大 cluster-node-timeout 參數

    我們發現當集群規模達到一定程度時,集群間消息通訊開銷的帶寬是極其可觀的。

    集群通信機制

    Redis 集群采用無中心的方式,為了維護集群狀態統一,節點之間需要互相交換消息。Redis采用交換消息的方式被稱為 Gossip ,基本思想是節點之間互相交換信息最終所有節點達到一致,更多關于 Gossip 可參考 https://en.wikipedia.org/wiki/Gossip_protocol 。

    Gossip in Redis Cluster

    總結集群通信機制的一些要點:

    • Who:集群中每個節點

    • When:定時發送,默認每隔一秒

    • What:一個長度為 16,384 的 Bitmap 與集群中其它節點狀態的十分之一

    如何理解集群中節點狀態的十分之一?假如集群中有 700 個節點,十分之一就是 70 個節點狀態,節點狀態具體數據結構見下邊代碼:

    我們將注意力放在數據包大小與流量上,每個節點狀態大小為 104 byte,所以對于 700 個節點的集群,這部分消息的大小為 70 * 104 = 7280,大約為 7KB。另外每個 Gossip 消息還需要攜帶一個長度為 16,384 的 Bitmap,大小為 2KB,所以每個 Gossip 消息大小大約為 9KB。

    隨著集群規模的不斷擴大,每臺主機的流量不斷增長,我們懷疑集群間通信的流量已經大于前端請求產生的流量,所以做了以下實驗以明確集群流量狀況。

    實驗過程

    實驗環境為:節點 704,物理主機 40 臺,每臺物理主機有 16 個節點,集群采用一主一從模式,集群中節點 cluster-node-timeout 設置為 30 秒。

    實驗的大概思路為,分別截取一分鐘時間內一個節點,在集群通信端口上,進入方向與出去方向的流量,并統計出消息條數,并最終計算出臺主機因為集群間通訊產生的帶寬開銷。實驗具體過程如下:

    通過實驗能看到進入方向與出去方向在 60s 內收到的數據包數量為 2,700 多個。因為 Redis 規定每個節點每一秒只向一個節點發送數據包,所以正常情況每個節點平均 60s 會收到 60 個數據包,為什么會有這么大的差距?

    原來考慮到 Redis 發送對象節點的選取是隨機的,所以存在兩個節點很久都沒有交換消息的情況,為了保證集群狀態能在較短時間內達到一致性,Redis 規定當兩個節點超過 cluster-node-timeout 的一半時間沒有交換消息時,下次心跳交換消息。

    解決了這個疑惑,接下來看帶寬情況。先看 Redis Cluster 集群通信端口進入方向每臺主機的每秒帶寬為:

    再看 Redis Cluster 集群通信端口出去方向每臺主機的每秒帶寬為:

    所以每臺主機進入方向的帶寬為:

    為什么需要加和

    我們以節點 A 主動與節點 B 發生消息交換為例進行說明,交換過程如下圖:

    Redis Cluster msg exchange

    首先 A 隨機一個端口向節點 B 的集群通訊端 17,380 發送 PING 消息,之后節點 B 通過 17,380 端口向節點 A 發送 PONG 消息,PONG 消息的內容與 PING 消息的內容相似,每個消息的大小也一樣(9KB)。同理當節點 B 主動與節點 A 發生消息交換時也是同樣的過程。

    可以看出對于節點 A 進入方向的帶寬不僅包含集群通訊端口的還包含隨機端口的帶寬。而對于節點 A 進入方向隨機端口的帶寬,正是其它節點出去方向的帶寬。所以每臺主機進入方向的帶寬為上邊公式計算的加和。同理出去方帶寬與進入方帶寬一樣為 107.5MBit / s。

    cluster-node-timeout 對帶寬的影響

    集群中每臺主機的帶寬狀況如下圖:

    集群帶寬圖 (http://image.cnthrowable.com/upload/throwable_blog/itbroblog/blog/1468919903506_309.png)

    每臺主機的進出口帶寬都大概在 150MBit / s 左右,其中集群通信帶寬占 107.5MBit / s,所以前端請求的帶寬占用大概為 45MBit / s。再來看當把 cluster-node-timeout 從 20s 調整到 30s 時,主機的帶寬變化情況:

    帶寬變化 (http://image.cnthrowable.com/upload/throwable_blog/itbroblog/blog/1468920308772_304.jpg)

    從圖中,可以看到帶寬下降 50MBit / s,效果非常明顯。

    經過以上實驗我們能得出兩個結論:

    1. 集群間通信占用大量帶寬資源

    2. 調整 cluster-node-timeout 參數能有效降低帶寬

    Redis Cluster 判定節點為 fail 的機制

    但是并不是 cluster-node-timeout 越大越好。當 cluster-node-timeou 增大的時候集群判斷節點 fail 的時間會增加,從而 failover 的時間窗口會增加。集群判定節點為fail所需時間的計算公式如下:

    當節點向失敗節點發出 PING 消息,并且在 cluster-node-timeout 時間內還沒有收到失敗節點的 PONG 消息,此時判定它為 pfail 。pfail 即部分失敗,它是一種中間狀態,該狀態隨著集群心跳不斷傳播。再經過一半 cluster-node-timeout 時間后,所有節點都與失敗的節點發生過心跳并且把它標記為 pfail 。當然也可能不需要這么長時間,因為其它節點之間的心跳同樣會傳遞 pfail 狀態,這里姑且以最大時間計算。

    Redis Cluster 規定當集群中超過一半以上節點認為一個節點為 pfail 狀態時,會把它標記為 fail 狀態,并廣播給其他所有節點。對于每個節點而言平均一秒鐘收到一個心跳包,每次心跳都會攜帶隨機的十分之一的節點個數。所以現在問題抽像為經過多長時間一個節點會積累到一半的 pfail 狀態數。這是一個概率問題,因為個人并不擅長概率計算,這里直接取了一個較大概率能滿足條件的數值 10。

    所以上述公式不是達到這么長時間一定會判定節點為 fail,而是經過這么長時間集群有很大概率會判定節點 fail 。

    Redis Cluster 默認 cluster-node-timeout 為 15s,我們將它設置成了 30s。也就是說 700 節點的集群,集群間帶寬開銷為 104.5MBit / s,判定節點失敗時間窗口大概為 55s,實際上大多數情況都小于 55s,因為上邊的計算都是按照高位時間估算的。

    總而言之, 對于大的 Redis 集群 cluster-node-timeout 參數的需要謹慎設定 。

    提高 Redis 集群吞吐的方法

    2. 控制主節點寫命令傳播

    Redis 中主節點的每個寫命令傳播到以下三個地方:

    • 本地 AOF 文件,以持久化持數據

    • 主節點的所有從節點,以保持主從數據同步

    • 本節點的 repl_backlog 緩存,主要為了支持部分同步功能,詳見官網 Replcation 文檔 Partial resynchronization 部分: http://redis.io/topics/replication

    其中 repl_backlog 部分傳播在 replicationFeedSlaves 函數中完成。

    減少從節點的數量

    高可用的集群不應該出現單點,所以 Redis 集群一般都會是主從模式。Redis 的主從同步機制是所有的主節點的寫請求,會同步到所有的從節點。如果沒有從節點,對于主節點來說,它只需要處理該請求即可。但對于有 N 個從節點的主節點來說,它需要額外的將請求傳播給 N 個從節點。請注意這里是對于每個寫請求都會這樣處理。顯而易見從節點的數量對主節點的吞吐量的影響是比較大的,我們采用的是一主一從模式。

    因為從節點不需要同步數據,生產環境中觀察主節點的 CPU 占用率要比從節點機器要高,這對這條結論起到了佐證的作用。

    關閉 AOF 功能

    如果開啟 AOF 功能,每個寫請求都會 Append 到本地 AOF 文件中,雖然 Linux 中寫文件操作會利用到操作系統緩存機制,但是如果關閉 AOF 功能主線程中省去了寫 AOF 文件的操作,顯然會對吞吐量的增加有幫助。

    AOF 是 Redis 的一種持久化方式,如果關閉了 AOF 功能怎么保證數據的安全性。我們的做法是定時在從節點 BGSAVE。當然具體采用何種策略需要結合具體情況來決定。

    去掉頻繁的 Cluster nodes 命令

    在運維過程中發現前端請求的平均 RT 增加不少,大概 50% 左右。通過一番調研,發現是 頻繁的 cluster nodes 命令導致 。

    當時集群規模為 500+ 節點,cluster nodes 命令返回的結果大小有 103KB。cluster nodes 命令的頻率為:每隔 20s 向集群所有節點發送。

    提高 Redis 集群吞吐的方法

    3. 調優 hz 參數

    Redis 會定時做一些任務,任務頻率由 hz 參數規定,定時任務主要包含:

    • 主動清除過期數據

    • 對數據庫進行漸式Rehash

    • 處理客戶端超時

    • 更新請求統計信息

    • 發送集群心跳包

    • 發送主從心跳

    以下是作者對于 hz 參數的介紹:

    我們沒有修改 hz 參數的經驗,由于其復雜性,并且在 hz 默認值 10 的情況下,理論上不會對 Redis 吞吐量產生太大影響,建議沒有經驗的情況下不要修改該參數。

    參考資料

    關于 Redis Cluster 可以參考官方的兩篇文檔:

    • Redis cluster tutorial: http://www.redis.io/topics/cluster-tutorial

    • Redis Cluster specification: http://www.redis.io/topics/cluster-spec

    posted on 2016-12-15 14:32 jinfeng_wang 閱讀(158) 評論(0)  編輯  收藏 所屬分類: 2016-REDIS
    主站蜘蛛池模板: 亚洲黄色三级网站| 亚洲精品乱码久久久久久按摩| 久久狠狠高潮亚洲精品| 久久久精品国产亚洲成人满18免费网站| 亚洲av成人一区二区三区在线观看| 久久人午夜亚洲精品无码区| 日韩成人免费aa在线看| 亚洲欧好州第一的日产suv| 午夜免费不卡毛片完整版| 亚洲精品久久久久无码AV片软件| 最好免费观看韩国+日本| 国产亚洲美女精品久久久久| 伊在人亚洲香蕉精品区麻豆| 一个人免费观看视频在线中文| 亚洲色中文字幕无码AV| 久久久久久久99精品免费| 亚洲youjizz| 情侣视频精品免费的国产| 男人j进女人p免费视频| 亚洲AV无码日韩AV无码导航 | 91亚洲国产成人久久精品| 免费精品国产自产拍在线观看图片| 亚洲人成在线播放| 国产成人精品免费直播| 99精品免费视品| 亚洲性猛交xx乱| 国产乱子伦精品免费女| 成人毛片100免费观看| 亚洲精品高清国产麻豆专区| 国产美女精品久久久久久久免费| h视频免费高清在线观看| 日韩精品一区二区亚洲AV观看| 在线观看免费成人| 亚洲一级片免费看| 亚洲乱码卡一卡二卡三| 免费播放春色aⅴ视频| 人妻无码一区二区三区免费| 国产青草亚洲香蕉精品久久| 亚洲国产精品久久66| 四虎永久在线精品免费观看地址| 中文无码成人免费视频在线观看|