Deploying and Scaling Logstash


elk+redis已是目前很多中小型公司比較青睞的開源日誌蒐集組合之一,主要是因爲安裝配置簡單,社區活躍、開源免費等等.

隨着公司業務的變多,日誌量追漸增大,單節點的elk+redis已經滿足不了業務的需求,這時候擴容或許是一件非常普遍的行爲,那麼如何做到自動擴容和"縮容"呢?


先來看一張簡化版的擴譜圖

wKiom1dKsfXCwvLNAADbD9RvVYQ508.png-wh_50


在看完這張簡化版的擴譜圖之後,我們首先要明白elasticsearch cluster是如何做到Discovery的?

wKiom1dLvJ2hBrodAABsRCaZAjI791.png

Elasticsearch是一個點對點的系統,節點之間直接通信並且節點之間的關係都是對等的;

2.0版本之後,爲了安全考慮,默認禁用了multicast(組播)功能;但是Es還支持單播(unicast)方式

如果不涉及到Es性能優化,其實配置集羣相當簡單,只需要配置以下核心參數即可:

discovery.zen.ping.unicast.hosts: ["10.100.100.81", "10.100.100.82"]
# 指定Es集羣中每個節點的host地址,集羣中所有的配置保持一致.

discovery.zen.minimum_master_nodes: 2
# 指定master節點的個數(hosts / 2)+ 1
# 這裏的hosts是指集羣節點數之和.


(1) Logstash插件介紹

# logstash-shipping
logstash-input-file     # 數據源.
logstash-output-redis   # 輸出到消息隊列.
    
# logstash-indexing
logstash-input-redis    # 從消息隊列中取數據.
logstash-output-elasticsearch   # 輸入到elasticsearch 持久化存儲.


(2) 爲什麼會有這個架構呢?

2015.10 elk+redis(v1) 上線
2016.5  elk+redis(v2) 方案已定(擴譜圖)

elk_v1 上線之後 研發使用後的反應很好.
在elk_v1使用的過程中國區測試環境沒有出過問題,但是美國正式環境就經常性問題不斷?比如
1> redis堵了;
2> kibana界面打不開或者打開之後之後一直處於Searching狀態,無法正常打開日誌.
3> kibana界面崩潰了
4> es所在的機器cpu非常吃緊
主要原因是因爲美國正式環境日誌量比中國測試環境日誌量大的多,經過heap插件查看日誌量在20~40G/天

個人臨時性的解決辦法就是 elasticsearch集羣;
於是乎就"悄悄"的在美國正式環境上部署了一套3個節點的es集羣,完成後告訴大領導,大領導回覆
"3臺實例比較貴,日誌只是偶爾看.",大領導想實現一種如果哪天日誌量比較大的話我們就擴容,如果日誌量小的我們就縮容
但是要保證日誌儘可能不能丟失,因爲我們使用的亞馬遜的AWS費用比較昂貴.


(3) 如何實現動態擴容和縮容呢?


首先要明白elasticsearch集羣的原理?

wKioL1dKvwGzwaTkAADH0XoMnKA937.png

logstash-output-elasticsearch
    hosts 類型爲 數組
    默認是本地的['127.0.0.1']
    
假如你搭建了三個節點的elasticsearch集羣,並指定master和node節點,這個時候我們只需要在
output-elasticsearch插件做以下更改就可以了
hosts => ["cluster-node1", "cluster-node2", "cluster-node3"],
之後kibana連接任何一臺elasticsearch就可以完整的查看所有數據.


(3.1) 基於以上原則 我們做了改變,也就是上面的擴譜圖.

1. 每臺要蒐集日誌的機器上都運行一個logstash-shipping服務
並指定input插件爲日誌文件或日誌文件目錄
而output插件就是消息隊列redis、kafka、mq等

2. 集羣的任何一個節點上都運行logstash-indexing、redis、elasticsearch、kibana、haproxy服務.
redis就是消息隊列服務;
logstash-indexing從消息隊列中取數據並寫入到elasticsearch;
kibana從elasticserach查詢數據;

這裏有兩個問題要特別說明:
1> elasticsearch如何自動建立集羣的
# Pass an initial list of hosts to perform discovery when new node is started:
discovery.zen.ping.unicast.hosts:  ["127.0.0.1", "[::1]"]

# Prevent the "split brain" by configuring the majority of nodes (total number of nodes / 2 + 1):
discovery.zen.minimum_master_nodes: 2

因爲以上參數的都是動態可變的,因此選擇用consul-template來自動更改,然後reload服務。
關於consul-template的一些高級用法可以參考官方文檔,挺詳細的
 也可以私下交流 

2> haproxy是代理什麼服務?
haproxy是對redis服務的代理;
看以下幾個參數
logstash-output-redis host array # 解決隊列的單點故障,可以同時指定多個redis實例.
logstash-input-redis host string # 只能指定一個redis實例.
如果output-redis指定的是多個redis實例,不能解決多個redis的請求、壓力負載是均衡的,
如果這裏指定haproxy的代理redis實例的地址,用haproxy的負載均衡策略就可以解決
redis負載不均衡的問題?


擴展總結:

核心在於集羣的每個節點上都要啓動logstash-indexing、redis、elasticsearch、kibana、haproxy以上四個服務,elasticsearch和haproxy代理redis等這些動態的都是通過service discovery(consul)以及consul-template刷新完成的


單節點elk+redis性能架構瓶頸及解決辦法?

(1) Redis隊列堵了?
logstash-output-redis   
data_type => list
logstash的output插件到Redis,通常情況下我們指定的數據類型爲list;
如果你的App日誌產生量在某一段時間內特別大,這個時候Redis有可能出現隊列的長度幾百萬,這個
時候你應該從哪裏入手以及解決呢?從以下兩點入手:
1> 日誌量不大,日誌只寫到Redis,但是不從Redis取,導致了只寫不出.
2> 日誌量很大,日誌量寫的很快,但是從Redis取的很慢,導致了Redis每秒鐘都在不停的增加.


(2) 如何解決Redis隊列堵了問題?
增加線程數、增加往Es寫入的頻率和一次從Redis消費的數目
flush_size 批量寫入ES數量
idle_flush_time 批量寫入ES頻率 

(3) 如何動態監控redis隊列?
要注意監控redis隊列長度,如果長時間堆集說明elk出問題了,要儘快解決否則Redis服務有可能會掛; 
每2S檢查一下redis中數據列表長度,100次 
# redis-cli -r 100 -i 1 llen logstash:redis

(4) 什麼情況下要擴展到Es集羣?
觀察過很長時間Es對cpu的影響比較大,內存往往都挺正常的;
硬件配置4核cpu、8G內存;
如果你登錄kibana去查看日誌,然後在登錄到對應es的服務器上用top看服務器的性能,如果cpu
在300%左右或更高並且kibana界面一直處於Searching狀態,那麼建議你換Es集羣吧!
觀察io也正常、內存也正常、就是cpu偶爾會很高.


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