close

html模版唯品會峰值系統架構演變 摘要:在唯品會,用戶來得越早,越能買到又便宜又好的東西,所以在大促一開始會湧入大量用戶,形成系統流量峰值。本文總結瞭唯品會419時日志平臺遇到的問題和解決方案,同時根據實踐經驗,整理瞭在面對峰值前要做的準備。

唯品會每年最大力度的促銷活動在4月19日,就是419(For One Night),意在告訴唯品會用戶隻有這一晚有這麼大的折扣力度(本文中用“大促”就指代419) 。唯品會是一個閃購網站,用戶來得越早,越能買到又便宜又好的東西,所以在大促的一開始,會湧入大量用戶,形成系統流量峰值。

本文總結瞭唯品會419時日志平臺遇到的問題和解決方案,同時根據實踐經驗,整理瞭在面對峰值前要做的準備。

2013年419唯品會的日志平臺,包括消息中間件、計算和數據可視化。前兩者和峰值系統相關度更大一些。在2013年419時,我們使用Flume來收集日志,RabbitMQ作為傳輸日志的消息中間件,用Storm和Redis進行計算,然後通過腳本將Redis的數據寫入MySQL,前端從MySQL中獲取數據做數據可視化。架構如圖1所示。

圖1 2013年日志平三馬達電動病床宜蘭電動床臺架構

在這次419之前,我們對這個系統並不是很有信心。一個原因是剛開始做這塊內容,很多工具都不夠成熟。另一個原因是在大促之前,我們還在開發新功能,既沒有穩定運行一段時間,也沒有做容量規劃之類的事情。

最後的結果確實如此,4月19日0點,大量用戶進入唯品會購物,系統計算開始出現延遲,最初是1分鐘,後面逐漸擴大到10分鐘,最後由於雪崩效應,整個集群垮瞭。在分佈式系統中,“雪崩效應”指的是系統中一個小問題會逐漸擴大,最後造成整個集群宕機。前面這個例子,一開始的計算延遲是1分鐘,這在可以接受的范圍內,但因為這個延遲,系統需要付出更多的代價去計算,如此惡性循環,數據延遲會越來越大,最後導致整個集群宕機。

在大促之後,我們進行瞭全面分析,發現這個系統的瓶頸在於RabbitMQ和Storm。

作為整個平臺輸送數據的管道,RabbitMQ的性能直接決定瞭後端消費數據系統的消費能力。整個平臺就像是大炮,大炮發射再快,輸送炮彈的速度跟不上都沒用。這次大促中,RabbitMQ的性能出瞭問題。我們需要處理的日志量是每秒15萬條左右,而我們使用RabbitMQ的環境下,每一臺RabbitMQ服務器大約能達1.2萬條日志每秒,由4臺機器組成RabbitMQ集群,所以當流量暴漲時,RabbitMQ服務器負載會變得很高,而produce/consume速度變慢。在當時的情況下,我們並不能判斷這個Queue的堵塞是由於下遊的Storm消費得慢,還是RabbitMQ本身慢造成。

再看Storm。在分析Storm出問題的原因之前,先先介紹一下使用Storm計算的內容:一是根據用戶訪問日志計算PV/UV;二是根據Nginx日志計算各個域的訪問量、響應時間和4xx/5xx數。由於Storm在各個計算節點之間無法共享數據(不像Spark有broadcast),我們隻能借助Redis來做一個類似MapReduce中的Reduce功能。為瞭讓大傢能深入瞭解,下面詳細介紹一下如何使用Storm計算這些數據。

PV在Redis中有不同的key,如b2c_pv和mobile_pv,對Storm中得到的每條日志進行邏輯判斷決定是b2c還是mobile訪問,再使用Redis的incr操作(incr[key],表示將key對應的value加1,如果key不存在,則在這個操作前,會先置為0)。

UV我們計算的是每5分鐘的UV,方法很簡單。在Redis中有一個DB專門用來計算UV,Storm將每個用戶的cid(標識用戶唯一身份的id)incr到DB中,這樣能保證一個cid對應一個key。最後匯總通過Redis的“keys *”來獲取DB中key的數目,這樣就獲取到瞭cid的數目。又因為我們計算的是5分鐘的UV,所以還需要一個crontab,每5分鐘將DB中的內容truncate掉。

計算Nginx日志實際上,計算Nginx日志非常簡單,就是分割和計算。將一條Nginx日志分割後,就能知道這次訪問的狀態碼是什麼,響應時間是多少。然後DB中會有不同的key,如domain是cart,那麼cart域的響應時間在Redis DB裡的key就是cart_resp_time,訪問量就是cart_count,2xx數量就是cart_2xx_count。根據從日志獲取的值,我們會使用Redis的incrby來操作(incrby和incr類似,incr是value加1,incrby可以指定增加的數字)。然後在計算metrics時,腳本先獲取當前的cart_count,然後sleep 1秒,再獲取一次cart_count,這兩個的差值是這1秒鐘內cart域的訪問量。同樣的方法,可以獲取這1秒的響應時間,與訪問量相除,就可以計算出這1秒的平均響應時間。

介紹完計算邏輯,可以瞭解到,Storm的處理邏輯非常簡單,主要工作就是“分割日志”和“操作Redis計數”。

為瞭判斷到底是RabbitMQ慢還是Storm慢,我們先將Storm停瞭,然後用一個Python腳本向Queue發送數據和消費Queue裡的數據,這樣來減小Producer和Consumer性能對RabbitMQ的性能影響。這樣測試後發現,每臺RabbitM居家電動床Q的吞吐大概是1w條數據每秒,而且負載很高。後來,我們使用Erlang的HiPE特性(即High Performance Erlang),將性能提升20%,大概達到1.2w條數據每秒。但仍然不能滿足我們的要求。我們要求達到15w msg/s,加上25%的冗餘,此時需要15×(1+25%)/1.2≈16臺服務器,比較多。再考慮到唯品會正處於快速增長期,目前是15w msg/s,很有可能明年就翻幾番。使用RabbitMQ似乎不太符合我們的需求,因為在可預見的將來,需要大量服務器來支撐。此外,RabbitMQ對服務器的CPU消耗非常大。

RabbitMQ的消費者除瞭Storm外,還有Elastic-Search(ES)。使用ES來做日志的全文檢索,包括Nginx日志和PHP錯誤日志,因為Nginx日志的計算隻能幫助運維人員和開發人員定位到某個域出問題,再深入地分析,就要從出錯時的日志入手瞭。我們的日志還會有一份全量流入HDFS,原本用日志的搜索直接從HDFS來獲取,但發現用Hive查詢速度非常慢,大約需要幾分鐘。ES是基於Solr的一個全文檢索引擎,有一個很好用的前端Kibana。在這次大促中,由於前端的RabbitMQ掛瞭,所以ES沒有受到很大的壓力。

老人電動床補助……

作者姚仁捷,唯品會數據平臺與應用部門研發工程師,從事日志平臺相關工作,關註Flume、Kafka、Storm和ElasticSearch等技術。對Zabbix監控系統有深入研究,出版瞭《Zabbix監控系統深度實踐》。新浪微博:@超大杯摩卡星冰樂

居家照護床本文節選自《程序員》11月刊,歡迎訂閱《程序員》雜志iPad/Android版。



本文《程序員》原創文章,未經允許不得轉載,如需轉載請聯系market#csdn.net(#換成@)




2015中國大數據技術大會為瞭更好幫助企業深入瞭解國內外最新大數據技術,掌握更多行業大數據實踐經驗,進一步推進大數據技術創新、行業應用和人才培養,2015年12月10-12日,由中國計算機學會(CCF)主辦,CCF大數據專傢委員會承辦,中國科學院計算技術研究所、北京中科天璣科技有限公司及CSDN共同協辦的2015中國大數據技術大會(Big Data Technology Conference 2015,BDTC 2015)將在北京新雲南皇冠假日酒店隆重舉辦。

D7EA8CF985D436ED

arrow
arrow
    創作者介紹
    創作者 uao640o6e8 的頭像
    uao640o6e8

    控制在範圍內

    uao640o6e8 發表在 痞客邦 留言(0) 人氣()