限流系統如何發現系統的熱點

限流系統是對資源調用的控制組件,主要涵蓋授權、限流、降級、調用統計等功能模塊。限流系統有兩個基礎概念:資源和策略,對特定的資源採取不同的控制策略,起到保障應用穩定性的作用。限流系統提供了多個默認切入點覆蓋了大部分使用場景,保證對應用的低侵入性;同時也支持硬編碼或者自定義aop的方式來支持特定的使用需求。限流系統提供了全面的運行狀態監控,實時監控資源的調用情況(qps、rt、限流降級等信息)。

如何利用限流系統的特性,來統計熱點呢?在這裏,我們主要介紹一下,限流系統是如何來判斷熱點的,它的工作原理是什麼,它的性能如何;它目前已經在哪些場景裏面使用。

1. 熱點的特性

a) 海量的統計基數

可能的熱點分爲兩種,一種是事前已知的(例如營銷人員的已經整理出秒殺商品的列表),另外一種是突發的,不可以預計的(例如被刷單的商品,或者是黑馬產品)。對於前面一種,只需要計算這些已知的列表即可,但是對於後者,由於基數是海量的,舉個例子,如果有一個方法,它傳入的參數是商品id, 這個商品的id以淘寶的規模來說,是上億的。如果把所有的商品id都記錄統計起來,再進行排序,統計出熱點,這對於實時的工具來說,是不可行的。所以爲了解決熱點統計,我們必須找到一個好的數據結構,這個結構能夠僅保存最常常被訪問的一定數量商品id,並且可以控制結構的大小,統計量。這是非常重要的一個步驟。

b) 統計熱點的單位時間的維度

這裏有一個必須強調的概念: 單位時間而不是總訪問量。 打個比方,一個商品,在一小時以內被訪問了3600次,但是它很均勻的每秒被訪問一次,那麼這個商品可能在系統的承受範圍之內,並會對系統帶來損傷;而另外一個商品,它一小時被訪問了60次,但都落在同一秒,那麼這個商品可能就是一個熱點商品。對於”單位時間”的定義,是決策一個參數是否成爲熱點的一個重要的因素;如果太粗,必然會帶來毛刺,導致系統性能不平滑;如果太細,會給性能帶來挑戰。

c) 在分佈式系統給統計帶來的挑戰

熱點的統計範圍可能是單機,也可能是集羣。如何能快速的在集羣中統計,並且讓限流規則在單機上生效,是非常重要的。

2. 如何解決上述問題

2.1 首先,找到一個可行的數據結構

這個結構必須滿足訪問修改快速,併發性好,佔用內存空間少,存儲的個數大小可控制,並且可以驅逐訪問量少的entry,從而可以達到實時統計熱點的查詢數字。

其實,業界有一個現成的好結構。它就是google團隊用於guava裏的ConcurrentLinkedHashMap (http://code.google.com/p/concurrentlinkedhashmap)。

它有下面幾個特點:

2.1.a 支持併發。它是實現了ConcurrentMap接口的。基本上它的實現是遵循concurrentMap的思想的。這裏就不多贅述。

2.1.b 它把我們普通concurrenthashmap的segments用一個額外的雙鏈表維護起來,通過操作這個鏈表,裏面的entry可以在O(1)的時間之類刪除或者重新排序。當一個entry被訪問,則被移動到表頭;當這個map的容量超過預設,則移除位於鏈表尾的entry。這樣就可以保證表頭是最新被使用的entry,表尾是最近最少被使用的entry

94cd7120395086cf4803992008b7f17bda28e7c2

2.1.c 從另外一個角度來說,可以把ConcurrentLinkedHashMap 分成兩個view. 一個是同步的,一個是異步的。Hashtable對於調用方來說是同步的,鏈表對於調用方式不透明的,異步的。

9d67db20c4f8d60978ef73f762bdcafc25835e1c

2.1.d 性能和concurrenthashmap的比較, 肯定比concurrenthashmap差,但是屬於可以忍受的範圍。下面是官方給出的數據

539d274b766dbfacb97cfc66f24e9658bef7081f

綜上所述,我們可以利用這個LRU concurrent map link,保證我們在單位時間內,僅保存有限數量訪問量較高的key, 最近比較少訪問的key,我們則可以認爲它不是熱點,當map的Size達到上限之後,清除這個key

2.2 統計單位時間的維度

現在我們來看第二個問題,如何統計單位時間的key的qps. 其實這個正是限流系統的拿手好戲,用動態滑動窗口平滑的統計qps.

簡單的說,限流系統爲每個簇點(可以簡單的理解爲需要統計的方法),做了一個滑動窗口。更具體的說,即限流系統把採樣窗口長度設爲2秒,這個採樣窗口又被分割爲20個格子。通過用一定的算法來統計這20個格子的平均滑動窗口累積平均值來進行決策。
爲什麼採用平均滑動窗口累計平均值是爲了削平毛刺qps(在某個點突發的qps)對整體的影響。該公式如下:
e013a13198b40fee7e1e6930140eb2dd615d7e6b
更具體的說明在: http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average 可以查到。

說到這裏,聰明的讀者應該早就猜到了,限流系統通過把兩個利器結合起來,即滑動窗口和google concurrent link hashmap,可以統計在固定的時間,最常常使用的參數的值。
限流系統數據結構如下所示:

f23bcb04935c288c72e159bc5d9ee820713dccbb

具體的代碼在: http://gitlab.alibaba-inc.com/middleware-asp/限流系統 歡迎大家來指正

2.3 如何解決集羣的挑戰

2.3.1 幸運的是,限流系統天生自帶獲取簇點qps的功能

使用過限流系統的人都會發現,8719這個端口是被限流系統佔用了的。通過這個端口,我們可以用獲取到簇點的qps統計信息。有了這個“後門”,我們就可以輕鬆快速的獲取到qps的信息了

2.3.2 如何在大集羣裏彙總這些qps的信息

接下來要解決的問題就是,如何在上千臺機器裏面快速彙總這些信息。還好之前我們在做2.0.7的集羣統計的時候,有了一定的經驗。 這個算法後來也用在了預案分配巨大的url task中。簡單的說,就是用一個隊列來放任務,多個線程來執行任務,一個線程來merge取回的結果。通過使用這個方法,一個比較大的集羣,例如buy等,2秒可以返回統計結果。

b7969b7cd134ab8ede52777876d7e595471d4999

有了集羣的總體彙總信息之後,我們再將這個信息利用diamond來推廣到具體的機器上去。這樣的延遲大概是2-3s左右。

3 總結以及限流系統性能報告:

簡單的說,存放一個這樣的結構,大概大小是8k. 它的默認參數是每個簇點的存放2s的滑動窗口,20個格子,每個格子最多可以保存200個參數,那麼在最壞的情況下,這個結構的大小將會是8k+4000個參數大小。

吞吐量在我的日常機器上是29W,在生產機上應該會更好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章