一、ES相关

Elasticsearch(简称ES)是java语言开发,是一个分布式、RESTful 风格的搜索和数据分析引擎,用于集中存储日志数据。

图中elasticsearch我是用3台服务器做的集群,logstash也是3台服务

ELK介绍

ELK 是三个开源软件的缩写,提供一套完整的企业级日志平台解决方案。

分别是:

• Elasticsearch:搜索、分析和存储数据

• Logstash :采集日志、格式化、过滤,最后将数据推送到Elasticsearch存储

• Kibana:Kibana 是一个免费且开放的用户界面,能够让您对 Elasticsearch 数据进行可视化,并让您在 Elastic Stack 中进行导航。

• Beats :集合了多种单一用途数据采集器,用于实现从边缘机器向 Logstash 和Elasticsearch 发送数据。里面应用最多的是Filebeat,是一个轻量级日志采集器。

ES术语

• Index:索引是多个文档的集合

• Type:一个Index可以定义一种或多种类型,将Document逻辑分组

• Document:Index里每条记录称为Document,若干文档构建一个Index。我个人理解document是json文件,因为数据存在本地就是文件类型。

• Field:ES存储的最小单元

image-20220602090005705

索引,分片,副本分片理解

标准说法:
    1、分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点里。 当你的集群规模扩大或者缩小时, Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。
	2、一个副本分片只是一个主分片的拷贝。副本分片作为硬件故障时保护数据不丢失的冗余备份,并为搜索和返回文档等读操作提供服务。
	3、主分片的数目在索引创建时就已经确定了下来

Elasticsearch 添加数据时需要用到索引——保存相关数据的地方。 索引实际上是指向一个或者多个物理 分片 的 逻辑命名空间 。
	一个 分片 是一个底层的 工作单元 ,它仅保存了全部数据中的一部分。 在分片内部机制中,我们将详细介绍分片是如何工作的,而现在我们只需知道一个分片是一个 Lucene 的实例,以及它本身就是一个完整的搜索引擎。 我们的文档被存储和索引到分片内,但是应用程序是直接与索引而不是与分片进行交互。
	Elasticsearch 是利用分片将数据分发到集群内各处的。分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点里。 当你的集群规模扩大或者缩小时, Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。
	一个副本分片只是一个主分片的拷贝。副本分片作为硬件故障时保护数据不丢失的冗余备份,并为搜索和返回文档等读操作提供服务。
	主分片的数目在索引创建时就已经确定了下来

主切片在初始定义好了之后,后期可否修改?

不可以修改,因为会影响document的id,导致以前数据找不到了。间接方法:只能建一个新的索引index,其定义与源index相同,但是具有更多的primary shard,然后把原索引的数据reindex到新索引里面去,以达到修改的目的。

分布式理解

主机a有2份数据(主机a是master),主机a把它的数据复制一份放到主机b上,当主机a死机了,他的数据不会丢失;此时,来了另外主机c,主机a会把主机b存的两份数据,分一份给主机c,此时主机a有2份数据,主机b和c分别的各存了其中一份(注意主机b,c不是全部复制主机a的所有数据),这样就成了分布式保存,他和同步复制不一样,效率比同步的高。
副本是只读,不可以删除修改,写入要经过master来操作,操作完成后再分发到各副本。

es集群原理

	一个运行中的 es 实例称为一个节点,而集群是由一个或者多个拥有相同 cluster.name 配置的节点组成, 它们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。
	当一个节点被选举成为 主 节点时, 它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。 而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量的增加它也不会成为瓶颈。 
	作为用户,我们可以将请求发送到 集群中的任何节点 ,包括主节点。 每个节点都知道任意文档(理解为行)所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。 无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回給客户端。 Elasticsearch 对这一切的管理都是透明的。

集群健康

	Elasticsearch 的集群监控信息中包含了许多的统计数据,其中最为重要的一项就是 集群健康 , 它在 status 字段中展示为 green 、 yellow 或者 red 。
green,表示所有的主分片和副本分片都正常运行。
yellow,表示所有的主分片都正常运行,但副本分片有的不正常运行。这时候可以继续使用不影响,这种情况就类似某个节点断开了,集群会临时变为yellow,但是随着master会把切片重新自动分配,一两分钟后就又变为green了,当集群下架某个节点的时候能看到此现象。
red,表示有一些主分片没能正常运行。
总结:集群的状态是看分片的状态。如果所有分片在一个机器,分片停止了,表示集群就是red(通常es不会把所有主分片放在一个主机器,他们的副本分片也会分开放)。
#这3个状态一定要记住。集群是yellow没事可以继续工作,如果出现red就不能工作了。

选举的基本原则

ES针对当前集群中全部的Master Eligible Node进行选举获得master节点,为了不出现脑裂现象,ES选择了分布式系统常见的quorum(多数派)思想,也就是只有得到了超过半数选票的节点才能成为master。在ES中使用 discovery.zen.minimum_master_nodes 属性设置quorum,这个属性通常设置为 eligibleNodesNum / 2 + 1。git

如何触发一次选举,什么时候触发?

当知足以下条件是,集群内就会发生一次master选举github

  1. 当前master eligible节点不是master
  2. 当前master eligible节点与其它的节点通讯没法发现master
  3. 集群中没法链接到master的master eligible节点数量已达到 discovery.zen.minimum_master_nodes 所设定的值。(超过一半的人没法连接到master)

es如何选举master

  1. 寻找clusterStateVersion比本身高的master eligible的节点,向其发送选票。(clusterStateVersion是表示节点集群状态信息的一个版本标识,因为有的节点更新快,有的更新慢。)
  2. 若是clusterStatrVersion同样,则计算本身能找到的master eligible节点(包括本身)中节点id最小的一个节点,向该节点发送选举投票
  3. 若是一个节点收到足够多的投票(即 minimum_master_nodes 的设置),而且它也向本身投票了,那么该节点成为master开始发布集群状态。

集群的扩容、缩容

  • 新增一台服务器加入到集群中,
配置同样的集群名字,开启es服务即可。
  • 集群缩容一台服务器(多台服务器关闭一台恢复到green后,再关闭下一台)

这里有好几种情况:

1、直接关闭服务器即可,关闭服务器后实时观察集群健康状态,它会变yellow,然后过个1分钟又会变为green。原因是因为关闭节点后,一些副本切片不能访问(此时变为yellow),集群会自动分配切片,分配完成后变为green,分配的时间取决于数据的大小。

2.1 如果你关闭的节点是master节点,并且所有的主切片都在这台服务器,那么它会重新选择master,在选举的时候,集群状态是red的,因为主分片已经失去了。当你选举好master后,又变回gred。 
2.2 如果关闭的节点master节点,且只是部分的主切片放在这台服务器,关闭过程中是red-->yellow-->green(原因看下面文档链接),过几分钟后恢复到green(其实默认情况下主切片不会放在同一个服务器,这是es内部机制)。
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_coping_with_failure.html

3、如果关闭的旧master重新开机后,还会恢复到master吗?不会了,master被其它机器当了,你只有等下次重新选举才能当上master。

#官方说法:当集群只有一台服务器master,没有副本切片,此时集群状态是一直yellow,不会变为green,因为它的副本分片都访问不到。但是我亲测,只有一台服务器的时候,集群状态显示未连接(图形界面看到的,,用curl命令访问集群状态是卡主的,访问不了),也就说一台服务器不叫集群了;当我把其它机器的es服务开起来后,集群又自动恢复green。

配置文件路径,端口

#es
config/elasticsearch.yml
端口:["192.168.68.19:9200","192.168.68.128:9200","192.168.68.129:9200"]
http.port: 9200
#transport.tcp.port: 9300      #集群之间

#logstash
conf.d/test.yml #输入输出定义的文件目录
config/logstash.yml #全局配置文件
端口:  9600-9700

#kibana
[root@elk2 kibana]# cat config/kibana.yml 
server.port: 5601
客户端访问http://192.168.68.128:5601/app/home#/

#kafka
zookeeper端口是2181,kafka端口9092,也是读取和写入端口;
zookeeper集群使用的端口2888和3888,2888是follower与leader交换信息的端口;3888是当leader挂了用来执行选举时候相互通信的端口。
都在config目录下,zookeeper配置文件zookeeper.properties,kafka配置文件是server.properties

二、logstash相关

Logstash能够将采集日志、格式化、过滤,最后将数据推送到Elasticsearch存储。

Input:输入,输入数据可以是Stdin、File、TCP、Redis、Syslog等。

Filter:过滤,将日志格式化。有丰富的过滤插件:Grok正则捕获、Date时间处理、Json编解码、Mutate数据修改等。

Output:输出,输出目标可以是Stdout、File、TCP、Redis、ES等

  • logstash原理

Logstash 事件处理管道具有三个阶段:输入→过滤器→输出。输入生成事件,过滤器修改它们,输出将它们发送到其他地方。输入和输出支持编解码器,使您能够在数据进入或退出管道时对其进行编码或解码,而无需使用单独的过滤器。

输入插件(Input,file)

1、input输入阶段:从哪里获取日志

常用插件:

• Stdin(一般用于调试)

• File

• Redis

• Beats(例如filebeat)

过滤插件

过滤阶段:用来将日志格式化处理

常用插件: • json #处理json格式的文件 • kv #key,value存储的数据 • grok #通过正则匹配日志 • geoip #解析ip所属地址 • date #将指定的日期替换成为一定的格式

三、Kibana 相关

Kibana 是一个图形页面系统,用于对 Elasticsearch 数据可视化。他的配置文件设置直接连接es地址。

数据搜索

索引模式:将ES索引关联到Kibana,然后就可以再Discover菜单查看

kibana有两种查询语法:Lucene和KQL,默认KQL是打开的,在查询栏,点击KQL可以关闭。Lucene是一种老方式查询,两种语法要小区别,用到的时候再说,建议用KQL。

Kibana 搜索语法:两种方式都是以Key:Value的形式构建查询条件

四、filebeat相关

​ 术语:harvesters (直译:收割机,采集器)

Filebeat是一个轻量级日志采集器,将采集的数据推送到Logstash、或ES存储(它可以直接推送到es,只是常用我们把它推送到logstash。)

filebeat也有简单的过滤,写在配置文件里面,如果复杂一点的,通常采用logstash。

早期的ELK架构中使用Logstash收集、解析日志,但是Logstash对内存、CPU、io等资源消耗比较高。相比Logstash,Beats所占系统的CPU和内存几乎可以忽略不计。

​ filebeat内置的模块,比如采集Nginx,mysql,HAProxy Module,AWS,tomcat,IIS Module,Iptables Module ,MySQL Module的日志,直接用就可以了,模块写好了采集这些日志的格式,在filebeat的yml配置文件可以配置。

五、kafka相关

发布订阅消息传递

  • 在发布-订阅消息系统中,消息被持久化到一个topic中
  • 消费者可以订阅一个或多个topic,消费者可以消费该topic中所有的数据,同一条数据可以被多个消费者消费,数据被消费后不会立马删除。
  • kafka采取拉取模型,由自己控制消费速度,以及消费的进度,消费者可以按照任意的偏移量进行消费

kafka介绍

Kafka  是一种支持高吞吐量、有容错性、持久性、的分布式发布订阅消息系统,它是apahe基金会开源的软件。它是消息中间件的一种,由scala和java语言开发。

#特性
高吞吐量 :即使是非常普通的硬件Kafka也可以支持每秒数百万的消息。
容错性:允许集群中节点失败。(若副本数量为n,则允许n-1个节点失败)
持久性:存放数据在磁盘,可以设置存放时间,设置永久都可以。
顺序保证:在大多数情况下,数据处理的顺序很重要,大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理,kafka一个partition内的消息的有序性。注意是一个partition,如果数据分开保存在多个partition的话,顺序是会不分先后可以读取到的。

异步通信: 很多时候,用户不想也不需要立即处理消息,消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它,想向队列中放入多少消息就放多少,然后在需要的时候再去处理。

术语

"Broker" Kafka角色被称为broker,它只负责消息传递。
"Topic" 每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处);类似于文件系统中的文件夹,事件是该文件夹中的文件。
	Kafka 中的主题始终是多生产者和多订阅者:一个主题可以有零个、一个或多个向其写入事件的生产者,以及零个、一个或多个订阅这些事件的消费者。主题中的事件可以根据需要随时读取——与传统的消息传递系统不同,事件在消费后不会被删除。相反,您可以通过每个主题的配置设置来定义 Kafka 应该将您的事件保留多长时间,之后旧事件将被丢弃。Kafka 的性能在数据大小方面实际上是恒定的,因此长时间存储数据是非常好的。
	我个人把topic理解为一个表,每个事件是一行,在读取和写入都要指定这个表名字;其实官方理解为文件夹,这也是很直观的。
	物理上不同topic的消息分开存储。

"Producer" 负责发布消息到Kafka broker,通常是应用服务。
"Consumer" 消息消费者,向Kafka broker读取消息的客户端,通常是logstash或es。
"Consumer Group" 每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。
"ISR" (in sync replicas)加入同步队列的副本,可以理解为一个加入同步队列清单,默认的broker在ISR清单中,不在清单的,就是broker挂机了。

kafka增加消费的并发方式:

1、使用增加分区数量、消费者数量方式增加消费能力。比如3个分区,一个人消费者,消费者压力很大。扩大到3个消费者,3个消费者属于一个组,这样一个消费者可以消费1个分区,数据不会重复,增加了消费者的能力,增加了消费的并发。

原理

#个人理解
	kafka是把数据存在topic中,每个topic包括多个partition,partition可以分布在各个broker主机(这个实现了kafka的分布式特性),其中partition有副本数,副本支持读操作。
	leader,follower是负责管理分区的数据同步,因为partition保存在不同机器,就是说明数据保存在不同机器,如何保证数据一致性,leader来协调。Leader 处理一切对 Partition (分区)的读写请求
	Follower 唯一的任务就是从Leader那里异步复制消息,保持与Leader一致的状态。如果Leader宕机,其中一个Follower会被选举为新的Leader。
	一个分区保证了数据的顺序性,多个分区数据顺序性就没有了;分区里面是切片,切片是一个顺序的存储数据。

partition数量修改

partition数不可以减少,只可以增加。

如何选举leader?

集群中任意一台 Broker都能充当leader的角色,leader有的也叫控制器,但是在运行过程中,只能有一个Broker成为leader,行使其管理和协调的职责。实际上,Broker 在启动时,会尝试去ZooKeeper 中创建 /controller 节点。
Kafka 当前选举控制器的规则是:第一个成功创建/controller临时节点的Broker会被指定为控制器。

集群扩容

​ 集群加入一台新机器怎么配置。

文档:https://kafka.apache.org/documentation.html#basic_ops_cluster_expansion

	1、将服务器添加到 Kafka 集群很容易,只需为它们分配一个唯一的代理 ID 并在您的新服务器上启动 Kafka。然而,这些新服务器不会自动分配任何数据分区,因此除非将分区移动到它们,否则它们将不会做任何工作,直到创建新主题。
	2、迁移数据的过程是手动启动的,但完全自动化。在幕后发生的事情是,Kafka 将添加新服务器作为它正在迁移的分区的追随者,并允许它完全复制该分区中的现有数据。当新服务器完全复制此分区的内容并加入同步副本时,现有副本之一将删除其分区的数据。
   (其实就是要你指定topic,哪些topic进行迁移,然后写一个json格式的文件,利用分配工具进行topic的迁移。--generate 参数生成计划,--execute参数执行计划,--verify验证结果 )

	#迁移前topic信息。 
	#Replicas: 1 表示副本在broker序号1
[root@elk3 kafka]# bin/kafka-topics.sh  --topic testtopic22 --describe  --bootstrap-server 192.168.68.22:9092      
Topic: testtopic22      TopicId: P74XEkE3SH6kgDxG8hZEIg PartitionCount: 1       ReplicationFactor: 1    Configs: segment.bytes=1073741824
        Topic: testtopic22      Partition: 0    Leader: 1       Replicas: 1     Isr: 1
        
   #指定迁移topic。测试用testtopic22
[root@elk3 bin]# vi topics-to-move.json
{"topics": [{"topic": "testtopic22"}],
  "version":1
}
	#生成迁移的计划,"partition":0 表示分区是0,--broker-list "2"迁移到的broker序号,--generate 参数生成计划
[root@elk3 bin]# ./kafka-reassign-partitions.sh --bootstrap-server 192.168.68.129:9092 --topics-to-move-json-file topics-to-move.json --broker-list "2" --generate               
Current partition replica assignment
{"version":1,"partitions":[{"topic":"testtopic22","partition":0,"replicas":[1],"log_dirs":["any"]}]}
Proposed partition reassignment configuration
{"version":1,"partitions":[{"topic":"testtopic22","partition":0,"replicas":[2],"log_dirs":["any"]}]}

	#把建议的计划保存到json文件
[root@elk3 bin]# vi topic-reassignment.json 
{"version":1,"partitions":[{"topic":"testtopic22","partition":0,"replicas":[2],"log_dirs":["any"]}]}
	#开始迁移。--execute参数执行计划。
[root@elk3 bin]# ./kafka-reassign-partitions.sh --bootstrap-server 192.168.68.129:9092 --reassignment-json-file topic-reassignment.json --execute
Current partition replica assignment
{"version":1,"partitions":[{"topic":"testtopic22","partition":0,"replicas":[1],"log_dirs":["any"]}]}
Save this to use as the --reassignment-json-file option during rollback
Successfully started partition reassignment for testtopic22-0
	#查看执行状态。--verify 
[root@elk3 bin]# ./kafka-reassign-partitions.sh --bootstrap-server 192.168.68.129:9092 --reassignment-json-file topic-reassignment.json --verify 
Status of partition reassignment:
Reassignment of partition testtopic22-0 is complete.

Clearing broker-level throttles on brokers 1,2
Clearing topic-level throttles on topic testtopic22

	#查看迁移后信息。
[root@elk3 bin]# ./kafka-topics.sh --describe --topic testtopic22 --bootstrap-server 192.168.68.129:9092
Topic: testtopic22      TopicId: P74XEkE3SH6kgDxG8hZEIg PartitionCount: 1       ReplicationFactor: 1    Configs: segment.bytes=1073741824
        Topic: testtopic22      Partition: 0    Leader: 2       Replicas: 2     Isr: 2

集群缩容

删除一台机器

这个官方说后期会出一个工具,前期就直接关机就好了,理论是你做好了集群就直接关闭机器,当然在关闭前,你想要把数据迁移走也是可以的,后期官方会出工具
https://kafka.apache.org/documentation/#basic_ops_decommissioning_brokers