在生产环境中,我们为了更好的服务于业务,通常会通过优化的手段来实现服务对外的性能最大化,节省系统性能开支;关注我的朋友们都知道,前段时间一直在搞ELK,同时也记录在了个人的博客篇章中,从部署到各个服务应用的采集都做了详细的介绍,但是并没有关于ELK方面的优化,那么,我们对于这些日志分析平台,我们如何去优化呢?优化的手段又有哪些呢?下面请听我娓娓道来~

【ES优化】

ES在前面的部署环节(https://www.cnblogs.com/bixiaoyu/p/9460554.html)已经简单了提到调优,但是不全;Elasticsearch作为数据持久化存储环节,主要就是接受采集端发送过来的数据,执行写磁盘,建立索引库,最后将结构化的数据存储到ES集群上,这是ES所需要完成的工作

1.1:JVM内存的优化

首先我们需要了解什么是jvm内存?作用是什么?

jvm内存其实就是java内存堆,也是jvm需要管理的最大的一块内存空间,主要就是存放各种类型的实例对象;在java中,堆的概念被划分为,新生代和老年代,这样更有利于jvm管理内存堆中的对象,分配和回收

我们设置堆内存主要就是创建实例对象,让所有对象实例和数据都在堆上进程分配,可以动态的分配内存大小;

-Xms1g     #设置堆最小的内存
-Xmx1g    #设置堆最大的内存

如何设置最合理呢?

首先我们要知道堆内存设置的越大,ES可用的堆就越大,同时呢,可用的缓存空间就越大,但是不能无限大,因为这样会浪费大量的内存,太多的堆内存可能会系统垃圾回收机制异常;

优化准则:

将最小堆(xms)和最大堆(xmx)设置为相同值即可,这样可以防止内存堆运行的有所变动;

内存堆的值不要超过系统物理内存的50%(可以等于实际物理内存的一半),以确保有足够的物理内存给内核文件系统使用;

ES堆内存大小为什么不能超过物理 内存的50%?

除了堆内存设置过大会造成资源浪费之后,还有一个原因,

堆内存对于ES来说是个不可缺少的部分,能够对提高数据的执行效率,还有一个内存使用者,那就是是-lucene

Lucene是一个开源的全文检索引擎工具 ,而我们的ES底层是基于Lucene来实现的丰富的检索功能;Lucene的性能依赖于操作系统之间的交互,如何说我们把可用的内存都给了ES的话,那么Lucene还有剩余的内存空间吗?这将会严重的影响性能;因此,我们最多只能将50%的可用内存资源分配给ES堆内存,剩下的50%留给Lucene了

ps:这里注意一下,我们的Luceen使用的是物理内存剩余的50%,它并不使用堆内存;切记不要与ES堆内存混淆

1.2:ES所在操作系统的内存优化

可通过禁用swap·分区,如果是混合服务器的话可通过减低swap分区的使用积极性;

/dev/mapper/centos-swap swap swap defaults 0 0    #进入/etc/fstab/.将其注释,永久生效;临时生效直接swapoff -a即可

降低swao分区使用积极性,这句话是什么意思呢?首先我们要知道,系统的内存使用空间到达一定的阀值时候,便会占用swap空间,这个时候我们是可以控制这个阀值的;swappiness=0表示最大限度使用物理内存,也就是说,当物理内存使用100%之后,才去使用swap交换分区;

如何设置呢?

比如说,我们现在需要设置系统内存大小阀值,当物理内存使用90%的时候,只剩10%的物理内存,再去使用swap空间

100-10=90%

# vim /etc/sysctl.conf

vm.swappiness = 10

#修改之后执行sysctl -p生效

#cat /proc/sys/vm/swappiness
10

1.3:·硬件优化(硬盘类型/raid类型)

服务器硬盘选用SSD硬盘,配置成raid 0阵列以获得更佳的IO性能;

【Logstash优化】

logstash.yml配置优化:

1)pipline.workers:控制output或filter插件的工作线程数(只能设置为正整数),因为logstash中的grok正则及其消耗系统计算字眼,同时filte也会存在瓶颈,此时增加工作线程,以提高性能

2)pipeline.batch.size:批量执行event的最大值,该值用于input批量处理事件值,再打包发送给filter和output.可以提高性能,但是会增加额外的内存开销

3)pipeline.batch.delay:批量处理事件的最大等待值(input需要按照batch处理的最大发送到消息队列,需要设置一个超时事件)

Logstash同样运行在JVM内存中,关于jvm内存的配置原则不在述说和,和上述ES一样;

堆内存一般要求初始值和最大值设置一致,防止动态调整堆内存大小的消耗;jvm内存的分配设置太大会拖慢系统,浪费资源,设置太小的话Logstash无法启动

【Kafka的性能优化】

既然我们在ELK中用到了Kafka,那么优化也是必须的,先来回顾一下,kafka是一个高吞吐分布式消息系统,并且提供了持久化,高性能主要表现在以下两点:

第一,磁盘的连续读写性能远远高于随机读写

第二:拆分一个topic主题分配多个partition分区,这样可以提供并发和吞吐量;

另外,我们的kafka消息读写为什么这么高效?原因何在?

我们要知道linux系统内核为文件设置一个缓存机制,所有对文件读写的数据内容都会存在着缓存中,称之为:page cache(页缓存)

缓存 机制:

当一个文件发生读操作时,系统会先去page cache页缓存中读取,如果找到,便会直接返回,没有缓存中没有需要读取的数据内容,那么会去磁盘中读取,此时系统写入一份到缓存中。,最终返回数据;

当有写操作时,亦是如此,数据会首先写入缓存并进行标识,等待批量保存到文件系统,减少了磁盘的操作次数和系统额外开销

我们的kafka就是依赖于这种机制,数据的读写交互便是在缓存中完成接力,不会因为kafka写入磁盘数据影响吞吐量,这就是为什么kafka非常高效的根本原因

降低文件系统页面缓存

主要针对于下面两个参数

vm.dirty_background_ratio:  #指定了当文件系统缓存页数量达到系统内存的百分比阀值的时候,便会触发pdflush/flush/kdmflush后台运行写进程,将一定的缓存数据写入磁盘中

vm.dirty_ratio:             #指定了当文件系统缓存页熟练达到系统设定的百分比阀值时候,为了保证避免数据丢失,系统不得不开始处理缓存页面,在这个过程中,可能很多应用会因为系统刷新内存数据,导致应用IO进程阻塞;这个时候呢,系统就会转入同时处理页缓存和堵塞应用

ps:建议将vm.dirty_background_ratio设置为5%,vm.diry_ratio设置为10%;根据不同环境,需要进行测试而定

topic的拆分:

kafka读写单位是partition,将一个topic分配到多个partition可以提高系统的吞吐量,但前提是将不同的partition分配到不同的磁盘上,如果多个partition位于一个磁盘上就会出现多个进程同时对磁盘上多个文件进行读写,这样造成了磁盘的频繁调度,破坏了磁盘读写的连续性

如何实现将不同的partition分配到不同的磁盘上呢?

我们可以将磁盘上的多个目录配置到broker的log.dirs上

# vim /usr/local/kafka/config/server.properties 

log.dirs=/disk1/logs,/disk2/logs/,/disk3/logs    #kafaka在新建partition时,会将partition分布在paritition最少的目录上面,因此,不能将同一个磁盘上的多个目录设置到logs.dirs上

kafka配置参数优化:

num.network.threads=3    #broker处理消息的最大线程数

num.io.threads=8      #broker处理磁盘IO的线程数

一般num.network.threads主要就是处理网络IO,读写缓冲区数据,基本没有IO等待,配置线程数量为CPU核数n+1

num.io.threads主要进行磁盘IO操作,高峰期可以能有些等待,因此配置较大一点,配置线程数量为CPU核数的2~3倍即可

日志保留策略优化:

kafka被打量的写入日志消息后,会生成打量的数据文件,也就是日志消息,这样会占用大量的磁盘空间。

减少日志保留时间,通过log.retention.hours设置,单位是小时

log.retention.hours=72    #保留日志数据的时间范围,过后便会删除

段文件大小优化

段文件配置大小为1GB,这样有利于快速的回收磁盘空间,重启kafka加载也会更快,如果说文件过小,那么文件数量就会较多,kafka启动的时候回单线扫描(log.dir)下的所有文件,文件较多启动较慢,会影响性能,

log.segment.bytes=1073741824    #段文件最大大小,超过该阀值,会自动创建新的日志段

Logs数据文件写盘策略优化

为了大幅度提高producer写入吞吐量,需要制定定期批量写入文件磁盘的计划

每当producer写入10000条消息事,便会将数据写入磁盘,

#log.flush.interval.messages=10000   #强行将数据刷新到磁盘之前所能接受的消息数

#log.flush.interval.ms=1000       #在强制刷新之前,消息可以停留在日志中最长的时间(单位毫秒,每间隔1秒时间,刷数据到磁盘中)

【Filebeat优化】

还记得我们为什么要使用filebeat采集日志数据吗?那是因为Logstash功能虽然强大,但是它依赖于java,在海量日志环境中,logstash进程会消耗更多的系统资源,这将严重的影响业务系统的性能,而我们说的filebeat是基于go语言,没有任何依赖,配置简单,占用系统资源少,比logstash更加的轻量级;但是有点还是需要注意。在日志量比较大的情况下或者日志异常突发时,filebeat也会占用大量的系统内存开销,所以说这方面的优化,也是至关重要的

内存优化,Filebeat内存收到两种模式的限制,一种是内存模式,第二种是文件缓存模式,任选其一即可

queue.mem:
events: #表示队列可以存储的事件数量。默认值是4096个事件。
flush.min_events: #发布所需的最小事件数量。 默认值是0,表示可以直接输出发布事件,而无需额外的等待时间。 如果设置为非0,必须等待,在满足指定的事件数量后才能输出发布事件。
flush.timeout: 5s #表示最早的可用事件在队列中等待的最长时间,超过这个时间,立即输出发布事件,默认值是0s,表示立即可以输出发布事件

配置含义:该队列能够存储4096个事件数量,如果超过512个可用的事件则在队列中等待5秒之后,将事件转发至output输出

文件缓存模式调优

此模式可以限制最大的使用内存

ueue.spool:
file:
path: "${path.data}/spool.dat" #Spool file的路径
size: 512MiB #Spool file的大小,也就是缓冲区的大小。
page_size: 16KiB #文件的页面大小。默认值为4096(4KiB)。
write:
buffer_size: 10MiB #写缓冲区大小。一旦超过缓冲区大小,就刷新写缓冲区。
flush.timeout: 5s #写缓冲区中最旧事件的最长等待时间。如果设置为0,则在write.flush.events或write.buffer_size满足时写入缓冲区仅刷新一次。
flush.events: #缓冲事件的数量。一旦达到上限,就刷新写缓冲区。

文件系统资源的优化:

fliebeat对日志的采集有一个弊端,那就是只要发现日志就会坚持把日志收集完,否则的话就会永久锁住文件句柄不放手,就算日志文件被删除,也不会放手,这就导致了文件系统大量的文件句柄被filebeat占用,导致收集日志异常,故此对其进行优化

1)close_inactive:1m   #表示没有新日志采集后,多长时间关闭文件句柄;(也就是说无数据采集时候,等待多长时间便会自动关闭文件句柄),这里设置1分钟

2)close_timeout:3h    #限定的数据传输时间,这里是指传输了三小时就强行关闭文件句柄,该配置解决了文件句柄耗尽的问题,但也存在着数据丢失的风险,需要综合考虑

3)clean_inactive:72h   #表示多久会清理一次文件描述符在registry文件,默认值0表示不清理,如果不清理,registry会变大,带来性能问题

4)ignore_older:70h    #设置了clean_inactive,就需要设置ignore_older,并且保证该值小于clean_inactive

[小结]

关于ELK综合方面的优化,也就介绍这么多了,其实ELK的优化方面很少,我个人觉得已经足够了,主要就是针对不同的环境和业务需求进行调参,调整适合自己的才是最好的,当然前提是你要知参数的各个含义;优化也是一个综合的技术,

无论什么服务,我们能做到的优化点无非就是硬件,系统以及服务配置的调参;逐步测试,一步步达到最优的状态;这是进行优化的基本策略和思路(ps:本章可能还有很多优化策略没有写到,欢迎大佬填坑补充~)

1002-谈谈ELK日志分析平台的性能优化理念的更多相关文章

  1. 浅谈ELK日志分析平台

    作者:珂珂链接:https://zhuanlan.zhihu.com/p/22104361来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 小编的话 “技术干货”系列文章 ...

  2. 搭建ELK日志分析平台(上)—— ELK介绍及搭建 Elasticsearch 分布式集群

    笔记内容:搭建ELK日志分析平台(上)-- ELK介绍及搭建 Elasticsearch 分布式集群笔记日期:2018-03-02 27.1 ELK介绍 27.2 ELK安装准备工作 27.3 安装e ...

  3. ELK日志分析平台.1-搭建

    ELK日志分析平台.1-搭建 2017-12-28 | admin 一.简介1.核心组成    ELK由Elasticsearch.Logstash和Kibana三部分组件组成:    Elastic ...

  4. ELK日志分析平台

    ELK日志分析平台 ELK(1):  ELK-简介 ELK(2):  ELK-安装环境和安装包 ELK(3):  ELK-安装elasticsearch ELK(4):  ELK-安装logstash ...

  5. elk日志分析平台安装

    ELK安装 前言 什么是ELK? 通俗来讲,ELK是由Elasticsearch.Logstash.Kibana 三个开源软件的组成的一个组合体,这三个软件当中,每个软件用于完成不同的功能,ELK 又 ...

  6. ELK日志分析平台系统windows环境搭建和基本使用

    ELK(ElasticSearch, Logstash, Kibana),三者组合在一起就可以搭建实时的日志分析平台啦! Logstash主要用来收集.过滤日志信息并将其存储,所以主要用来提供信息. ...

  7. ELK日志分析平台搭建

    ELK平台介绍 在搜索ELK资料的时候,发现这篇文章比较好,于是摘抄一小段: 以下内容来自:http://baidu.blog.51cto.com/71938/1676798 日志主要包括系统日志.应 ...

  8. ELK日志分析平台环境部署 (yum安装)

    前言:通常体质被分散存储在不同的设备上面,在庞大的服务器集群中,我们需要集中化的管理,日志的统计和检索,一般我们使用grep和awk,wc等linux命令虽然能够实现检索和统计,但是呢,对于要求更高的 ...

  9. 在Windows系统下搭建ELK日志分析平台

    简介: ELK由ElasticSearch.Logstash和Kiabana三个开源工具组成: Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索 ...

随机推荐

  1. 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建一:建立MAVEN Web项目

    一:创建maven web项目er

  2. CF1059C Sequence Transformation

    原题链接 题目大意 读入一个正整数\(n\).你有一个长度为\(n\)的排列.对于一次操作,我们需要做一下几步: 1.将目前序列内所有数的\(gcd\)加入答案中 2.将序列内随意删除一个数 3.如果 ...

  3. (二叉树 递归) leetcode 144. Binary Tree Preorder Traversal

    Given a binary tree, return the preorder traversal of its nodes' values. Example: Input: [1,null,2,3 ...

  4. 1.5分布式通讯框架-RMI

    分布式通信框架-RMI讲解 什么是RPC Remote procedure call protocal RPC协议其实是一个规范.常用PRC框架:Dubbo.Thrif.RMI.Webservice. ...

  5. spring boot本地调试服务器部署项目

    项目本地测试然后发布到服务器上,各种BUG层出不穷.那么下面配置下,然后在本地调试部署在服务器上的程序吧 一.首先idea打开你的项目,服务器上传打包的程序.然后如下命令启动(linux),绿色参数为 ...

  6. vue 开发微信小程序

    介绍 mpvue (github 地址请参见)是一个使用 Vue.js 开发小程序的前端框架.框架基于 Vue.js 核心,mpvue 修改了 Vue.js的 runtime 和 compiler 实 ...

  7. jpa返回List<Map<String, Object>>相当于jdbctemplate的queryForlist

    public class Test(){ @PersistenceContext(unitName = "manageFactory") protected EntityManag ...

  8. Luogu P4321 随机漫游

    期望DP要倒着推 Luogu P4321 题意 LOJ #2542 不一定是树,询问点不一定均为1 $Solution$ 设计一个巧妙的DP状态 设$ F(S,x)$表示当前在点$ x$已经走遍了$ ...

  9. Leetcode#191. Number of 1 Bits(位1的个数)

    题目描述 编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量). 示例 : 输入: 11 输出: 3 解释: 整数 11 的二进制表示为 000000 ...

  10. Django REST Framework API Guide 07

    本节大纲 1.Permissions 2.Throttling Permissions 权限是用来授权或者拒绝用户访问API的不同部分的不同的类的.基础的权限划分 1.IsAuthenticated ...