01 EFK日志收集系统概述
- 01 EFK日志收集系统概述
- 02 Elasticsearch入门
- 03 Elasticsearch集群
1.ELK诞生的背景
1.1 没有ELK分析日志前
没有日志分析工具之前,运维工作存在哪些痛点?
- 痛点1、生产出现故障后,运维需要不停的查看各种不同的日志进行分析?是不是毫无头绪?
- 痛点2、项目上线出现错误,如何快速定位问题?如果后端节点过多、日志分散怎么办?
- 痛点3、开发人员需要实时查看日志但又不想给服务器的登陆权限,怎么办?难道每天帮开发取日志?
- 痛点4、如何在海量的日志中快速的提取我们想要的数据?比如:PV、UV、TOP10的URL?如果分析的日志数据量大,那么势必会导致查询速度慢、难度增大,最终则会导致我们无法快速的获取到想要的指标。
- 痛点5、CDN公司需要不停的分析日志,那分析什么?主要分析命中率,为什么?因为我们给用户承诺的命中率是90%以上。如果没有达到90%,我们就要去分析数据为什么没有被命中、为什么没有被缓存下来。*
1.2 使用ELK分析日志后
如上所有的痛点都可以使用日志分析系统ELK解决,通过ELK,将运维所有的服务器日志,业务系统日志都收集到一个平台下,然后提取想要的内容,比如错误信息,警告信息等,当过滤到这种信息,就马上告警,告警后,运维人员就能马上定位是哪台机器、哪个业务系统出现了问题,出现了什么问题。
2.ELK技术债是什么
2.1 什么是ELK
其实 ELK
不是一个单独的技术,而是一套技术的组合,是由 elasticsearch、logstash、kibana
组合而成的。
ELK
是一套开源免费、功能强大的日志分析管理系统。ELK
可以将我们的系统日志、网站日志、应用系统日志等各种日志进行收集、过滤、清洗,然后进行集中存放并可用于实时检索、分析。
E: elasticsearch
数据存储;L: logstash
数据采集、数据清洗、数据过滤;K: kibana
数据分析、数据展示;
2.2 什么是EFK
简单来说就是将 Logstash
替换成了 filebeat
,那为什么要进行替换?
因为 logstash
是基于 JAVA
开发的,在收集日志时会大量的占用业务系统资源,从而影响正常线上业务。
而替换成 filebeat
这种较为轻量的日志收集组件,会让业务系统的运行更加的稳定。
2.3 什么是ELFK
2.4 EFK收集哪些日志
- 代理:
Haproxy、Nginx
- web:
Nginx、Tomcat、Httpd、PHP
- db:
mysql、redis、mongo、elasticsearch
- 存储:
nfs、glusterfs、fastdfs
- 系统:
message、security
- 业务:`app
02 Elasticsearch入门
1.ES基本介绍
1.1 ES是什么
Elasticsearch
是一个分布式、RESTful
风格的搜索和数据分析引擎。
1.2 ES主要功能
数据存储、数据搜索、数据分析。
1.3 ES相关术语
1.3.1 文档 Document
Document
文档就是用户存在 es
中的一些数据,它是 es
中存储的最小单元。(类似于表中的一行数据。)注意:每个文档都有一个唯一的 ID
表示,可以自行指定,如果不指定 es
会自动生成。
1.3.2 索引 Index
索引其实是一堆文档 Document
的集合。(它类似数据库的中的一个表)
1.3.3 字段 Filed
在 ES
中,Document
就是一个 Json Object
,一个Json Object
其实是由多个字段组成的,每个字段它有不同的数据类型。
字符串:text、keyword。
数值型:long,integer,short,byte,double,float
布尔:boolean
日期:date
二进制:binary
范围类型:integer_range,float_range,long_range,double_range,date_range
1.4 ES术语总结
ES
索引、文档、字段关系小结:
一个索引里面存储了很多的 Document
文档,一个文档就是一个json object
,一个json object
是由多个不同或相同的 filed
字段组成;
2.ES操作方式
1.ES的操作和我们传统的数据库操作不太一样,它是通过 RestfulAPI 方式进行对ES进行操作,其实本质上就是通过 http 的方式去变更我们的资源状态。
通过 URI 的方式指定要操作的资源,比如 Index、Document等。
通过 Http Method 指明资源操作方法,如GET、POST、PUT、DELETE 等。
2.常见操作ES的两种方式:Curl 命令行、Kibana DevTools
3.安装配置kibana,用于数据展示。注意: Kibana不产生数据,需要获取ES的数据进行展示。
[root@es-node1 ~]# rpm -ivh kibana-7.4.0-x86_64.rpm
#配置kibana
[root@kibana ~]# grep "^[a-Z]" /etc/kibana/kibana.yml
server.port: 5601 #kibana默认监听端口
server.host: "0.0.0.0" #kibana监听地址段
elasticsearch.hosts: ["http://localhost:9200"] #kibana丛coordinating节点获取数据
i18n.locale: "zh-CN" #kibana汉化
#启动kibana
[root@kibana ~]# systemctl start kibana
[root@kibana ~]# systemctl enable kibana
3.ES索引API
es
有专门的 Index API
,用于创建、更新、删除索引配置等*
3.1 创建索引
创建索引 api
如下:
# 创建索引
PUT /oldxu_index
#查看所有已存在的索引
GET _cat/indices
3.2 删除索引
删除索引 api
如下:
#删除索引
DELETE /oldxu_index
4.ES文档 API
ES
为索引添加文档,有专门的 Document API
- 创建文件
- 查询文档
- 更新文档
- 删除文档
4.1 创建文档
创建文档,需要指定ID
#创建一个文档(指定ID)
POST /oldxu_index/_doc/1
{
"username": "oldxu",
"age": 18,
"salary": 1000000
}
创建文档,不指定ID
4.2 查询文档
查询文档,指定要查询的文档id
查询文档,搜索所有文档,用_search
4.3 批量创建文档
es
允许通过 _bulk
一次创建多个文档,从而减少网络传输开销,提升写入速率。
#批量创建document
POST _bulk
{"index":{"_index":"tt","_id":"1"}}
{"name":"oldxu","age":"18"}
{"create":{"_index":"tt","_id":"2"}}
{"name":"oldqiang","age":"30"}
{"delete":{"_index":"tt","_id":"2"}}
{"update":{"_id":"1","_index":"tt"}}
{"doc":{"age":"20"}}
4.4 批量查询文档
es
允许通过 _mget
一次查询多个文档。
#批量查询document
GET _mget
{
"docs": [
{
"_index": "tt",
"_id": "1"
},
{
"_index": "tt",
"_id": "2"
}
]
}
03 Elasticsearch集群
- 01 EFK日志收集系统概述
- 02 Elasticsearch入门
- 03 Elasticsearch集群
1.ES集群基本介绍
1.1 ES集群的好处
es
天然支持集群模式,其好处主要有两个:
- 1.能够增大系统的容量,如内存、磁盘,使得
es
集群可以支持PB级的数据; - 2.能够提高系统可用性,即使部分节点停止服务,整个集群依然可以正常服务;
1.2 ES如何组集群
ELasticsearch
集群是由多个节点组成的,通过 cluster.name
设置集群名称,并且用于区分其它的集群,每个节点通过 node.name
指定节点的名称。
- 单节点ES,如下图所示;
- 如果单节点出现问题,服务就不可用了,如何新增一个
es
节点加入集群
2.ES集群环境部署
2.1 环境准备
主机名称 | IP地址 |
---|
2.2 安装ES软件
所有集群节点都需要安装 ES
软件
# yum install java -y
# rpm -ivh elasticsearch-7.4.0-x86_64.rpm
2.3 node1集群节点配置
[root@es-node1-172 ~]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu #集群名称
node.name: es-node1 #节点名称
path.data: /var/lib/elasticsearch #数据存储路径
path.logs: /var/log/elasticsearch #日志存储路径
#bootstrap.memory_lock: true #不使用swap分区
network.host: #本机内网IP
http.port: 9200 #监听端口
discovery.seed_hosts: ["172.16.1.161", "172.16.1.162", "172.16.1.163"] #集群主机列表
cluster.initial_master_nodes: ["172.16.1.161", "172.16.1.162", "172.16.1.163"] #仅第一次启动集群时进行选举
2.4 node2集群节点配置
[root@oldxu-es-node2-172 ~]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu
node.name: es-node2
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: #本机内网IP
discovery.seed_hosts: ["172.16.1.161", "172.16.1.162", "172.16.1.163"]
cluster.initial_master_nodes: ["172.16.1.161", "172.16.1.162", "172.16.1.163"]
2.5 node3集群节点配置
[root@oldxu-es-node3-172 ~]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu
node.name: es-node3
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: #本机内网IP
discovery.seed_hosts: ["172.16.1.161", "172.16.1.162", "172.16.1.163"]
cluster.initial_master_nodes: ["172.16.1.161", "172.16.1.162", "172.16.1.163"]
http.cors.enabled: true
http.cors.allow-origin: "*"
2.6 ES集群检查-cerebro
如何通过可视化方式检查 ES
集群状态;可以通过 cerebro
可视化工具检测;cerebro 传送门
[root@openvpn ~]# rpm -ivh cerebro-0.8.5-1.noarch.rpm
[root@openvpn ~]# vim /etc/cerebro/application.conf
data.path = "/tmp/cerebro.db"
[root@openvpn ~]# systemctl start cerebro
[root@openvpn-192 ~]# netstat -lntp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp6 0 0 :::9000 :::* LISTEN 504/java
3.ES集群节点类型
es
集群中节点类型介绍
Cluster State
Master
Data
Coordinating
3.1 Cluster State
Cluster State
:集群相关的数据称为cluster state
;会存储在每个节点中,主要有如下信息:
- 1)节点信息,比如节点名称、节点连接地址等
- 2)索引信息,比如索引名称、索引配置信息等
3.2 Master
- 1.
ES
集群中只能有一个master
节点,master
节点用于控制整个集群的操作; - 2.
master
主要维护Cluster State
,当有新数据产生后,Master
会将最新的数据同步给其他Node
节点; - 3.
master
节点是通过选举产生的,可以通过node.master: true
指定为Master
节点。( 默认true
)
当我们通过API
创建索引 PUT /oldxu_index
,Cluster State
则会发生变化,由 Master
同步至其他 Node
节点;
3.3 Data
- 1.存储数据的节点即为
data
节点,默认节点都是data
类型,相关配置node.data: true
( 默认为true
) - 2.当创建索引后,索引创建的数据会存储至某个节点,能够存储数据的节点,称为
data
节点;
3.4 Coordinating
- 1.处理请求的节点即为
coordinating
节点,该节点为所有节点的默认角色,不能取消 - 2.
coordinating
节点主要将请求路由到正确的节点处理。比如创建索引的请求会由coordinating
路由到master
节点处理;当配置node.master: false、node.data:false
则为coordinating
节点
4.ES集群分片副本
4.1 提高ES集群可用性
- 如何提高 ES 集群系统的可用性;有如下两个方面;
- 1.服务可用性:
- 1)2个节点的情况下,允许其中1个节点停止服务;
- 2)多个节点的情况下,坏的节点不能超过集群一半以上;
- 2.数据可用性:
- 1)通过副本
replication
解决,这样每个节点上都有完备的数据。 - 2)如下图所示,
node2
上是oldxu_index
索引的一个完整副本数据。
4.2 增大ES集群的容量
- 1.如何增大 ES 集群系统的容量;我们需要想办法将数据均匀分布在所有节点上;
- 引入分片
shard
解决;
- 1)通过副本
- 2.什么是分片,将一份完整数据分散为多个分片存储;
- 2.1 分片是
es
支持Pb
级数据的基石 - 2.2 分片存储了索引的部分数据,可以分布在任意节点上
- 2.3 分片存在主分片和副本分片之分,副本分片主要用来实现数据的高可用
- 2.4 副本分片的数据由主分片同步,可以有多个,从而提高读取数据的吞吐量
- 注意:主分片数在索引创建时指定且后续不允许在更改;默认ES7分片数为1个
- 2.1 分片是
- 3.如下图所示:在3个节点的集群中创建
oldxu_index
索引,指定3个分片,和1个副本; -
PUT /oldxu_index { "settings": { "index": { "number_of_shards": 3, "number_of_replicas": 1 } } }
4.3 增加节点能否提高容量
问题:目前一共有3个ES节点,如果此时增加一个新节点是否能提高
oldxu_index
索引数据容量?
答案:不能,因为oldxu_index
只有3个分片,已经分布在3台节点上,那么新增的第四个节点对于oldxu_index
而言是无法使用到的。所以也无法带来数据容量的提升;4.4 增加副本能否提高读性能
问题:目前一共有3个ES节点,如果增加副本数是否能提高
oldxu_index
的读吞吐量;
答案:不能,因为新增的副本还是会分布在这node1、node2、node3
这三个节点上的,还是使用了相同的资源,也就意味着有读请求来时,这些请求还是会分配到node1、node2、node3
上进行处理、也就意味着,还是利用了相同的硬件资源,所以不会提升读取的吞吐量;
问题:如果需要增加读吞吐量性能,应该怎么来做;
答案:增加读吞吐量还是需要添加节点,比如在增加三个节点node4、node5、node6
那么将原来的R0、R1、R2
分别迁移至新增的三个节点上,当有读请求来时会被分配node4、node5、node6
,也就意味着有新的CPU、内存、IO
,这样就不会在占用node1、node2、node3
的硬件资源,那么这个时候读吞吐量才会得到真正的提升;
4.5 副本与分片总结
- 分片数和副本的设定很重要,需要提前规划好
- 1.过小会导致后续无法通过增加节点实现水平扩容;
- 2.设置分片过大会导致一个节点上分布过多的分片,造成资源浪费。分片过多也会影响查询性能;
5.ES集群健康检查
5.1 如何判断集群状态
Cluster Health
获取集群的健康状态,整个集群状态包括以下三种:
- 1.
green
健康状态,指所有主副分片都正常分配 - 2.
yellow
指所有主分片都正常分配,但是有副本分片未正常分配 - 3.
red
有主分片未分配,表示索引不完备,写可能有问题。(但不代表不能存储数据和读取数据)
5.2 如何获取集群状态
我们可以通过
GET _cluster/health?pretty=true
方式获取集群状态;[root@es-node1-172 ~]# curl http://172.16.1.162:9200/_cluster/health?pretty=true { "cluster_name" : "my-oldxu", "status" : "green", # 重点关注status一栏 "timed_out" : false, "number_of_nodes" : 3, "number_of_data_nodes" : 3, "active_primary_shards" : 33, "active_shards" : 66, "relocating_shards" : 0, "initializing_shards" : 0, "unassigned_shards" : 0, "delayed_unassigned_shards" : 0, "number_of_pending_tasks" : 0, "number_of_in_flight_fetch" : 0, "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 100.0 }
5.1 Shell脚本检查状态
通过
Shell
脚本获取集群状态信息;如果出现异常则触发报警邮件;[root@es-node1-172 ~]# curl http://172.16.1.162:9200/_cluster/health?pretty=true { "cluster_name" : "my-oldxu", "status" : "green", "timed_out" : false, "number_of_nodes" : 3, "number_of_data_nodes" : 3, "active_primary_shards" : 33, "active_shards" : 66, "relocating_shards" : 0, "initializing_shards" : 0, "unassigned_shards" : 0, "delayed_unassigned_shards" : 0, "number_of_pending_tasks" : 0, "number_of_in_flight_fetch" : 0, "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 100.0 } #shell检测脚本 # curl -s http://172.16.1.162:9200/_cluster/health?pretty=true | grep "status" |awk -F '"' '{print $4}'
6.ES集群故障转移
6.1 什么是故障转义
所谓故障转移指的是,当集群中有节点发生故障时,这个集群是如何进行自动修复的。
ES
集群目前是由3个节点组成,如下图所示,此时集群状态是green
6.2 模拟节点故障
- 假设:
node1
所在机器宕机导致服务终止,此时集群会如何处理;大体分为三个步骤:
- 1.重新选举
- 2.主分片调整
- 3.副本分片调整
6.2.1 重新选举
node2
和node3
发现node1
无法响应;一段时间后会发起master
选举,比如这里选择node2
为master
节点;此时集群状态变为Red
状态;
6.2.2 主分片调整
node2
发现主分片P0
未分配,将node3
上的R0
提升为主分片;此时所有的主分片都正常分配,集群状态变为Yellow
状态;
6.2.3 副本分片调整
node2
将P0
和P1
主分片重新生成新的副本分片R0、R1
,此时集群状态变为Green
;
7.ES文档路由原理
ES文档分布式存储,当一个文档存储至 ES集群时,存储的原理是什么样的?
如图所示,当我们想一个集群保存文档时,Document1是如何存储到分片P1的?选择P1的依据是什么?
其实是有一个文档到分片的映射算法,其目是使所有文档均匀分布在所有的分片上,那么是什么算法呢?随机还是轮询呢? 这种是不可取的,因为数据存储后,还需要读取,那这样的话如何读取呢?
实际上,在ES 中,通过如下的公式计算文档对应的分片存储到哪个节点,计算公式如下:shard = hash(routing) % number_of_primary_shards # hash 算法保证将数据均匀分散在分片中 # routing 是一个关键参数,默认是文档id,也可以自定义。 # number_of_primary_shards 主分片数 # 注意:该算法与主分片数相关,一但确定后便不能更改主分片。 # 因为一旦修改主分片修改后,Share的计算就完全不一样了。
7.1 文档的创建流程
7.2 文档的读取流程
7.3 文档批量创建的流程
7.4 文档批量读取的流程
8.ES扩展集群节点
8.1 节点扩展环境准备
es-node4 172.16.1.164 es-node5 172.16.1.165主机名称 IP地址 8.2 节点扩展1配置
[root@oldxu-es-node4-172 ~]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml cluster.name: my-oldxu node.name: es-node4 path.data: /var/lib/elasticsearch path.logs: /var/log/elasticsearch network.host: 0.0.0.0 #bootstrap.memory_lock: true node.data: true #data节点 node.master: false #不参与master选举 discovery.seed_hosts: ["172.16.1.161", "172.16.1.162", "172.16.1.163"]
8.3 节点扩展2配置
[root@oldxu-es-node5-172 ~]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml cluster.name: my-oldxu node.name: es-node5 path.data: /var/lib/elasticsearch path.logs: /var/log/elasticsearch #bootstrap.memory_lock: true network.host: 0.0.0.0 node.data: true #data节点 node.master: false #不参与master选举 discovery.seed_hosts: ["172.16.1.161", "172.16.1.162", "172.16.1.163"]
8.4 节点扩展检查
通过
cerebor
检查集群扩展后的状态;如果出现集群无法加入、或者加入集群被拒绝,尝试删除/var/lib/elasticsearch
下的文件,然后重启es
;