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> redis堵了;</code>
<code>2> kibana界面打不开或者打开之后之后一直处于Searching状态,无法正常打开日志.</code>
<code>3> kibana界面崩溃了</code>
<code>4> 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 => [</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> 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> 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 => list</code>
<code>logstash的output插件到Redis,通常情况下我们指定的数据类型为list;</code>
<code>如果你的App日志产生量在某一段时间内特别大,这个时候Redis有可能出现队列的长度几百万,这个</code>
<code>时候你应该从哪里入手以及解决呢?从以下两点入手:</code>
<code>1> 日志量不大,日志只写到Redis,但是不从Redis取,导致了只写不出.</code>
<code>2> 日志量很大,日志量写的很快,但是从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,如需转载请自行联系原作者