ELK的使用场景及集群构建(全)
ELK的使用场景及集群构建(全)
1、没有日志分析工具之前,运维工作存在哪些痛点?
- 痛点1、生产出现故障后,运维需要不停的查看各种不同的日志进行分析?是不是毫无头绪?
- 痛点2、项目_上线出现错误,如何快速定位问题?如果后端节点过多日志分散怎么办 ?
- 痛点3、开发人员需要实时查看日志但又不想给服务器的登陆权限,怎么办?难道每天帮开发取志?
- 痛点4、如何在海量的日志中快速的提取我们想要的数据?比如:PV、UV、 TOP10的URL ?如果分析的日志数据量大,那么势必会导致查询速度慢难度增大最终则会导致我们无法快速的获取到想要的指标。
- 痛点5、CDN公司需要不停的分析日志,那分析什么?主要分析命中率,为什么?因为我们给用户承诺的命中率是90%以上。如果没有达到90% ,我们就要去分析数据为什么没有被命中、为什么没有被缓存下来。
2.使用ELK日志分析系统之后?
- 如上所有的痛点都可以使用日志分析系统ELK解决,通过ELK ,将运维所有的服务器日志,业务系统曰志都收集到一个平台下,然后提取想要的内容,比如错误信息,警告信息等,当过滤到这种信息,就马上告警,告警后,运维人员就能马上定位是哪台机器哪个业务系统出现了问题,出现了什么问题,快速定位问题进行故障解决。
3.什么是ELK?
其实ELK不是-一个单独的技术,而是一套技术的组合 ,是由elasticsearch、logstash、 kibana组合而成的。
E: elastic search java负责存储收集过来的日志 L: logstashjava日志收集(早期) K: kibana java负责过滤分析,绘图展示日志数据
4.什么EFK?
简单来说就是将L ogstash替换成了filebeat。那为什么要进行替换?因为logstash是基于JAVA开发的,在收集日志时会大量的5用业务系统资源,从而影响正常线上业务。
- Filebeat比Logstash更加轻量级,启动快。
5.使用EFK收集哪些日志?
容器: docker
代理: Haproxy、 Nginx
web : Nginx、 Tomcat、 Httpd、 PHP
db : mysql redis、 mongo、 elasticsearch
存储: nfs、glusterfs、 fastdfs
系统: message、 security
业务:app
-
1、什么是Elasticsearch?
Elasticsearch是一个分布式、 RESTful 风格的搜索和数据分析引擎。
-
2、Elasticsearch主要的功能?
数据存储、数据搜索数据分析。
-
3、Elasticsearch术语:文档Document
Document文档就是用户存在es中的一些数据,它是es中存储的最小单元。( 类似于Table中的一行数据。)注意:每个文档都有一个唯一的ID 表示,可以自行指定,如果不指定es会自动生成。
字符串: text、keyword.
数值型: long,integer,short,byte, double,float
布尔: boolean
日期: date
二-进制: binary
范围类型: integer_ range,float range,long range,double_ range,date _range
-
ES索引、文档字段系小结:
一个索引里面存储 了很多的Document文档, 一个文档就是- 1json object json object
是由多个不同或相同的iled字段组成。 -
一个表里面有多个数据,每个数据由多个不同的字段组织在一起的。 --->mysql
ES操作方式
ES的操作和我们传统的数据库操作不太一样,它是通过RestfulAP/方式进行对ES进行操作,
其实本质上就是通过http的方式去变更我们的资源状态。
通过URI的方式指定要操作的资源,比如Index. Document等。
通过Http Method指明资源操作方法,如GET、POST、 PUT、 DELETE等。
2.常见操作ES的两种方式: Curl命令行Kibana Dev Tools
环境准备
ES: elastic.co/cn/
es-node1 ---> 10.0.0.161 172.16.1.161
es-node2 ---> 10.0.0.162 172.16.1.162
es-node3 ---> 10.0.0.161 172.16.1.163
官方网站: elastic.co --->版本elk7.4(本教程使用)------->现在最新的是7.5
[root@es-node1 ~]# yum install java -y
[root@es-node1 local]# ls
bin etc include lib libexec share
elasticsearch-7.4.0-x86_64.rpm games kibana-7.4.0-x86_64.rpm lib64 sbin src
[root@es-node1 local]# rpm -ivh elasticsearch-7.4.0-x86_64.rpm kibana-7.4.0-x86_64.rpm
[root@es-node1 ~]# vim /etc/elasticsearch/jvm.options
# Xmx represents the maximum size of total heap space
-Xms512m #实际生产环境大于内存的一半,最大不超过32G ##此处必须修改,不然起不来
-Xmx512m
[root@es-node1 ~]# systemctl enable elasticsearch.service
[root@es-node1 ~]# systemctl start elasticsearch.service
[root@es-node1 ~]# vim /etc/kibana/kibana.yml
......
# To allow connections from remote users, set this parameter to a non-loopback address.
server.host: "0.0.0.0"
......
# Supported languages are the following: English - en , by default , Chinese - zh-CN .
i18n.locale: "zh-CN"
#中文字符集
[root@es-node1 ~]# systemctl start kibana.service
[root@es-node1 ~]# systemctl enable kibana.service
#访问
http://10.0.0.161:5601/
4.0 创建索引---->找到扳手工具
4.ES文档API
ES为索引添加文档,有专门的Document API
创建文件
● 查询文档
● 更新文档
● 删除文档
4.1创建文档
创建文档,指定ID
查询文档,搜索所有文档,用_search
4.2查询文档,获取指定的id数据
4.3
上述案例代码展现
# 创建一个索引
PUT /oldxu_es
# 查看所有的索引
GET _cat/indices
# 删除索引
DELETE /oldxu_es
#给oldxu_es索引录入一个文档
POST /tt/_doc/2
{
"name": "oldxu",
"age": 18,
"salary": 1000000000
}
POST /oldxu_es/_doc/2
{
"name": "oldguo",
"age": 35,
"salary": 100
}
#获取所有的文档 默认前10个
GET /oldxu_es/_search
#获取指定的id数据
GET /oldxu_es/_doc/1
#模糊查询
GET /oldxu_es/_search
{
"query": {
"term": {
"name": "oldxu"
}
}
}
#删除指定id的文档
DELETE /oldxu_es/_doc/1
#
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"}}
#一次查询多个文档
GET _mget
{
"docs": [
{
"_index": "tt",
"_id": "1"
},
{
"_index": "tt",
"_id": "2"
}
]
}
4.ES集群环境搭建
#删除所有的es相关的数据 (集群无法组件的情况)
[root@es-node1 ~]# rm -rf /var/lib/elasticsearch/*
[root@es-node1 ~]# systemctl stop elasticsearch.service
[root@es-node1 ~]# systemctl stop kibana
配置node1
[root@es-node1 ~]# grep '^[a-Z]' /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu
node.name: node1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["10.0.0.161", "10.0.0.162", "10.0.0.163"]
cluster.initial_master_nodes: ["10.0.0.161", "10.0.0.162", "10.0.0.163"]
scp -rp /etc/elasticsearch/elasticsearch.yml root@172.16.1.162:/etc/elasticsearch/elasticsearch.yml
scp -rp /etc/elasticsearch/elasticsearch.yml root@172.16.1.163:/etc/elasticsearch/elasticsearch.yml
scp /etc/elasticsearch/jvm.options root@172.16.1.162:/etc/elasticsearch/jvm.options
scp /etc/elasticsearch/jvm.options root@172.16.1.163:/etc/elasticsearch/jvm.options
配置node2
[root@es-node2 ~]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu
node.name: node2
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["10.0.0.161", "10.0.0.162", "10.0.0.163"]
cluster.initial_master_nodes: ["10.0.0.161", "10.0.0.162", "10.0.0.163"]
配置node3
[root@es-node3 ~]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu
node.name: node3
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["10.0.0.161", "10.0.0.162", "10.0.0.163"]
cluster.initial_master_nodes: ["10.0.0.161", "10.0.0.162", "10.0.0.163"]
启动所有节点
systemctl start elasticsearch
通过 curl 检查集群环境是否正常
curl http://172.16.1.163:9200/_cluster/health?pretty
kibana
GET /_cluster_health
#先rz上传cerebro-0.8.5-1.noarch.rpm
[root@es-node1 ~]# rpm -ivh cerebro-0.8.5-1.noarch.rpm
[root@es-node1 ~]# vim /etc/cerebro/application.conf
......#将./修改为/tmp/
data.path = "/tmp/cerebro.db"
[root@es-node1 ~]# systemctl enable cerebro
1.Cluster State : ES集群相关的数据称为
cluster
state
主要记录如下信息:
1.节点信息,比如节点名称、节点连接地址等
2.索引信息,比如索引名称、索引配置信息等
2.Master节点
1.es集群中只能有一个master书点, master节点用于控制整个集群的操作。
2.我们的cluster state存储在每个节点上,但只能由master维护最新版本并同步给其他节点。
3.master节点是通过集群中所有节点选举产生的,(10.0.0.161,10.0.0.162,10.0.0.163)可以通node.master: true (默认为true)
3.Datal节点----(所有都默认为true)---->是用来存储数据的
1.存储数据的书点即为data节点,默认节点都是data类型,相关配置node .data: true (默认为true )
2.当创建索引后,索引创建的数据会存储至某个节点,能够存储数据的书点,称为data节点。
4.Coordinating节点
1.处理请求的节点即为coordinating节点,该节点为所有节点的默认角色,不能取消。
coordinating节点主要将请求路由到正确的节点处理,比如创建索引的请求路由到master节点.
4.ES集群分片副本.
1、如何提高es集群系统的可用性?
1.服务可用性:
1 )2个节点的情况下,允许其中1个节点停止服务
2 )多个节点的情况下,坏节点不能超过一半以上
2.数据可用性:
1 )副本(replication )解决,这样每个节点上都有完备的数据。
2 )服务可用性如下图所示, node2_上是oldxu_ index索引的一个完整副本数据。
2.如何增大es集群系统的容量?
1.如何将数据分布所有节点上?的
1 )引入分片(shard )解决问题
2.什么是分片,分片是es.支持Pb级数据的基石
2 )分片存储了索引的部分数据,可以分布在任意节点上
3 )分片存在主分片和副本分片之分,副本分片主要用来实现数据的高可用
4 )副本分片的数据由主分片同步,可以有多个,从而提高读取数据的吞吐量
5 )注意:主分片数在索引创建时指定且后续不允许在更改,默认ES7分片数为1个
3.如下图所示:在3个节点的集群中创建oldxu_index 索引,指定3个分片,和1个副本。(cerebro创建测试)
3.F1 :目前-共有3 ES节点,如果此时增加-个新节点是否能提高oldxu_ index 索引数据容量?
不能,因为oldxu_ index 只有3个分片,已经分布在3台节点上,那么新增的第四个节点对于
oldxu_ _index而言是无法使用到的。所以也无法带来数据容量的提升。
4.F2 :目前- -共有3个ES节点,如果增加副本数是否能提高oldxu_ index 的读吞量?
不能,因为新增的副本还是会分布在这node1、node2、 node3、 这三个节点上的,还是使用了相
同的资源,也就意味着有读请求来时,这些请求还是会分配到hode1、node2、 node3. 上进行处
理也就意味着,还是利用了相同的硬件资源,所以不会提升读取的吞吐量。
如果要需要增加读吞吐量,怎么办?
增加读吞吐量还是需要添加书点,比如在增加三个节点node4、node5、 node6 ,那么将原来
的R0、R1、 R2分别迁移至新增的三个节点上,当有读请求来时会被分配node4、node5、
node6 ,也就意味着有新的CPU、内存、I0 ,这样就不会在占用hode1、node2、 node3的硬件资源,那么这个时候读吞吐量才会得到真正的提升。
总结:分片数和副本的设定很重要,需要提前规划好
1.过小会导致后续无法通过增加节点实现水平打容
2.设置分片过大会导致一 个节点上分布过多的分片,造成资源浪费。分片过多也会影响查询性能。
中
5.ES集群健康检查
(Cluster Health获取集群的健康状态,整个集群状态包括以下三种:
1 ) green健康状态,指所有主副分片都正常分配
2 ) yellow指所有主分片都正常分配,但是有副本分片未正常分配
3 )red有主分片未分配,表示索引不完备,写也可能有问题。 (但不代表不能存储数据和读取数据)
4 )可以通过GET_cluster/health?pretty=true 方式获取集群状态
实战1 : 通过Shell脚本获取集群状态信息
[root@es-node1 ~]# curl http://172.16.1.163:9200/_cluster/health?pretty
{
"cluster_name" : "my-oldxu",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 3,
"number_of_data_nodes" : 3,
"active_primary_shards" : 4,
"active_shards" : 8,
"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
}
[root@es-node1 ~]#
6.ES集群故障转移
所谓故障转移指的是,当集群中有节点发生故障时,这个集群是如何进行自动修复的。
ES集群是由3个节点组成,如下图所示,此时集群状态是green
假设: node1所在机器宕机导致服务终止,此时集群会如何处理?
1.node2和node3发现node 1无法响应一段时间后会发起master选举 ,比如这里选择node2为
master节点。此时集群状态变为Red。
2.node2发现主分片P0未分配,将node3_上的R0提升为主分片。此时由于所有的主分片都正常分
配,集群状态变为Yellow。
3.Node2将P0和P1生成新的副本R0、R1 ,此时集群状态变为Green。
ES文档路由原理(重要)
ES文档分布式存储,当-一个文档存储至ES集群时,存储的原理是什么样的?
如图所示,当我们想一个集群保存文档时, Document1是如何存储到分片P1的?选择P1的依据是什么?
其实是有一个文档到分片的映射算法,其目是使所有文档均匀分布在所有的分片上,那么是什么
算法呢?随机还是轮询呢?这种是不可取的,因为数据存储后,还需要读取,那这样的话如何读
取呢?实际上,在ES中,通过如下的公式计算文档对应的分片存储到哪个书点,计算公式如下
shard = hash(routing) % number_ of_ primary_ _shards
# hash 算法保证将数据均匀分散在分片中
# routing 是一个关键参数,默认是文档id,也可以自定义。
# number_ of_ primary_ shards 主分片数
#注意:该算法与主分片数相关,一但确定后便不能更改主分片。
#因为一旦修改主分片修改后,Share的计算就完全不一样了。
1、文档的创建流程
2、文档的读取流程
3.文档批量创建的流程?
4.文档批量读取的流程?
添加(扩展集群)节点
环境:web01: 10.0.0.7 web02: 10.0.0.8 内存2G 内核1G
将elasticsearch-7.4.0-x86_64.rpm上传至家目录
两台服务器均执行:
[root@web02 ~]# yum install java -y
[root@web02 ~]# rpm -ivh elasticsearch-7.4.0-x86_64.rpm
[root@web01 ~]# vim /etc/elasticsearch/elasticsearch.yml
[root@web01 ~]# grep '^[a-Z]' /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu
node.name: node4
node.master: false
node.data: true
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["10.0.0.161", "10.0.0.162"]
[root@web02 ~]# grep '^[a-Z]' /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu
node.name: node5
node.master: false
node.data: false
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["10.0.0.161", "10.0.0.162"]
[root@web01 ~]# vim /etc/elasticsearch/jvm.options
......
# Xmx represents the maximum size of total heap space
-Xms512m
-Xmx512m
......
[root@web01 ~]# tail -f /var/log/elasticsearch/my-oldxu.log
systemctl stop elasticsearch.service
systemctl start elasticsearch.service