使用云服務最大好處是按量付費,無需預留資源,因此各云產品都有計量計費需求。本文介紹一種基于日志服務按量計費方案,該方案每天處理千億級計量日志,被眾多云產品使用。
按量計費日志
使用場景
電力公司:每10秒會收到一條日志,記錄該10秒內每個用戶ID下該周期內功耗、峰值、均值等,每天、每小時和每月給用戶提供賬單。
運營商:每隔10秒從基站收到時間段內某個手機號碼的動作(上網、電話、短信、VoIP)、使用量(流量)、時長等信息,后端計費服務統計出該區間內消耗資費。
天氣預測API服務:根據用戶調用接口類型、城市、查詢類型、結果大小等對用戶請求進行收費。
要求與挑戰
既要算對,又要算準是一件要求很高的事情,系統要求如下:
準確可靠:既不可多算,也不能少算。
靈活:支持補數據等場景,例如一部分數據沒有推送過來,當需要修正時可以重新計算。
實時性強:能夠做到秒級計費,對于欠費場景快速切斷。
其他需求(Plus):
賬單修正功能:在實時計費失敗時,我們可以通過理想計費進行對賬。
查詢明細:支持查看自己消費明細。
現實中還有兩類挑戰:
不斷增長的數據量:隨著用戶以及調用上升,數據規模會越來越大,如何保持架構的彈性伸縮。
容錯處理:計費程序可能有Bug,如何確保計量數據與計費程序獨立。
本文介紹一種基于日志服務按量計費方案,該方案已在線上穩定運行多年,從未出現過一例算錯、延遲等情況,供大家參考。
工作原理
以日志服務LogHub功能為例:
使用LogHub進行計量日志實時采集與計量程序對接:LogHub支持的50+種接入手段。
計量程序每隔固定時間消費LogHub中步長數據,在內存中計算生成計費數據結果。
(附加)對明細數據查詢需求,可以將計量日志配置索引查詢。
(附加)將計量日志推送至OSS、MaxCompute進行離線存儲,進行T+1等對賬與統計。
實時計量程序內部結構:
根據LogHub讀取接口GetCursor功能,選定某個時間段日志(例如10:00-11:00)Cursor。
通過PullLogs接口消費該時間段內數據。
在內存中進行數據統計與計算,拿到結果,生成計費數據。
我們可以以此類推,把選擇時間計算邏輯修改為1分鐘,10秒鐘等。
性能分析:
假設每天有10億條計量日志,每條長度為200字節,數據量為200GB。
LogHub默認SDK或Agent都帶壓縮功能,實際存儲數據量為40GB(一般至少有5倍壓縮率),一個小時數據量為1.6GB。
LogHub讀取接口一次最大支持讀1000個包(每個包最大為5MB),在千兆網條件下2秒內即可讀完。
加上內存中數據累計與計算時間,對1小時計量日志進行匯總,不超過5秒。
計量日志生成計費結果過程
計量日志記錄了您所涉及計費的項目,后端計費模塊根據計費項和規則進行運算,產生最后賬單。例如如下原始訪問日志記錄了項目(Project)使用情況:
microtime:1457517269818107 Method:PostLogStoreLogs Status:200 Source:203.0.113.10 ClientIP:198.51.100.10 Latency:1968 InFlow:1409 NetFlow:474 OutFlow:0 UserId:44 AliUid:1264425845****** ProjectName:app-myapplication ProjectId:573 LogStore:perf UserAgent:ali-sls-logtail APIVersion:0.5.0 RequestId:56DFF2D58B3D939D691323C7
計量計費程序讀取原始日志,根據規則生成用戶在各維度使用數據(包括流量、使用次數、出流量等):
數據量大應如何解決
在一些計費場景下(例如運營商、IoT等),計量日志量會很大(例如十萬億,數據量為每天2PB),折算壓縮數據后一小時有16TB,以萬兆網絡讀取需要1600秒,已不能滿足快速出賬單需求。
控制產生的計費數據量
對于產生計量日志程序進行改造(例如Nginx),先在內存中做聚合,每隔1分鐘轉儲一次該時間段聚合的匯總計量日志結果。這樣數據量就和總體的用戶數相關了。假設Nginx該時間段內有1000個用戶,一個小時數據量為1000*200*60=12GB(壓縮后為240MB)。
將計量日志處理并行化
LogHub下每個日志庫可以分配不同Shard(分區),我們可以分配3個分區,3個計量消費程序。為了保證一個用戶計量數據總是由一個消費程序處理,我們可以根據用戶ID Hash到固定Shard中。例如杭州市西湖區用戶寫在1號Shard,杭州上城區用戶數據寫在2號Shard,這樣后臺計量程序就可水平擴展。
其他問題
補數據怎么辦?
LogHub下每個Logstore可以設置生命周期(1~365天),如果計費程序需要重新消費數據,在生命周期內可以根據任意時間段進行計算。
計量日志散落在很多服務器中怎么辦?
使用Logtail Agent實時采集。
使用自定義用戶標識定義一套動態機器組彈性伸縮。
查詢明細需求如何滿足?
對LogHub中的數據創建索引,支持實時查詢與統計分析。
Inflow>300000 and Method=Post* and Status in [200 300]
您也可以在查詢后加上統計分析:
Inflow>300000 and Method=Post* and Status in [200 300] | select max(Inflow) as s, ProjectName group by ProjectName order by s desc
存儲日志并進行T+1對賬。
日志服務提供LogHub中數據投遞功能,其支持自定義分區、自定義存儲格式等配置。將日志存儲在OSS、MaxCompute上,利用E-MapReduce、MaxCompute、Hadoop、Hive、Presto、Spark等進行計算。