分布式流处理平台Kafka
kafaka简介
kafka之前是有LinkedIn开发并开源的,LinkedIn之前也开源过很多系统,比如下面:
1. 分布式数据同步系统Databus,是一个低延迟、可靠的、支持事务的、保持一致性的数据变更抓取系统。它可以将来源无关的数据同步,比如我们项目有很多数据来源,那么我们可以将这些数据同步到同一个地方去。
2. 高性能计算引擎Cubert。
3. java异步处理框架ParSeq。
4. kafka流处理平台。
LinkedIn将kafka开源后,后来kafka被Apache基金会收纳了,并于2012年项目成熟后从Apache Incubator毕业成为Apache的顶级项目。
kafka的官方地址: http://kafka.apache.org/
kafka相关资料:
Apache生态圈网址:https://cwiki.apache.org/confluence/display/kafka/ecosystem
kafka版本:http://kafka.apache.org/downloads (可以查看每个版本的发布时间 )
Kafka可视化工具:https://www.kafkatool.com/download.html
kafka集群监控工具eagle:http://www.kafka-eagle.org/
Zookeeper:https://zookeeper.apache.org/
那么kafka到底是什么能做什么,官方解释如下
从官方说明可以知道如下:
1.可以发布和订阅数据的流,类似于消息队列。可以源源不断的发布数据流,并且消费端可以不断的去消费数据流。
2.可以存储数据流,并且可以容忍存储过程中发生的错误。
3.可以在数据产生的时候就可以对数据进行处理。
Kafka的功能
1.构建实时数据流管道。
2.构建实时数据处理应用。
简单说就是可以传输数据及处理数据。
Kafka可以说是,面向数据流的生产,转换,存储,消费为整体的处理平台。
kafka是一个消费队列,但是也不仅仅是一个消费队列。
Kafka的应用场景
1.消息队列。相比其他消息队列支持多副本,多分区,有很高的容错性,吞吐量也很高,可以处理大规模的数据,消息可以重复被消费。
2.日志收集。kafka可以支持更多的数据源,忽律不同日志文件的差异,可以抽象的将数据转换以数据流的方式传递数据,并且kafka延迟更低。
3.行为跟踪记录。使用kafka的发布订阅模式,可以使用kafka用来记录用户浏览活动时候,如浏览网页、搜索、点击等操作活动,这些信息被各个服务器发布到kafka的topic中,然后消费者通过订阅这些topic来做实时的监控分析以及其他的离线处理。
6.事件源。
7.持久性日志(commit log)。
Kafka基本概念
1.Topic:逻辑概念,kafka消息类别,对数据进行分类和隔离,方便对消息管理。
2.Producer(生产者):消息和数据的生产者,向Kafka的一个topic发布消息的进程/代码/服务。由外围应用程序去实现。
3.Consumer(消费者):消息和数据的消费者,订阅数据(topic)并且处理其发布消息的进程/代码/服务。由外围应用程序去实现。
4.Consumer Group:逻辑概念,对于同一个topic,会广播给不同的group ,一个group中只有一个Consumer可以消费该消息。
5.Broker:物理概念,kafka集群中的每个Kafka节点,相当于kafka服务物理上的服务器节点。一个Kafka节点就是一个broker。
6.Partition:物理概念,Kafka下数据存储的基本单元,一个topic数据会被分散存储到多个Partition,每一个Partition是有序的,那么可以得知每个Topic包含一个或多个Partition。kafka将一个Partition会放在一个Broker里面。
1)每一个Topic会被切分为多个Partitions。
2)消费者数目少于或者等于Partition的数目。避免一个partition被多个Consumer消费。
3)Broker Group中的每一个Broker保存Topic的一个或者多个Partitions。Broker Group是对broker分组,多个Broker节点组成一个Broker Group。
4)Consumer Group中的仅有一个Consumer读取Topic的一个或者多个Partitions,并且是唯一的Consumer。Consumer Group避免一个分区呗多个Consumer消费。
7.Replication(副本):同一个Partition可能会有多个副本Replica,多个Replica之间数据是一致的。当集群中broker挂掉情况,系统可以主动使Replica提供服务。系统默认设置每一个topic的replication为1,也就是没有副本,可以在创建topic时候单独设置,可以节省资源。
8.Replication Leader:一个Partition的多个Replica上需要一个Leader负责该Partition上与Producer和Consumer交互,并且只有一个。
Replication特点:
Replication的基本单位是topic的Partition,可以很细粒度的管理副本。
所有的读和写都从leader进,followers只是作为备份。
followers必须及时复制leader的数据。当leader挂掉,副本再去承接读和写的时候数据不会丢失。
leader和follower的同步机制:
写数据的时候,生产者就写 leader,然后 leader将数据落地写本地磁盘,接着其他 follower 自己主动从 leader来pull数据。一旦所有 follower同步好数据了,就会发送 ack给 leader,leader收到所有 follower的 ack之后,就会返回写成功的消息给生产者。
消费的时候,只会从 leader去读,但是只有一个消息已经被所有 follower都同步成功返回 ack的时候,这个消息才会被消费者读到。
以上特点就是可以增加容错性及可扩展性。
9.ReplicaManager:负责管理当前borker所有分区和副本的信息,处理KafkaController发起的请求,副本状态的切换,添加,读取消息。如果Replication Leader挂掉了,ReplicaManager还负责选举出新的Replication Leader。
Kafka特点
1. 首先kafka是一个分布式系统。
2. 有多分区,每个Partition。
3. 多副本。
4. 多订阅者。kafka一个Topic可以有一个或者多个订阅者,但是每个订阅者都要有一个Partition。
5. 基于Zookeeper的调度,负责元数据信息的管理和维护。
6. 高性能,主要有高吞吐量,低延时,高并发,时间复杂度为O(1)。
7. 持久性和扩展性,kafka也是一个存储系统,可以持久化数据。kafka提供了多副本来增强数据的高可用。支持在线水平扩展,一个Broker可以保存一个或者多个Partition,通过增加机器就可以存放新的Partition。
8. 消息自动平衡。可以避免消息过于集中在服务器的某几台机器上,可以防止过于频繁的访问这几台服务器上,从而才生热点问题。通过消息自动平衡功能可以将消息均衡到各个服务器上,在消费者订阅时候可以达到连接的一个均衡。
kafka基本结构
图片来源于官网
Producers产生数据经由Kafka然后在流向了Consumer,kafka暴露出两个接口
1. Connectors:跟数据库交互。
2. Stream Processors:跟其他App端一种流式的交互。
下面是提供的调用Api
1. Producer Api
2. Consumer Api
3. Stream Api
4. Connectors Api
kafka是强依赖于zookeeper组件。体现在下面三方面。
1. 将一些信息存放在zookeeper上,来进行所有Broker的管理。
1) broker信息。
2)topic还有Partition的分布信息。Producer生产的数据推送到kafka集群的时候,一些信息的变更都会记录在Zookeeper上。
2. 记录消息分区于消费者的关系及消息消费进度Offset记录。
3. 生产者将消息发送到Broker上使用zookeeper进行负载均衡。
kafka消息结构
Offset(消息偏移量):记录当前消息偏移是多少。
Length:记录当前整个消息长度。
CRC32:校验字段,用于校验当前消息的完整性。可以避免因为数据不完整而导致消费失败。
Magic:现在很多分布式系统都有这个字段。它是一个固定的数字,可以快速判断是不是kafka的消息。假如该Magic字段信息和kafka设定的Magic信息不一致,kafka会丢掉信息。
attributes:可选字段,只有一位,是一个枚举值。用于存放当前消息一些属性。
Key:没有长度限制。
Value:没有长度限制。
Kafka高级特性
1.消息事务
很多消息中间件并不存在消息事物这个概念。而在kafka中流处理需求增强,以及现在对不准确的数据处理容忍度在降低,为了保证对数据处理结果的准确性,所以需要消息事务。
数据传输事务定义有3种如下:
1) 最多一次:消息不回被重复发送,最多被传输一次,但也有可能不传输。
2)最少一次:消息不回被漏发送,最少被传输一次,但也有可能被重复传输。这个也是目前大部分消息队列的传输模式,虽然不回漏发但是可能会多次重复发送,那么就需要消费端自己做好幂等性。
3)精确的一次(Exactly once):不会漏传输也不会重复传输,每个消息都会被传输仅仅一次。这样不用担心数据缺失,也不用在消费端做幂等校验。
kafka自身是如何保证事务性?
1)内部重试机制:可以处理内部超时,内部局部失败等问题。比如kafka一个消息传输组件Procedure,它有个send()方法去进行数据等发送,如果发送失败会重新发送,而且自己做了幂等处理无需用户关注。
2)多分区原子写入:和数据库原子性一样,保证数据写入的完整性,kafka事务保证每个topic的原子写入。
3)避免僵尸实例:
可以避免僵尸实例对事务性的破坏,每个事务Producer分配一个唯一的transactional.id,在进程重新启动时kafka能够区分不同的Producer实例,避免针对同一个Producer分配不同的实例。
Kafka增加了一个与transactional.id相关的epoch,用于存储每个transactional.id内部元数据的变更。一旦epoch被触发,任何具有相同的transactional.id和更旧的epoch的Producer被视为僵尸,Kafka会拒绝来自这几Procedure的后续事务性写入,不会因为僵尸实例的存在而产生脏数据。这个就相当于一种版本机制,老得版本会被新的版本锁替代。
kafka事务的支持对于用户来说相当于一个黑盒子,用户无需关心底层。
2.零拷贝(zero copy):
零拷贝技术在很多系统中都有实现,比如Linux系统,其他的MQ系统都有应用。
先看下零拷贝技术原理
文件传输到网路的公共数据路径:
操作系统将数据从磁盘读入到内核空间的页缓存。
应用程序将数据从内核空间读入到用户空间缓存中。因为应用程序是无法之间读取内核空间的信息。
应用程序将数据写回到内核空间到socket缓存中。
操作系统将数据从socket缓冲区复制都网卡缓冲区,以便将数据经网络发出。
所以以上可以看出一个文件从磁盘到网卡发送到网络过程中需要经历四次拷贝。
零拷贝过程
操作系统将数据从磁盘去入到内核空间的页缓存。
将数据的位置和长度的信息的描述符增加至内核空间(socket缓冲区)。
操作系统将数据从内核拷贝到网卡缓冲区,以便将数据经网络发出。
零拷贝优化后是:内核空间和用户空间的交互次数为零。
文件传输到网络的公共数据路径演变图
网络传输持久性日志块:
kafka本身是对大量的流数据处理,需要通过网络传输持久性的日志块,这个本身是非常消耗性能的。kafka使用Java Nio channel.transforTo()方法去实现零拷贝技术,它在底层其实是使用了Linux sendfile系统调用,通过sendfile系统调用来将整体的拷贝性能极大的提升。
kafka安装
1.安装要点:kafka依赖于Zookeeper,Kafka通过Zookeeper来对元数据信息的管理,比如集群,主题,分区等,所以要安装好Zookeeper。
2.下载kafka,我下载的是这个版本
php kafka扩展安装
官方地址:https://arnaud.le-blanc.net/php-rdkafka-doc/phpdoc/rdkafka.installation.html
使用pecl安装
如果安装出现下面错误
Connection to `ssl://pecl.php.net:443' failed: Connection refused
出现这个错误主要是因为缺失默认证书导致的,解决方法如下:
1. 查看 default_cert_file 的路径
2. 下载证书
wget -P /etc/ssl/ curl.haxx.se/ca/cacert.pem #去掉前面的http:// 我在操作时候会报错 chmod 744 /etc/ssl/cacert.pem
操作过程如下
然后在执行命令
pecl install rdkafka
就可以正常下载安装了。
最后在php.ini文件中添加extension=rdkafka.so
在执行php -m | grep rdkafka查看,验证添加成功。
使用phpinfo查看,安装成功。
其他的错误:
在pecl install rdkafka时候会报下面的错误。
是因为有一个依赖:librdkafka。解决方法
git clone git://github.com/edenhill/librdkafka.git #这里协议写成git,如果写成https会下载不下来 cd librdkafka ./configure make && make install
然后在执行pecl install rdkafka,执行成功,如下:
php调用kafka参考:https://github.com/arnaud-lb/php-rdkafka
其他的客户端调用 : https://cwiki.apache.org/confluence/display/KAFKA/Clients