1. 程式人生 > >網站運維技術與實踐之資料分析與報警

網站運維技術與實踐之資料分析與報警

  對於日益積累的監控資料,顯然需要有規劃地進行儲存和分析,做到“故障沒來時有預防,故障來臨時有提示,故障到來時有解決方案”。
  
  一、時間序列儲存
  
  對於大多數監控資料,都有一個天然的類似資料庫主鍵的屬性,那就是時間。所以,通常情況下,各類監控系統的後臺資料庫都可以認為是時間序列的資料儲存,並由此誕生了一批針對監控資料儲存開發的資料庫,其中最有代表性是RRDtool和Graphite。
  
  1.RRDtool(Round-Robin DataBase Tool)
  
  Round-Robin(迴圈)在運維人員眼裡是一個很熟悉的詞彙。負載均衡中最基礎的演算法就是Round-Robin,意即逐一迴圈。這個詞很形象地描繪了RRD資料庫的內部結構。
  
  RRD資料庫是一個固定空間大小的檔案,其內部可以看做一個固定刻度的圓形錶盤,每個刻度儲存一個時間點的資料。表上有一個指標,永遠指向最新寫入資料的位置。指標隨著資料寫入轉動,轉完一圈後,就覆蓋掉之前的資料從頭繼續。
  
  上面這段描述中,有一點需要單獨拿出來支出,即"指標歲隨資料寫入轉動"。這個資料寫入,並不等同於運維人員呼叫rrdtool命令插入資料。這也是RRD資料庫和普通資料庫一個明顯的不同-在指定的時間間隔後,如果RRD每個收到明確的資料插入請求,它依然會自行發起一次“空”資料寫入,佔據這個刻度空間。這也是我們一般用鐘錶比喻RRD的原因,指標實際是定時轉動的。
  
  2.Graphite
  
  相對1999年誕生的RRD,2006年才出生的Graphite通過與Statsd實時監控系統的結合,在最近幾年大資料的浪潮中得到迅速普及和發展。
  
  Graphite專案包括三部分:展示圖形的graphite-web,接收和寫入資料的carbon,資料儲存引擎whisper。這裡我們先不談論graphite-web而專注於資料部分。
  
  Graphite與RRD一脈相承,事實上,最開始的Graphite就是打算通過額外的Python指令碼存取分散式的RRD檔案(看起來更類似於Cacti的角色)。
  
  但最終Graphite沒有選擇RRD而是自己用Python實現儲存引擎whisper,主要原因如下:
  
  (1)Graphite的設計更傾向於展示資料而不是各種演算法
  
  在實際運用中,類似"網站訪問500錯誤數統計"是Graphite常見的典型需求之一。而在網站一切正常的情況下,500錯誤肯定是具有偶發性質的。這與RRD資料結構設想的“有規律的定時記錄資料”是相互衝突的。
  
  (2)效能問題
  
  在Graphite專案開始的時候,RRD在同一時刻,只允許往一個數據庫裡寫入一個數值,而whisper可以合併多個數值批量寫入。這樣在高負載情況下,同時操作大量檔案時,Graphite就不會被“磁碟IOPS“的瓶頸限制住。不過RRDtool現在已經解決了效能問題。但是在在第一點沒有解決之前,雖然Python寫的whisper效能比C寫的rrdtool慢2~5倍,Graphite也會繼續使用自己的whisper引擎。
  
  3.OpenTSDB
  
  時間序列資料庫家族裡還有一個新加入的成員:HBase社群的OpenTSDB。OpenTSDB只儲存最基本的<timestamp,value>鍵值對,其餘功能都依賴於HBase叢集完成。有興趣的讀者可以參閱其官網,地址:http://opentsdb.net。
  
  總的來說,從RRDtool到Graphite再到OpenTSDB,資料庫中內建的資料型別和聚合演算法越來越少,資料儲存的可靠性和可擴充套件性越來越強。具體如何選擇,就取決於資料量大小和運維團隊二次開發能力。
  
  二、全文搜尋引擎ElasticSearch
  
  前面說到的RRD、Graphite、OpenTSDB等,都只能儲存數值型資料,這需要我們提前先整理好資料,因此不足以應對突發性的需求。比如,網站新出現的熱門話題,我們需要關注這個話題的相關監控資料,這時候再動手建立資料庫,然後寫指令碼過濾日誌,最後匯入庫中繪圖,不過等到這個過程完了,恐怕就晚了。
  
  或許大家在應對這個問題的時候,都通過搜尋引擎知道了Spluck這個工具,可惜的是這不是一個開源軟體,它只提供每天索引500MB的免費試用版本。有些運維人員只好先行裁剪資料,只匯入所需的部分來進行查詢,倒可以算是一種臨時抱佛腳的解決辦法。
  
  1.簡介
  
  ElasticSearch是一個分散式的Lucene全文搜尋引擎,提供RestFul的API介面,也是最近相當流行的日誌儲存分析平臺。它提供更加強大的搜尋和統計功能。
  
  關於全文搜尋的基礎原理,不瞭解的讀者可以參考《大規模Web服務開發技術》中的》第九章挑戰全文搜尋技術 電子書的下載地址為:http://vdisk.weibo.com/s/zmzzSciGaVonL(感恩網際網路時代為我們學習提供很多渠道)
  

  glGenBuffers(NumBuffers, Buffers);
    glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
        vertices, GL_STATIC_DRAW);
    ShaderInfo shaders[www.hjylp178.com] www.ysyl157.com= {
        { GL_VERTEX_SHADER, "triangles.vert" },
        { GL_FRAGMENT_SHADER, "triangles.frag" },
        { GL_NONE, NULL www.dasheng178.com}
    GLuint program =www.mcyllpt.com LoadShaders(shaders);
    glUseProgram(program);
    glVertexAttribPointer(vPosition, 2, GL_FLOAT,
        GL_FALSE, 0, BUFFER_OFFSET(0));
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(VAOs[Triangles]);
    glDrawArrays(GL_TRIANGLES,www.furggw.com  0, NumVertices);
    glFlush(www.meiwanyule.cn);

  目前ElasticSearch幾個著名的客戶如下:
  
  (1)Mozilla,自動構建和測試叢集,通過Flume傳送ES。
  
  (2)Sony,採用ES進行娛樂專案的使用數、使用者評分、標題和說明等的儲存和搜尋。
  
  (3)StumbleUpon,著名社交內容推薦引擎公司,用ES索引HBase資料方便不熟悉Hadoop程式設計的開發人員完成搜尋功能,稱上手快,1小時內搞定。
  
  (4)Infochimps,著名大資料分析服務公司,通過ES索引超過2.5億個物件,4TB以上的Hadoop資料。
  
  (5)Ataxo Social Inside,捷克斯洛伐克的一家社交輿情監控分析公司,從網頁資料庫到後臺分析都用ES。
  
  (6)MetaCPAN和Github,都是程式碼託管網站,用ES做開源專案程式碼搜尋。
  
  ElasticSearch中文社群:https://elasticsearch.cn/
  
  ElasticSearch權威指南下載:http://www.java1234.com/a/javaziliao/shuji/2016/0104/5478.html
  
  2.安裝
  
  ElaticSearch官網提供了各個版本的deb安裝包。因為ES是一個Java專案,沒有什麼動態庫依賴,所以我們可以很容易地根據deb生成rpm安裝包。
  
  ES原始碼託管:https://github.com/elastic/elasticsearch/
  
  也可以選擇直接下載程式碼後執行./bin/elasticsearch即可
  
  Linux安裝教程:https://blog.csdn.net/sinat_28224453/article/details/51134978
  
  Windows安裝教程:https://www.cnblogs.com/zhangchenliang/p/4214408.html
  
  3.叢集
  
  ES叢集的部署可謂是“傻瓜式”的,唯一需要自定義的地方就是/etc/elasticsearch/elasticsearch.yml裡的cluster.name。然後,在Discovery可達的範圍內,所有的elasticsearch node會自動尋找和自己有相同cluster.name的兄弟,然後按照最樸素的先來後到的規則確定master。到此,叢集就完成了。
  
  在ES叢集中,存在多種角色,如下:
  
  (1)master node:有資格被選舉成為master的node。但是和MySQL的master-slave結構不同,ES中master的作用只是負責維護整個cluster的state,也就是nodes和shards的列表,然後通知其他所有的API,也就是常說的CRUD,都是可以直接發給叢集裡任何一個master node的,這個node會自動根據請求來操作整個叢集。
  
  (2)data node:儲存資料的node。ES中,data node上有index和shard兩級實際存在的目錄。但邏輯上,index一旦建立,其shards數就不能再變更,因為ES的shard方法就是簡單的取餘;而replica數是可以隨時通過API調整的。
  
  (3)client node:如果一個node 不儲存資料,那麼它在接收到請求的時候,只能從master上獲取shards列表,然後把請求轉發給相應的data node,最後再把結果轉發回去。但本質上,client node也是cluster的一部分。在這種配置時,通常是cluster內部採用9300埠的transport通訊,只留幾個client node開放9200埠的HTTP介面對外接收RestFul請求。
  
  關於ES的基礎操作在此就不列舉了,感興趣的可以參照前面的ES權威指南下載地址,下載下來仔細研究,畢竟我這裡只是普及和稍微講講理論知識和對應的應用場景罷了。
  
  另外關於資料視覺化分析工具,在此說兩個,一個是Gnuplot,另外一個是AmCharts。另外宣告一下,視覺化工具絕非這兩個,還有很多,大家可以根據自己的需求百度或Google搜尋找找。
  
  三、報警
  
  對於運維工作來說,還剩下一個更需要實時性的功能-報警。報警的方式有很多種,最常見的就是電子郵件、簡訊等。隨著通訊的發達,很多工具支援像微信告警等手段,比如我上家公司就通過Zabbix加微信聯合報警。
  
  1.SendMail
  
  郵件傳送是產品運維乃至運營工作中的很重要部分。sendEmail和postFix的配置部署也是Linux運維人員的必備技能之一。不過在監控系統中,我們可以用更簡潔易用的命令來快速完成工作。
  
  sendEmail就是這樣一個工具。下載地址:http://caspian.dotconf.net
  
  2.WebSocket
  
  在工作時間段,運維人員更經常停留在瀏覽器介面而不是郵件客戶端介面,至於手機等裝置,離視線更加遙遠,所以在這種情況下,我們可以通過瀏覽器的幫助,使用成本極低的網頁報警,同樣可以獲得很好的效果。
  
  網頁實時重新整理,是近年來最流行的技術話題之一。從運維的實際需求出發,我們不用考慮太多併發的效能問題,更需要考慮的是快捷開發,簡單上手。就此,這裡推薦開發社群的小軟體:Juggernaut。下載地址:https://github.com/maccman/juggernaut
  
  3.手機推送
  
  運維人員下班之後,尤其是在下班路上,除了傳統的簡訊報警,在移動網際網路時代,也有了更加“時髦”的處理方式,那就是:用手機APP來收報警。
  
  手機推送訊息,是很多APP都有的基礎功能。我們不需要自己從頭研究推送原理,然後實現全套系統,直接使用JPush極光推送,可以極簡單地實現這個報警功能。極光推送APP的示例:
  
  註冊賬戶->新建應用(純頁面操作,填寫應用名稱,獲取對應的Key和master secret)->下載Example包->用adt eclipse開啟eclipse專案並生成APK檔案
  
  4.分級和歸併
  
  前面三種工具,以及其他還沒有提到的各種資訊傳送渠道,都只解決了一個問題:把資訊傳遞到運維人員身邊。但這個資訊是否能有效讓運維人員對故障作出判斷並解決問題呢?
  
  實際的工作中,並不缺乏這樣的情況:半夜被報警叫醒,只是一個磁碟85%的小問題,支援到明早上上班再解決肯定沒問題,於是繼續睡覺。結果早上一看,在昨晚半小時重複一次磁碟報警,還夾著一條宕機。
  
  這就是告警設計的另一個重要方向:如何提高資訊的有效傳遞。歸納起來,就是要”有多又少"-不同意義的資訊要多,一點不能遺漏;相同的資訊要少,每條都可以引起運維人員的快速響應。
  
  一般來說,做到這點有兩個辦法:分級和歸併。
  
  其實分級告警和歸併過濾在Nagios報警設計中都有所體現,比如WARNING、CRITICAL和RECOVERY狀態的區別,主機和服務的dependency關係,報警的escalations變更等。只要用好Nagios的細節控制,就可以減少很多無謂的報警。
  
  對於非Nagios體系的監測告警,我們則需要自己動手完成。設計思路上,完全可以參考Nagios專案。實現辦法上則可以完全從告警出口處控制。一般我們使用的簡訊閘道器,都會採用MySQL作為簡訊儲存。我們可以限制MySQL資料庫的許可權,自己編寫一個簡單的HTTP服務作為簡訊告警的統一接收入口。這樣,在HTTP服務接收到資訊之後,可以先對MySQL中的近期資料進行查詢統計,一旦經過邏輯計算認為應該被歸併過濾掉,那麼在最後資訊入庫的時候,直接將SQL中是否發生的列標記為已傳送,或者自定義代表被過濾的其他數字-請注意,雖然資訊最後被過濾,但千萬不能直接丟棄掉。“被過濾”也是一種記錄,也有價值。