Deploying and Scaling Logstash

  1. 云栖社区>
  2. 博客>
  3. 正文

Deploying and Scaling Logstash

技术小胖子 2017-11-16 20:35:00 浏览703
展开阅读全文

elk+redis已是目前很多中小型公司比较青睐的开源日志搜集组合之一,主要是因为安装配置简单,社区活跃、开源免费等等.

随着公司业务的变多,日志量追渐增大,单节点的elk+redis已经满足不了业务的需求,这时候扩容或许是一件非常普遍的行为,那么如何做到自动扩容和"缩容"呢?


先来看一张简化版的扩谱图

wKiom1dKsfXCwvLNAADbD9RvVYQ508.png-wh_50


在看完这张简化版的扩谱图之后,我们首先要明白elasticsearch cluster是如何做到Discovery的?

wKiom1dLvJ2hBrodAABsRCaZAjI791.png

Elasticsearch是一个点对点的系统,节点之间直接通信并且节点之间的关系都是对等的;

2.0版本之后,为了安全考虑,默认禁用了multicast(组播)功能;但是Es还支持单播(unicast)方式

如果不涉及到Es性能优化,其实配置集群相当简单,只需要配置以下核心参数即可:

1
2
3
4
5
6
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插件介绍

1
2
3
4
5
6
7
# logstash-shipping
logstash-input-file     # 数据源.
logstash-output-redis   # 输出到消息队列.
     
# logstash-indexing
logstash-input-redis    # 从消息队列中取数据.
logstash-output-elasticsearch   # 输入到elasticsearch 持久化存储.


(2) 为什么会有这个架构呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

1
2
3
4
5
6
7
8
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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刷新完成的


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
(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偶尔会很高.









     本文转自zys467754239 51CTO博客,原文链接:http://blog.51cto.com/467754239/1784253,如需转载请自行联系原作者

网友评论

登录后评论
0/500
评论
技术小胖子
+ 关注