本文收录在Linux运维企业架构实战系列

做了几周的测试,踩了无数的坑,总结一下,全是干货,给大家分享~

一、elk 实用知识点总结

1、编码转换问题(主要就是中文乱码)

(1)input 中的codec => plain 转码

codec => plain {
charset => "GB2312"
}

将GB2312 的文本编码,转为UTF-8 的编码

(2)也可以在filebeat中实现编码的转换(推荐)

filebeat.prospectors:
- input_type: log
paths:
- c:\Users\Administrator\Desktop\performanceTrace.txt
encoding: GB2312

2、删除多余日志中的多余行

(1)logstash filter 中drop 删除

    if ([message] =~ "^20.*-\ task\ request,.*,start\ time.*") {   #用正则需删除的多余行
drop {}

(2)日志示例

2018-03-20 10:44:01,523 [33]DEBUG Debug - task request,task Id:1cbb72f1-a5ea-4e73-957c-6d20e9e12a7a,start time:2018-03-20 10:43:59   #需删除的行
-- Request String : {"UserName":"15046699923","Pwd":"ZYjyh727","DeviceType":2,"DeviceId":"PC-20170525SADY","EquipmentNo":null,"SSID":"pc","RegisterPhones":null,"AppKey":"ab09d78e3b2c40b789ddfc81674bc24deac","Version":"2.0.5.3"} -- End
-- Response String : {"ErrorCode":0,"Success":true,"ErrorMsg":null,"Result":null,"WaitInterval":30} -- End

3、grok 处理多种日志不同的行

(1)日志示例:

2018-03-20 10:44:01,523 [33]DEBUG Debug - task request,task Id:1cbb72f1-a5ea-4e73-957c-6d20e9e12a7a,start time:2018-03-20 10:43:59
-- Request String : {"UserName":"15046699923","Pwd":"ZYjyh727","DeviceType":2,"DeviceId":"PC-20170525SADY","EquipmentNo":null,"SSID":"pc","RegisterPhones":null,"AppKey":"ab09d78e3b2c40b789ddfc81674bc24deac","Version":"2.0.5.3"} -- End
-- Response String : {"ErrorCode":0,"Success":true,"ErrorMsg":null,"Result":null,"WaitInterval":30} -- End

(2)在logstash filter中grok 分别处理3行

match => {
"message" => "^20.*-\ task\ request,.*,start\ time\:%{TIMESTAMP_ISO8601:RequestTime}"
match => {
"message" => "^--\ Request\ String\ :\ \{\"UserName\":\"%{NUMBER:UserName:int}\",\"Pwd\":\"(?<Pwd>.*)\",\"DeviceType\":%{NUMBER:DeviceType:int},\"DeviceId\":\"(?<DeviceId>.*)\",\"EquipmentNo\":(?<EquipmentNo>.*),\"SSID\":(?<SSID>.*),\"RegisterPhones\":(?<RegisterPhones>.*),\"AppKey\":\"(?<AppKey>.*)\",\"Version\":\"(?<Version>.*)\"\}\ --\ \End.*"
}
match => {
"message" => "^--\ Response\ String\ :\ \{\"ErrorCode\":%{NUMBER:ErrorCode:int},\"Success\":(?<Success>[a-z]*),\"ErrorMsg\":(?<ErrorMsg>.*),\"Result\":(?<Result>.*),\"WaitInterval\":%{NUMBER:WaitInterval:int}\}\ --\ \End.*"
}
... 等多行

4、日志多行合并处理—multiline插件(重点)

(1)示例:

① 日志

2018-03-20 10:44:01,523 [33]DEBUG Debug - task request,task Id:1cbb72f1-a5ea-4e73-957c-6d20e9e12a7a,start time:2018-03-20 10:43:59
-- Request String : {"UserName":"15046699923","Pwd":"ZYjyh727","DeviceType":2,"DeviceId":"PC-20170525SADY","EquipmentNo":null,"SSID":"pc","RegisterPhones":null,"AppKey":"ab09d78e3b2c40b789ddfc81674bc24deac","Version":"2.0.5.3"} -- End
-- Response String : {"ErrorCode":0,"Success":true,"ErrorMsg":null,"Result":null,"WaitInterval":30} -- End

② logstash grok 对合并后多行的处理(合并多行后续都一样,如下)

filter {
  grok {
    match => {
      "message" => "^%{TIMESTAMP_ISO8601:InsertTime}\ .*-\ task\ request,.*,start\ time:%{TIMESTAMP_ISO8601:RequestTime}\n--\ Request\ String\ :\ \{\"UserName\":\"%{NUMBER:UserName:int}\",\"Pwd\":\"(?<Pwd>.*)\",\"DeviceType\":%{NUMBER:DeviceType:int},\"DeviceId\":\"(?<DeviceId>.*)\",\"EquipmentNo\":(?<EquipmentNo>.*),\"SSID\":(?<SSID>.*),\"RegisterPhones\":(?<RegisterPhones>.*),\"AppKey\":\"(?<AppKey>.*)\",\"Version\":\"(?<Version>.*)\"\}\ --\ \End\n--\ Response\ String\ :\ \{\"ErrorCode\":%{NUMBER:ErrorCode:int},\"Success\":(?<Success>[a-z]*),\"ErrorMsg\":(?<ErrorMsg>.*),\"Result\":(?<Result>.*),\"WaitInterval\":%{NUMBER:WaitInterval:int}\}\ --\ \End"
    }
  }
}

(2)在filebeat中使用multiline 插件(推荐)

① 介绍multiline

pattern:正则匹配从哪行合并

negate:true/false,匹配到pattern 部分开始合并,还是不配到的合并

match:after/before(需自己理解)

  after:匹配到pattern 部分后合并,注意:这种情况最后一行日志不会被匹配处理

  before:匹配到pattern 部分前合并(推荐)

② 5.5版本之后(before为例)

filebeat.prospectors:
- input_type: log
paths:
- /root/performanceTrace*
fields:
type: zidonghualog
multiline.pattern: '.*\"WaitInterval\":.*--\ End'
multiline.negate: true
multiline.match: before

③ 5.5版本之前(after为例)

filebeat.prospectors:
- input_type: log
paths:
- /root/performanceTrace*
input_type: log
multiline:
pattern: '^20.*'
negate: true
match: after

(3)在logstash input中使用multiline 插件(没有filebeat 时推荐)

① 介绍multiline

pattern:正则匹配从哪行合并

negate:true/false,匹配到pattern 部分开始合并,还是不配到的合并

what:previous/next(需自己理解)

  previous:相当于filebeat 的after

  next:相当于filebeat 的before

② 用法

input {
file {
path => ["/root/logs/log2"]
start_position => "beginning"
codec => multiline {
pattern => "^20.*"
negate => true
what => "previous"
}
}
}

(4)在logstash filter中使用multiline 插件(不推荐)

(a)不推荐的原因:

  ① filter设置multiline后,pipline worker会自动将为1

  ② 5.5 版本官方把multiline 去除了,要使用的话需下载,下载命令如下:

  /usr/share/logstash/bin/logstash-plugin install logstash-filter-multiline

(b)示例:

filter {
multiline {
pattern => "^20.*"
negate => true
what => "previous"
}

5、logstash filter 中的date使用

(1) 日志示例

2018-03-20 10:44:01 [33]DEBUG Debug - task request,task Id:1cbb72f1-a5ea-4e73-957c-6d20e9e12a7a,start time:2018-03-20 10:43:59

(2) date 使用

        date {
match => ["InsertTime","YYYY-MM-dd HH:mm:ss "]
remove_field => "InsertTime"
}

注:

match => ["timestamp" ,"dd/MMM/YYYY H:m:s Z"]

  匹配这个字段,字段的格式为:日日/月月月/年年年年 时/分/秒 时区

也可以写为:match => ["timestamp","ISO8601"](推荐)

(3)date 介绍

  就是将匹配日志中时间的key 替换为@timestamp 的时间,因为@timestamp 的时间是日志送到logstash 的时间,并不是日志中真正的时间。

6、对多类日志分类处理(重点)

① 在filebeat 的配置中添加type 分类

filebeat:
prospectors:
-
paths:
#- /mnt/data/WebApiDebugLog.txt*
- /mnt/data_total/WebApiDebugLog.txt*
fields:
type: WebApiDebugLog_total
-
paths:
- /mnt/data_request/WebApiDebugLog.txt*
#- /mnt/data/WebApiDebugLog.txt*
fields:
type: WebApiDebugLog_request
-
paths:
- /mnt/data_report/WebApiDebugLog.txt*
#- /mnt/data/WebApiDebugLog.txt*
fields:
type: WebApiDebugLog_report

② 在logstash filter中使用if,可进行对不同类进行不同处理

filter {
if [fields][type] == "WebApiDebugLog_request" { #对request 类日志
if ([message] =~ "^20.*-\ task\ report,.*,start\ time.*") { #删除report 行
drop {}
}
grok {
match => {"... ..."}
}
}

③ 在logstash output中使用if

if [fields][type] == "WebApiDebugLog_total" {
elasticsearch {
hosts => ["6.6.6.6:9200"]
index => "logstashl-WebApiDebugLog_total-%{+YYYY.MM.dd}"
document_type => "WebApiDebugLog_total_logs"
} 

二、对elk 整体性能的优化

1、性能分析

(1)服务器硬件Linux:1cpu 4GRAM

假设每条日志250 Byte

(2)分析

① logstash-Linux:1cpu 4GRAM

每秒500条日志

去掉ruby每秒660条日志

去掉grok后每秒1000条数据

 filebeat-Linux:1cpu 4GRAM

每秒2500-3500条数据

每天每台机器可处理:24h*60min*60sec*3000*250Byte=64,800,000,000Bytes,约64G

③ 瓶颈在logstash 从redis中取数据存入ES,开启一个logstash,每秒约处理6000条数据;开启两个logstash,每秒约处理10000条数据(cpu已基本跑满);

④ logstash的启动过程占用大量系统资源,因为脚本中要检查java、ruby以及其他环境变量,启动后资源占用会恢复到正常状态。

2、关于收集日志的选择:logstash/filter

(1)没有原则要求使用filebeat或logstash,两者作为shipper的功能是一样的,区别在于:

① logstash由于集成了众多插件,如grok,ruby,所以相比beat是重量级的;

② logstash启动后占用资源更多,如果硬件资源足够则无需考虑二者差异;

③ logstash基于JVM,支持跨平台;而beat使用golang编写,AIX不支持;

④ AIX 64bit平台上需要安装jdk(jre) 1.7 32bit,64bit的不支持;

⑤ filebeat可以直接输入到ES,但是系统中存在logstash直接输入到ES的情况,这将造成不同的索引类型造成检索复杂,最好统一输入到els 的源。

(2)总结

  logstash/filter 总之各有千秋,但是,我推荐选择:在每个需要收集的日志服务器上配置filebeat,因为轻量级,用于收集日志;再统一输出给logstash,做对日志的处理;最后统一由logstash 输出给els。

3、logstash的优化相关配置

(1)可以优化的参数,可根据自己的硬件进行优化配置

① pipeline 线程数,官方建议是等于CPU内核数

默认配置 ---> pipeline.workers: 2

可优化为 ---> pipeline.workers: CPU内核数(或几倍cpu内核数)

② 实际output 时的线程数

默认配置 ---> pipeline.output.workers: 1

可优化为 ---> pipeline.output.workers: 不超过pipeline 线程数

③ 每次发送的事件数

默认配置 ---> pipeline.batch.size: 125

可优化为 ---> pipeline.batch.size: 1000

④ 发送延时

默认配置 ---> pipeline.batch.delay: 5

可优化为 ---> pipeline.batch.size: 10

(2)总结

  通过设置-w参数指定pipeline worker数量,也可直接修改配置文件logstash.yml。这会提高filter和output的线程数,如果需要的话,将其设置为cpu核心数的几倍是安全的,线程在I/O上是空闲的。

  默认每个输出在一个pipeline worker线程上活动,可以在输出output 中设置workers设置,不要将该值设置大于pipeline worker数。

  还可以设置输出的batch_size数,例如ES输出与batch size一致。

  filter设置multiline后,pipline worker会自动将为1,如果使用filebeat,建议在beat中就使用multiline,如果使用logstash作为shipper,建议在input 中设置multiline,不要在filter中设置multiline。

(3)Logstash中的JVM配置文件

  Logstash是一个基于Java开发的程序,需要运行在JVM中,可以通过配置jvm.options来针对JVM进行设定。比如内存的最大最小、垃圾清理机制等等。JVM的内存分配不能太大不能太小,太大会拖慢操作系统。太小导致无法启动。默认如下:

-Xms256m #最小使用内存

-Xmx1g #最大使用内存

4、引入Redis 的相关问题

(1)filebeat可以直接输入到logstash(indexer),但logstash没有存储功能,如果需要重启需要先停所有连入的beat,再停logstash,造成运维麻烦;另外如果logstash发生异常则会丢失数据;引入Redis作为数据缓冲池,当logstash异常停止后可以从Redis的客户端看到数据缓存在Redis中;

(2)Redis可以使用list(最长支持4,294,967,295条)或发布订阅存储模式;

(3)redis 做elk 缓冲队列的优化:

① bind 0.0.0.0 #不要监听本地端口

② requirepass ilinux.io #加密码,为了安全运行

③ 只做队列,没必要持久存储,把所有持久化功能关掉:快照(RDB文件)和追加式文件(AOF文件),性能更好

  save "" 禁用快照

  appendonly no 关闭RDB

④ 把内存的淘汰策略关掉,把内存空间最大

  maxmemory 0 #maxmemory为0的时候表示我们对Redis的内存使用没有限制

5、elasticsearch 节点优化配置

(1)服务器硬件配置,OS 参数

(a) /etc/sysctl.conf 配置

vim /etc/sysctl.conf

① vm.swappiness = 1                     #ES 推荐将此参数设置为 1,大幅降低 swap 分区的大小,强制最大程度的使用内存,注意,这里不要设置为 0, 这会很可能会造成 OOM
② net.core.somaxconn = 65535 #定义了每个端口最大的监听队列的长度
③ vm.max_map_count= 262144 #限制一个进程可以拥有的VMA(虚拟内存区域)的数量。虚拟内存区域是一个连续的虚拟地址空间区域。当VMA 的数量超过这个值,OOM
④ fs.file-max = 518144 #设置 Linux 内核分配的文件句柄的最大数量

[root@elasticsearch]# sysctl -p 生效一下

(b)limits.conf 配置

vim /etc/security/limits.conf

elasticsearch    soft    nofile          65535
elasticsearch hard nofile 65535
elasticsearch soft memlock unlimited
elasticsearch hard memlock unlimited

(c)为了使以上参数永久生效,还要设置两个地方

vim /etc/pam.d/common-session-noninteractive

vim /etc/pam.d/common-session

添加如下属性:

session required pam_limits.so

可能需重启后生效

(2)elasticsearch 中的JVM配置文件

-Xms2g

-Xmx2g

① 将最小堆大小(Xms)和最大堆大小(Xmx)设置为彼此相等。

② Elasticsearch可用的堆越多,可用于缓存的内存就越多。但请注意,太多的堆可能会使您长时间垃圾收集暂停。

③ 设置Xmx为不超过物理RAM的50%,以确保有足够的物理内存留给内核文件系统缓存。

④ 不要设置Xmx为JVM用于压缩对象指针的临界值以上;确切的截止值有所不同,但接近32 GB。不要超过32G,如果空间大,多跑几个实例,不要让一个实例太大内存

(3)elasticsearch 配置文件优化参数

① vim elasticsearch.yml

bootstrap.memory_lock: true  #锁住内存,不使用swap
#缓存、线程等优化如下
bootstrap.mlockall: true
transport.tcp.compress: true
indices.fielddata.cache.size: 40%
indices.cache.filter.size: 30%
indices.cache.filter.terms.size: 1024mb
threadpool:
search:
type: cached
size: 100
queue_size: 2000

② 设置环境变量

vim /etc/profile.d/elasticsearch.sh export ES_HEAP_SIZE=2g    #Heap Size不超过物理内存的一半,且小于32G

(4)集群的优化(我未使用集群)

① ES是分布式存储,当设置同样的cluster.name后会自动发现并加入集群;

② 集群会自动选举一个master,当master宕机后重新选举;

③ 为防止"脑裂",集群中个数最好为奇数个

④ 为有效管理节点,可关闭广播 discovery.zen.ping.multicast.enabled: false,并设置单播节点组discovery.zen.ping.unicast.hosts: ["ip1", "ip2", "ip3"]

6、性能的检查

(1)检查输入和输出的性能

Logstash和其连接的服务运行速度一致,它可以和输入、输出的速度一样快。

(2)检查系统参数

① CPU

注意CPU是否过载。在Linux/Unix系统中可以使用top -H查看进程参数以及总计。

如果CPU使用过高,直接跳到检查JVM堆的章节并检查Logstash worker设置。

② Memory

注意Logstash是运行在Java虚拟机中的,所以它只会用到你分配给它的最大内存。

检查其他应用使用大量内存的情况,这将造成Logstash使用硬盘swap,这种情况会在应用占用内存超出物理内存范围时。

③ I/O 监控磁盘I/O检查磁盘饱和度

使用Logstash plugin(例如使用文件输出)磁盘会发生饱和。

当发生大量错误,Logstash生成大量错误日志时磁盘也会发生饱和。

在Linux中,可使用iostat,dstat或者其他命令监控磁盘I/O

④ 监控网络I/O

当使用大量网络操作的input、output时,会导致网络饱和。

在Linux中可使用dstat或iftop监控网络情况。

(3)检查JVM heap

  heap设置太小会导致CPU使用率过高,这是因为JVM的垃圾回收机制导致的。

  一个快速检查该设置的方法是将heap设置为两倍大小然后检测性能改进。不要将heap设置超过物理内存大小,保留至少1G内存给操作系统和其他进程。

  你可以使用类似jmap命令行或VisualVM更加精确的计算JVM heap

转自https://www.cnblogs.com/along21/

14.3-ELK重难点总结和整体优化配置的更多相关文章

  1. ELK重难点总结和整体优化配置

    本文收录在Linux运维企业架构实战系列 做了几周的测试,踩了无数的坑,总结一下,全是干货,给大家分享~ 一.elk 实用知识点总结 1.编码转换问题(主要就是中文乱码) (1)input 中的cod ...

  2. Collection集合重难点梳理,增强for注意事项和三种遍历的应用场景,栈和队列特点,数组和链表特点,ArrayList源码解析, LinkedList-源码解析

    重难点梳理 使用到的新单词: 1.collection[kəˈlekʃn] 聚集 2.empty[ˈempti] 空的 3.clear[klɪə(r)] 清除 4.iterator 迭代器 学习目标: ...

  3. 李洪强漫谈iOS开发[C语言-008]- C语言重难点

      C语言学习的重难点 写程序的三个境界: 照抄的境界,翻译的境界,创新的境界 1  伪代码: 描述C语言的编程范式 范式: 规范的一种表示 对于C的范式学会的话,C, C++ Java 都会了 2 ...

  4. English--音标重难点

    English|音标重难点 在拥有了,音标的元音与辅音的基础之后,需要对于这些音标进行加以区分,毕竟方言对于口型的影响非常的大. 前言 目前所有的文章思想格式都是:知识+情感. 知识:对于所有的知识点 ...

  5. 这是一份非常适合收藏的Android进阶/面试重难点整理

    写在前面 记得我大二时“不务正业”地自学Android并跟了老师做项目,到大三开始在目前的公司实习,至今毕业已有几年多,学习Android已经6.7年多了!但总感觉知识点很零散,并且不够深入,遇到瓶颈 ...

  6. 《十天学会 PHP》的重难点

    记录一下我在学习<十天学会 PHP>(第六版)的过程中的遇到的重难点,该课程是学习制作一个简单的留言板. 准备工作 XAMPP(Apache + MySQL + PHP + PERL) 是 ...

  7. html和css的重难点知识

    目录 html总难点总结: 1. 块级标签与内联标签的区别 1.1 块级标签: 1.2 内联标签: 2. 选择器 2.1 定义 2.2 选择器的分类 2.1 选择器的分类 3. css中margin, ...

  8. 老猿Python重难点知识博文汇总

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 除了相关教程外,老猿在学习过程中还写了大量的学习随笔,内容比较杂,文章内容也参差不齐,为了方便,老猿 ...

  9. 项目实战14.1—ELK 企业内部日志分析系统

    本文收录在Linux运维企业架构实战系列 一.els.elk 的介绍 1.els,elk els:ElasticSearch,Logstash,Kibana,Beats elk:ElasticSear ...

随机推荐

  1. 完美解决百度地图MarkerClusterer 移动地图时,Marker 的Label 丢失的问题

    这篇文章来自http://www.cnblogs.com/jicheng1014   不好意思,那些rss 站太生猛了. 先吐槽一下百度地图的开发者,其实这个问题我绝对不是第一个遇到的人 很多人把这个 ...

  2. php面试题分享

    1.nginx使用哪种网络协议? nginx是应用层 我觉得从下往上的话 传输层用的是tcp/ip 应用层用的是http fastcgi负责调度进程 2. <? echo 'hello tush ...

  3. mysql必知必会学习笔记(1)

    chapter 13 13.1 数据分组 如果要将数据分为多个逻辑组怎么办?? 要用数据分组 13.2 创建分组 使用group by子句.group by会指示对mysql进行分组,然后对每个组进行 ...

  4. WCF 内置绑定在不同的传输安全模式下的信道层

    basicHttpBinding Transport安全模式信道层 Message安全模式信道层 TransportWithMessageCredential安全模式信道层 TransportCred ...

  5. 谷歌地图自定义popup框

    谷歌地图的infowindow 不提供官方的定制化 <!DOCTYPE html> <html> <head> <meta name="viewpo ...

  6. 关于Mdi窗口-父窗口上的控件把子窗口的挡住的问题

    using System.Runtime.InteropServices; [DllImport("user32")] public static extern int SetPa ...

  7. jQuery图片组展示插件----Galleria使用简介

    1.技术目标 掌握Galleria插件的基本操作 2.Galleria简介 Galleria是一个jQuery插件,可用于展示多张图片,操作也比较简单, 展示效果也非常不错,如图: 提示:Galler ...

  8. Centos7.5搭建ELK-6.5.0日志分析平台

    Centos7.5搭建ELK-6.5.0日志分析平台 1. 简介 工作工程中,不论是开发还是运维,都会遇到各种各样的日志,主要包括系统日志.应用程序日志和安全日志,对于开发人员来说,查看日志,可以实时 ...

  9. valueOf() 和 toString()

    valueOf():如果存在任意原始值,返回最适合该对象类型的原始值. toString():将该对象的原始值以字符串形式返回. 这两个方法一般是交由JS去隐式调用,以满足不同的运算情况.  举个栗子 ...

  10. new Date(str)返回的时间结果在移动端比PC端快了8小时

    最近开发过程中,后端传过来一个“2018-03-15T17:53:19.6307928”字符串,需要将字符串转换成“2018-03-15  17:53”的格式展示出来.首先我使用了var time=n ...