基于Kafka的nginx日志收集分析与监控平台(1)+https://developer.aliyun.com/article/1557847
4、为什么选择filebeat?
日志采集器有很多,比如Logstash,虽然Logstash的功能强大,但是它依赖java并且在数据量大的时候进程会消耗过多的系统资源,会严重影响业务系统的性能。
而filebeat就是一个完美的替代者,它基于Go语言没有任何依赖,配置文件简单。同时,filebeat比logstash更加轻量级,所以占用系统资源极少,非常适合安装在生产机器上。
Filebeat可以直接将数据发送到Elasticsearch、Kafka或者Redis,在那里可以进一步处理和增强数据,然后在Kibana中将其可视化,目前来说Filebeat是 ELK 日志系统在Agent上的第一选择。
5.4 kafka集群
5.4.1 什么是kafka?
Kafka是是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志、访问日志,消息服务等等。
kafka是一个消息中间件。
kafka通常用在:日志收集、业务解耦、流量削峰。
kafka的主要应用场景是:日志收集系统和消息系统。
5.4.2 什么是消息中间件?
面向消息的系统(消息中间件)是在分布式系统中完成消息的发送和接收的基础软件。消息中间件也可以称消息队列,是指用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息队列模型,可以在分布式环境下扩展进程的通信。
消息中间件:是两种通信模式:点对点、发布订阅(kafka)。
kafka是消息中间件中的一种。kafka支持的通信方式:发布—订阅。
5.4.3 使用kafka做日志统一收集的原因
1、故障发生时方便定位问题
2、日志集中管理,后续需要日志的程序需要直接懂kafka获取日志即可。
3、尽可能的减少日志处理对nginx的影响。
kafka的日志在/opt/kafka_2.12-2.8.1/logs下,主要看server.log
5.4.4 kafka基本架构
从上图中,producer就是生产者,是数据的入口。图中的producer在写入数据的时候永远在找leader,不会直接将数据写入follower。
消息写入leader之后,follower是主动的去leader进行同步的!producer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内的数据是有序的!
5.4.5 kafka相关概念
Producer:生产者,消息的产生者,是消息的入口。
Broker:broker是kafka实例,每个服务器上有一个或者多个kafka的实例,我们暂时认为每个broker对应一台服务器,每个kafka集群内的broker都有一个不重复的编号,如:broker1、broker2、broker3。
Topic:消息的主题,可以理解为消息的分类,kafka的数据保存在topic。在每个broker上都可以创建多个topic。
Partition:topic的分区,每个topic可以有一个或者多个分区(partition),partition是比较具体的东西,partition在服务器上的表现形式就是一个一个的文件夹,每个partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件、log文件、.timeindex文件三个文件,log文件就是实际是存储message的地方,而index和timeindex文件为索引文件,用于检索消息。分区的作用是做负载,提高kafka的吞吐量。同一个topic在不同分区的数据是不重复的,partition的表现形式就是一个一个的文件夹。
图中,这个的partition有三组segment文件,每个log文件的大小是一样的,但是存储的message数量是不一定相等的,(每条的message大小不一致)。文件的命名是以该segment最小offset来命令的,如000.index存储offset为0~368795的消息,kafka就是利用分段+索引的方式来解决查找效率的问题。
Segment:partition物理上由多个segment组成,Partition的结构:Partition在服务器上的表现形式就是一个一个的文件夹,每个Partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件、.log文件、.timeindex文件这三个文件,log文件就实际是存储message的地方,而index和timeindex文件为索引文件,用于检索消息。
Replication:每个分区都有多个副本,副本的作用就是做备胎。当主分区(leader)故障的时候会选择一个备胎(follower)上位,成为leader。在kafka中默认副本的最大数量是10个,并且副本的数量不能大于一个副本(包括自己)。
kafka的副本机制每个主题上会划分成若干个分区。副本就是在分区层级下定义的,每个分区都会配置若干个副本。在同一个分区下的所有副本保存有相同的消息序列,这些副本保存在不同的broker上,能够对抗部分broker宕机带来的数据不可用。
Message:每一条发送的消息主体。
Consumer:消费者,即消息的消费方,是消息的出口。
Consumer Group:我们可以将多个消费组组成一个消费者组,在kafka的设计中同一个分区的数据只能被消费者组中的某一个消费者消费。同一个消费者组的消费者可以消费同一个topic的不同分区的数据,这也是为了提高kafka的吞吐量。
Zookeeper:kafka集群依赖zookeeper来保存集群的元信息,来保证系统的可用性。
5.4.6 kafka工作流程分析
1、发送数据:
从上图中,producer就是生产者,是数据的入口。图中的producer在写入数据的时候永远在找leader,不会直接将数据写入follower。
消息写入leader之后,follower是主动的去leader进行同步的!producer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内的数据是有序的。
2、写入数据示意图如下:
数据会写入到不同的分区,那kafka为什么要做分区:
分区的主要目的是:
① 方便扩展。因为一个topic可以有多个partition,所以我们可以通过扩展机器去轻松应对日益增长的数据量。
② 提高并发。以partition为读写单位,可以多个消费者同时消费数据,提高了消息的处理效率。
3、保存数据:
producer将数据写入kafka后,集群就需要对数据进行保存了!kafka将数据保存在磁盘,kafka初始会单独开辟一块磁盘空间,顺序写入数据(效率比随机写入高)。
5.4.6 kafka如何保证高可用?
多个broker +多个partition +多个 replica
5.4.7 kafka如何保证数据一致性?
如何保证消费者消费数据一致性:消费者可以连接到任何一台机器,机器会告诉它leader在哪里,如何通过leader进行外界交互。
同一个消费组,里面的消费者同一时刻只能消费一个partition的数量。
一个消费组里面的每一个消费者可以同时去消费一个topic里面的不同分区里的数据。
针对topic来说。只要能连接上这个kafka,消费者都可以进行消费,只要有权限获取到topic,消费者之间的消费互不影响。
1、producer可以通过request.required.acks设置。
① 生产者一致性:
保证消息不丢失是一个消息队列中间件的基本保证,那producer在向kafka写入消息的时候,为了保证消息不丢失,就可以通过ACK回答机制。在生产者向队列写入数据的时候可以设置参数来确定是否确认kafka接收到数据,ack参数可以设置为1、1、-1
acks =0 ,生产者不会等待任何来自服务器的响应。生产者不需要接收响应,发完就发下一条,不确保消息是否发送成功。安全性最低但是效率最高。
ack1=1 (默认值):leader收到就会发送响应给生产者,只需要确保leader发送成功,再发送下一条。
acks=-1 (ISR),等待ISR列表中的每一个副本都接收到,才给生产者响应。生产者才会接收到来自服务器的成功响应,这个模式是最安全的,但是效率很低。
acks=2,除了一个leader收到,还需要一个flower收到。
ack= n,除了一个leader收到,还需要等到n-1个follower收到。
ack= all,代表producer往集群发送数据需要所有的follower都完成从leader的同步才会发送下一条,确保leader发送成功和所有的副本都完成备份。安全性最高,但是效率最低。
2、消费者消费数据时,引入了High Water Mark机制、木桶效应,只能消费ISR列表里偏移量最小的副本的消息数量。
5.4.8 kafka中怎样才能知道消费者消费到哪一步了?
1、使用offset偏移量:记录消费者消费偏移量。
本来offset保存在本地,但是现在保存在kafka的**__consumer_offsets**中主题中,每次消费每隔几秒就会写入,需要的时候,就会自动去kafka的主题里面拿。
也阔以自己写一个文档,里面的写入你上次消费的记录。
消费者消费的时候,会记录自己的消费偏移量,消费偏移量可以自己保存在本地,也可以提交到kafka的_consumer_offsets主题里的保存。
bin/kafka-console-consumer.sh --bootstrap-server 192.168.2.152:9092 --topic nginxlog --from-beginning
执行kafka-console-consumer.sh的时候,就会自动保存到kafka主题中。
[root@nginx-kafka01 opt]# cd /data [root@nginx-kafka01 data]# ls cleaner-offset-checkpoint __consumer_offsets-30 log-start-offset-checkpoint __consumer_offsets-0 __consumer_offsets-33 meta.properties __consumer_offsets-12 __consumer_offsets-36 nginxlog-0 __consumer_offsets-15 __consumer_offsets-39 recovery-point-offset-checkpoint __consumer_offsets-18 __consumer_offsets-42 replication-offset-checkpoint __consumer_offsets-21 __consumer_offsets-45 replication-offset-checkpoint.tmp __consumer_offsets-24 __consumer_offsets-48 sc-0 __consumer_offsets-27 __consumer_offsets-6 sc-1 __consumer_offsets-3 __consumer_offsets-9 sc-2 [root@nginx-kafka01 data]# cd nginxlog-0/ [root@nginx-kafka01 nginxlog-0]# ls 00000000000000000000.index 00000000000000000000.timeindex 00000000000000000000.log leader-epoch-checkpoint index记录每个offset所对应的的每个位置,是一个二进制文件,真正的是存放在多个log文件中。 发送过来的数据都存放在log文件中。 /data里面存放kafka数据的位置:
数据的存储目录:
文件夹:-<分区号>
每一个partition的数据都是由很多个segment存储,每一个segment(段)。每一个segment由一个index(索引)和log文件组成。分出多个segment:段便于做数据清理。
存放在多个log文件里面的原因:
方便kahka清除数据,按时间或者大小存储,不会永久保存,定期保存,默认保存七天,可以进行修改。修改配置文件为:/opt/kafka_2.12-2.8.1/config
kafka可以按照两个维度清理数据:
1、按照大小
2、按时间
任意一个条件满足,都可以触发日志清理。
5.5 zookeeper
5.5.1 什么是zookeeper?
zookeeper是分布式应用协调管理服务、配置管理、域名管理、分布式数据管理、集群管理。
5.5.2 zookeeper的工作原理
zookeeper架构图:
zk集群中,节点存活数必须过半,集群才能正常使用。一般集群的节点数都设置为奇数,方便选举,而且容错率一样。
如果不过半容易脑裂。就比如一个大集群,里面有5个节点,zk1-5,里面存活的数必须过半,进行选举,所以节点里面一般以奇数。如果zk4和zk5坏掉了,至少也得有前三台都存活。
什么是脑裂?脑裂(split -brain)就是“大脑分裂”,也就是本来一个“大脑”被拆分成了两个或多个“大脑”,我们都知道,如果一个人有多个大脑,如何是相互独立,就会导致人体“手舞足蹈,不听使唤”。
脑裂通常会出现在集群环境中,比如ElasticSearch、Zookeeper集群,而这些集群环境有一个统一的特点,就是它们有一个大脑,比如ElasticSearch集群中有一个Master节点,Zookkeeper集群中有Leader节点。
Zookeeper集群中的脑裂场景
对于一个集群,想要提高这个集群的可用性,通常会采用多机房部署,比如现在有一个由6台zkServer所组成的一个集群,部署在两个机房里面:
正常情况下,这个集群中只会有一个leader,那么如果机房之间的网络断掉之后,两个机房内的zkServer还是可以相互通信的,如果不考虑过半机制的话,那么就会有出现每个机房内部都将会选出一个Leader。
对于这种情况的话,我们可以看得出来,原本应该是统一的一个集群对外提供服务的,但是现在变成了两个集群同时对外提供服务,如果过了一会,断了的网络突然联通了,那么此时就会出现问题了,两个集群刚刚都对外提供服务了,就会出现数据应该怎么合并,数据冲突怎么解决等问题。
刚刚说到脑裂场景的时候,有一个前提条件就是没有考虑过半机制,所以实际上Zookeeper集群中是不会出现脑裂问题的,而不会出现的原因就跟过半机制相关。
基于Kafka的nginx日志收集分析与监控平台(3)+https://developer.aliyun.com/article/1557851