天天看點

Deploying and Scaling Logstash

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

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

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

<a href="http://s1.51cto.com/wyfs02/M00/82/13/wKiom1dKsfXCwvLNAADbD9RvVYQ508.png-wh_500x0-wm_3-wmp_4-s_1109204964.png" target="_blank"></a>

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

<a href="http://s1.51cto.com/wyfs02/M00/82/18/wKiom1dLvJ2hBrodAABsRCaZAjI791.png" target="_blank"></a>

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

2.0版本之後,為了安全考慮,預設禁用了multicast(多點傳播)功能;但是Es還支援單點傳播(unicast)方式

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

1

2

3

4

5

6

<code>discovery.zen.</code><code>ping</code><code>.unicast.hosts: [</code><code>"10.100.100.81"</code><code>, </code><code>"10.100.100.82"</code><code>]</code>

<code># 指定Es叢集中每個節點的host位址,叢集中所有的配置保持一緻.</code>

<code>discovery.zen.minimum_master_nodes: 2</code>

<code># 指定master節點的個數(hosts / 2)+ 1</code>

<code># 這裡的hosts是指叢集節點數之和.</code>

(1) Logstash插件介紹

7

<code># logstash-shipping</code>

<code>logstash-input-</code><code>file</code>     <code># 資料源.</code>

<code>logstash-output-redis   </code><code># 輸出到消息隊列.</code>

<code>    </code> 

<code># logstash-indexing</code>

<code>logstash-input-redis    </code><code># 從消息隊列中取資料.</code>

<code>logstash-output-elasticsearch   </code><code># 輸入到elasticsearch 持久化存儲.</code>

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

8

9

10

11

12

13

14

15

<code>2015.10 elk+redis(v1) 上線</code>

<code>2016.5  elk+redis(v2) 方案已定(擴譜圖)</code>

<code>elk_v1 上線之後 研發使用後的反應很好.</code>

<code>在elk_v1使用的過程中國區測試環境沒有出過問題,但是美國正式環境就經常性問題不斷?比如</code>

<code>1&gt; redis堵了;</code>

<code>2&gt; kibana界面打不開或者打開之後之後一直處于Searching狀态,無法正常打開日志.</code>

<code>3&gt; kibana界面崩潰了</code>

<code>4&gt; es所在的機器cpu非常吃緊</code>

<code>主要原因是因為美國正式環境日志量比中國測試環境日志量大的多,經過heap插件檢視日志量在20~40G/天</code>

<code>個人臨時性的解決辦法就是 elasticsearch叢集;</code>

<code>于是乎就</code><code>"悄悄"</code><code>的在美國正式環境上部署了一套3個節點的es叢集,完成後告訴大上司,大上司回複</code>

<code>"3台執行個體比較貴,日志隻是偶爾看."</code><code>,大上司想實作一種如果哪天日志量比較大的話我們就擴容,如果日志量小的我們就縮容</code>

<code>但是要保證日志盡可能不能丢失,因為我們使用的亞馬遜的AWS費用比較昂貴.</code>

(3) 如何實作動态擴容和縮容呢?

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

<code>logstash-output-elasticsearch</code>

<code>    </code><code>hosts 類型為 數組</code>

<code>    </code><code>預設是本地的[</code><code>'127.0.0.1'</code><code>]</code>

<code>假如你搭建了三個節點的elasticsearch叢集,并指定master和node節點,這個時候我們隻需要在</code>

<code>output-elasticsearch插件做以下更改就可以了</code>

<code>hosts =&gt; [</code><code>"cluster-node1"</code><code>, </code><code>"cluster-node2"</code><code>, </code><code>"cluster-node3"</code><code>],</code>

<code>之後kibana連接配接任何一台elasticsearch就可以完整的檢視所有資料.</code>

<a href="http://s1.51cto.com/wyfs02/M01/82/12/wKioL1dKvcvwGNi8AADH0XoMnKA424.png-wh_500x0-wm_3-wmp_4-s_2246500349.png" target="_blank"></a>

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

16

17

18

19

20

21

22

23

24

25

26

27

28

29

<code>1. 每台要搜集日志的機器上都運作一個logstash-shipping服務</code>

<code>并指定input插件為日志檔案或日志檔案目錄</code>

<code>而output插件就是消息隊列redis、kafka、mq等</code>

<code>2. 叢集的任何一個節點上都運作logstash-indexing、redis、elasticsearch、kibana、haproxy服務.</code>

<code>redis就是消息隊列服務;</code>

<code>logstash-indexing從消息隊列中取資料并寫入到elasticsearch;</code>

<code>kibana從elasticserach查詢資料;</code>

<code>這裡有兩個問題要特别說明:</code>

<code>1&gt; elasticsearch如何自動建立叢集的</code>

<code># Pass an initial list of hosts to perform discovery when new node is started:</code>

<code>discovery.zen.ping.unicast.hosts:  [</code><code>"127.0.0.1"</code><code>, </code><code>"[::1]"</code><code>]</code>

<code># Prevent the "split brain" by configuring the majority of nodes (total number of nodes / 2 + 1):</code>

<code>因為以上參數的都是動态可變的,是以選擇用consul-</code><code>template</code><code>來自動更改,然後reload服務。</code>

<code>關于consul-</code><code>template</code><code>的一些進階用法可以參考官方文檔,挺詳細的</code>

<code> </code><code>也可以私下交流 </code>

<code>2&gt; haproxy是代理什麼服務?</code>

<code>haproxy是對redis服務的代理;</code>

<code>看以下幾個參數</code>

<code>logstash-output-redis host array # 解決隊列的單點故障,可以同時指定多個redis執行個體.</code>

<code>logstash-input-redis host string # 隻能指定一個redis執行個體.</code>

<code>如果output-redis指定的是多個redis執行個體,不能解決多個redis的請求、壓力負載是均衡的,</code>

<code>如果這裡指定haproxy的代理redis執行個體的位址,用haproxy的負載均衡政策就可以解決</code>

<code>redis負載不均衡的問題?</code>

<code></code>

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

<code>(1) Redis隊列堵了?</code>

<code>logstash-output-redis   </code>

<code>data_type =&gt; list</code>

<code>logstash的output插件到Redis,通常情況下我們指定的資料類型為list;</code>

<code>如果你的App日志産生量在某一段時間内特别大,這個時候Redis有可能出現隊列的長度幾百萬,這個</code>

<code>時候你應該從哪裡入手以及解決呢?從以下兩點入手:</code>

<code>1&gt; 日志量不大,日志隻寫到Redis,但是不從Redis取,導緻了隻寫不出.</code>

<code>2&gt; 日志量很大,日志量寫的很快,但是從Redis取的很慢,導緻了Redis每秒鐘都在不停的增加.</code>

<code>(2) 如何解決Redis隊列堵了問題?</code>

<code>增加線程數、增加往Es寫入的頻率和一次從Redis消費的數目</code>

<code>flush_size 批量寫入ES數量</code>

<code>idle_flush_time 批量寫入ES頻率 </code>

<code>(3) 如何動态監控redis隊列?</code>

<code>要注意監控redis隊列長度,如果長時間堆集說明elk出問題了,要盡快解決否則Redis服務有可能會挂; </code>

<code>每2S檢查一下redis中資料清單長度,100次 </code>

<code># redis-cli -r 100 -i 1 llen logstash:redis</code>

<code>(4) 什麼情況下要擴充到Es叢集?</code>

<code>觀察過很長時間Es對cpu的影響比較大,記憶體往往都挺正常的;</code>

<code>硬體配置4核cpu、8G記憶體;</code>

<code>如果你登入kibana去檢視日志,然後在登入到對應es的伺服器上用</code><code>top</code><code>看伺服器的性能,如果cpu</code>

<code>在300%左右或更高并且kibana界面一直處于Searching狀态,那麼建議你換Es叢集吧!</code>

<code>觀察io也正常、記憶體也正常、就是cpu偶爾會很高.</code>

     本文轉自zys467754239 51CTO部落格,原文連結:http://blog.51cto.com/467754239/1784253,如需轉載請自行聯系原作者

繼續閱讀