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偶尔会很高.
相关文章
相关标签/搜索