Deploying and Scaling Logstash


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

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


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

wKiom1dKsfXCwvLNAADbD9RvVYQ508.png-wh_50


在看完這張簡化版的擴譜圖以後,咱們首先要明白elasticsearch cluster是如何作到Discovery的?安全

wKiom1dLvJ2hBrodAABsRCaZAjI791.png

Elasticsearch是一個點對點的系統,節點之間直接通訊而且節點之間的關係都是對等的;性能優化

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

若是不涉及到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


首先要明白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偶爾會很高.
相關文章
相關標籤/搜索