1. 背景

服務質量 QoS (Quality of Service) 是用於評估服務方滿足客戶服務需求的能力,也是客戶體驗的關鍵。隨著雲計算技術的發展,越來越多的服務提供商,開始在雲場景下給客戶提供了各種各樣的雲服務(IaaS、Paas、SaaS),無一例外,每一種服務都有對應對客戶承諾的服務質量,這是雲服務提供商的核心競爭力之一。但是如何保證雲服務的 QoS 確不是一件容易的事情,在很多系統裏是一個自上而下的系統工程,甚至要實現精細化的 QoS 控制很多時候都需要和性能做權衡。為了嘗試去解決這個問題,打算從塊存儲(這種簡單的 I/O 場景,後期描述若未明確說明,都是指代塊存儲場景)這個角度來寫幾篇討論一下一個系統的 QoS 方案所面臨的問題和基本的解決思路,大概規劃有 3 篇,列表如下:

  • (1)QoS (一) 限流:任何一種服務都有流量的控制,從最前端控制雲服務的流量,做好多租戶資源隔離限制是 QoS 的第一步
  • (2)QoS (二)單機調度:多租戶是雲服務的基本特徵,但從物理層面,多租戶的資源都是共享的同一個物理資源池,精細化的資源隔離單單依靠前端的流量控制遠遠不夠的,如果做好系統精細的 I/O 調度是保證雲服務公平和質量基礎,而首當其衝的,就是單機的公平調度(這裡可以理解為單盤)
  • (3)QoS (三) 分散式調度:在當前的分散式系統中,僅僅做到單機的 I/O 公平調度當然是不夠的,如何從整個分散式系統全局出發做調度,想想都是一件極具挑戰性的問題

這次開篇,首先聊聊限流~

2. 限流

對於一般的 I/O 類型的服務來說,通常限流需要做兩個方面,一個是 iops/tps/qps,這裡以塊存儲為例,iops;另一方面是吞吐(throughput),一般來說是帶寬。後面將主要從 iops 和 bandwidth 兩個因素來描述如何限流

那為什麼要從最前端來限流 ?首先 QoS 本身有規定用戶的服務性能參數,對每個租戶做限制,保證給多少錢出多少活,畢竟不是做慈善的;其次一個租戶的流量不限制,本身也會影響其他租戶的性能的公平和穩定。

在限流方面有兩個基本的演算法,分別是漏斗演算法和令牌桶演算法,它們都是早期在計算機領域被用於控制網路介面收發通信數據的速率的演算法,也可以直接使用在 I/O 流控上面。本小節很多描述,包括圖片都參考 [1]。

2.1. 漏斗演算法

如上圖所示,漏斗演算法(Leaky bucket),所有的流量先進入漏斗中,然後流量按照固定速率輸出,在流入速率大於流出速率時,就會意味著溢出,也就是數據包被丟棄。其核心的特點就是強制限制了流量的速率。

對於我們用來做 I/O 限流,直接將漏斗的輸出速率設定為 IOPS 和 bandwidth 即可

2.2. 令牌桶演算法

令牌桶演算法(Token Bucket):是網路流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一種演算法。典型情況下,令牌桶演算法用來控制發送到網路上的數據的數目,並允許突發數據的發送。令牌桶演算法示意圖如下所示:

其大致的流程容量固定的令牌桶自行以恆定的速率源源不斷地產生令牌。如果令牌不被消耗,或者被消耗的速度小於產生的速度,令牌就會不斷地增多,直到把桶填滿。後面再產生的令牌就會從桶中溢出。最後桶中可以保存的最大令牌數永遠不會超過桶的大小。所有的請求被下發之前得首先得去令牌桶中取一個令牌,然後消耗掉,才能將請求下發下去。這樣通過控制令牌的產生的速率,來限定流量。

但是,相比漏斗演算法,「令牌桶演算法」不僅可以通過固定的令牌產生速率來限制數據的平均傳輸速率以外,還允許某種程度的突發傳輸。在「令牌桶演算法」中,只要令牌桶中存在令牌,那麼就允許數據傳輸,那麼意味著,閑時令牌桶中的令牌會積累滿(輸出的速率小於令牌產生的速率),如果之後在來突發流量或者 I/O 的時候,就能夠以大於令牌桶令牌產生的速率應對突發請求,直到令牌桶中的令牌被消耗完。

3. 案例實踐

3.1. Ceph

在 Ceph librbd 塊存儲中就使用了令牌桶演算法用來做 iops 限制,具體的令牌桶實現是在類 TokenBucketThrottle 中,思路比較簡單,詳細的分析和代碼細節可以參考文獻 [2],這裡不再贅述。

需要說明的是這個 TokenBucketThrottle 也可以用來做 bandwidth 限制,只需要將 iops 的統計換成 I/O size 的統計即可。

3.2. Qemu

Qemu 使用的 「漏斗演算法」 來實現塊設備 I/O 的 qos 控制,不過和傳統的漏斗演算法有些差異,詳細分析我們這裡以 iops 配置參數為例,主要參考 [3],如下:

iops-total = 100 // 表示漏斗水漏走的速率
iops-total-max = 2000 //
iops-total-max-length = 60 //

其中 100 表示漏斗水漏出的速率,往漏斗中倒數的最大速率時 2000, 最長時間為 60 s,那麼漏斗的容量為 2000*60=12000。

???未完待續 ......

4. 總結

上文簡單介紹了使用漏斗和令牌演算法做 iops 和 bandwidth 的限制,但是並不能解決所有問題,這裡列舉兩個問題,供大家一起思考和交流:

  1. 上面的描述都是如何使用漏斗和令牌桶演算法限制 iops 或者 bandwidth,那麼如何同時滿足 iops 和 bandwidth 的限制 ?
  2. 在限制 iops 的時候,實際上不同的 I/O size 的大小是不一樣,如果不區分對待,顯然是不公平 ?那麼該怎麼處理不同 I/O 大小的 request 呢?

Notes

水平和時間有限,論文很多細節沒看那麼細,難免有錯誤和理解不到位的地方,歡迎指出和交流~

參考文獻

[1]. 流量調整和限流技術. "colobu.com/2014/11/13/r"

[2]. rbd image qos. blog.csdn.net/dongsheng

[3]. QEMUQoS特性及原理分析和LibrbdQoS定義. 2cto.com/net/201610/558


推薦閱讀:
查看原文 >>
相關文章