关于kafka:聊聊-Kafka-Consumer-源码解析之-ConsumerNetworkClient

一、Consumer 的应用Consumer 的源码解析次要来看 KafkaConsumer,KafkaConsumer 是 Consumer 接口的实现类。KafkaConsumer 提供了一套封装良好的 API,开发人员能够基于这套 API 轻松实现从 Kafka 服务端拉取音讯的性能,这样开发人员基本不必关怀与 Kafka 服务端之间网络连接的治理、心跳检测、申请超时重试等底层操作,也不用关怀订阅 Topic 的分区数量、分区正本的网络拓扑以及 Consumer Group 的 Rebalance 等 Kafka 具体细节,KafkaConsumer 中还提供了主动提交 offset 的性能,使的开发人员更加关注业务逻辑,进步了开发效率。 上面咱们来看一个 KafkaConsumer 的示例程序: /** * @author: 微信公众号【老周聊架构】 */public class KafkaConsumerTest { public static void main(String[] args) { Properties props = new Properties(); // kafka地址,列表格局为host1:port1,host2:port2,...,无需增加所有的集群地址,kafka会依据提供的地址发现其余的地址(倡议多提供几个,以防提供的服务器敞开) 必须设置 props.put("bootstrap.servers", "localhost:9092"); // key序列化形式 必须设置 props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); // value序列化形式 必须设置 props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("group.id", "consumer_riemann_test"); KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); // 可生产多个topic,组成一个list String topic = "riemann_kafka_test"; consumer.subscribe(Arrays.asList(topic)); while (true) { ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100)); for (ConsumerRecord<String, String> record : records) { System.out.printf("offset = %d, key = %s, value = %s \n", record.offset(), record.key(), record.value()); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }}从示例中能够看出 KafkaConsumer 的外围办法是 poll(),它负责从 Kafka 服务端拉取音讯。外围办法的具体细节我想放在下一篇再细讲,关乎生产侧的客户端与 Kafka 服务端的通信模型。这一篇咱们次要从宏观的角度来分析下 Consumer 生产端的源码。 ...

November 30, 2021 · 5 min · jiezi

关于kafka:kafka学习笔记

https://kafka.apache.org/down... 作用命令形容启动 ZKbin/zookeeper-server-start.sh -daemon config/zookeeper.propertiesKafka 安装包自带 ZK,能够单节点启动启动 Kafka 服务器bin/kafka-server-start.sh config/server.properties 创立 Topic(test)bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test Topic 列表bin/kafka-topics.sh --list --zookeeper localhost:2181 启动 Producerbin/kafka-console-producer.sh --broker-list localhost:9092 --topic test 启动 Consumerbin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning Topic 相干信息(test)bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic test启动 ZK

November 28, 2021 · 1 min · jiezi

关于kafka:kafka消费组

conusmer分区调配是通过组治理协定来施行的:具体如下: consumer group外面的各个consumer都向 group coordinator发送JoinGroup申请,这样group coordinator就有了所有consumer的成员信息,于是它从中选出一个consumer作为Leader consumer,并通知Leader consumer说:你拿着这些成员信息和我给你的topic分区信息去安顿一下哪些consumer负责生产哪些分区吧 接下来,Leader consumer就依据咱们配置的调配策略(由参数partition.assignment.strategy指定)为各个consumer计算好了各自待生产的分区。于是,各个consumer向 group coordinator 发送SyncGroup申请,但只有Leader consumer的申请中有分区调配策略,group coordinator 收到leader consumer的分区调配计划后,把该计划下发给各个consumer。画个图,就是上面这样的:而在失常状况下 ,当有consumer进出consumer group时就会触发rebalance,所谓rebalance就是从新制订一个分区调配计划。而制订好了分区调配计划,就得及时告知各个consumer,这就与 heartbeat.interval.ms参数无关了。具体说来就是:每个consumer 都会依据 heartbeat.interval.ms 参数指定的工夫周期性地向group coordinator发送 hearbeat,group coordinator会给各个consumer响应,若产生了 rebalance,各个consumer收到的响应中会蕴含 REBALANCE_IN_PROGRESS 标识,这样各个consumer就晓得曾经产生了rebalance,同时 group coordinator也晓得了各个consumer的存活状况。 那为什么要把 heartbeat.interval.ms 与 session.timeout.ms 进行比照呢?session.timeout.ms是指:group coordinator检测consumer产生解体所需的工夫。一个consumer group外面的某个consumer挂掉了,最长须要 session.timeout.ms 秒检测进去。 举个示例session.timeout.ms=10,heartbeat.interval.ms=3,session.timeout.ms是个"逻辑"指标,它指定了一个阈值---10秒,在这个阈值内如果coordinator未收到consumer的任何音讯,那coordinator就认为consumer挂了。而heartbeat.interval.ms是个"物理"指标,它通知consumer要每3秒给coordinator发一个心跳包,heartbeat.interval.ms越小,发的心跳包越多,它是会影响发TCP包的数量的,产生了理论的影响,这也是我为什么将之称为"物理"指标的起因。 如果group coordinator在一个heartbeat.interval.ms周期内未收到consumer的心跳,就把该consumer移出group,这有点说不过去。就如同consumer犯了一个小错,就一棍子把它打死了。事实上,有可能网络延时,有可能consumer呈现了一次长时间GC,影响了心跳包的达到,说不定下一个heartbeat就失常了。 而heartbeat.interval.ms必定是要小于session.timeout.ms的,如果consumer group产生了rebalance,通过心跳包外面的REBALANCE_IN_PROGRESS,consumer就能及时晓得产生了rebalance,从而更新consumer可生产的分区。而如果超过了session.timeout.ms,group coordinator都认为consumer挂了,那也当然不必把 rebalance信息通知该consumer了。 在while true循环中执行consumer.poll拉取音讯这个过程中,其实背地是有2个线程的,即一个kafka consumer实例蕴含2个线程:一个是heartbeat 线程,另一个是processing线程,processing线程可了解为调用consumer.poll办法执行音讯解决逻辑的线程,而heartbeat线程是一个后盾线程,对程序员是"暗藏不见"的。如果音讯解决逻辑很简单,比如说须要解决5min,那么 max.poll.interval.ms可设置成比5min大一点的值。而heartbeat 线程则和下面提到的参数 heartbeat.interval.ms无关,heartbeat线程 每隔heartbeat.interval.ms向coordinator发送一个心跳包,证实本人还活着。 在用户线程中,个别会做一些失败的重试解决。原本生产解决须要很长的工夫,如果某个consumer解决超时:音讯解决逻辑的时长大于max.poll.interval.ms (或者音讯处理过程中产生了异样),被coordinator移出了consumer组,这时因为失败的重试解决,主动从线程池中拿出一个新线程作为消费者去订阅topic,那么意味着有新消费者退出group,就会引发 rebalance

November 19, 2021 · 1 min · jiezi

关于kafka:Kafka-网络响应处理

接管实现的数据broker的响应,是通过监听OP_READ事件开始的。当有read事件的时候,就会通过SelectionKey找到对应的KafkaChannel。 KafkaChannel接管到响应,就开始读取收到的数据,因为网络传输会有拆包的过程,所以接收数据的时候,就须要进粘包,kafka是这样解决的,首先定义一个音讯的大小,用4个字节示意,而后前面跟着音讯内容。 比方5aaaaa3bbb4cccc这种音讯。 读取的时候会先拿到5,再读取aaaaa,这样第一个音讯就读取到了。 而后往下读,拿到3,再读取bbb,这样第二个音讯就读取到了。 而后往下读,拿到4,再读取cccc,这样第三个音讯就读取到了。 读完后,把数据存在NetworkReceive,并放入KafkaChannel映射的队列中。 当解决完SelectionKey所有的事件后,就开始遍历每个KafkaChannel映射的队列,取出队列头的NetworkReceive寄存在completedReceives。 不须要回调的申请咱们在发送申请的时候,会把申请进行了缓存。 有些申请是不须要返回值的,此时就间接封装一个空的ClientResponse,放入到responses列表。 并且从inFlightRequests中,移除对应的ClientRequest。 须要回调的申请completedReceives是曾经拿到的申请,当咱们遍历completedReceives的时候,就会依据node的id把inFlightRequests缓存中对应的ClientRequest取出来,如果这个申请须要返回值,就会封装一个ClientResponse,放入ClientResponse列表表。 同样的,对应的ClientRequest也会从inFlightRequests中移除。 失去连贯的申请如果失去了连贯,首先就会更改状态为DISCONNECTED。 而后把inFlightRequests对应的ClientRequest都新增一个disconnected为true的ClientResponse。 失落连贯后,就会要求从新拉取元数据。 连贯的申请这个操作就跟下面相同,把曾经是CONNECTED的状态,批改为CONNECTED。 解决超时的申请咱们的申请都缓存在inFlightRequests中,所以间接从inFlightRequests缓存中,拿出每个node对应的ClientRequest申请,依据发送申请工夫和以后的工夫比照,就晓得这个ClientRequest是否超时,如果超时了,就敞开对应的Channel。其余操作跟下面的失去连贯的申请一样解决。 回调解决此时,咱们曾经拿到了ClientResponse的列表,包含不解决的ClientResponse、超时或者端口连贯disconnected为true的ClientResponse以及须要解决的ClientResponse。 此时就间接遍历ClientResponse,来解决这些回调。 如果响应里,有异样,然而能够容许重试,就会把RecordBatch从新放入batchs里。 如果有异样,然而不能重试,就把这个异样返回给咱们自定义的回调函数。 如果没有异样,就封装好RecordMetadata返回给咱们自定义的回调函数。

November 17, 2021 · 1 min · jiezi

关于kafka:Kafka-网络请求

初始化网络连接假如咱们音讯要发送到192.168.1.10的broker中,假如ID为1,在建设连贯的时候,会在缓存中,保留这个Node的连贯状态,包含DISCONNECTED, CONNECTING, CONNECTED,因为咱们是建设连贯,所以刚开始内存中的状态就是CONNECTING。 与broker创立连贯,其实就是规范的NIO操作了,创立一个SocketChannel与192.168.1.10连贯,并在这个SocketChannel上注册了一个OP_CONNECT。 注册完后,就须要把SelectionKey封装成一个KafkaChannel,通过node的id作为映射,保留在内存里。并且SelectionKey和KafkaChannel须要做绑定,这样就能够把监听到的事件交给KafkaChannel进行解决。 到这里,咱们能够看到,ID为1的node对应着一个连贯状态以及一个KafkaChannel。如果创立连贯失败了,连贯状态就会被改为DISCONNECTED。 如果连贯胜利了,状态就会改为CONNECTED。 绑定OP_WRITE在发送数据的时候,须要绑定OP_WRITE事件。在绑定之前,须要判断是否能够发送这个申请。 1、连贯是否曾经建设 当咱们内存中,有node对应的连贯状态,且这个连贯状态为CONNECTED,那就是曾经建设好了连贯。 2、Channel曾经筹备好了 内存中,有node对应的KafkaChannel,且这个KafkaChannel曾经筹备好了。 3、申请数量不超过5 这个是由max.in.flight.requests.per.connection设置的,默认为5,也就是说,在生产者客户端,最多只有5个申请,如果此时,曾经有5个申请了,那以后的申请就不能进行发送。 如果以上三个条件都满足,就会把申请缓存起来,用来判断不能超过5个申请数。 每个broker都对应这个一个队列,申请数量不超过5,指的是每个broker对应的申请数量。 而后从缓存中拿到KafkaChannel,通过KafkaChannel注册已OP_WRITE事件。 发送申请发送之前,这里要先看看连贯状态,如果还没有连贯,那就要实现网络连接才能够发送。实现连贯后,开始监听OP_READ事件。 如果音讯曾经发送进来了,此时就须要把OP_WRITE移除掉。 因为可能如下图一样,可能有多个发送的OP_WRITE在SelectionKey中,那就须要进行迭代,把每个申请都发送进来。

November 16, 2021 · 1 min · jiezi

关于kafka:Kafka知识点总结

1、什么是Kafka?Kafka是一个 Scala 语言开发的多分区、多正本、分布式的基于公布/订阅模式的音讯队列。目前 Kafka 曾经定位为一个分布式流式解决平台,它以高吞吐、可长久化、可程度扩大、反对流数据处理等多种个性而被宽泛应用。 2、Kafka架构 Kafak 总体架构图中蕴含多个概念:(1)ZooKeeper: Zookeeper 负责保留 broker 集群元数据,并对控制器进行选举等操作。(2)Producer: 音讯生产者,就是向 kafka broker 发消息的客户端。(3)Broker: 一个独立的 Kafka 服务器被称作 broker,一个集群由多个 broker 组成,一个 broker 能够包容多个 topic。broker负责接管来自生产者的音讯,为音讯设置偏移量,并将音讯存储在磁盘。broker 为消费者提供服务,对读取分区的申请作出响应,返回曾经提交到磁盘上的音讯。(4)Consumer: 音讯消费者,向 kafka broker 取音讯的客户端。(5)Consumer Group:消费者组,一个消费者组能够蕴含一个或多个 Consumer。消费者组内每个消费者负责生产不同分区的数据,一个分区只能由一个组内消费者生产。消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。应用多分区+多消费者形式能够极大进步数据上游的处理速度,同一消费者组中的消费者不会反复生产音讯,同样的,不同生产组中的消费者生产音讯时互不影响。Kafka 就是通过消费者组的形式来实现音讯 P2P 模式和播送模式。(6)Topic: Kafka 中的音讯以 Topic 为单位进行划分,能够了解为一个队列。生产者将音讯发送到特定的 Topic,而消费者负责订阅 Topic 的音讯并进行生产。(7)Partition: 为了实现扩展性,一个十分大的 topic 能够散布到多个 broker(服务器)上,一个 topic 能够分为多个 partition,每个 partition 是一个有序的队列。同一个主题下不同分区蕴含的音讯是不同的,分区在存储层面能够看作一个可追加的日志(Log)文件,音讯在被追加到分区日志文件的时候都会调配一个特定的偏移量(offset)。(8)Offset: 分区中每条音讯都会调配一个有序的id,即偏移量。offset 不逾越分区,也就是说 Kafka 保障的是分区有序性而不是主题有序性。(9)Replica: 正本,为保障集群中的某个节点产生故障时,该节点上的 partition 数据不失落,且 kafka 依然可能持续工作,kafka 提供了正本机制,一个 topic 的每个分区都有若干个正本,一个 leader 和若干个 follower。通常只有 leader 正本对外提供读写服务,当主正本所在 broker 解体或产生网络异样,Kafka 会在 Controller 的治理下会从新抉择新的 leader 正本对外提供读写服务。(10)Record: 理论写入 Kafka 中并能够被读取的音讯记录。每个 record 蕴含了key、value 和 timestamp。(11)Leader: 每个分区多个正本的 "主" 正本,生产者发送数据的对象,以及消费者生产数据的对象都是 leader。(12)Follower: 每个分区多个正本中的"从" 正本,实时从 Leader 中同步数据,放弃和 leader 数据的同步。Leader 产生故障时,某个 follow 会成为新的 leader。(13)ISR(In-Sync Replicas):正本同步队列,示意和 leader 放弃同步的正本的汇合(包含leader自身)。如果 follower 长时间不与 leader 同步数据则将该正本踢出ISR队列。leader产生故障会从ISR中选举新leader。(14)OSR(Out-of-Sync Replicas):因同步提早过高而被踢出ISR的正本存在OSR。(15)AR(Assigned Replicas):所有正本汇合,即 AR = ISR + OSR 。 ...

November 16, 2021 · 5 min · jiezi

关于kafka:Kafka-缓冲区里的数据什么时候发送

咱们数据都写入了缓冲区,那这里的数据不可能始终放在缓存里的,所以kafka有一个线程,叫做Sender,这个线程,会始终运行,查看缓冲区里的能够发送的音讯,就会把他收回去,上面看看有几种场景能够发消息。 内存池不够上一篇也提供,当申请的内存不足时,就会进入阻塞状态,这个阻塞状态是在waiters的deque里放入一个Condition对象,所以当waiters里有Condition对象的时候,阐明此事内存池是不够的,此事就能够发送音讯了。 批次写满咱们回顾一下上篇的内容,每个RecordBatch默认为16k,可能会有多个音讯往一个RecordBatch写,当写满16k的时候,此时就具备了发送进来的条件。 所以Sender就会从元数据里拿到每一个topic+partition形成的TopicPartition,每一个TopicPartition又有一个Deque,从Deque里拿出曾经写满的RecordBatch收回去。 这里有个比拟重要的是,每次都只查看deque里的第一个RecordBatch,只有他满了,就能够开始发送。 工夫到了如果RecordBatch始终不到16k,那音讯也不能始终寄存在缓存里吧,所以lingerMs,默认0ms,通过linger.ms进行设置。也就是当lingerMs毫秒后,这个RecordBatch如果没有16k,也会发送进来。所以这里咱们个别不能用默认值,当默认为0ms的时候,Sender每次都间接把音讯收回去,这样就失去了RecordBatch按批次散发的劣势了。 因为kafka发送失败的时候会进行重试,所以如果有重试的话,那以重试的工夫作为准,通过retry.backoff.ms进行设置,默认100ms,所以重试的时候,当超过100ms的时候也会主动收回去。 如果过期了,这些RecordBatch就会从队列里移除,并且开释对应的内存资源。 其余其余两个,散布为缓冲区敞开的时候或者有过程在flush的时候。 连贯当确认到能够发送的deque的时候,就会把对应的Node给记录下来,寄存在Node列表中,这个Node是每个partition的leader节点,如果没有对应的leader节点,就须要进行标记,等发送的时候再从新拉取元数据信息。 遍历完每个RecordBatch的队列后,此时还没有达到要收回去的条件,毕竟Node里对应的broker服务器,此时还不晓得能不能连贯的上,所以还要验证有没有连贯,如果没有,看看能不能连贯的上,如果都不行,阐明这个Node节点是用不了了,此时就要把这个Node从Node列表中,那这个Node对应的音讯就不能发送了。 下面的Node对应的是broker服务器,如果Node0和Node1是一个服务器,那发送的时候,就会把同一个服务器的对应的RecordBatch封装成一个个的ClientRequest一起发送。

November 11, 2021 · 1 min · jiezi

关于kafka:聊聊-Kafka-Producer-的网络模型

一、Producer 的网络模型咱们后面几篇有说 Producer 发送流程的源码剖析,但那个是大的轮廓,波及到发送很多相干的内容,比方: 获取 topic 的 metadata 信息key 和 value 的序列化获取该 record 要发送到的 partition向 RecordAccmulator 中追加 record 数据唤醒 sender 线程发送 RecordBatch那这篇老周次要来说下 Producer 的网络模型,这里间接给出 Producer 的网络模型图,如下: 从图中能够看出,KafkaProducer 相当于客户端,与 Sender 调用层交互,Sender 调用 NetworkClient,NetworkClient 调用 Selector,而 Selector 底层封装了 Java NIO 的相干接口。心中有了 Producer 的网络模型大抵轮廓后,咱们接下来就能够来剖析 Producer 的网络模型。 二、Producer 与 Broker 的交互流程咱们在业务代码通过生产者 producer 调用 send 办法来发送音讯,不难发现都是通过走 Producer 的实现类 KafkaProducer 的 send 办法: 2.1 org.apache.kafka.clients.producer.KafkaProducer#doSend下面的两个 send 办法最终会走到 doSend 办法里来: 这块的源码老周在前两篇的 Producer 源码解析那一篇剖析了的哈,这里次要说下与 Broker 通信的交互剖析。次要有两点: ...

November 8, 2021 · 3 min · jiezi

关于kafka:Kafka-消息写入消息累加器流程

kafka在音讯指定好分区后,并没有间接把音讯收回去,而是把音讯寄存在内存中,再分批收回去,这样就缩小了网络传输的次数,缩小了网络的开销,整体的效率就会失去了很大的晋升。治理音讯的内存叫做RecordAccumulator,即音讯累加器。 batches上一章咱们曾经晓得了音讯是往哪个partition发的,所以topic和partition就会组成一个TopicPartition对象。 如果一个topic有3个partition,那就会有3个TopicPartition,这3个TopicPartition在音讯累加器里,就有对应的3个队列Deque,这个信息,寄存在数据结构为CopyOnWriteMap的batches中。 当然RecordAccumulator一开始的时候,必定是没有对应的Deque,比方topic1+0的TopicPartition刚筹备往Deque扔数据的时候,就会看看是否有这个TopicPartition对应的Deque,如果有,就拿进去用,如果没有,就会创立一个。 Deque和是TopicPartition在RecordAccumulator是以map来做映射关系的,因为get的时候比拟多,put的时候时候比拟少,是一个写少读多的 场景,所以这个map是CopyOnWriteMap的构造,在put的时候会先复制再写,导致内存有肯定的耗费,然而对于get来说,因为没有加锁,而且是线程平安的,性能就大大的晋升。 RecordBatchDeque队列里寄存的并不是音讯自身,而是一个个封装音讯的RecordBatch,每个RecordBatch默认大小为16k,由batch.size进行设置。 如果第一个音讯封装后有4k,第二个音讯封装后有10k,那这两个音讯是放在同一个RecordBatch的。 如果音讯的大小超过了默认的16k,那这个RecordBatch的大小就是以理论的大小为准。 BufferPool下面的内存空间并不是能够始终申请的,他有一个总的空间,默认大小为32M,由buffer.memory进行设置。 内存空间通过BufferPool进行治理,每次申请一个新的RecordBatch,都要看看以后已用的空间+以后申请的RecordBatch是不是小于32M,如果小,那就能够始终申请。 BufferPool外面也有一个Deque队列,当大小为16k的RecordBatch用完的时候,就会把这个空间寄存在BufferPool的Deque里,当申请内存的时候,就能够间接从Deque里拿进去。这样做的目标是为了避免反复的创建对象,进而引起垃圾回收。 如果申请的时候,32M的内存都被耗费完了,此时就会阻塞在这里,等有空间偿还了,会被唤醒持续申请内存了。 如果RecordBatch的大小并不等于16k,那他此时是没有方法回收到BufferPool的Deque里,所以只能等着垃圾回收,所以咱们应用kafka的时候,batch.size的大小要依据业务须要进行扩充,比方咱们根本都是发送500k的数据,BufferPool的Deque实际上并没有起到什么作用,JVM还会始终进行垃圾回收。

October 26, 2021 · 1 min · jiezi

关于kafka:聊聊-KafkaProducer-Metadata-读取与更新机制

一、前言咱们上一篇说了 聊聊 Kafka:Producer 源码解析,这一篇咱们来说下 Producer Metadata 的读取与更新机制。上一篇从宏观上介绍了 Producer 的宏观模型,其中通过 waitOnMetadata() 办法获取 topic 的 metadata 信息这一块货色很多,所以独自拎一篇进去讲。 二、Metadata2.1 什么是 Metadata Metadata 是指 Kafka 集群的元数据,蕴含了 Kafka 集群的各种信息,间接看源码便可知: public class Metadata implements Closeable { private final Logger log; // retry.backoff.ms: 默认值为100ms,它用来设定两次重试之间的工夫距离,防止有效的频繁重试。 private final long refreshBackoffMs; // metadata.max.age.ms: 默认值为300000,如果在这个工夫内元数据没有更新的话会被强制更新。 private final long metadataExpireMs; // 更新版本号,每更新胜利1次,version自增1,次要是用于判断metadata是否更新 private int updateVersion; // 申请版本号,每发送一次申请,version自增1 private int requestVersion; // 上一次更新的工夫(蕴含更新失败) private long lastRefreshMs; // 上一次更新胜利的工夫 private long lastSuccessfulRefreshMs; private KafkaException fatalException; // 非法的topics private Set<String> invalidTopics; // 未认证的topics private Set<String> unauthorizedTopics; // 元数据信息的Cache缓存 private MetadataCache cache = MetadataCache.empty(); private boolean needFullUpdate; private boolean needPartialUpdate; // 会收到metadata updates的Listener列表 private final ClusterResourceListeners clusterResourceListeners; private boolean isClosed; // 存储Partition最近一次的leaderEpoch private final Map<TopicPartition, Integer> lastSeenLeaderEpochs;}MetadataCache:Kafka 集群中对于 node、topic 和 partition 的信息。(是只读的) ...

October 24, 2021 · 3 min · jiezi

关于kafka:聊聊-KafkaProducer-Metadata-读取与更新机制

一、前言咱们上一篇说了 聊聊 Kafka:Producer 源码解析,这一篇咱们来说下 Producer Metadata 的读取与更新机制。上一篇从宏观上介绍了 Producer 的宏观模型,其中通过 waitOnMetadata() 办法获取 topic 的 metadata 信息这一块货色很多,所以独自拎一篇进去讲。 二、Metadata2.1 什么是 Metadata Metadata 是指 Kafka 集群的元数据,蕴含了 Kafka 集群的各种信息,间接看源码便可知: public class Metadata implements Closeable { private final Logger log; // retry.backoff.ms: 默认值为100ms,它用来设定两次重试之间的工夫距离,防止有效的频繁重试。 private final long refreshBackoffMs; // metadata.max.age.ms: 默认值为300000,如果在这个工夫内元数据没有更新的话会被强制更新。 private final long metadataExpireMs; // 更新版本号,每更新胜利1次,version自增1,次要是用于判断metadata是否更新 private int updateVersion; // 申请版本号,每发送一次申请,version自增1 private int requestVersion; // 上一次更新的工夫(蕴含更新失败) private long lastRefreshMs; // 上一次更新胜利的工夫 private long lastSuccessfulRefreshMs; private KafkaException fatalException; // 非法的topics private Set<String> invalidTopics; // 未认证的topics private Set<String> unauthorizedTopics; // 元数据信息的Cache缓存 private MetadataCache cache = MetadataCache.empty(); private boolean needFullUpdate; private boolean needPartialUpdate; // 会收到metadata updates的Listener列表 private final ClusterResourceListeners clusterResourceListeners; private boolean isClosed; // 存储Partition最近一次的leaderEpoch private final Map<TopicPartition, Integer> lastSeenLeaderEpochs;}MetadataCache:Kafka 集群中对于 node、topic 和 partition 的信息。(是只读的) ...

October 24, 2021 · 3 min · jiezi

关于kafka:Go-操作kafka包sarama

概述sarama 是一个纯 Go 客户端库,用于解决 Apache Kafka(0.8 及更高版本)。它包含一个用于轻松生成和应用音讯的高级 API,以及一个用于在高级 API 有余时控制线路上的字节的低级 API。在github上stars上比拟多(举荐)。 开源包:https://github.com/Shopify/sa...文档地址:https://pkg.go.dev/github.com...闲话少叙,上示例 package mainimport ( "context" "fmt" "github.com/Shopify/sarama" "log" "os" "os/signal" "sync")type consumerGroupHandler struct {}func (consumerGroupHandler) Setup(sarama.ConsumerGroupSession) error { return nil}func (consumerGroupHandler) Cleanup(sarama.ConsumerGroupSession) error { return nil }// ConsumeClaim must start a consumer loop of ConsumerGroupClaim's Messages().func (consumerGroupHandler) ConsumeClaim(session sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error { for msg := range claim.Messages() { log.Printf("Message claimed: value = %s, timestamp = %v, topic = %s", msg.Value, msg.Timestamp, msg.Topic) session.MarkMessage(msg, "") } return nil}//消费者组func SaramaConsumerGroup() { config := sarama.NewConfig() config.Consumer.Return.Errors = false config.Version = sarama.V0_10_2_0 // specify appropriate version config.Consumer.Offsets.Initial = sarama.OffsetOldest // 未找到组生产位移的时候从哪边开始生产 group, err := sarama.NewConsumerGroup([]string{"localhost:9092"}, "my-group", config) if err != nil { panic(err) } defer func() { _ = group.Close() }() // Track errors go func() { for err := range group.Errors() { fmt.Println("ERROR", err) } }() fmt.Println("Consumed start") // Iterate over consumer sessions. ctx := context.Background() for { topics := []string{"my_topic"} handler := consumerGroupHandler{} // `Consume` should be called inside an infinite loop, when a // server-side rebalance happens, the consumer session will need to be // recreated to get the new claims err := group.Consume(ctx, topics, handler) if err != nil { panic(err) } }}//消费者func SaramaConsumer() { consumer, err := sarama.NewConsumer([]string{"localhost:9092"}, sarama.NewConfig()) if err != nil { panic(err) } defer func() { if err := consumer.Close(); err != nil { log.Fatalln(err) } }() partitionConsumer, err := consumer.ConsumePartition("my_topic", 0, sarama.OffsetNewest) if err != nil { panic(err) } defer func() { if err := partitionConsumer.Close(); err != nil { log.Fatalln(err) } }() // Trap SIGINT to trigger a shutdown. signals := make(chan os.Signal, 1) signal.Notify(signals, os.Interrupt) consumed := 0ConsumerLoop: for { select { case msg := <-partitionConsumer.Messages(): log.Printf("Consumed message offset %d\n", msg.Offset) consumed++ case <-signals: break ConsumerLoop } } log.Printf("Consumed: %d\n", consumed)}//异步生产者Goroutinesfunc SyncProducer() { config := sarama.NewConfig() config.Producer.Return.Successes = true config.Producer.Return.Errors = true producer, err := sarama.NewAsyncProducer([]string{"localhost:9092"}, config) if err != nil { panic(err) } // Trap SIGINT to trigger a graceful shutdown. signals := make(chan os.Signal, 1) signal.Notify(signals, os.Interrupt) var ( wg sync.WaitGroup enqueued, successes, producerErrors int ) wg.Add(1) go func() { defer wg.Done() for range producer.Successes() { successes++ } }() wg.Add(1) go func() { defer wg.Done() for err := range producer.Errors() { log.Println(err) producerErrors++ } }()ProducerLoop: for { message := &sarama.ProducerMessage{Topic: "my_topic", Value: sarama.StringEncoder("testing 456")} select { case producer.Input() <- message: enqueued++ case <-signals: producer.AsyncClose() // Trigger a shutdown of the producer. break ProducerLoop } } wg.Wait() log.Printf("Successfully produced: %d; errors: %d\n", successes, producerErrors)}//异步生产者Selectfunc SyncProducerSelect() { producer, err := sarama.NewAsyncProducer([]string{"localhost:9092"}, nil) if err != nil { panic(err) } defer func() { if err := producer.Close(); err != nil { log.Fatalln(err) } }() // Trap SIGINT to trigger a shutdown. signals := make(chan os.Signal, 1) signal.Notify(signals, os.Interrupt) var enqueued, producerErrors intProducerLoop: for { select { case producer.Input() <- &sarama.ProducerMessage{Topic: "my_topic", Key: nil, Value: sarama.StringEncoder("testing 123")}: enqueued++ case err := <-producer.Errors(): log.Println("Failed to produce message", err) producerErrors++ case <-signals: break ProducerLoop } } log.Printf("Enqueued: %d; errors: %d\n", enqueued, producerErrors)}//同步生产模式func SaramaProducer() { producer, err := sarama.NewSyncProducer([]string{"localhost:9092"}, nil) if err != nil { log.Fatalln(err) } defer func() { if err := producer.Close(); err != nil { log.Fatalln(err) } }() msg := &sarama.ProducerMessage{Topic: "my_topic", Value: sarama.StringEncoder("testing 123")} partition, offset, err := producer.SendMessage(msg) if err != nil { log.Printf("FAILED to send message: %s\n", err) } else { log.Printf("> message sent to partition %d at offset %d\n", partition, offset) }}func main() { //生产者 go SyncProducer() //go SaramaProducer() //go SyncProducerSelect() //消费者 SaramaConsumerGroup() //SaramaConsumer()}linkshttps://pkg.go.dev/github.com/Shopify/saramahttps://github.com/Shopify/sarama目录上一节:下一节:

October 16, 2021 · 3 min · jiezi

关于kafka:聊聊-Kafka编译-Kafka-源码并搭建源码环境

一、前言老周这里编译 Kafka 的版本是 2.7,为啥采纳这个版本来搭建源码的浏览环境呢?因为该版本相对来说比拟新。而我为啥不必 2.7 后的版本呢?比方 2.8,这是因为去掉了 ZooKeeper,还不太稳固,生产环境也不太倡议应用,所以以 2.7 版本进行源码搭建并钻研。 二、环境筹备JDK:1.8.0_241Scala:2.12.8Gradle:6.6Zookeeper:3.4.14三、环境搭建3.1 JDK 环境搭建 这个就不必我说了吧,搞 Java 的本机都有 JDK 环境。 3.2 Scala 环境搭建 下载链接:https://www.scala-lang.org/download/2.12.8.html 这里老周是 Mac OS 零碎,这里大家看着本人的零碎来下就好了哈。 3.2.1 配置 Scala 环境变量 终端输出以下命令进行编辑: vim ~/.bash_profile# 这里的门路是你装置SCALA_HOME=/Users/Riemann/Tools/scala-2.12.8export SCALA_HOMEexport PATH=$PATH:$SCALA_HOME/bin# 使环境变量失效,在命令行执行。source ~/.bash_profile3.2.2 验证 终端输出以下命令: scala -version呈现以下提醒,阐明 Scala 环境搭建胜利。 3.3 Gradle 环境搭建 首先来到 Gradle官网:https://services.gradle.org/distributions/ 如下图:咱们抉择想要装置的公布版本,gradle-x.x-bin.zip 是须要下载的装置公布版,gradle-x.x-src.zip 是源码,gradle-x.x-all.zip 则是下载全副的文件。 我本地为 gradle-6.6。 Gradle下载的源码不须要装置,咱们将下载的压缩包在本机的目录下间接解压即可,解压后的目录如下图所示。 3.3.1 配置 Gradle 环境变量 终端输出以下命令进行编辑: vim ~/.bash_profile# 这里的门路是你装置GRADLE_HOME=/Users/Riemann/Tools/gradle-6.6export GRADLE_HOMEexport PATH=$PATH:$GRADLE_HOME/bin# 使环境变量失效,在命令行执行。source ~/.bash_profile3.3.2 验证 ...

October 10, 2021 · 3 min · jiezi

关于kafka:如何才能证明你对kafka了如指掌

1.kafka根本运行原理及架构关键词prducer:生产者consumer:消费者consumer group:消费者组 cluster:kafka集群broker:kafka节点topic:主题partation:音讯分区(一个topic能够为多个partation组成)relica:正本(partation会有多个正本散布在多个beoker上,保障数据不丢) 两种生产模式点对点模式:音讯不存储,生产胜利立刻删除,一个音讯只能生产一次公布订阅模式:音讯被生产后不会删除 工作流程音讯的生产和生产都是面向topic。topic是一个逻辑上的概念,其实物理上就是一个或多个partation,一个partation由多个segment文件组成,segment由.log和.index文件组成。log存储数据,kafka采纳文件开端追加存储的形式。每条数据都有本人的offset,不便消费者灵便抉择地位生产。index文件出差农户索引信息。kafka采纳分片索引机制。 ACK0:producer发送音讯后,不期待ack间接返回胜利1:期待以后partation的leader落盘胜利返回ack,不期待follower-1(all):期待所有partation落盘胜利返回 2.绝对于其它音讯队列中间件,kafka有哪些劣势与劣势?速度快,并发强。结构设计简略,不便定制扩大。 3.音讯队列常见问题反复生产:借用数据库事务,新加一张音讯表。用id或流水号去重。 音讯失落(音讯可靠性传输)producer发送时失落:ack机制保障(三个级别:0,1,-1)kafka本人失落:同上,保障落盘,再发送ack应答。consumer生产产生谬误失落:同上,生产胜利且不报错,再发送ack。 程序生产:producer保障发送有序kafka将须要保障程序的音讯落在同一个队列中consumer生产时,为了保障有序,只能有一个线程去生产 如幂等音讯,提早生产等等问题,在kafka中是如何解决的参考:https://www.cnblogs.com/jiuju...https://blog.csdn.net/yuanlon...

October 10, 2021 · 1 min · jiezi

关于kafka:kafka-分区是怎么指定的

在构建ProducerRecord的时候说过,ProducerRecord除了topic和value外,还有两个可选的,包含partition和key。在拉取到元数据后,咱们就开始依据分区来对这条音讯进行发送。 指定分区指定分区,就是指 构建ProducerRecord的时候,topic为topic1的ProducerRecord指定partition为1,假设broker此时有3个,别离为broker0、broker1、broker2,那这个音讯将会发送给broker1。 没有key如果没有指定分区的时候,就会依据分区器进行分区的计算,咱们这里间接用默认的分区器进行分区,所以又分为指定key和没有key的状况。 如果没有指定key的时候,这里也有两种状况: topic1对应可用的分区数大于0,那依据topic1对应可用的分区数进行轮询。topic1对应可用的分区数等于0,此时依据topic1对应的分区数进行轮询。轮询的意思就是,这一次发给broker0,下一次发给broker1,再下一次发给broker2,而后再从broker0开始。 指定key如果指定了key,那kafka就会通过murmur2算法,对key的值进行进行,比方key为a的时候,计算的值为32,这个32会对broker的数量3进行取模,失去的余数为2,此时就会发送给broker2。 这里须要留神的是,这个key曾经是序列化后的key。

October 6, 2021 · 1 min · jiezi

关于kafka:Kafka-元数据的拉取流程

上一篇曾经晓得元数据在什么时候拉取的,咱们这里看看他整个拉取的流程。 topics元素的拉取,是依据生产者的发送的topic来拉取的,并不是拉取所有的元数据,所以在发送音讯的时候,就会把这个topic寄存在topics中,这个topics就是记录了以后已有的topic,数据类型是map,他的key就是topic,value刚开始默认为-1。所以topic1发送的时候,就会在topics新增一个topic1->-1的键值对。 版本号和更新标识因为元数据的拉取,是由Sender线程来执行的(这个前面流程会讲到),所以须要一个更新标识needUpdate,来告知Sender线程,我须要拉取元数据。 同时,Sender线程在胜利拉取元数据后,也须要告知其余线程,这里就须要一个版本号version,每次胜利拉取,就进行累加,所以其余线程就会拿本人的版本号跟内存里的版本号进行比照,发现内存的版本号比本人大,那就是拉取元数据胜利了。 在拉取的时候,此时version=0,以后线程保留的version也是0,needUpdate为true,阐明须要拉取元数据。 sender线程sender线程有一个死循环,他会始终运行,元数据的发送以及音讯的发送,都要通过ender线程。 版本号和更新标识筹备好后,就开始唤醒sender线程,实际上sender线程最终会唤醒NIO的Selector上的线程。 这里波及到网络传输局部,咱们就简要的讲一下,网络传输等前面再讲。简略的说,就是sender线程会把申请交给NIO的Selector,而后再解决Selector收到的申请。 sender线程解决完音讯后,就会更新元数据里的信息,而后版本号累加,needUpdate改为false。 下面topics中,topic1对应的value是1,此时曾经拉取到元数据了,这里的value就要改为以后工夫+5 60 1000,即以后工夫+5分钟。意思是当某个topic超过5分钟没有发送音讯,就会从topics中移除,下次更新的时候,就不会拉取这个topic的元数据信息。 休眠sender线程辛辛苦苦拉取元数据的时候,发送音讯的线程在干什么呢? 他进入了休眠,也就是wait,被唤醒有两种状况,一个是sender线程更新完元数据再唤醒他,另外一个是休眠工夫到了,他会有一个最大等待时间,默认60s。 被唤醒后,就会查看以后拉取的工夫是不是超过了,如果超过60s还没有拉取到元数据,此时就要抛异样的。 另外还要判断,以后保留的版本号是不是小于内存的版本号,如果小于,他就晓得更新胜利了,反之,阐明还没更新胜利,他就会持续休眠,期待下一次唤醒。 缓存Sender拉取元数据后,是保留在内存中的,这样下次发送音讯的时候,就间接从内存拿了,并不会每次都向下面的流程一样,一次次的从Kafka拉取元数据,既升高了生产者发送音讯的效率,也加大了Kafka的压力。 如果某个topic在5分钟内会至多发一条音讯,那个这个topic就会保留在topics中。生产者客户端每5分钟就会更新元数据,所以继续发送的音讯,他在缓存中的元数据都会始终的更新。

October 6, 2021 · 1 min · jiezi

关于kafka:Kafka-元数据的拉取时机

元数据生产者发消息给Kafka,是须要晓得Kafka的ip、端口等节点信息,这些节点信息是元数据的一部分,属于元数据Metadata的Cluster的一部分。咱们每一个topic,在Kafka是分布式的模式寄存的,所以一个topic就会有多个分区,每个分区对应值着不同的ip、端口等信息。所以每个topic有多少分分区,每个分区的leader节点replica节点的ip、端口信息等,也属于元数据Metadata的Cluster的一部分。对于生产者客户端来说,这些元数据都是Kafka的信息,所以往kafka发送音讯之前,就须要拉取元数据。 初始化Metadata是KafkaProducer的一个属性,在KafkaProducer初始化的时候,也会实例化一个Metadata对象,可能有人感觉,实例化Metadata后,就会去拉取元数据信息。 然而kafka并没有这么做,只是对集群元数据做了一个初始化,咱们在上一篇曾经晓得KafkaProducer是有配置bootstrap.servers这个属性的。所以初始化的时候,就是把配置的地址,转换为Node,Node就存储着配置的ip和port,放在Cluster对象实例里,下面曾经说过,Cluster对象也是Metadata的属性。因为bootstrap.servers是能够配置多个的,所以在Cluster中存储的是Node列表。 所以KafkaProducer初始化的时候并没有加载元数据的,这是懒加载的编程思维。 发送时在元数据里,咱们曾经看到Metadata的cluster寄存topic相干的信息,如果发送的时候,发现这个topic在cluster中并没有对应的信息,那就须要去拉取元数据信息。 默认状况下,咱们只拉取本人要发送音讯的对应的topic的元数据的信息,并不会拉取所有的元数据信息,所以在初始化的时候,并不会拉取元数据,因为那时候,基本不晓得生产者须要发送哪些topic。等到下一次往这个topic发送数据的时候,间接就会从Metadata的cluster中拿数据。 某个机会Metadata在实例化的时候,会有两个结构参数,一个读取配置config里的metadata.max.age.ms信息,默认是5分钟,这个作用是,间隔上次胜利拉取的工夫超过5分钟会刷新一下。 另外一个参数读取配置config里的retry.backoff.ms信息,默认100ms,这个作用是,间隔上一次更新元数据的工夫跟以后工夫比照,如果还没有到100ms,那就不能更新元数据,防止频繁更新。留神这里只是和上次更新的工夫比拟,并不是胜利拉取的工夫。 如果有一个拉取元数据的工作了,那就不能持续去拉取元数据。 对于能不能拉取元数据,次要还是看下面三种状况。

October 6, 2021 · 1 min · jiezi

关于kafka:Kafka-生产者客户端发送消息的大致流程

kafka也有生产者和消费者的概念,生产者把音讯发给kafka,消费者从kafka拿音讯进行生产,这个跟之前的activemq和rabbitmq相似。咱们从生产者发消息开始,探讨kafka的整个流程。这里的版本是0.10.1.0。 音讯对象音讯对象 ProducerRecord蕴含了topic、partition、key、value、timestamp,其中topic和value在构建ProducerRecord时是必须的。 topic代表了一个汇合的名称,当音讯发往kafka的时候,kafka须要把这个音讯寄存起来的,此时就须要一个汇合的名称,把同一个汇合的音讯,寄存在一起,这个就类比于mysql的表,同一个表的数据,都是寄存在一个表中。 value是音讯的主体,比方咱们往名称为topic1的topic发送一个hello的音讯时,这个value就等于hello。 partition代表着分区号,kafka是分布式系统的,也就是说,一个topic的数据,会寄存在多个服务器中,所以就有很多分区,设置partition能够指定音讯发完哪个分区。 key作为音讯的键,能够依据key对这个音讯进行分区。 timestamp指音讯的工夫戳,既能够示意音讯的工夫戳,也能够示意音讯追加到日志文件的工夫。 咱们假设一个音讯体为hello的音讯发送给topic1。 KafkaProducer音讯构建好后,咱们就须要把音讯收回去,不然构建干嘛,对吧。 负责发消息的是KafkaProducer,每个KafkaProducer都有一个clientId,如果没有设置,就会默认为producer-+数字,这个数字是AtomicInteger类型的,所以是线程平安的,没有设置的话,clientId就是producer-1、producer-2。因为KafkaProducer也是线程平安的,所以客户端构建一个KafkaProducer用来发送音讯,也是能够的。 发送音讯的时候,咱们是须要晓得服务器(即broker)地址的,所以实例化KafkaProducer的时候,bootstrap.servers也是须要赋值的,如果有多个的话,用逗号隔开,格局为host1:port1,host2:port2,这里咱们假如服务器地址为hadoop1:9092。 拦截器拦截器并不是必须的,比方对音讯做一些定制化的操作,对topic和value批改等或者定制回调函数,不过失常状况,个别是不必的。 序列化在网络传输中,broker是以以字节数组(byte[])的模式进行接管的,所以在发送的时候,须要事后把音讯的key和value进行序列化。 在初始化KafkaProducer的时候,设置key.serializer和value.serialize来制订key和value的序列化器。 分区器Kafka是一个分布式系统,每个topic都对应着多个broker,所以咱们在发送音讯之前,须要对音讯调配他所在的分区。 音讯累加器Kafka并不是一条一条的音讯进行发送,而且保留在音讯累加器这个缓存中,而后再批次发送,这样能够缩小网络传输的资源耗费,进而晋升性能。 Sender线程音讯保留在内存后,Sender线程就会把符合条件的音讯依照批次进行发送。除了发送音讯,元数据的加载也是通过Sender线程来解决的。 Sneder线程发送音讯以及接管音讯,都是基于java NIO的Selector。通过Selector把音讯收回去,并通过Selector接管音讯。 前面咱们缓缓对本章的内容进行开展。

October 3, 2021 · 1 min · jiezi

关于kafka:Kafka存储系统在Twitter的应用分析

当开发者通过API生产Twitter的公共数据时,他们须要取得可靠性、速度和稳定性方面的保障。因而,在不久前,咱们推出了Account Activity Replay API帮忙开发者们晋升他们零碎的稳定性。这个API是一个数据恢复工具,开发者能够用它来检索最早产生在5天前的事件,复原因为各种起因(包含在实时传递时忽然产生的服务器中断)没有被传递的事件。除了构建API来晋升开发者体验,咱们还做了一些优化:• 进步Twitter外部工程师的生产力• 放弃零碎的可维护性。具体来说,就是尽量减少开发人员、站点可靠性工程师和其余与零碎交互的人员的上下文切换 基于这些起因,在构建这个API所依赖的回放零碎时,咱们利用了Account Activity API现有的实时零碎设计。这有助于咱们重用现有的工作,并最小化上下文切换累赘和培训工作。实时零碎采纳了公布和订阅架构。为了放弃架构的一致性,构建一个能够读取数据的存储层,咱们想到了传统的流式技术——Kafka。背景 两个数据中心产生实时事件,事件被写入到跨数据中心的主题上,实现数据冗余。但并不是所有的事件都须要被传递,所以会有一个外部应用程序负责对事件进行筛选。这个应用程序生产来自这些主题的事件,依据保留在键值存储中的一组规定来大数据培训查看每一个事件,并决定是否应该通过咱们的公共API 将消息传递给特定的开发者。事件是通过Webhook传递的,每个Webhook URL都有一个开发人员负责保护,并有惟一的ID标识。 存储和分区 通常,在构建一个须要存储层的回放零碎时,人们可能会应用基于Hadoop和HDFS的架构。但咱们抉择了Kafka,次要基于以下两个起因:• 已有的实时零碎采纳了公布和订阅架构• 回放零碎存储的事件量不是PB级的,咱们存储的数据不会超过几天。此外,执行Hadoop的MapReduce作业比在Kafka上生产数据老本更高、速度更慢,达不到开发者的冀望 要利用实时管道来构建回放管道,首先要确保事件被存储在Kafka中。咱们把Kafka主题叫作delivery_log,每个数据中心都有一个这样的主题。而后,这些主题被穿插复制,实现数据冗余,以便反对来自数据中心之外的重放申请。事件在被传递之前通过去重操作。在这个Kafka主题上,咱们应用默认的分区机制创立了多个分区,分区与WebhookId的散列值(事件记录的键)一一对应。咱们思考过应用动态分区,但最终决定不应用它,因为如果其中一个开发人员生成的事件多于其余开发人员,那么这个分区蕴含的数据将多于其余分区,造成了分区的不平衡。相同,咱们抉择固定数量的分区,而后应用默认分区策略来散布数据,这样就升高了分区不平衡的危险,并且不须要读取Kafka主题的所有分区。重放服务基于申请的WebhookId来确定要读取哪个分区,并为该分区启动一个新的Kafka消费者。主题的分区数量不会发生变化,因为这会影响键的散列和事件的散布。咱们应用了固态磁盘,依据每个时间段读取的事件数量来调配空间。咱们抉择这种磁盘而不是传统的硬盘驱动器,以此来取得更快的处理速度,并缩小与查找和拜访操作相干的开销。因为咱们须要拜访低频数据,无奈取得页面缓存优化的益处,所以最好是应用固态磁盘。为了最小化存储空间,咱们应用了snappy压缩算法。咱们晓得大部分解决工作都在生产端,之所以抉择snappy,是因为它在解压时比其余Kafka所反对的压缩算法 (如gzip和lz4) 更快。申请和解决 在咱们设计的这个零碎中,通过API调用来发送重放申请。咱们从申请音讯体中获取WebhookId和要重放的事件的日期范畴。这些申请被长久化到MySQL中,相当于进入了队列,直到它们被重放服务读取。申请中的日期范畴用于确定要读取的分区的偏移量。消费者对象的offsetForTimes函数用于获取偏移量。重放服务解决每个重放申请,它们通过MySQL互相协调,解决数据库中的下一个须要重放的记录。重放过程定期轮询MySQL,获取须要被解决的挂起作业。一个申请会在各种状态之间转换。期待被解决的申请处于凋谢状态(OPEN STATE),刚退出队列的申请处于启动状态(STARTED STATE),正在被解决的申请处于进行中状态(ONGOING STATE),已解决实现的申请将转换到已实现状态(COMPLETED STATE)。一个重放过程只会抉择一个尚未启动的申请 (即处于关上状态的申请)。每隔一段时间,当一个工作过程将一个申请退出队列后,它会在MySQL表中写入工夫戳,示意正在解决以后的重放作业。如果重放过程在解决申请时死掉了,相应的作业将被重新启动。因而,除了将处于关上状态的申请退出队列之外,重放操作还将读取处于已开始或正在进行中的、在预约义的分钟数内没有心跳的作业。在读取事件时会进行去重操作,而后事件被公布到消费者端的Webhook URL上。去重是通过保护被读取事件的散列值缓存来实现的。如果遇到具备雷同散列值的事件,就不传递这个事件。总的来说,咱们的解决方案与传统的将Kafka作为实时、流式零碎的用法不一样。咱们胜利地将Kafka作为存储系统,构建了一个API,在进行事件复原时晋升了用户体验和数据拜访能力。咱们利用已有的实时零碎设计让零碎的保护变得更加容易。此外,客户数据的复原速度达到了咱们的预期。

September 28, 2021 · 1 min · jiezi

关于kafka:Kafka丢失数据问题优化及重复消费原因分析

数据失落是一件十分重大的事件事,针对数据失落的问题咱们须要有明确的思路来确定问题所在,针对这段时间的总结,我集体面对kafka数据失落问题的解决思路如下: 是否真正的存在数据失落问题比方有很多时候可能是其余共事操作了测试环境,所以首先确保数据没有第三方烦扰。理清你的业务流程,数据流向数据到底是在什么中央失落的数据,在Kafka之前的环节或者Kafka之后的流程失落?比方Kafka的数据是由flume提供的,兴许是flume失落了数据,Kafka天然就没有这一部分数据。如何发现有数据失落,又是如何验证的?从业务角度思考,例如:教育行业,每年高考后数据量微小,然而却反常的比高考前还少,或者源端数据量和目标端数据量不符。定位数据是否在Kafka之前就曾经失落还是生产端失落数据的Kafka反对数据的从新回放性能(换个生产group),清空目标端所有数据,从新生产。如果是在生产端失落数据,那么屡次生产后果齐全截然不同的几率很低。如果是在写入端失落数据,那么每次后果应该齐全一样(在写入端没有问题的前提下)。Kafka环节失落数据常见的Kafka环节失落数据的起因有:如果auto.commit.enable=true,当consumer fetch了一些数据但还没有齐全解决掉的时候,刚好到commit interval登程了提交offset操作,接着consumer crash掉了。这时曾经fetch的数据还没有解决实现但曾经被commit掉,因而没有机会再次被解决,数据失落。网络负载很高或者磁盘很忙写入失败的状况下,没有主动重试重发消息。没有做限速解决,超出了网络带宽限速。kafka肯定要配置上音讯重试的机制,并且重试的工夫距离肯定要长一些,默认1秒钟并不合乎生产环境(网络中断工夫有可能超过1秒)。如果磁盘坏了,会失落曾经落盘的数据。单批数据的长度超过限度会失落数据,报kafka.common.MessageSizeTooLargeException异样解决:Consumer side:fetch.message.max.bytes- this will determine the largest size of a message that can be fetched by the consumer.Broker side:replica.fetch.max.bytes- this will allow for the replicas in the brokers to send messages within the cluster and make sure the messages are replicated correctly. If this is too small, then the message will never be replicated, and therefore, the consumer will never see the message because the message will never be committed (fully replicated).Broker side:message.max.bytes- this is the largest size of the message that can be received by the broker from a producer.Broker side (per topic):max.message.bytes- this is the largest size of the message the broker will allow to be appended to the topic. This size is validated pre-compression. (Defaults to broker'smessage.max.bytes.)6. partition leader在未实现正本数follows的备份时就宕机的状况,即便选举出了新的leader然而曾经push的数据因为未备份就失落了。Kafka是多正本的,当你配置了同步复制之后。多个正本的数据都在PageCache外面,呈现多个正本同时挂掉的概率比1个正本挂掉的概率就很小了。(官网举荐是通过副原本保证数据的完整性的)Kafka的数据一开始就是存储在PageCache上的,定期flush到磁盘上的,也就是说,不是每个音讯都被存储在磁盘了,如果呈现断电或者机器故障等,PageCache上的数据就失落了。能够通过log.flush.interval.messages和log.flush.interval.ms来配置flush距离,interval大丢的数据多些,小会影响性能但在0.8版本,能够通过replica机制保证数据不丢,代价就是须要更多资源,尤其是磁盘资源,Kafka以后反对GZip和Snappy压缩,来缓解这个问题是否应用replica取决于在可靠性和资源代价之间的balance。同时Kafka也提供了相干的配置参数,来让你在性能与可靠性之间衡量(个别默认):当达到上面的音讯数量时,会将数据flush到日志文件中。默认10000log.flush.interval.messages=10000当达到上面的工夫(ms)时,执行一次强制的flush操作。interval.ms和interval.messages无论哪个达到,都会flush。默认3000mslog.flush.interval.ms=1000查看是否须要将日志flush的工夫距离log.flush.scheduler.interval.ms = 3000Kafka的优化倡议 producer端• 设计上保证数据的牢靠安全性,根据分区数做好数据备份,设立正本数等push数据的形式:同步异步推送数据:衡量安全性和速度性的要求,抉择相应的同步推送还是异步推送形式,当发现数据有问题时,能够改为同步来查找问题。• flush是Kafka的外部机制,Kafka优先在内存中实现数据的替换,而后将数据长久化到磁盘Kafka首先会把数据缓存(缓存到内存中)起来再批量flush。能够通过log.flush.interval.messages和log.flush.interval.ms来配置flush距离。• 能够通过replica机制保证数据不丢代价就是须要更多资源,尤其是磁盘资源,Kafka以后反对GZip和Snappy压缩,来缓解这个问题。是否应用replica(正本)取决于在可靠性和资源代价之间的balance(均衡)。• broker到Consumer kafka的consumer提供两种接口high-level版本曾经封装了对partition和offset的治理,默认是会定期主动commit offset,这样可能会丢数据的。low-level版本本人治理spout线程和partition之间的对应关系和每个partition上的已生产的offset(定期写到zk)。并且只有当这个offset被ack后,即胜利解决后,才会被更新到zk,所以根本是能够保证数据不丢的即便spout线程crash(解体),重启后还是能够从zk中读到对应的offset。• 异步要思考到partition leader在未实现正本数follows的备份时就宕机的状况,即便选举出了新的leader然而曾经push的数据因为未备份就失落了不能让内存的缓冲池太满,如果满了内存溢出,也就是说数据写入过快,Kafka的缓冲池数据落盘速度太慢,这时必定会造成数据失落。尽量保障生产者端数据始终处于线程阻塞状态,这样一边写内存一边落盘。异步写入的话还能够设置相似flume回滚类型的batch数,即依照累计的音讯数量,累计的工夫距离,累计的数据大小设置batch大小。• 设置适合的形式,增大batch大小来减小网络IO和磁盘IO的申请,这是对于Kafka效率的思考不过异步写入失落数据的状况还是难以管制,还是得稳固整体集群架构的运行,特地是zookeeper,当然正对异步数据失落的状况尽量保障broker端的稳固运作吧。Kafka不像hadoop更致力于解决大量级数据,Kafka的音讯队列更擅长于解决小数据。针对具体业务而言,若是源源不断的push大量的数据(eg:网络爬虫),能够思考消息压缩。然而这也肯定水平上对CPU造成了压力,还是得联合业务数据进行测试抉择broker端topic设置多分区,分区自适应所在机器,为了让各分区均匀分布在所在的broker中,分区数要大于broker数。分区是Kafka进行并行读写的单位,是晋升kafka速度的要害。 ...

September 27, 2021 · 1 min · jiezi

关于kafka:告别Kafka-Stream让轻量级流处理更加简单

简介: 还在花精力去选型Kafka组件去做荡涤转化?来试试Kafka ETL工作性能! 一说到数据孤岛,所有技术人都不生疏。在 IT 倒退过程中,企业不可避免地搭建了各种业务零碎,这些零碎独立运行且所产生的数据彼此独立关闭,使得企业难以实现数据共享和交融,并造成了"数据孤岛"。 因为数据散落在不同数据库、音讯队列中,计算平台间接拜访这些数据时可能遇到可用性、传输提早,甚至零碎吞吐问题。如果回升到业务层面,咱们会发现这些场景随时都会遇到:汇总业务交易数据、旧零碎数据迁徙到新零碎中、不同零碎数据整合。因而,为了能让数据更加实时、高效的交融并反对各业务场景,企业通常抉择应用各种 ETL 工具以达到上述目标。 因而,咱们能够看到企业自行摸索的各种解决方案,比方应用自定义脚本,或应用服务总线(Enterprise Service Bus,ESB)和音讯队列(Message Queue,MQ),比方应用企业应用集成(Enterprise application integration,EAI)通过底层构造的设计来横贯企业异构零碎、利用、数据源等,实现数据的无缝共享与替换。 只管以上伎俩都算实现了无效实时处理,但也给企业带来更难决断的选择题:实时,但不可扩大,或可扩大。但批处理。与此同时,随着数据技术、业务需要的一直倒退,企业对 ETL 的要求也一直晋升: 除了反对事务性数据,也须要可能解决诸如 Log、Metric 等类型越来越丰盛的数据源;批处理速度须要进一步晋升;底层技术架构须要反对实时处理,并向以事件为核心演进。能够看到,流解决/实时处理平台作为事件驱动交互的基石。它向企业提供了全局化的数据/事件链接、即时数据拜访、繁多零碎统管全域数据以及继续索引/查问能力。也正是面对以上技术与业务需要,Kafka 提供了一个全新思路: 作为实时、可扩大音讯总线,不再须要企业应用集成;为所有音讯解决目的地提供流数据管道;作为有状态流解决微服务的根底构建块。咱们以购物网站数据分析场景为例,为了实现精细化经营,经营团队以及产品经理须要将泛滥用户行为、业务数据以及其余数据数据进行汇总,这其中包含但不限于: 用户各类点击、浏览、加购、登陆等行为数据;根底日志数据;APP 被动上传数据;来自 db 中的数据;其余。这些数据会集到 Kafka,而后数据分析工具对立从 Kafka 中获取所需的数据进行剖析计算。因为 Kafka 采集的数据源十分多且格局也各种各样。在数据进入上游数据分析工具之前,须要进行数据荡涤,例如过滤、格式化。在这里研发团队有两个抉择:(1)写代码去生产 Kafka 中的音讯,荡涤实现后发送到指标 Kafka Topic。(2)应用组件进行数据荡涤转换,例如:Logstash、Kafka Stream、Kafka Connector、Flink等。 看在这里,大家必定会有疑难:Kafka Stream 作为流式解决类库,间接提供具体的类给开发者调用,整个利用的运行形式次要由开发者管制,方便使用和调试。这有什么问题吗?尽管以上办法的确可能很快解决问题,但其问题也不言而喻。 研发团队须要自行编写代码,且须要前期继续保护,运维老本较大;对于很多轻量或简略计算需要,引入一个全新组件的技术老本过高,须要进行技术选型;在某组件选定后,须要研发团队进行学习并继续保护,这就带来了不可预期的学习老本、保护老本。 为了解决问题,咱们提供了一个更加轻量的解决方案:Kafka ETL 性能。 应用 Kafka ETL 性能后,只需通过 Kafka 控制台进行简略配置,在线写一段荡涤代码,即可实现 ETL 的目标。可能存在的高可用、保护等问题,齐全交由 Kafka。 那么接下来,咱们为大家展现如何疾速的创立数据 ETL 工作,仅需 3 步即可。 Step 1 : 创立工作 抉择 Kafka 起源实例、起源 Topic,以及对应的抉择 Kafka 指标实例、指标 Topic。并配置音讯初始地位、失败解决以及创立资源形式。 ...

September 24, 2021 · 1 min · jiezi

关于kafka:弃用-Java-8-和-Scala-212Apache-Kafka-300-上线

ApacheKafka是一个分布式流媒体平台,能够解决大量的数据,并使你可能将音讯从一个端点传递到另一个端点。 它具备高性能、长久化、多正本备份、横向扩大的能力。 本周二,Apache 官网发表,Apache Kafka 3.0.0 正式上线,此版本更新了许多重要内容,其中包含: 惯例变动: KIP-750(第一局部):弃用 Kafka 中对 Java 8 的反对KIP-751(第一局部):弃用 Kafka 中对 Scala 2.12 的反对Kafka 对 Java 8 和 Scala 2.12 的反对将在 4.0 版本中彻底移除,以让开发者有工夫进行调整。 其余重要变动: KIP-630:Kafka Raft 反对元数据主题的快照KIP-679:Producer 将默认启用最强的交付保障KIP-695:进一步改良 Kafka Streams 工夫戳同步KIP-699:更新 FindCoordinator 以一次解析多个 CoordinatorKIP-709:扩大 OffsetFetch 申请以承受多个组 IDKIP-716:容许应用 MirrorMaker2 配置偏移同步主题的地位KIP-720:弃用 MirrorMaker v1KIP-721:在连贯Log4j配置中默认启用连接器日志上下文KIP-722:默认启用连接器客户端笼罩KIP-724:删除对音讯格局 v0 和 v1 的反对KIP-740:清理了 Steam 中的 公共 API TaskIdKIP-741:在 Kafka Streams 中将默认 SerDe 更改为 nullKIP-745:在 Kafka Connect 的一次调用中重新启动连接器的工作更多信息请查看官网博客: https://blogs.apache.org/kafka/

September 24, 2021 · 1 min · jiezi

关于kafka:告别Kafka-Stream让轻量级流处理更加简单

作者|白玙 一说到数据孤岛,所有技术人都不生疏。在 IT 倒退过程中,企业不可避免地搭建了各种业务零碎,这些零碎独立运行且所产生的数据彼此独立关闭,使得企业难以实现数据共享和交融,并造成了"数据孤岛"。 因为数据散落在不同数据库、音讯队列中,计算平台间接拜访这些数据时可能遇到可用性、传输提早,甚至零碎吞吐问题。如果回升到业务层面,咱们会发现这些场景随时都会遇到:汇总业务交易数据、旧零碎数据迁徙到新零碎中、不同零碎数据整合。因而,为了能让数据更加实时、高效的交融并反对各业务场景,企业通常抉择应用各种 ETL 工具以达到上述目标。 因而,咱们能够看到企业自行摸索的各种解决方案,比方应用自定义脚本,或应用服务总线(Enterprise Service Bus,ESB)和音讯队列(Message Queue,MQ),比方应用企业应用集成(Enterprise application integration,EAI)通过底层构造的设计来横贯企业异构零碎、利用、数据源等,实现数据的无缝共享与替换。 只管以上伎俩都算实现了无效实时处理,但也给企业带来更难决断的选择题:实时,但不可扩大,或可扩大。但批处理。与此同时,随着数据技术、业务需要的一直倒退,企业对 ETL 的要求也一直晋升: 除了反对事务性数据,也须要可能解决诸如 Log、Metric 等类型越来越丰盛的数据源;批处理速度须要进一步晋升;底层技术架构须要反对实时处理,并向以事件为核心演进。能够看到,流解决/实时处理平台作为事件驱动交互的基石。它向企业提供了全局化的数据/事件链接、即时数据拜访、繁多零碎统管全域数据以及继续索引/查问能力。也正是面对以上技术与业务需要,Kafka 提供了一个全新思路: 作为实时、可扩大音讯总线,不再须要企业应用集成;为所有音讯解决目的地提供流数据管道;作为有状态流解决微服务的根底构建块。咱们以购物网站数据分析场景为例,为了实现精细化经营,经营团队以及产品经理须要将泛滥用户行为、业务数据以及其余数据数据进行汇总,这其中包含但不限于: 用户各类点击、浏览、加购、登陆等行为数据;根底日志数据;APP 被动上传数据;来自 db 中的数据;其余。这些数据会集到 Kafka,而后数据分析工具对立从 Kafka 中获取所需的数据进行剖析计算。因为 Kafka 采集的数据源十分多且格局也各种各样。在数据进入上游数据分析工具之前,须要进行数据荡涤,例如过滤、格式化。在这里研发团队有两个抉择:(1)写代码去生产 Kafka 中的音讯,荡涤实现后发送到指标 Kafka Topic。(2)应用组件进行数据荡涤转换,例如:Logstash、Kafka Stream、Kafka Connector、Flink等。 看在这里,大家必定会有疑难:Kafka Stream 作为流式解决类库,间接提供具体的类给开发者调用,整个利用的运行形式次要由开发者管制,方便使用和调试。这有什么问题吗?尽管以上办法的确可能很快解决问题,但其问题也不言而喻。 研发团队须要自行编写代码,且须要前期继续保护,运维老本较大;对于很多轻量或简略计算需要,引入一个全新组件的技术老本过高,须要进行技术选型;在某组件选定后,须要研发团队进行学习并继续保护,这就带来了不可预期的学习老本、保护老本。 为了解决问题,咱们提供了一个更加轻量的解决方案:Kafka ETL 性能。 应用 Kafka ETL 性能后,只需通过 Kafka 控制台进行简略配置,在线写一段荡涤代码,即可实现 ETL 的目标。可能存在的高可用、保护等问题,齐全交由 Kafka。 那么接下来,咱们为大家展现如何疾速的创立数据 ETL 工作,仅需 3 步即可。 Step 1 : 创立工作抉择 Kafka 起源实例、起源 Topic,以及对应的抉择 Kafka 指标实例、指标 Topic。并配置音讯初始地位、失败解决以及创立资源形式。 Step 2:编写ETL主逻辑咱们能够抉择 Python3 作为函数语言。 ...

September 24, 2021 · 1 min · jiezi

关于kafka:技术干货|基于Apache-Hudi-的CDC数据入湖内附干货PPT下载渠道

简介: 阿里云技术专家李少锋(风泽)在Apache Hudi 与 Apache Pulsar 联结 Meetup 杭州站上的演讲整顿稿件,本议题将介绍典型 CDC 入湖场景,以及如何应用 Pulsar/Hudi 来构建数据湖,同时将会分享 Hudi 内核设计、新愿景以及社区最新动静。 本文PPT下载链接: 李少锋(风泽) - 阿里云技术专家-《基于Apache Hudi的CDC数据入湖》.pdf 一、CDC背景介绍首先咱们介绍什么是CDC?CDC的全称是Change data Capture,即变更数据捕捉,它是数据库畛域十分常见的技术,次要用于捕捉数据库的一些变更,而后能够把变更数据发送到上游。它的利用比拟广,能够做一些数据同步、数据散发和数据采集,还能够做ETL,明天次要分享的也是把DB数据通过CDC的形式ETL到数据湖。 对于CDC,业界次要有两种类型:一是基于查问的,客户端会通过SQL形式查问源库表变更数据,而后对外发送。二是基于日志,这也是业界宽泛应用的一种形式,个别是通过binlog形式,变更的记录会写入binlog,解析binlog后会写入音讯零碎,或间接基于Flink CDC进行解决。 它们两者是有区别的,基于查问比较简单,是入侵性的,而基于日志是非侵入性,对数据源没有影响,但binlog的解析比较复杂一些。 基于查问和基于日志,别离有四种实现技术,有基于工夫戳、基于触发器和快照,还有基于日志的,这是实现CDC的技术,上面是几种形式的比照。 通过这个表格比照能够发现基于日志的综合最优,但解析比较复杂,但业界有很多开源的binlog的解析器,比拟通用和风行的有Debezium、Canal,以及Maxwell。基于这些binlog解析器就能够构建ETL管道。 上面来看下业界比拟风行的一种CDC入仓架构。 整个数据入仓是分实时流是离线流,实时流解析binlog,通过Canal解析binlog,而后写入Kafka,而后每个小时会把Kafka数据同步到Hive中;另外就是离线流,离线流须要对同步到Hive的贴源层的表进行拉取一次全量,如果只有后面的实时流是数据是不全的,必须通过离线流的SQL Select把全量导入一次数据,对每张ODS表会把存量数据和增量数据做一个Merge。这里能够看到对于ODS层的实时性不够,存在小时、天级别的提早。而对ODS层这个延时能够通过引入Apache Hudi做到分钟级。 二、CDC数据入湖办法基于CDC数据的入湖,这个架构非常简单。上游各种各样的数据源,比方DB的变更数据、事件流,以及各种内部数据源,都能够通过变更流的形式写入表中,再进行内部的查问剖析,整个架构非常简单。 架构尽管简略,但还是面临很多挑战。以Apache Hudi数据湖为例,数据湖是通过文件存储各种各样的数据, 对于CDC的数据处理须要对湖里某局部文件进行牢靠地、事务性变更,这样能够保障上游查问不会看到局部后果,另外对CDC数据须要高效的做更新、删除操作,这就须要疾速定位到更改的文件,另外是对于每小批量的数据写入,心愿可能主动解决小文件,防止繁冗的小文件解决,还有面向查问的布局优化,能够通过一些技术手段如Clustering革新文件布局,对外提供更好的查问性能。 而Apache Hudi是怎么应答这些挑战的呢?首先反对事务性写入,包含读写之间的MVCC机制保障写不影响读,也能够管制事务及并发保障,对于并发写采纳OCC乐观锁机制,对更新删除,内置一些索引及自定义保障更新、删除比拟高效。另外是面向查问优化,Hudi外部会主动做小文件的治理,文件会主动长到用户指定的文件大小,如128M,这对Hudi来说也是比拟外围的个性。另外Hudi提供了Clustering来优化文件布局的性能。 下图是典型CDC入湖的链路。下面的链路是大部分公司采取的链路,后面CDC的数据先通过CDC工具导入Kafka或者Pulsar,再通过Flink或者是Spark流式生产写到Hudi里。第二个架构是通过Flink CDC直联到MySQL上游数据源,间接写到上游Hudi表。 其实,这两条链路各有优缺点。第一个链路对立数据总线,扩展性和容错性都很好。对于第二条链路,扩展性和容错性会略微差点,但因为组件较少,保护老本相应较低。 这是阿里云数据库OLAP团队的CDC入湖链路,因为咱们咱们做Spark的团队,所以咱们采纳的Spark Streaming链路入湖。整个入湖链路也分为两个局部:首先有一个全量同步作业,会通过Spark做一次全量数据拉取,这里如果有从库能够直连从库做一次全量同步,防止对主库的影响,而后写到Hudi。而后会启动一个增量作业,增量作业通过Spark生产阿里云DTS里的binlog数据来将binlog准实时同步至Hudi表。全量和增量作业的编排借助了Lakehouse的作业主动编排能力,协调全量和增量作业,而对于全量和增量连接时利用Hudi的Upsert语义保障全增量数据的最终的一致性,不会呈现数据偏多和偏少的问题。 在Lakehouse的CDC入湖链路中,咱们团队也做了一些优化。 第一个是原库的Schema变更解决,咱们对接的客户某些列的减少、删除或者批改某些列的场景。在Spark写Hudi之前会做Schema的测验,看这个Schema是不是非法,如果非法就能够失常写入,如果不非法的话,则会写入失败,而删除字段会导致Schema校验不非法,导致作业失败,这样稳定性是没有保障的。因而咱们会捕获Schema Validation的异样,如果发现是缩小了字段,咱们会把之前的字段做主动补全,而后做重试,保障链路是稳固的。 第二个有些客户表没有主键或者主键不合理,比方采纳更新工夫字段作为主键,或者设置会变动的分区字段,这时候就会导致写入Hudi的数据和源库表数据对不上。因而咱们做了一些产品层面的优化,容许用户正当设置主键和分区映射,保障同步到Hudi里和源库是数据齐全对齐的。 还有一个常见需要是用户在上游库中减少一个表,如果应用表级别同步的话,新增表在整个链路是无奈感知的,也就无奈同步到Hudi中,而在Lakehouse中,咱们能够对整库进行同步,因而在库中新增表时,会主动感知新增表,将新增表数据主动同步到Hudi,做到原库减少表主动感知的能力。 还有一个是对CDC写入时候性能优化,比方拉取蕴含Insert、Update、Delete等事件的一批数据,是否始终应用Hudi的Upsert形式写入呢?这样管制比较简单,并且Upsert有数据去重能力,但它带来的问题是找索引的效率低,而对于Insert形式而言,不须要找索引,效率比拟高。因而对于每一批次数据会判断是否都是Insert事件,如果都是Insert事件就间接Insert形式写入,防止查找文件是否更新的开销,数据显示大略能够晋升30%~50%的性能。当然这里也须要思考到DTS异样,从新生产数据时,复原期间不能间接应用Insert形式,否则可能会存在数据反复,对于这个问题咱们引入了表级别的Watermark,保障即便在DTS异常情况下也不会呈现数据反复问题。 三、Hudi外围设计接着介绍下Hudi 的定位,依据社区最新的愿景,Hudi的定义是流式数据湖平台,它反对海量数据更新,内置表格局以及反对事务的贮存,一系列列表服务Clean、Archive、 Compaction、Clustering等,以及开箱即用的数据服务,以及自身自带的运维工具和指标监控,提供很好的运维能力。 这是Hudi官网的图,能够看到Hudi在整个生态里是做湖存储,底层能够对接HDFS以及各种云厂商的对象存储,只有兼容Hadoop协定接。上游是入湖的变动事件流,对上能够反对各种各样的数据引擎,比方presto、Spark以及云上产品;另外能够利用Hudi的增量拉取能力借助Spark、Hive、Flink构建派生表。 整个Hudi体系结构是十分齐备的,其定位为增量的解决栈。典型的流式是面向行,对数据逐行解决,解决十分高效。 ...

September 6, 2021 · 1 min · jiezi

关于kafka:躬行系列Kafka-eagle部署

版本抉择v2.0.6 下载地址https://codeload.github.com/s... 部署细节因为kafka-eagle用的是jmx拉取数据,所以须要批改kafka启动脚本。vim kafka-server-start.sh 28 if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then 29 export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G" 30 fi改为 28 if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then 29 export KAFKA_HEAP_OPTS="-server -Xms2G -Xmx2G -XX:PermSize=128m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=8 -XX:ConcGCThreads=5 -XX:InitiatingHeapOccupancyPercent=70" 30 export JMX_PORT="9999" 31 #export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G" 32 fi解压,kafka-eagle是嵌套的压缩。须要解压两次能力失去真正的安装包。 tar -zxvf kafka-eagle-bin-2.0.6.tar.gzcd kafka-eagle-bin-2.0.6tar -zxvf kafka-eagle-web-2.0.6-bin.tar.gzkafka-eagle必须配置环境变量。 vim /etc/profileexport KE_HOME=/usr/local/kafka-eagle-web-2.0.6export PATH=$PATH:$KE_HOME/bin批改配置文件:system-config.properties个别须要批改的配置项都在上面了。 ####################################### multi zookeeper & kafka cluster list######################################kafka.eagle.zk.cluster.alias=cluster1cluster1.zk.list=192.168.1.73:2181,192.168.1.52:2181,192.168.1.102:2181####################################### kafka offset storage######################################cluster1.kafka.eagle.offset.storage=kafka####################################### kafka mysql jdbc driver address######################################kafka.eagle.driver=com.mysql.cj.jdbc.Driverkafka.eagle.url=jdbc:mysql://127.0.0.1:3306/ke?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNullkafka.eagle.username=rootkafka.eagle.password=123456留神启动日志里的用户名明码 ...

August 29, 2021 · 1 min · jiezi

关于kafka:躬行系列Kafka集群部署

版本抉择kafka_2.12-0.11.0.3版本号阐明:kafka应用Scala开发的,后面的2.12是Scala的版本号,前面的才是kafka的版本号。0.11的版本,曾经是kafka比较完善的一个版本了,前面新版都是对streaming的各种加强。如果仅用作音讯队列,那么用0.11版本即可。 下载地址https://archive.apache.org/di... 部署细节下载、上传、解压缩等过程省略。次要的配置文件就是:/config/server.properties要害配置: #broker id必须全局惟一broker.id=0#log的地位就是理论数据存储的地位log.dirs=/usr/local/kafka_2.12-0.11.0.3/data#开启删除topic的性能delete.topic.enable=true#zookeeper集群配置zookeeper.connect=192.168.1.73:2181,192.168.1.52:2181,192.168.1.102:2181常用命令启动:./kafka-server-start.sh -daemon ../config/server.properties进行:./kafka-server-stop.sh stop

August 29, 2021 · 1 min · jiezi

关于kafka:Kafka的一些定义及实现

一些专业术语根本定义Topic:主题,相当于为某一类业务产生音讯数据。Broker:相当于服务端,接管解决客户端音讯申请。同一台linux机器能够通过server.properties配置多个broker,也能够在多台机器上散布多个broker,防止单机宕机造成服务不可用。Partition:分区,topic能够分成多个分区,音讯散布在不同分区里,全局惟一。leader正本:领导者正本。对外提供服务,同时一个broker里可能会有不同分区的leader和follower,然而不会同时存在同一个分区的leader和follower。follower正本:追随者正本。不对外提供服务,只从leader正本拉取数据做同步工作。在leader挂掉之后能够参加选举。offset:音讯位移,须要被动或者被动的提交,用于记录上一次生产地位。ISR:分区中保护了一个动静汇合ISR,其中会保留leader正本以及一些在肯定工夫内(replica.lag.time.max.ms,默认10秒)与leader正本数据绝对同步的follower正本,follower会因为这个前提动静进出ISR。Consumer Group:消费者组,consumer实例能够配置groupid,对于一个消费者组的多个consumer来说,它们会一起协调来瓜分一个主题下的所有分区(换言之,一个topic的单个分区的音讯,只有一个consumer能获取到)。不同消费者组是相互隔离的,不受彼此影响。一般来说,消费者组内的消费者实例不能大于主题下的分区总数,否则会呈现有的实例调配不到分区变成闲暇状态。Rebalance:重均衡。消费者组内的某个实例挂掉之后,须要对残余的consumer实例从新进行topic下的分区的调配,这个过程可能会很久,此时所有的实例都须要进行工作,相似JVM中的“STOP THE WORLD”。产生重均衡的条件有,组内消费者实例数量发生变化,订阅topic数变动,分区数发生变化。Coordinator:协调者,协调Consumer Group中的服务,包含执行Rebalance以及提供位移治理和组成员治理等 音讯流转流程图 broker及leader选举机制broker leader选举在kafka集群中,会有多个broker节点,第一个在zk上胜利创立长期节点/controller的就是控制器,其余的broker则会通过controller path在zk上注册watch,当控制器broker退出时,所有的broker节点都通过watch感知到,它们会去竞争创立新的/controller。zk会保障只有一个broker胜利创立长期节点,其余的broker会收到异样告诉,只能去注册新的watch。个人感觉这是一种相似分布式锁+监听器的模式。 分区leader正本选举个别状况下,分区的leader正本只会从ISR中选举,依照AR汇合(所有正本汇合)的程序默认第一个follower正本成为新的leader,除非配置unclean.leader.election.enable进行unclean领导者选举,也就是非同步正本参加选举。 要害配置信息(consumer)enable.auto.commit 手动提交或者主动提交,主动提交是在调用 poll 办法时,提交上次 poll 解决过后的位移auto.commit.interval.ms 主动提交距离heartbeat.interval.ms 心跳距离session.timeout.ms consumer过期工夫,超过这个工夫没有收到申请Coordinator就会认为consumer挂了max.poll.interval.ms 两次poll的最大间隔时间 kafka罕用linux命令linux下启动zookeeper服务和kafka,就能够进行音讯的生产与生产了 后盾启动 nohup ./bin/kafka-server-start.sh ./config/server.properties >>/usr/local/kafka/kafka_2.12-2.8.0/logs/kafka.log 2>&1 &cd ../ 进行服务 ./kafka_2.12-2.8.0/bin/kafka-server-stop.sh查问端口号 netstat -anlpt|grep 9092生产者 bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test_topic消费者 bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test_topic --from-beginning查看topics ./kafka-topics.sh --list --zookeeper localhost:2181

August 25, 2021 · 1 min · jiezi

关于kafka:kafka日志清理引发的core-dump问题

原文链接:http://fxbing.github.io/2021/...团队开发了kafka on hdfs的性能,用以将kafka数据存储在hdfs上,然而在应用的过程中发现,有机器呈现core dump景象。 本文基于kafka版本0.10.2排查过程一、排查core dump文件因为呈现了屡次core dump问题,所以首先须要从core dump文件中进行剖析。从core dump文件能够看出,以下几个问题: 挂掉的线程名称都是hdfs相干的,所以揣测与hdfs相干性能无关挂掉的代码地位都与index读取逻辑无关,所以揣测和index清理逻辑无关 二、剖析代码 剖析kafka本地日志删除的代码发现,本地日志删除通过asyncDeleteSegment进行,asyncDeleteSegment进行删除时首先会rename本地日志文件和索引文件,而后提早肯定工夫进行删除。 /** a file that is scheduled to be deleted */ val DeletedFileSuffix = ".deleted"/** * Perform an asynchronous delete on the given file if it exists (otherwise do nothing) * * @throws KafkaStorageException if the file can't be renamed and still exists */ private def asyncDeleteSegment(segment: LogSegment) { segment.changeFileSuffixes("", Log.DeletedFileSuffix) def deleteSeg() { info("Deleting segment %d from log %s.".format(segment.baseOffset, name)) segment.delete() } scheduler.schedule("delete-file", deleteSeg, delay = config.fileDeleteDelayMs) }/** * Change the suffix for the index and log file for this log segment */ def changeFileSuffixes(oldSuffix: String, newSuffix: String) { def kafkaStorageException(fileType: String, e: IOException) = new KafkaStorageException(s"Failed to change the $fileType file suffix from $oldSuffix to $newSuffix for log segment $baseOffset", e) try log.renameTo(new File(CoreUtils.replaceSuffix(log.file.getPath, oldSuffix, newSuffix))) catch { case e: IOException => throw kafkaStorageException("log", e) } try index.renameTo(new File(CoreUtils.replaceSuffix(index.file.getPath, oldSuffix, newSuffix))) catch { case e: IOException => throw kafkaStorageException("index", e) } try timeIndex.renameTo(new File(CoreUtils.replaceSuffix(timeIndex.file.getPath, oldSuffix, newSuffix))) catch { case e: IOException => throw kafkaStorageException("timeindex", e) } } 然而在hdfs相干的清理性能中,间接进行的日志清理而没有rename和delay操作,所以揣测清理日志和索引时,如果文件仍被读取,强行删除会导致core dump。 ...

August 15, 2021 · 1 min · jiezi

关于kafka:Kafka-和-Kinesis-之间的对比和选择

在古代大型数据环境下,音讯的发送和解决就变得十分重要了。 作为音讯发送解决畛域外面的大象,那就是 Kafka 了。 Kafka 和 Kinesis 间接的关系 在比照 Kafka 和 Kinesis 和之前,咱们须要对 Kinesis 有所理解。 什么是 Kafka Apache Kafka 是一个开源,分布式,可伸缩的公布-订阅音讯零碎。 负责该软件的组织是 Apache Software Foundation。 该代码是用 Scala 编写的,最后是由 LinkedIn 公司开发的。 它于2011年开源,成为 Apache 的顶级我的项目。 该我的项目旨在提供一个对立的低提早平台,该平台可能实时处理数据馈送。 对于须要零碎之间集成的不同企业基础架构,它变得越来越有价值。 心愿集成的零碎能够依据其需要公布或订阅特定的Kafka主题。 Kafka受事务日志的影响, Apache Kafka 背地的思维是成为可伸缩的音讯队列,其构造相似于事务日志。 这个平台被指定为实时数据流。 Kafka 容许组织特定主题下的数据。 用一句话来说就是 Kafka 的音讯解决能力就是快,十分的快。 什么是 Kinesis 简略来说 Kinesis 就是 AWS 的云平台的实现。 与自行部署 Kafka 来说,你不须要保护硬件平台,不须要为硬件领取费用可能十分快的进行部署。 Amazon Kinesis 可让您轻松收集、解决和剖析实时流数据,以便您及时取得见解并对新信息疾速做出响应。Amazon Kinesis 提供多种外围性能,能够经济高效地解决任意规模的流数据,同时具备很高的灵活性,让您能够抉择最合乎应用程序需要的工具。 借助 Amazon Kinesis,您能够获取视频、音频、应用程序日志和网站点击流等实时数据,也能够获取用于机器学习、剖析和其余应用程序的 IoT 遥测数据。 如何抉择 对有抉择艰难症的童鞋和公司来说兴许上面的比照可能帮你做出一些决定。 次要区别 Kafka 是开源的分布式消息传递解决方案,而 Kinesis 是 mazon提供的托管平台。 ...

August 7, 2021 · 1 min · jiezi

关于kafka:大数据之-Hadoop10Kafka

一、Kafka概述1、定义Kafka是一个分布式的基于公布/订阅模式的音讯队列,次要利用于大数据实时处理畛域。 2、基础架构 (1)Producer :音讯生产者,就是向kafka broker发消息的客户端;(2)Consumer :音讯消费者,向kafka broker取音讯的客户端;(3)Consumer Group (CG):消费者组,由多个consumer组成。消费者组内每个消费者负责生产不同分区的数据,一个分区只能由一个消费者生产;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。(4)Broker :一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker能够包容多个topic。(5)Topic :能够了解为一个队列,生产者和消费者面向的都是一个topic;(6)Partition:为了实现扩展性,一个十分大的topic能够散布到多个broker(即服务器)上,一个topic能够分为多个partition,每个partition是一个有序的队列;(7)Replica:正本,为保障集群中的某个节点产生故障时,该节点上的partition数据不失落,且kafka依然可能持续工作,kafka提供了正本机制,一个topic的每个分区都有若干个正本,一个leader和若干个follower。(8)leader:每个分区多个正本的“主”,生产者发送数据的对象,以及消费者生产数据的对象都是leader。(9)follower:每个分区多个正本中的“从”,实时从leader中同步数据,放弃和leader数据的同步。leader产生故障时,某个follower会成为新的leader。 针对下面的概念,咱们能够这样了解:不同的主题好比不同的高速公路,分区好比某条高速公路上的车道,音讯就是车道上运行的车辆。如果车流量大,则扩宽车道,反之,则缩小车道。而消费者就好比高速公路上的收费站,凋谢的收费站越多,则车辆通过速度越快。 对于消费者组(Consumer Group)规定,同一消费者组内不容许多个消费者生产同一分区的音讯,而不同的消费者组能够同时生产同一分区的音讯。也就是说,分区与同一个消费者组中的消费者的对应关系是多对一而不是一对多。 二、集群装置Kafka1、下载安装Kafka依赖Zookeeper集群,搭建Kafka集群之前,须要先搭建好Zookeeper集群,咱们在前边曾经搭建过Zookeeper集群了。 kafka和Zookeeper版本对应关系: 从Apache官网 下载kafka(地址:http://kafka.apache.org/downl... )的稳固版本,咱们依据之Zookeeper版本,下载kafka_2.12-2.5.0.tgz(因为Kafka应用Scala和Java编写,2.12指Scala版本号,2.5.0指Kafka版本号) 在centos01 节点中,切换到目录 /opt/softwares/ 中,并进入到该目录中,先下载,而后解压到目录 /opt/modules/ $ cd /opt/softwares/$ wget https://archive.apache.org/dist/kafka/2.5.0/kafka_2.12-2.5.0.tgz$ tar -zxvf kafka_2.12-2.5.0.tgz -C /opt/modules/2、编写配置文件切换目录到装置目录下,装置目录名字 kafka_2.12-2.5.0 cd /opt/modules/kafka_2.12-2.5.0在/opt/modules/kafka_2.12-2.5.0目录下创立logs文件夹 [root@centos01 kafka_2.12-2.5.0]# mkdir logs[root@centos01 kafka_2.12-2.5.0]# ls -l总用量 56drwxr-xr-x. 3 root root 4096 4月 8 2020 bindrwxr-xr-x. 2 root root 4096 4月 8 2020 configdrwxr-xr-x. 2 root root 8192 7月 29 23:17 libs-rw-r--r--. 1 root root 32216 4月 8 2020 LICENSEdrwxr-xr-x. 2 root root 6 7月 29 23:49 logs-rw-r--r--. 1 root root 337 4月 8 2020 NOTICEdrwxr-xr-x. 2 root root 44 4月 8 2020 site-docs[root@centos01 kafka_2.12-2.5.0]# 批改配置文件 /config/server.properties ...

July 29, 2021 · 5 min · jiezi

关于kafka:Kafka-简易使用指南

装置mkdir /app/kafka cd /app/kafkawget https://mirrors.bfsu.edu.cn/apache/kafka/2.8.0/kafka_2.13-2.8.0.tgztar -xzf kafka_2.13-2.8.0.tgzcd kafka_2.13-2.8.0## 装置 JDKyum install java-1.8.0-openjdk.x86_64 -y# 启动 zookeeperbin/zookeeper-server-start.sh config/zookeeper.properties# 启动 kafka brokerbin/kafka-server-start.sh config/server.properties音讯操作# 创立 Topicbin/kafka-topics.sh --create --topic quickstart-events --bootstrap-server localhost:9092# 生产音讯bin/kafka-console-producer.sh --topic quickstart-events --bootstrap-server localhost:9092# 生产音讯bin/kafka-console-consumer.sh --topic quickstart-events --from-beginning --bootstrap-server localhost:9092配置 supervisor 启动kafka-zookeeper.conf[program:kafka-zookeeper]command = /app/kafka/kafka_2.13-2.8.0/bin/zookeeper-server-start.sh /app/kafka/kafka_2.13-2.8.0/config/zookeeper.propertiesautostart = true startsecs = 5 autorestart = true startretries = 3 user = root redirect_stderr = true stdout_logfile_maxbytes = 20MB stdout_logfile_backups = 20 stdout_logfile = /app/kafka/log/zookepper.logkafka-server.conf[program:kafka-server]command = /app/kafka/kafka_2.13-2.8.0/bin/kafka-server-start.sh /app/kafka/kafka_2.13-2.8.0/config/server.propertiesautostart = true startsecs = 5 autorestart = true startretries = 3 user = root redirect_stderr = true stdout_logfile_maxbytes = 20MB stdout_logfile_backups = 20 stdout_logfile = /app/kafka/log/server.log

July 22, 2021 · 1 min · jiezi

关于kafka:Kafka-javanetBindException-Address-already-in-use

问题形容启动kafka集群出错。开启kafka集群先要开启zookeeper,执行命令开启zookeeper出错: ERROR Unexpecte exception, exiting abnormally(org.apache.zookeeper.erver.ZookeeperServerMain)java,net,BindException: 地址已在应用 at xxx at xxx 问题剖析可能是端口被占用的起因 问题解决1、先查看端口占用状况 sudo netstat -atunlp | grep 21812、杀死占用过程 sudo kill -9 <占用端口的PID>3、重新启动Zookeeper即可 相干文章 Zookeeper启动不胜利,日志报猜你想看 Kafka 入门介绍

July 19, 2021 · 1 min · jiezi

关于kafka:kafka实战分区重分配可能出现的问题和排查问题思路生产环境实战干货非常干建议收藏

日常运维问题排查 怎么可能少了滴滴开源的 滴滴开源LogiKM一站式Kafka监控与管控平台 这篇文章源自于,一位群友的问题,而后就写下了这篇文章 进群加V :jjdlmn_ Kafka专栏整顿地址 请戳这里0.0 先定义一下名词: 迁徙前的Broker: OriginBroker 、 迁徙后的正本 TargetBroker 前提在这之前如果你比拟理解 <font color=red>分区重调配的原理</font> 的话,上面的可能更好了解;举荐你浏览一下上面几篇文章(如果你点不进去阐明我还没有公布) [【kafka源码】ReassignPartitionsCommand源码剖析(正本扩缩、数据迁徙、正本重调配、正本跨门路迁徙)]()[【kafka运维】正本扩缩容、数据迁徙、正本重调配、正本跨门路迁徙]() Kafka的灵魂伴侣Logi-KafkaManger(4)之运维管控–集群运维(数据迁徙和集群在线降级) 如果你不想费那个精力,那间接看上面我画的这张图,你本人也能剖析进去可能呈现的问题;以及怎么排查 所有异常情况Kafka专栏整顿地址 请戳这里 1. TargetBroker若不在线,迁徙脚本执行会失败TargetBroker若不在线, 在开始执行工作脚本的时候,校验都不会被通过呢情景演示BrokerId角色状态正本0一般Broker失常test-01一般Broker宕机无当初将分区topic-test-0 从Broker0 迁徙到 Broker1 sh bin/kafka-reassign-partitions.sh --zookeeper xxxxxx:2181/kafka3 --reassignment-json-file config/reassignment-json-file.json --execute --throttle 1000000执行异样 Partitions reassignment failed due to The proposed assignment contains non-existent brokerIDs: 1kafka.common.AdminCommandFailedException: The proposed assignment contains non-existent brokerIDs: 1 at kafka.admin.ReassignPartitionsCommand$.parseAndValidate(ReassignPartitionsCommand.scala:348) at kafka.admin.ReassignPartitionsCommand$.executeAssignment(ReassignPartitionsCommand.scala:209) at kafka.admin.ReassignPartitionsCommand$.executeAssignment(ReassignPartitionsCommand.scala:205) at kafka.admin.ReassignPartitionsCommand$.main(ReassignPartitionsCommand.scala:65) at kafka.admin.ReassignPartitionsCommand.main(ReassignPartitionsCommand.scala)2. TargetBroker在开始迁徙过程中宕机,导致迁徙工作始终在进行中<font face="黑体" color=red size=5>Kafka专栏整顿地址 请戳这里</font> ...

July 17, 2021 · 2 min · jiezi

关于kafka:kafka运维Kafka全网最全最详细运维命令合集精品强烈建议收藏

首发公众号: 石臻臻的杂货铺 ID:jjdlmn集体wx: jjdlmn_ 以下大部分运维操作,都能够应用 LogI-Kafka-Manager 在平台上可视化操作; @[TOC] 1.TopicCommand1.1.Topic创立bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 3 --partitions 3 --topic test相干可选参数 参数形容例子--bootstrap-server 指定kafka服务指定连贯到的kafka服务; 如果有这个参数,则 --zookeeper能够不须要--bootstrap-server localhost:9092--zookeeper弃用, 通过zk的连贯形式连贯到kafka集群;--zookeeper localhost:2181 或者localhost:2181/kafka--replication-factor 正本数量,留神不能大于broker数量;如果不提供,则会用集群中默认配置--replication-factor 3--partitions分区数量,当创立或者批改topic的时候,用这个来指定分区数;如果创立的时候没有提供参数,则用集群中默认值; 留神如果是批改的时候,分区比之前小会有问题--partitions 3--replica-assignment 正本分区调配形式;创立topic的时候能够本人指定正本分配情况;--replica-assignment BrokerId-0:BrokerId-1:BrokerId-2,BrokerId-1:BrokerId-2:BrokerId-0,BrokerId-2:BrokerId-1:BrokerId-0 ; 这个意思是有三个分区和三个正本,对应调配的Broker; 逗号隔开标识分区;冒号隔开示意正本--config <String: name=value>用来设置topic级别的配置以笼罩默认配置;只在--create 和--bootstrap-server 同时应用时候失效; 能够配置的参数列表请看文末附件例如笼罩两个配置 --config retention.bytes=123455 --config retention.ms=600001--command-config <String: command 文件门路>用来配置客户端Admin Client启动配置,只在--bootstrap-server 同时应用时候失效;例如:设置申请的超时工夫 --command-config config/producer.proterties ; 而后在文件中配置 request.timeout.ms=3000001.2.删除Topicbin/kafka-topics.sh --bootstrap-server localhost:9092 --delete --topic test反对正则表达式匹配Topic来进行删除,只须要将topic 用双引号包裹起来例如: 删除以create_topic_byhand_zk为结尾的topic; bin/kafka-topics.sh --bootstrap-server localhost:9092 --delete --topic "create_topic_byhand_zk.*".示意任意匹配除换行符 \n 之外的任何单字符。要匹配 . ,请应用 . 。·*·:匹配后面的子表达式零次或屡次。要匹配 * 字符,请应用 *。.* : 任意字符删除任意Topic (慎用) ...

July 8, 2021 · 6 min · jiezi

关于kafka:kafka客户端参数说明kafkaclient-24版本

一:生产端生产端的参数定义在类:org.apache.kafka.clients.consumer.ConsumerConfig。 1.1:bootstrap.servers:默认值:空用于建设到Kafka群集的初始连贯的主机/端口对的列表。客户机将应用所有服务器而不仅仅应用这里配置的节点。因为这些服务器地址仅用于初始化连贯,并通过现有配置的来发现全副的kafka集群成员(集群随时会变动),所以此列表不须要蕴含残缺的集群地址(但尽量多配置几个,以避免配置的服务器宕机)格局:host1:port1,host2:port2,... 1.2:client.dns.lookup:默认值:default管制客户端如何应用DNS查找。如果配置为use_all_dns_ips,则顺次连贯到每个返回的IP地址,直到胜利建设连贯。如果配置为resolve_canonical_bootstrap_servers_only,则将每个疏导地址解析成一个canonical名称列表。 1.3:group.id:默认值:null消费者所属的消费者组的惟一标识。上面2种状况下,group.id必须要设置:(1):基于kafka的offset管理策略。 (2):KafkaConsumer应用subscribe接口订阅音讯。 1.4:group.instance.id:默认值:null消费者实例ID,只容许非空字符串。如果设置,则使用者将被视为动态成员,这意味着在任何时候消费者组中只容许有一个具备此ID的实例。如果不设置,消费者将作为动静成员退出群,这是传统行为。 1.5:session.timeout.ms:默认值:10000毫秒消费者组外面,检测消费者失败的会话超时工夫。消费者会固定周期发送心跳音讯到服务端,当服务端在指定工夫内没有收到心跳音讯,则认为消费者失落。这时候,服务端会从消费者组里踢出该节点,而后从新再均衡。须要留神的是:该值必须在 group.min.session.timeout.ms 和group.max.session.timeout.ms 之间。 1.6:heartbeat.interval.ms:默认值:3000毫秒kafka生产组外面冀望的心跳间隔时间。心跳是用来确保消费者会议放弃沉闷,并在新消费者退出或来到个人时促成再均衡。该值必须设置为低于session.timeout.ms的配置。但通常应设置为比这个值的三分之一还小。 1.7:partition.assignment.strategy:默认值:RangeAssignor.class当应用组治理时,客户端将应用分区调配策略的类名来调配消费者实例之间的分区所有权。通过实现org.apache.kafka.clients.consumer.ConsumerPartitionAssignor接口,能够插入自定义调配策略。 1.8:metadata.max.age.ms:默认值:5601000毫秒强制刷新元数据的周期时间。即便没有任何分区领导层更改,也能够被动发现任何新的代理或分区。 1.9:enable.auto.commit:默认值:true如果为true,消费者的offset将在周期性的在后盾主动提交。 1.10:auto.commit.interval.ms:默认值:5000毫秒消费者主动提交offset的频率。当enable.auto.commit的值为true时无效。 1.11:client.id:默认值:""发出请求时要传递给服务器的id字符串,这样做的目标是通过容许在服务器端申请日志记录中蕴含逻辑应用程序名称,从而可能跟踪ip/端口以外的申请源。 1.12:client.rack:默认值:""此客户端的机架标识符。这能够是任何字符串值,批示此客户端的物理地位。它与broker配置“broker.rack”绝对应 1.13:max.partition.fetch.bytes:默认值:110241024 (1M)。每个申请从服务器上每个分区返回的最大数据量。消费者批量从服务端获取数据,如果获取到的第一个非空的partition的数量大于该值,则依然会返回。 服务器端最大的返回数据量由 message.max.bytes 配置决定(这个是服务端的配置)。或者通过topic的 max.message.bytes 配置设置。 1.14:send.buffer.bytes:默认值:128*1024发送数据时要应用的TCP发送缓冲区的大小(SO_SNDBUF)。如果值为-1,则应用OS默认值。 1.15:receive.buffer.bytes: 默认值:64*1024读取数据时要应用的TCP接收缓冲区(SO_RCVBUF)的大小。如果值为-1,则应用OS默认值。 1.16:fetch.min.bytes: 默认值:1从服务器上获取申请返回的最小数据量。如果没有足够的数据可用,申请将期待大量数据积攒后再答复申请。默认设置为1字节意味着只有有一个字节的数据可用,或者提取申请在期待数据达到时超时,提取申请就会失去响应。将此值设置为大于1的值将导致服务器期待更大数量的数据累积,这会略微进步服务器吞吐量,但会减少一些提早。 1.17:fetch.max.bytes:默认值:5010241024(50M)每个申请从服务器上返回的最大数据量。消费者批量从服务端获取数据,如果获取到的第一个非空的partition的数量大于该值,则依然会返回。服务器端最大的返回数据量由 message.max.bytes 配置决定(这个是服务端的配置)。或者通过topic的 max.message.bytes 配置设置。 1.18:fetch.max.wait.ms: 默认值:500毫秒。如果没有足够的数据来立刻满足fetch.min.bytes给出的要求,则服务器在响应fetch申请之前将阻止的最长工夫。 1.19:reconnect.backoff.ms: 默认值:50毫秒尝试从新连贯到给定主机之前期待的根本工夫量。这样能够防止在严密循环中反复连贯到主机。此回退实用于客户端到代理的所有连贯尝试。 1.20:reconnect.backoff.max.ms: 默认值:1000毫秒从新连贯到反复连贯失败的代理时期待的最大工夫(毫秒) 1.21: retry.backoff.ms: 默认值值:100毫秒尝试重试对给定主题分区的失败申请之前期待的工夫量。这样能够防止在某些故障状况下以严密循环的形式反复发送申请。 1.22:auto.offset.reset: 默认值:latest。可选值("latest", "earliest", "none")如果Kafka中没有初始偏移量,或者服务器上不再存在以后偏移量(例如,因为该数据已被删除),该怎么办:earliest:主动将偏移量重置为最早偏移量latest:主动将偏移量重置为最新偏移量none:消费者组没有找到地位偏移量,抛出异样 1.23:check.crcs: 默认值:true主动查看已耗费记录的CRC32。这可确保不会产生对音讯的在线或磁盘损坏。此查看会减少一些开销,因而在寻求极其性能的状况下可能会禁用它。 1.24:metrics.sample.window.ms: 默认值:30000毫秒计算度量样本的工夫窗口。 1.25:metrics.num.samples为计算度量而保留的样本数。 1.26: metrics.recording.level: 默认值:INFO。可选值:DEBUG,INFO计算最高纪录级别。 1.27:key.deserializer: 默认值:接口 org.apache.kafka.common.serialization.Deserializer 的实现类。对KEY进行反序列化。 1.28:value.deserializer: 默认值:接口org.apache.kafka.common.serialization.Deserializer的实现类。用以对VALUE值进行反序列化。 1.29:request.timeout.ms:默认值:30000毫秒 配置管制客户端对发动的申请响应期待的最长工夫。如果在超时前没有收到响应,当重试次数没有用完之前,将发动重试,当重试次数用完之后,将失去失败。 1.30:default.api.timeout.ms: 默认值:60000毫秒消费者API可能阻塞的默认超时工夫。没有设置 timeout 参数时,应用该默认值。 1.31:connections.max.idle.ms:默认值:9*60000毫秒配置连贯的最大闲暇工夫。超过这个工夫连贯将敞开。 1.32:interceptor.classes:默认值:空列表接口org.apache.kafka.clients.consumer.ConsumerInterceptor的实现类列表。用以增加在消费者受到音讯之前的拦截器。 ...

July 4, 2021 · 2 min · jiezi

关于kafka:Kafka-Connector深度解读之JDBC源连接器

摘要我的项目须要应用Kafka Stream通过加载mysql数据库外面的数据,而后做一个相似于ETL数据过滤性能。以此将导入到某一个主题的kafka数据跟通过kafka connect连贯mysql的数据库外面的数据进行过滤去重。 内容一.kafka装置kafka连接器性能是kafka1.0版本以上引入的,咱们首先须要查看对应版本是否反对connect(直观的形式是:bin目录蕴含connect,conf目录蕴含connect);bin目录下: conf目录下: 咱们应用版本:kafka_2.11-1.0.1.jar. 其中2.11是Scala版本,1.0.1是Kafka版本;二.下载kafka-connect-jdbc插件去网站:https://www.confluent.io/hub/confluentinc/kafka-connect-jdbc下载;抉择对应的版本解压失去以下目录构造:失去: 将插件中lib外面的jar文件提取进去,放到kafka的libs目录: 三.将java的MySQL驱动拷贝到到kafka的libs目录 四:connect-mysql-source.properties配置文件将kafka-connect-jdbc中etc目录下文件复制到kafka的config目录下,并批改为connect-mysql-source.properties; 拷贝到kafka的config下: 依据本地数据源批改配置: # A simple example that copies all tables from a SQLite database. The first few settings are# required for all connectors: a name, the connector class to run, and the maximum number of# tasks to create:name=test-source-mysql-jdbc-autoincrementconnector.class=io.confluent.connect.jdbc.JdbcSourceConnectortasks.max=10# The remaining configs are specific to the JDBC source connector. In this example, we connect to a# SQLite database stored in the file test.db, use and auto-incrementing column called 'id' to# detect new rows as they are added, and output to topics prefixed with 'test-sqlite-jdbc-', e.g.# a table called 'users' will be written to the topic 'test-sqlite-jdbc-users'.#connection.url=jdbc:mysql://192.168.101.3:3306/databasename?user=xxx&password=xxxconnection.url=jdbc:mysql://127.0.01:3306/us_app?user=root&password=roottable.whitelist=ocm_blacklist_number#bulk为批量导入,此外还有incrementing和imestamp模式mode=bulk#timestamp.column.name=time#incrementing.column.name=idtopic.prefix=connect-mysql-配置阐明参考:https://www.jianshu.com/p/9b1dd28e92f0 ...

June 27, 2021 · 1 min · jiezi

关于kafka:kafka-kafkaerrorsNoBrokersAvailable-NoBrokersAvailable

问题形容简述: 在实现大数据试验课程中,应用pycharm编写脚本,启动kafka时遇到问题,执行producer.py文件报错,预期是要呈现 打印信息,然而却报错 consumer = KafkaConsumer('DAILY_SALES', bootstrap_servers=['0.0.0.0:9092']) File "/anaconda3/anaconda/lib/python3.6/site-packages/kafka/consumer/group.py", line 340, in __init__ self._client = KafkaClient(metrics=self._metrics, **self.config) File "/anaconda3/anaconda/lib/python3.6/site-packages/kafka/client_async.py", line 219, in __init__ self.config['api_version'] = self.check_version(timeout=check_timeout) File "/anaconda3/anaconda/lib/python3.6/site-packages/kafka/client_async.py", line 839, in check_version raise Errors.NoBrokersAvailable()kafka.errors.NoBrokersAvailable: NoBrokersAvailable上述代码不是理论报错信息,然而相似上述,次要是报错是 kafka.errors.NoBrokersAvailable: NoBrokersAvailable 晓得谬误后,搜查答案,网上的答案都没有见效,于是从新看了一下报错信息,寻得了一点线索,看了一下python解释器的配置,晓得大抵是什么起因导致的。 问题剖析根据上述的错误信息,过后应用的pycharm版本是2021最新版的,可能有版本问题 要求应用python3.xxx解释器,然而显示不反对unsupported,查看这个教程后得可能是版本太高,须要应用低版本(2019)pycharm,于是抱着试试的心态,从新下载安装2019pycharm 问题胜利解决 ! 问题解决具体就是剖析具体的报错信息,更换旧版的IDE 总结晋升 留神版本,环境兼容问题, python3.5在当前可能会弃用,所以在高版本的IDE中不太反对 相干文章 Kafka报错:kafka.errors.NoBrokersAvailable: NoBrokersAvailablepycharm配置环境呈现unsupportedlinux 查看python装置门路,版本号ubuntu中PyCharm的装置与卸载如何应用Pycharm编写我的项目 「应用教程」kafka.errors.NoBrokersAvailable: NoBrokersAvailable #1482Kafka SSL with Python: kafka.errors.NoBrokersAvailable: NoBrokersAvailable

June 25, 2021 · 1 min · jiezi

关于kafka:Kafka-源码解析Server-端的运行过程

摘要:Kafka网络模块之Server端,介绍Server端启动、接管申请和解决申请的过程。本文分享自华为云社区《Kafka网络模块-Server端》,原文作者:中间件小哥 。 SocketServer 是 Kafka server 端用于解决申请的模块,在 Kafka 启动过程创立、初始化、启动。 SocketServer启动过程: 依照 endpoint 程序初始化 Acceptor,每个 endpoint 对应一个 Acceptor,为每个 Acceptor 创立 Processor(数量由 num.network.threads 配置项决定),并启动 Acceptor,Acceptor 启动后会通过 selector 监听连贯,并将新建设的连贯交给 Processor 解决(轮询抉择 Processor)启动所有 ProcessorAcceptor启动、监听连贯过程:Acceptor启动后,会创立一个 serverSocketChannel,监听在该 acceptor 对应的 endpoint 上,并在 selector 上注册 OP_ACCEPT,而后进入死循环,每次循环,通过 selector 获取就绪的 key(即后面注册的 serverSocketChannel),表明有连贯来到,而后通过 accept() 创立一个和该连贯对应的 socketChannel,而后从该 acceptor 负责的 processors 中轮询抉择一个,将该 socketChannel 交给抉择的 processor 解决,行将连贯交给 processor。Acceptor 将连贯交给 processor 解决,是将 socketChannel 退出 processor 的连贯队列 newConnection 中,processor 在 run 办法中会一直地从中获取并解决。Processor 从 newConnection 获取到 socketChannel 后,在 selector 上注册 OP_READ,并创立对应的 KafkaChannel。Server端接管申请、解决的过程: ...

June 24, 2021 · 1 min · jiezi

关于kafka:Reactive-Spring实战-响应式Kafka交互

本文分享如何应用KRaft部署Kafka集群,以及Spring中如何实现Kafka响应式交互。 KRaft咱们晓得,Kafka应用Zookeeper负责为kafka存储broker,Consumer Group等元数据,并应用Zookeeper实现broker选主等操作。尽管应用Zookeeper简化了Kafka的工作,但这也使Kafka的部署和运维更简单。 Kafka 2.8.0开始移除了Zookeeper,并应用Kafka內部的仲裁(Quorum)控制器來取代ZooKeeper,官网称这个控制器为 "Kafka Raft metadata mode",即KRaft mode。从此用户能够在不须要Zookeeper的状况下部署Kafka集群,这使Fafka更加简略,轻量级。应用KRaft模式后,用户只须要专一于保护Kafka集群即可。 留神:因为该性能改变较大,目前Kafka2.8版本提供的KRaft模式是一个测试版本,不举荐在生产环境应用。置信Kafka后续版本很快会提供生产可用的kraft版本。 上面介绍一下如果应用Kafka部署kafka集群。这里应用3台机器部署3个Kafka节点,应用的Kafka版本为2.8.0。 1.生成ClusterId以及配置文件。(1)应用kafka-storage.sh生成ClusterId。 $ ./bin/kafka-storage.sh random-uuiddPqzXBF9R62RFACGSg5c-Q(2)应用ClusterId生成配置文件 $ ./bin/kafka-storage.sh format -t <uuid> -c ./config/kraft/server.propertiesFormatting /tmp/kraft-combined-logs留神:只须要在生成一个ClusterId,并应用该ClusterId在所有机器上生成配置文件,即集群中所有节点应用的ClusterId需雷同。 2.批改配置文件脚本生成的配置文件只能用于单个Kafka节点,如果在部署Kafka集群,须要对配置文件进行一下批改。 (1)批改config/kraft/server.properties(稍后应用该配置启动kafka) process.roles=broker,controller node.id=1listeners=PLAINTEXT://172.17.0.2:9092,CONTROLLER://172.17.0.2:9093advertised.listeners=PLAINTEXT://172.17.0.2:9092controller.quorum.voters=1@172.17.0.2:9093,2@172.17.0.3:9093,3@172.17.0.4:9093process.roles指定了该节点角色,有以下取值 broker: 这台机器将仅仅当作一个brokercontroller: 作为Raft quorum的控制器节点broker,controller: 蕴含以上两者的性能一个集群中不同节点的node.id须要不同。controller.quorum.voters须要配置集群中所有的controller节点,配置格局为<nodeId>@<ip>:<port>。 (2)kafka-storage.sh脚本生成的配置,默认将kafka数据寄存在/tmp/kraft-combined-logs/,咱们还须要/tmp/kraft-combined-logs/meta.properties配置中的node.id,使其与server.properties配置中放弃一起。 node.id=13.启动kafka应用kafka-server-start.sh脚本启动Kafka节点 $ ./bin/kafka-server-start.sh ./config/kraft/server.properties上面测试一下该kafka集群1.创立主题 $ ./bin/kafka-topics.sh --create --partitions 3 --replication-factor 3 --bootstrap-server 172.17.0.2:9092,172.17.0.3:9092,172.17.0.4:9092 --topic topic1 2.生产音讯 $ ./bin/kafka-console-producer.sh --broker-list 172.17.0.2:9092,172.17.0.3:9092,172.17.0.4:9092 --topic topic13.生产音讯 $ ./bin/kafka-console-consumer.sh --bootstrap-server 172.17.0.2:9092,172.17.0.3:9092,172.17.0.4:9092 --topic topic1 --from-beginning这部分命令的应用与低版本的Kafka保持一致。 Kafka的性能临时还不欠缺,这是展现一个简略的部署示例。Kafka文档:https://github.com/apache/kaf... Spring中能够应用Spring-Kafka、Spring-Cloud-Stream两个框架实现kafka响应式交互。上面别离看一下这两个框架的应用。 Spring-Kafka1.增加援用增加spring-kafka援用 <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> <version>2.5.8.RELEASE</version></dependency>2.筹备配置文件,内容如下 ...

June 22, 2021 · 2 min · jiezi

关于kafka:关于kafka的一点使用

以python为例,从pykafka到kafka-python到confluent-kafka到flink 要留神最好应用最新版本pykafka和kafka-python性能不是很好,具体情况也能够查到 confluent-kafka性能好一点,也反对异步,有事件轮循机制,所以在与torando联合应用如同有问题,因为tornado是单过程,加上GIL锁,能够看这个:https://github.com/confluenti... 有些低版本装置后提醒“confluent_kafka/src/confluent_kafka.h:22:32: fatal error: librdkafka/rdkafka.h: No such file or directory”,能够apt-get install librdkafka-dev -y 所以我的项目上最好用flink

June 15, 2021 · 1 min · jiezi

关于kafka:kafka集群搭建和zk集群搭建

kafka转载:https://segmentfault.com/a/11...zk转载:https://segmentfault.com/a/11...两个对照着看,另外在查看kafka音讯时始终有日志一直显示,不晓得怎么敞开掉,有晓得的童鞋能够指导下哈 肯定要先启动ZooKeeper 再启动Kafka 程序不能够扭转。先敞开kafka ,再敞开zookeeper。 zookeeper启动:别离在三台机器上执行:zkServer.sh start查看ZooKeeper状态:zkServer.sh status敞开:zkServer.sh stop kafka启动(留神必须在kafka的装置主目录上面执行该命令)在三台机器上别离执行以下命令:bin/kafka-server-start.sh ../config/server.properties &敞开:bin/kafka-server-stop.sh

June 15, 2021 · 1 min · jiezi

关于kafka:分享一款非常好用的kafka可视化web管理工具

应用过kafka的小伙伴应该都晓得kafka自身是没有治理界面的,所有操作都须要手动执行命令来实现。但有些命令又多又长,如果没有做笔记,别说是老手,就连新手也不肯定能记得住,每次想要应用的时候都要上网搜寻一下。有些崇尚geek精力的人或者感觉命令行才是真爱,但应用一款好用的可视化管理工具真的能够极大的晋升效率。 明天给大家介绍的这款工具叫做kafka-map,是我针对日常工作中高频应用的场景开发的,应用了这款工具之后就不用费神费劲的去查资料某个命令要怎么写,就像是:“给编程插上翅膀,给kafka装上导航”。 kafka-map 介绍kafka map是应用Java11和React开发的一款kafka可视化工具。 目前反对的性能有: 多集群治理集群状态监控(分区数量、正本数量、存储大小、offset)主题创立、删除、扩容(删除需配置delete.topic.enable = true)broker状态监控消费者组查看、删除重置offset音讯查问(反对String和json形式展现)发送音讯(反对向指定的topic和partition发送字符串音讯)性能截图增加集群 集群治理 broker 主题治理 生产组 查看生产组已订阅主题 topic详情——分区 topic详情——broker topic详情——生产组 topic详情——生产组重置offset topic详情——配置信息 生产音讯 生产音讯 docker 形式装置一行命令即可实现装置 docker run -d \ -p 8080:8080 \ -v /opt/kafka-map/data:/usr/local/kafka-map/data \ -e DEFAULT_USERNAME=admin -e DEFAULT_PASSWORD=admin --name kafka-map \ --restart always dushixiang/kafka-map:latest更多装置形式以及置信信息可查看: https://github.com/dushixiang... 欢送star和分享给其余小伙伴。

June 13, 2021 · 1 min · jiezi

关于kafka:kafka源码学习KafkaApisLEADERANDISR

原文链接:https://fxbing.github.io/2021...本文源码基于kafka 0.10.2版本 每当controller产生状态变更时,都会通过调用sendRequestsToBrokers办法发送leaderAndIsrRequest申请,本文次要介绍kafka服务端解决该申请的逻辑和过程。 LEADER_AND_ISR整体逻辑流程case ApiKeys.LEADER_AND_ISR => handleLeaderAndIsrRequest(request)在server端收到LEADER_AND_ISR申请后,会调用handleLeaderAndIsrRequest办法进行解决,该办法的解决流程如图所示: 源码handleLeaderAndIsrRequesthandleLeaderAndIsrRequest函数的逻辑后果次要分为以下几个局部: 结构callback函数onLeadershipChange,用来回调coordinator解决新增的leader或者follower节点校验申请权限,如果校验胜利调用replicaManager.becomeLeaderOrFollower(correlationId, leaderAndIsrRequest, metadataCache, onLeadershipChange)进行后续解决【此处该函数的主流程】,否则,间接返回错误码Errors.CLUSTER_AUTHORIZATION_FAILED.codedef handleLeaderAndIsrRequest(request: RequestChannel.Request) { // ensureTopicExists is only for client facing requests // We can't have the ensureTopicExists check here since the controller sends it as an advisory to all brokers so they // stop serving data to clients for the topic being deleted val correlationId = request.header.correlationId val leaderAndIsrRequest = request.body.asInstanceOf[LeaderAndIsrRequest] try { def onLeadershipChange(updatedLeaders: Iterable[Partition], updatedFollowers: Iterable[Partition]) { // for each new leader or follower, call coordinator to handle consumer group migration. // this callback is invoked under the replica state change lock to ensure proper order of // leadership changes updatedLeaders.foreach { partition => if (partition.topic == Topic.GroupMetadataTopicName) coordinator.handleGroupImmigration(partition.partitionId) } updatedFollowers.foreach { partition => if (partition.topic == Topic.GroupMetadataTopicName) coordinator.handleGroupEmigration(partition.partitionId) } } val leaderAndIsrResponse = if (authorize(request.session, ClusterAction, Resource.ClusterResource)) { val result = replicaManager.becomeLeaderOrFollower(correlationId, leaderAndIsrRequest, metadataCache, onLeadershipChange) new LeaderAndIsrResponse(result.errorCode, result.responseMap.mapValues(new JShort(_)).asJava) } else { val result = leaderAndIsrRequest.partitionStates.asScala.keys.map((_, new JShort(Errors.CLUSTER_AUTHORIZATION_FAILED.code))).toMap new LeaderAndIsrResponse(Errors.CLUSTER_AUTHORIZATION_FAILED.code, result.asJava) } requestChannel.sendResponse(new Response(request, leaderAndIsrResponse)) } catch { case e: KafkaStorageException => fatal("Disk error during leadership change.", e) Runtime.getRuntime.halt(1) } }becomeLeaderOrFollowerReplicaManager的次要工作有以下几个局部,具体代码地位见中文正文: ...

June 5, 2021 · 7 min · jiezi

关于kafka:Kafka源码阅读kafka源码导入idea老是报错实践

环境idea2020jdk1.8gradle3.5scala2.11.8zookeeper(单机集群都能够)kafka-0.10.1 步骤0.idea提前设置首先装置scala插件idea的设置外面左侧有一个“Plugins”,搜寻scala相干的插件,此时一开始是找不到的,而后点击“search in repositories”,找到一个“Scala”插件,他的类别是“Language”,在线装即可,他会下载之后装置。装置后如下图: 1.克隆源码git clone https://github.com/apache/kafka.git拉取近程分支: git fetch origin切换到目标分支 git checkout -b 0.10.1 origin/0.10.1这个时候切记不能先用idea间接关上我的项目! 2.打包环境kafka自带了一些Gradle的Task,能够生成出导入Eclipse或者Idea配置。在Kafka目录下执行 gradle jargradle idea这个时候目录下会呈现一个文件叫kafka.ipr在finder中双击这个文件,idea会主动关上并导入我的项目。个别Idea关上会,右下角会弹出一个框,意思是:咱们检测出这个是Gradle我的项目,须要导入Gradle的配置吗?这个时候,点击确认就行。 如果关上Idea啥也没产生,那么就须要咱们本人关上文件build.gradle注:也就是这个时候才会关上Idea 3.批改配置3.1 gradle.build文件文件增加: ScalaCompileOptions.metaClass.daemonServer = trueScalaCompileOptions.metaClass.fork = trueScalaCompileOptions.metaClass.useAnt = falseScalaCompileOptions.metaClass.useCompileDaemon = false3.2 创立文件创立log目录和 data目录创立resources目录,将config下的log4j.properties文件放到resources目录下 3.3 批改文件批改 config/server.properties 文件中的 ${kafka.logs.dir} 都改到新创建的log目录。批改config/server.properties 文件中 log.dirs 改为新创建的 data目录。 4.配置gradle注:配置次gradle特地重要,有时候咱们呈现的编译失败的问题很多时候是因为本地gradle配置问题,比方: * Where:Build file 'D:\idePro\kafka0.1.0.1\kafka-0.10.1\kafka-0.10.1\build.gradle' line: 305* What went wrong:A problem occurred evaluating root project 'kafka-0.10.1'.> Cannot set the value of read-only property 'additionalSourceDirs' for task ':jacocoRootReport' of type org.gradle.testing.jacoco.tasks.JacocoReport.* Try:Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.* Get more help at https://help.gradle.orgDeprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.Use '--warning-mode all' to show the individual deprecation warnings.See https://docs.gradle.org/6.5.1/userguide/command_line_interface.html#sec:command_line_warnings ...

June 5, 2021 · 1 min · jiezi

关于kafka:springboot整合kafka

kafka

June 3, 2021 · 1 min · jiezi

关于kafka:图解-Kafka画得太好了

Kafka 是支流的音讯流零碎,其中的概念还是比拟多的,上面通过图示的形式来梳理一下 Kafka 的外围概念,以便在咱们的头脑中有一个清晰的意识。 根底Kafka (Kafka是什么,次要利用在什么场景?)是一套流解决零碎,能够让后端服务轻松的互相沟通,是微服务架构中罕用的组件。 生产者消费者生产者服务 Producer 向 Kafka 发送音讯,消费者服务 Consumer 监听 Kafka 接管音讯。 一个服务能够同时为生产者和消费者。 Topics 主题Topic 是生产者发送音讯的指标地址,是消费者的监听指标。 一个服务能够监听、发送多个 Topics。 Kafka 中有一个【consumer-group(消费者组)】的概念。 这是一组服务,表演一个消费者。 如果是消费者组接管音讯,Kafka 会把一条音讯路由到组中的某一个服务。 这样有助于音讯的负载平衡,也不便扩大消费者。 Topic 表演一个音讯的队列。 首先,一条音讯发送了。 而后,这条音讯被记录和存储在这个队列中,不容许被批改。 接下来,音讯会被发送给此 Topic 的消费者。 然而,这条音讯并不会被删除,会持续保留在队列中。 持续发送音讯。 像之前一样,这条音讯会发送给消费者、不容许被改变、始终呆在队列中。 (音讯在队列中能呆多久,能够批改 Kafka 的配置) Partitions 分区下面 Topic 的形容中,把 Topic 看做了一个队列,实际上,一个 Topic 是由多个队列组成的,被称为【Partition(分区)】。 这样能够便于 Topic 的扩大。 生产者发送音讯的时候,这条音讯会被路由到此 Topic 中的某一个 Partition。 ...

June 2, 2021 · 1 min · jiezi

关于kafka:kafka原理

Kafka是最后由Linkedin公司开发,是一个分布式、反对分区的(partition)、多正本的(replica),基于zookeeper协调的分布式音讯零碎,它的最大的个性就是能够实时的解决大量数据以满足各种需要场景:比方基于hadoop的批处理零碎、低提早的实时零碎、storm/Spark流式解决引擎,web/nginx日志、拜访日志,音讯服务等等,用scala语言编写,Linkedin于2010年奉献给了Apache基金会并成为顶级开源我的项目。 1.前言音讯队列的性能好坏,其文件存储机制设计是掂量一个音讯队列服务技术水平和最要害指标之一。上面将从Kafka文件存储机制和物理构造角度,剖析Kafka是如何实现高效文件存储,及理论利用成果。 1.1 Kafka的个性: 高吞吐量、低提早:kafka每秒能够解决几十万条音讯,它的提早最低只有几毫秒,每个topic能够分多个partition, consumer group 对partition进行consume操作。可扩展性:kafka集群反对热扩大持久性、可靠性:音讯被长久化到本地磁盘,并且反对数据备份避免数据失落容错性:容许集群中节点失败(若正本数量为n,则容许n-1个节点失败)高并发:反对数千个客户端同时读写1.2 Kafka的应用场景: 日志收集:一个公司能够用Kafka能够收集各种服务的log,通过kafka以对立接口服务的形式凋谢给各种consumer,例如hadoop、Hbase、Solr等。音讯零碎:解耦和生产者和消费者、缓存音讯等。用户流动跟踪:Kafka常常被用来记录web用户或者app用户的各种流动,如浏览网页、搜寻、点击等流动,这些流动信息被各个服务器公布到kafka的topic中,而后订阅者通过订阅这些topic来做实时的监控剖析,或者装载到hadoop、数据仓库中做离线剖析和开掘。经营指标:Kafka也常常用来记录经营监控数据。包含收集各种分布式应用的数据,生产各种操作的集中反馈,比方报警和报告。流式解决:比方spark streaming和storm1.3 Kakfa的设计思维 Kakfa Broker Leader的选举:Kakfa Broker集群受Zookeeper治理。所有的Kafka Broker节点一起去Zookeeper上注册一个长期节点,因为只有一个Kafka Broker会注册胜利,其余的都会失败,所以这个胜利在Zookeeper上注册长期节点的这个Kafka Broker会成为Kafka Broker Controller,其余的Kafka broker叫Kafka Broker follower。(这个过程叫Controller在ZooKeeper注册Watch)。这个Controller会监听其余的Kafka Broker的所有信息,如果这个kafka broker controller宕机了,在zookeeper下面的那个长期节点就会隐没,此时所有的kafka broker又会一起去Zookeeper上注册一个长期节点,因为只有一个Kafka Broker会注册胜利,其余的都会失败,所以这个胜利在Zookeeper上注册长期节点的这个Kafka Broker会成为Kafka Broker Controller,其余的Kafka broker叫Kafka Broker follower。例如:一旦有一个broker宕机了,这个kafka broker controller会读取该宕机broker上所有的partition在zookeeper上的状态,并选取ISR列表中的一个replica作为partition leader(如果ISR列表中的replica全挂,选一个幸存的replica作为leader; 如果该partition的所有的replica都宕机了,则将新的leader设置为-1,期待复原,期待ISR中的任一个Replica“活”过去,并且选它作为Leader;或抉择第一个“活”过去的Replica(不肯定是ISR中的)作为Leader),这个broker宕机的事件,kafka controller也会告诉zookeeper,zookeeper就会告诉其余的kafka broker。Consumergroup:各个consumer(consumer 线程)能够组成一个组(Consumer group ),partition中的每个message只能被组(Consumer group )中的一个consumer(consumer 线程)生产,如果一个message能够被多个consumer(consumer 线程)生产的话,那么这些consumer必须在不同的组。 Kafka不反对一个partition中的message由两个或两个以上的同一个consumer group下的consumer thread来解决,除非再启动一个新的consumer group。所以如果想同时对一个topic做生产的话,启动多个consumer group就能够了,然而要留神的是,这里的多个consumer的生产都必须是程序读取partition外面的message,新启动的consumer默认从partition队列最头端最新的中央开始阻塞的读message。 当启动一个consumer group去生产一个topic的时候,无论topic外面有多个少个partition,无论咱们consumer group外面配置了多少个consumer thread,这个consumer group上面的所有consumer thread肯定会生产全副的partition;即使这个consumer group下只有一个consumer thread,那么这个consumer thread也会去生产所有的partition。因而,最优的设计就是,consumer group下的consumer thread的数量等于partition数量,这样效率是最高的。 同一partition的一条message只能被同一个Consumer Group内的一个Consumer生产。不可能一个consumer group的多个consumer同时生产一个partition。Consumer Rebalance的触发条件:(1): Consumer减少或删除会触发 Consumer Group的Rebalance(2)Broker的减少或者缩小都会触发 Consumer Rebalance。Consumer:Consumer解决partition外面的message的时候是o(1)程序读取的。所以必须保护着上一次读到哪里的offsite信息。high level API,offset存于Zookeeper中,low level API的offset由本人保护。一般来说都是应用high level api的。Consumer的delivery gurarantee,默认是读完message先commmit再解决message,autocommit默认是true,这时候先commit就会更新offsite+1,一旦解决失败,offsite曾经+1,这个时候就会丢message;也能够配置成读完音讯解决再commit,这种状况下consumer端的响应就会比较慢的,须要等解决完才行。如果producer的流量增大,以后的topic的parition数量=consumer数量,这时候的应答形式就是很想扩大:减少topic下的partition,同时减少这个consumer group下的consumer。Delivery Mode: Kafka producer 发送message不必保护message的offsite信息,因为这个时候,offsite就相当于一个自增id,producer就只管发送message就好了。然而Consumer端是须要保护这个partition以后生产到哪个message的offsite信息的,这个offsite信息,high level api是保护在Zookeeper上,low level api是本人的程序保护。当应用high level api的时候,先拿message解决,再定时主动commit offsite+1(也能够改成手动), 并且kakfa解决message是没有锁操作的。因而如果解决message失败,此时还没有commit offsite+1,当consumer thread重启后会反复生产这个message。然而作为高吞吐量高并发的实时处理零碎,at least once的状况下,至多一次会被解决到,是能够容忍的。如果无奈容忍,就得应用low level api来本人程序保护这个offsite信息,那么想什么时候commit offsite+1就本人搞定了。Topic & Partition:Topic相当于传统音讯零碎MQ中的一个队列queue,producer端发送的message必须指定是发送到哪个topic,然而不须要指定topic下的哪个partition,因为kafka会把收到的message进行load balance,平均的散布在这个topic下的不同的partition上( hash(message) % [broker数量] )。 在物理构造上,每个partition对应一个物理的目录(文件夹),文件夹命名是[topicname]_[partition]_[序号],一个topic能够有有数多的partition,依据业务需要和数据量来设置。 在kafka配置文件中可随时更高num.partitions参数来配置更改topic的partition数量,在创立Topic时通过参数指定parittion数量。Topic创立之后通过Kafka提供的工具也能够批改partiton数量。 一般来说,(1)一个Topic的Partition数量大于等于Broker的数量,能够进步吞吐率。(2)同一个Partition的Replica尽量扩散到不同的机器,高可用。 当add a new partition的时候,partition外面的message不会从新进行调配,原来的partition外面的message数据不会变,新加的这个partition刚开始是空的,随后进入这个topic的message就会从新参加所有partition的load balance。Partition Replica:每个partition能够在其余的kafka broker节点上存正本,以便某个kafka broker节点宕机不会影响这个kafka集群。存replica正本的形式是依照kafka broker的程序存。例如有5个kafka broker节点,某个topic有3个partition,每个partition存2个正本,那么partition1存broker1,broker2,partition2存broker2,broker3。。。以此类推(replica正本数目不能大于kafka broker节点的数目,否则报错。这里的replica数其实就是partition的正本总数,其中包含一个leader,其余的就是copy正本)。这样如果某个broker宕机,其实整个kafka内数据仍然是残缺的。然而,replica正本数越高,零碎尽管越稳固,然而回来带资源和性能上的降落;replica正本少的话,也会造成零碎丢数据的危险。(1)怎么传送音讯:producer先把message发送到partition leader,再由leader发送给其余partition follower。(2)在向Producer发送ACK前须要保障有多少个Replica曾经收到该音讯:依据ack配的个数而定。(3)怎么解决某个Replica不工作的状况:如果这个部工作的partition replica不在ack列表中,就是producer在发送音讯到partition leader上,partition leader向partition follower发送message没有响应而已,这个不会影响整个零碎,也不会有什么问题。如果这个不工作的partition replica在ack列表中的话,producer发送的message的时候会期待这个不工作的partition replca写message胜利,然而会等到time out,而后返回失败因为某个ack列表中的partition replica没有响应,此时kafka会主动的把这个部工作的partition replica从ack列表中移除,当前的producer发送message的时候就不会有这个ack列表下的这个部工作的partition replica了。(4)怎么解决Failed Replica复原回来的状况:如果这个partition replica之前不在ack列表中,那么启动后从新受Zookeeper治理即可,之后producer发送message的时候,partition leader会持续发送message到这个partition follower上。如果这个partition replica之前在ack列表中,此时重启后,须要把这个partition replica再手动加到ack列表中。(ack列表是手动增加的,呈现某个部工作的partition replica的时候主动从ack列表中移除的)Partition leader与follower:partition也有leader和follower之分。leader是主partition,producer写kafka的时候先写partition leader,再由partition leader push给其余的partition follower。partition leader与follower的信息受Zookeeper管制,一旦partition leader所在的broker节点宕机,zookeeper会冲其余的broker的partition follower上抉择follower变为parition leader。Topic调配partition和partition replica的算法:(1)将Broker(size=n)和待调配的Partition排序。(2)将第i个Partition调配到第(i%n)个Broker上。(3)将第i个Partition的第j个Replica调配到第((i + j) % n)个Broker上。Partition ack:当ack=1,示意producer写partition leader胜利后,broker就返回胜利,无论其余的partition follower是否写胜利。当ack=2,示意producer写partition leader和其余一个follower胜利的时候,broker就返回胜利,无论其余的partition follower是否写胜利。当ack=-1[parition的数量]的时候,示意只有producer全副写胜利的时候,才算胜利,kafka broker才返回胜利信息。这里须要留神的是,如果ack=1的时候,一旦有个broker宕机导致partition的follower和leader切换,会导致丢数据。message状态:在Kafka中,音讯的状态被保留在consumer中,broker不会关怀哪个音讯被生产了被谁生产了,只记录一个offset值(指向partition中下一个要被生产的音讯地位),这就意味着如果consumer解决不好的话,broker上的一个音讯可能会被生产屡次。message长久化:Kafka中会把音讯长久化到本地文件系统中,并且放弃o(1)极高的效率。咱们家喻户晓IO读取是十分耗资源的性能也是最慢的,这就是为了数据库的瓶颈常常在IO上,须要换SSD硬盘的起因。然而Kafka作为吞吐量极高的MQ,却能够十分高效的message长久化到文件。这是因为Kafka是程序写入o(1)的工夫复杂度,速度十分快。也是高吞吐量的起因。因为message的写入长久化是程序写入的,因而message在被生产的时候也是按程序被生产的,保障partition的message是程序生产的。个别的机器,单机每秒100k条数据。message有效期:不同的版本不一样,目前默认保留7天。Produer:Producer向Topic发送message,不须要指定partition,间接发送就好了。kafka通过partition ack来管制是否发送胜利并把信息返回给producer,producer能够有任意多的thread,这些kafka服务器端是不care的。Producer端的delivery guarantee默认是At least once的。也能够设置Producer异步发送实现At most once。Producer能够用主键幂等性实现Exactly once。Kafka高吞吐量: Kafka的高吞吐量体现在读写上,分布式并发的读和写都十分快,写的性能体现在以o(1)的工夫复杂度进行程序写入。读的性能体现在以o(1)的工夫复杂度进行程序读取, 对topic进行partition分区,consume group中的consume线程能够以很高能性能进行程序读。Kafka delivery guarantee(message传送保障):(1)At most once音讯可能会丢,相对不会反复传输;(2)At least once 音讯相对不会丢,然而可能会反复传输;(3)Exactly once每条信息必定会被传输一次且仅传输一次,这是用户想要的。冗余: replica有多个正本,保障一个broker node宕机后不会影响整个服务。扩展性: broker节点能够程度扩大,partition也能够程度减少,partition replica也能够程度减少。峰值: 在访问量剧增的状况下,kafka程度扩大, 利用依然须要持续发挥作用。可恢复性: 零碎的一部分组件生效时,因为有partition的replica正本,不会影响到整个零碎。程序保障性:因为kafka的producer的写message与consumer去读message都是程序的读写,保障了高效的性能。缓冲:因为producer那面可能业务很简略,而后端consumer业务会很简单并有数据库的操作,因而必定是producer会比consumer处理速度快,如果没有kafka,producer间接调用consumer,那么就会造成整个零碎的处理速度慢,加一层kafka作为MQ,能够起到缓冲的作用。异步通信:作为MQ,Producer与Consumer异步通信。2:kafka一些原理概念 ...

May 30, 2021 · 2 min · jiezi

关于kafka:kafka原理

Kafka是最后由Linkedin公司开发,是一个分布式、反对分区的(partition)、多正本的(replica),基于zookeeper协调的分布式音讯零碎,它的最大的个性就是能够实时的解决大量数据以满足各种需要场景:比方基于hadoop的批处理零碎、低提早的实时零碎、storm/Spark流式解决引擎,web/nginx日志、拜访日志,音讯服务等等,用scala语言编写,Linkedin于2010年奉献给了Apache基金会并成为顶级开源我的项目。**1.前言**音讯队列的性能好坏,其文件存储机制设计是掂量一个音讯队列服务技术水平和最要害指标之一。上面将从Kafka文件存储机制和物理构造角度,剖析Kafka是如何实现高效文件存储,及理论利用成果。1.1 Kafka的个性:- 高吞吐量、低提早:kafka每秒能够解决几十万条音讯,它的提早最低只有几毫秒,每个topic能够分多个partition, consumer group 对partition进行consume操作。- 可扩展性:kafka集群反对热扩大- 持久性、可靠性:音讯被长久化到本地磁盘,并且反对数据备份避免数据失落- 容错性:容许集群中节点失败(若正本数量为n,则容许n-1个节点失败)- 高并发:反对数千个客户端同时读写1.2 Kafka的应用场景:- 日志收集:一个公司能够用Kafka能够收集各种服务的log,通过kafka以对立接口服务的形式凋谢给各种consumer,例如hadoop、Hbase、Solr等。- 音讯零碎:解耦和生产者和消费者、缓存音讯等。- 用户流动跟踪:Kafka常常被用来记录web用户或者app用户的各种流动,如浏览网页、搜寻、点击等流动,这些流动信息被各个服务器公布到kafka的topic中,而后订阅者通过订阅这些topic来做实时的监控剖析,或者装载到hadoop、数据仓库中做离线剖析和开掘。- 经营指标:Kafka也常常用来记录经营监控数据。包含收集各种分布式应用的数据,生产各种操作的集中反馈,比方报警和报告。- 流式解决:比方spark streaming和storm1.3 Kakfa的设计思维- Kakfa Broker Leader的选举: Kakfa Broker集群受Zookeeper治理。所有的Kafka Broker节点一起去Zookeeper上注册一个长期节点,因为只有一个Kafka Broker会注册胜利,其余的都会失败,所以这个胜利在Zookeeper上注册长期节点的这个Kafka Broker会成为Kafka Broker Controller,其余的Kafka broker叫Kafka Broker follower。(这个过程叫Controller在ZooKeeper注册Watch)。 这个Controller会监听其余的Kafka Broker的所有信息,如果这个kafka broker controller宕机了,在zookeeper下面的那个长期节点就会隐没,此时所有的kafka broker又会一起去Zookeeper上注册一个长期节点,因为只有一个Kafka Broker会注册胜利,其余的都会失败,所以这个胜利在Zookeeper上注册长期节点的这个Kafka Broker会成为Kafka Broker Controller,其余的Kafka broker叫Kafka Broker follower。 例如:一旦有一个broker宕机了,这个kafka broker controller会读取该宕机broker上所有的partition在zookeeper上的状态,并选取ISR列表中的一个replica作为partition leader(如果ISR列表中的replica全挂,选一个幸存的replica作为leader; 如果该partition的所有的replica都宕机了,则将新的leader设置为-1,期待复原,期待ISR中的任一个Replica“活”过去,并且选它作为Leader;或抉择第一个“活”过去的Replica(不肯定是ISR中的)作为Leader),这个broker宕机的事件,kafka controller也会告诉zookeeper,zookeeper就会告诉其余的kafka broker。- Consumergroup: 各个consumer(consumer 线程)能够组成一个组(Consumer group ),partition中的每个message只能被组(Consumer group )中的一个consumer(consumer 线程)生产,如果一个message能够被多个consumer(consumer 线程)生产的话,那么这些consumer必须在不同的组。 Kafka不反对一个partition中的message由两个或两个以上的同一个consumer group下的consumer thread来解决,除非再启动一个新的consumer group。所以如果想同时对一个topic做生产的话,启动多个consumer group就能够了,然而要留神的是,这里的多个consumer的生产都必须是程序读取partition外面的message,新启动的consumer默认从partition队列最头端最新的中央开始阻塞的读message。 当启动一个consumer group去生产一个topic的时候,无论topic外面有多个少个partition,无论咱们consumer group外面配置了多少个consumer thread,这个consumer group上面的所有consumer thread肯定会生产全副的partition;即使这个consumer group下只有一个consumer thread,那么这个consumer thread也会去生产所有的partition。因而,最优的设计就是,consumer group下的consumer thread的数量等于partition数量,这样效率是最高的。 同一partition的一条message只能被同一个Consumer Group内的一个Consumer生产。不可能一个consumer group的多个consumer同时生产一个partition。- Consumer Rebalance的触发条件: (1): Consumer减少或删除会触发 Consumer Group的Rebalance(2)Broker的减少或者缩小都会触发 Consumer Rebalance - Consumer: Consumer解决partition外面的message的时候是o(1)程序读取的。所以必须保护着上一次读到哪里的offsite信息。high level API,offset存于Zookeeper中,low level API的offset由本人保护。一般来说都是应用high level api的。 Consumer的delivery gurarantee,默认是读完message先commmit再解决message,autocommit默认是true,这时候先commit就会更新offsite+1,一旦解决失败,offsite曾经+1,这个时候就会丢message;也能够配置成读完音讯解决再commit,这种状况下consumer端的响应就会比较慢的,须要等解决完才行。 如果producer的流量增大,以后的topic的parition数量=consumer数量,这时候的应答形式就是很想扩大:减少topic下的partition,同时减少这个consumer group下的consumer。![image.png](/img/bVcSl2y)- Delivery Mode: Kafka producer 发送message不必保护message的offsite信息,因为这个时候,offsite就相当于一个自增id,producer就只管发送message就好了。 然而Consumer端是须要保护这个partition以后生产到哪个message的offsite信息的,这个offsite信息,high level api是保护在Zookeeper上,low level api是本人的程序保护。 当应用high level api的时候,先拿message解决,再定时主动commit offsite+1(也能够改成手动), 并且kakfa解决message是没有锁操作的。因而如果解决message失败,此时还没有commit offsite+1,当consumer thread重启后会反复生产这个message。然而作为高吞吐量高并发的实时处理零碎,at least once的状况下,至多一次会被解决到,是能够容忍的。如果无奈容忍,就得应用low level api来本人程序保护这个offsite信息,那么想什么时候commit offsite+1就本人搞定了。 - Topic & Partition: Topic相当于传统音讯零碎MQ中的一个队列queue,producer端发送的message必须指定是发送到哪个topic,然而不须要指定topic下的哪个partition,因为kafka会把收到的message进行load balance,平均的散布在这个topic下的不同的partition上( hash(message) % [broker数量] )。 在物理构造上,每个partition对应一个物理的目录(文件夹),文件夹命名是[topicname]_[partition]_[序号],一个topic能够有有数多的partition,依据业务需要和数据量来设置。 在kafka配置文件中可随时更高num.partitions参数来配置更改topic的partition数量,在创立Topic时通过参数指定parittion数量。Topic创立之后通过Kafka提供的工具也能够批改partiton数量。 一般来说,(1)一个Topic的Partition数量大于等于Broker的数量,能够进步吞吐率。(2)同一个Partition的Replica尽量扩散到不同的机器,高可用。 当add a new partition的时候,partition外面的message不会从新进行调配,原来的partition外面的message数据不会变,新加的这个partition刚开始是空的,随后进入这个topic的message就会从新参加所有partition的load balance。 - Partition Replica: 每个partition能够在其余的kafka broker节点上存正本,以便某个kafka broker节点宕机不会影响这个kafka集群。存replica正本的形式是依照kafka broker的程序存。例如有5个kafka broker节点,某个topic有3个partition,每个partition存2个正本,那么partition1存broker1,broker2,partition2存broker2,broker3。。。以此类推(replica正本数目不能大于kafka broker节点的数目,否则报错。这里的replica数其实就是partition的正本总数,其中包含一个leader,其余的就是copy正本)。这样如果某个broker宕机,其实整个kafka内数据仍然是残缺的。然而,replica正本数越高,零碎尽管越稳固,然而回来带资源和性能上的降落;replica正本少的话,也会造成零碎丢数据的危险。 (1)怎么传送音讯:producer先把message发送到partition leader,再由leader发送给其余partition follower。 (2)在向Producer发送ACK前须要保障有多少个Replica曾经收到该音讯:依据ack配的个数而定。 (3)怎么解决某个Replica不工作的状况:如果这个部工作的partition replica不在ack列表中,就是producer在发送音讯到partition leader上,partition leader向partition follower发送message没有响应而已,这个不会影响整个零碎,也不会有什么问题。如果这个不工作的partition replica在ack列表中的话,producer发送的message的时候会期待这个不工作的partition replca写message胜利,然而会等到time out,而后返回失败因为某个ack列表中的partition replica没有响应,此时kafka会主动的把这个部工作的partition replica从ack列表中移除,当前的producer发送message的时候就不会有这个ack列表下的这个部工作的partition replica了。 (4)怎么解决Failed Replica复原回来的状况:如果这个partition replica之前不在ack列表中,那么启动后从新受Zookeeper治理即可,之后producer发送message的时候,partition leader会持续发送message到这个partition follower上。如果这个partition replica之前在ack列表中,此时重启后,须要把这个partition replica再手动加到ack列表中。(ack列表是手动增加的,呈现某个部工作的partition replica的时候主动从ack列表中移除的) - Partition leader与follower: partition也有leader和follower之分。leader是主partition,producer写kafka的时候先写partition leader,再由partition leader push给其余的partition follower。partition leader与follower的信息受Zookeeper管制,一旦partition leader所在的broker节点宕机,zookeeper会冲其余的broker的partition follower上抉择follower变为parition leader。 - Topic调配partition和partition replica的算法: (1)将Broker(size=n)和待调配的Partition排序。(2)将第i个Partition调配到第(i%n)个Broker上。(3)将第i个Partition的第j个Replica调配到第((i + j) % n)个Broker上 - Partition ack: 当ack=1,示意producer写partition leader胜利后,broker就返回胜利,无论其余的partition follower是否写胜利。当ack=2,示意producer写partition leader和其余一个follower胜利的时候,broker就返回胜利,无论其余的partition follower是否写胜利。当ack=-1[parition的数量]的时候,示意只有producer全副写胜利的时候,才算胜利,kafka broker才返回胜利信息。这里须要留神的是,如果ack=1的时候,一旦有个broker宕机导致partition的follower和leader切换,会导致丢数据。 ![image.png](/img/bVcSl4b) - message状态: 在Kafka中,音讯的状态被保留在consumer中,broker不会关怀哪个音讯被生产了被谁生产了,只记录一个offset值(指向partition中下一个要被生产的音讯地位),这就意味着如果consumer解决不好的话,broker上的一个音讯可能会被生产屡次。 - message长久化: Kafka中会把音讯长久化到本地文件系统中,并且放弃o(1)极高的效率。咱们家喻户晓IO读取是十分耗资源的性能也是最慢的,这就是为了数据库的瓶颈常常在IO上,须要换SSD硬盘的起因。然而Kafka作为吞吐量极高的MQ,却能够十分高效的message长久化到文件。这是因为Kafka是程序写入o(1)的工夫复杂度,速度十分快。也是高吞吐量的起因。因为message的写入长久化是程序写入的,因而message在被生产的时候也是按程序被生产的,保障partition的message是程序生产的。个别的机器,单机每秒100k条数据。 https://www.cnblogs.com/cxxjohnson/p/8921661.html

May 29, 2021 · 1 min · jiezi

关于kafka:Kafka-Java-Api

相干常识 1.Kafka提供了Producer类作为Java producer的api,该类有sync和async两种发送形式。默认是sync形式,即producer的调用类在音讯真正发送到队列中去当前才返回。(1)Kafka提供的java api中的Producer,底层只是保护该topic到每个broker的连贯,并不是一个传统意义上的连接池。在应用sync形式时,咱们应该本人实现一个连接池,外面蕴含若干Producer对象,以实现最大化写入效率。(2)在写入的数据频率不高或要求取得写入后果时,应应用sync形式,否则会因async的等待时间引入额定的提早。(3)在写入的数据频率很高时,应应用async形式,以batch的模式写入,取得最大效率。async形式与sync形式的不同在于,在初始化scala的producer时,会创立一个ProducerSendThread对象。而后,在调用send时,它并不是间接调用eventHandler.handle办法,而是把音讯放入一个长度由queue.buffering.max.messages参数定义的队列(默认10000),当队列满足以下两种条件时,会由ProducerSendThread触发eventHandler.handle办法,把队列中的音讯作为一个batch发送①工夫超过queue.buffering.max.ms定义的值,默认5000ms②队列中以后音讯个数超过batch.num.messages定义的值,默认200 2.Kafka的Consumer有两种Consumer的高层API、简略API–SimpleConsumer(1)Consumer的高层API次要是Consumer和ConsumerConnector,这里的Consumer是ConsumerConnector的动态工厂类class Consumer { public static kafka.javaapi.consumer.ConsumerConnector createJavaConsumerConnector(config: ConsumerConfig); } 具体的音讯的生产都是在ConsumerConnector中 创立一个音讯解决的流,蕴含所有的topic,并依据指定的Decoderpublic Map>>createMessageStreams(Map topicCountMap, Decoder keyDecoder, Decoder valueDecoder); 创立一个音讯解决的流,蕴含所有的topic,应用默认的Decoderpublic Map>> createMessageStreams(Map topicCountMap); 获取指定音讯的topic,并依据指定的Decoderpublic List>>createMessageStreamsByFilter(TopicFilter topicFilter, int numStreams, Decoder keyDecoder, Decoder valueDecoder); 获取指定音讯的topic,应用默认的Decoderpublic List> createMessageStreamsByFilter(TopicFilter topicFilter); 提交偏移量到这个消费者连贯的topicpublic void commitOffsets(); 敞开消费者public void shutdown(); 高层的API中比拟罕用的就是public List> createMessageStreamsByFilter(TopicFilter topicFilter);和public void commitOffsets(); (2)Consumer的简略API–SimpleConsumer 批量获取音讯public FetchResponse fetch(request: kafka.javaapi.FetchRequest); 获取topic的元信息public kafka.javaapi.TopicMetadataResponse send(request:kafka.javaapi.TopicMetadataRequest); 获取目前可用的偏移量public kafka.javaapi.OffsetResponse getOffsetsBefore(request: OffsetRequest); 敞开连贯public void close(); 对于大部分利用来说,高层API就曾经足够应用了,然而若是想做更进一步的管制的话,能够应用简略的API,例如消费者重启的状况下,心愿失去最新的offset,就该应用SimpleConsumer。 零碎环境 Linux Ubuntu 20.04OpenJDK-11.0.11kafka_2.13-2.8.0zookeeper-3.6.3IntelliJ IDEA 2021.1 (Ultimate Edition) ...

May 28, 2021 · 1 min · jiezi

关于kafka:4深潜KafkaProducer-RecordAccumulator精析

通过上一课时的介绍咱们理解到,业务线程应用 KafkaProducer.send() 办法发送 message 的时候,会先将其写入RecordAccumulator 中进行缓冲,当 RecordAccumulator 中缓存的 message 达到肯定阈值的时候,会由 IO 线程批量造成申请,发送到 kafka 集群。本课时咱们就重点来看一下 RecordAccumulator 这个缓冲区的构造。 首先,咱们从上图中能够看出,RecordAccumulator 会由业务线程写入、Sender 线程读取,这是一个非常明显的生产者-消费者模式,所以咱们须要保障 RecordAccumulator 是线程平安的。RecordAccumulator 中保护了一个 ConcurrentMap<TopicPartition, Deque<ProducerBatch>> 类型的汇合,其中的 Key 是 TopicPartition 用来示意指标 partition,Value 是 ArrayDeque<ProducerBatch> 队列,用来缓冲发往指标 partition 的音讯。 这里的 ArrayDeque 并不是线程平安的汇合,前面咱们会看到加锁的相干操作。 在每个 ProducerBatch 中都保护了一个 MemoryRecordsBuilder 对象,MemoryRecordsBuilder 才是真正存储 message 的中央。RecordAccumulator 、ProducerBatch、MemoryRecordsBuilder 这三个外围类的关系如下图所示: client模块message 格局既然咱们筹备深刻 KafkaProducer 进行剖析,那咱们就须要理解 message 在 kafka 外部的格局,而不是简略晓得 message 是个 KV。kafka 目前的 message 的格局有三个版本: V0:kafka0.10 版本之前V1:kafka 0.10 ~ 0.11 版本V2:kafka 0.11.0 之后的版本V0 版本在应用 V0 版本的 message 时,message 在 RecordAccumulator 中只是简略的沉积,并没有进行聚合,每个 message 都有独立的元信息,如下图所示: ...

May 26, 2021 · 12 min · jiezi

关于kafka:Kafka安装和测试

基本原理 Kafka是由LinkedIn开发的一个分布式的音讯零碎,应用Scala编写,它因能够程度扩大和高吞吐率而被宽泛应用。目前越来越多的开源分布式解决零碎如Cloudera、Apache Storm、Spark都反对与Kafka集成。Kafka是一种分布式的,基于公布/订阅的音讯零碎。次要设计指标如下:(1)以工夫复杂度为O(1)的形式提供音讯长久化能力,即便对TB级以上数据也能保障常数工夫复杂度的拜访性能(2)高吞吐率。即便在十分便宜的商用机器上也能做到单机反对每秒100K条以上音讯的传输(3)反对Kafka Server间的音讯分区,及分布式生产,同时保障每个Partition内的音讯程序传输(4)同时反对离线数据处理和实时数据处理(5)Scale out:反对在线程度扩大Kafka中各个组件的性能:(1)Broker: Kafka集群蕴含一个或多个服务器,这种服务器被称为broker(2)Topic:每条公布到Kafka集群的音讯都有一个类别,这个类别被称为Topic。(物理上不同Topic的音讯离开存储,逻辑上一个Topic的音讯尽管保留于一个或多个broker上,但用户只需指定音讯的Topic即可生产或生产数据,不用关怀数据存于何处)(3)Partition:Parition是物理上的概念,每个Topic蕴含一个或多个Partition(4)Producer:负责公布音讯到Kafka broker(5)Consumer:音讯消费者,向Kafka broker读取音讯的客户端(6)Consumer Group:每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)Producer应用Push模式将音讯公布到Broker,Consumer应用Pull模式从Broker订阅并生产音讯。 零碎环境Linux Ubuntu 20.04OpenJDK-11.0.11 工作内容Kafka装置依赖Scala、ZooKeeper,所以须要先装置Scala与ZooKeeper。而后在已装置好Scala和ZooKeeper的环境根底上,装置部署Kafka。 工作步骤1.首先在Linux本地,新建/data/kafka1目录,用于寄存实验所需文件。 mkdir -p /data/kafka1 切换目录到/data/kafka1下,应用wget命令,下载所需安装包scala-2.13.5.tgz,kafka_2.13-2.8.0.tgz以及apache-zookeeper-3.6.3-bin.tar.gz。 cd /data/kafka1 **wget https://adoptopenjdk.net/**wget https://www.apache.org/dyn/closer.cgi?path=/kafka/2.8.0/kafka_2.13-2.8.0.tgz wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.6.3/apache-zookeeper-3.6.3-bin.tar.gz 2.装置Scala。切换到/data/kafka1目录下,将Scala安装包scala-2.13.5.tgz解压到/apps目录下,并将解压后的目录,重命名为scala。 cd /data/kafka1 tar -xzvf /data/kafka1/scala-2.13.5.tgz -C /apps/ cd /apps mv /apps/scala-2.13.5/ /apps/scala 应用vim关上用户环境变量。 sudo vim ~/.bashrc 将以下Scala的门路信息,追加到用户环境变量中。 #scala export SCALA_HOME=/apps/scala export PATH=$SCALA_HOME/bin:$PATH 执行source命令,使环境变量失效。 source ~/.bashrc 3.切换到/data/kafka1目录下,将kafka的压缩包kafka_2.13-2.8.0.tgz解压到/apps目录下,并将解压缩后的目录,重命名为kafka。 cd /data/kafka1 tar -xzvf /data/kafka1/kafka_2.13-2.8.0.tgz -C /apps/ cd /apps mv /apps/kafka_2.13-2.8.0/ /apps/kafka 应用vim关上用户环境变量。 sudo vim ~/.bashrc 将以下Kafka的门路信息,追加到用户环境变量中。 ...

May 26, 2021 · 2 min · jiezi

关于kafka:Kafka是什么主要应用在什么场景

1、kafka是什么?Kafka是由LinkedIn开发的一个分布式基于公布/订阅的音讯零碎,应用Scala编写,它以可程度扩大和高吞吐率而被宽泛应用。 2、产生背景Kafka是一个音讯零碎,用作LinkedIn的流动流(Activity Stream)和经营数据处理管道(Pipeline)的根底。流动流数据是简直所有站点在对其网站应用状况做报表时都要用到的数据中最惯例的局部。 流动数据包含页面访问量(Page View)、被查看内容方面的信息以及搜寻状况等内容。这种数据通常的解决形式是先把各种流动以日志的模式写入某种文件,而后周期性地对这些文件进行统计分析。 经营数据指的3是服务器的性能数据(CPU、IO使用率、申请工夫、服务日志等等数据)。经营数据的统计办法品种繁多。 3、根本架构图 4、基本概念解释BrokerKafka集群蕴含一个或多个服务器,这种服务器被称为broker。broker端不保护数据的生产状态,晋升了性能。间接应用磁盘进行存储,线性读写,速度快:防止了数据在JVM内存和零碎内存之间的复制,缩小耗性能的创建对象和垃圾回收。 Producer负责公布音讯到Kafka broke Consumer音讯消费者,向Kafka broker读取音讯的客户端,consumer从broker拉取(pull)数据并进行解决。 Topic每条公布到Kafka集群的音讯都有一个类别,这个类别被称为Topic。(物理上不同Topic的音讯离开存储,逻辑上一个Topic的音讯尽管保留于一个或多个broker上但用户只需指定音讯的Topic即可生产或生产数据而不用关怀数据存于何处) PartitionParition是物理上的概念,每个Topic蕴含一个或多个Partition. Consumer Group每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group) Topic & PartitionTopic在逻辑上能够被认为是一个queue,每条生产都必须指定它的Topic,能够简略了解为必须指明把这条音讯放进哪个queue里。为了使得Kafka的吞吐率能够线性进步,物理上把Topic分成一个或多个Partition,每个Partition在物理上对应一个文件夹,该文件夹下存储这个Partition的所有音讯和索引文件。 若创立topic1和topic2两个topic,且别离有13个和19个分区,则整个集群上会相应会生成共32个文件夹(本文所用集群共8个节点,此处topic1和topic2 replication-factor均为1)。 5、实用场景Messaging对于一些惯例的音讯零碎,kafka是个不错的抉择;partitons/replication和容错,能够使kafka具备良好的扩展性和性能劣势.不过到目前为止,咱们应该很分明意识到,kafka并没有提供JMS中的"事务性""音讯传输担保(音讯确认机制)""音讯分组"等企业级个性;kafka只能应用作为"惯例"的音讯零碎,在肯定水平上,尚未确保音讯的发送与接管相对牢靠(比方,音讯重发,音讯发送失落等) Website activity trackingkafka能够作为"网站活性跟踪"的最佳工具;能够将网页/用户操作等信息发送到kafka中.并实时监控,或者离线统计分析等 MetricsKafka通常被用于可操作的监控数据。这包含从分布式应用程序来的聚合统计用来生产集中的经营数据提要。 Log Aggregationkafka的个性决定它非常适合作为"日志收集核心";application能够将操作日志"批量""异步"的发送到kafka集群中,而不是保留在本地或者DB中;kafka能够批量提交音讯/压缩音讯等,这对producer端而言,简直感觉不到性能的开销.此时consumer端能够使hadoop等其余系统化的存储和剖析零碎。 最初,关注公众号民工哥技术之路,能够获取我整顿的 音讯队列、中间件相干的技术文章、面试题精选,十分齐全。 链接:https://blog.csdn.net/code52/...

May 22, 2021 · 1 min · jiezi

关于kafka:2kafka-280-源码环境搭建

装置 JDKJDK 的装置非常简单,这里咱们装置 JDK 8 即可(尽管 JDK 当初的新版本是 16,然而国内生产环境还有相当一大部分还是停留在 8 这个版本上)。首先到 JDK下载地址下载对应零碎的 JDK 安装包即可,这里我应用的是 mac 零碎,下载 dmg 文件即可。 下载实现之后,双击 dmg 文件,始终下一步即可装置实现。 装置 scala咱们这里装置的 scala 版本是 2.13.1 版本 scala 2.13.1 下载地址。下载实现之后,间接解压到当前目录下即可。 下载 gradlekafka 的代码依赖是通过 gradle 治理的,咱们须要从 下载地址 下载 gradle 6.8 的压缩包,而后间接解压到当前目录下即可。 配置环境变量装置完 JDK、scala 以及 gradle 之后,咱们关上命令行,跳转到以后用户的根目录,关上 bash_profile 1sudo vim .bash_profile在 bash_profile 文件中配置 JAVA_HOME、SCALA_HOME、GRADLE_HOME 三个环境变量,并将它们增加到 PATH 变量上,如下图所示: 接下来,保留 bash_profile 文件,并执行 source 命令刷新文件: 1source .bash_profile最初,执行 java -version,scala -version 以及 gradle -version命令,检查一下环境变量是否配置胜利,失去上面张图展现的输入,即示意配置胜利: 装置 Zookeeperkafka在2.8.0版本之前是依赖 Zookeeper 来存储元数据信息的,从 2.8.0 版本开始,kafka 不再强依赖 Zookeeper ,而是本人实现了 raft 协定来存储元数据。 ...

May 19, 2021 · 2 min · jiezi

关于kafka:杨四正的kafka剖析课1kafka基本概念

<br/>Apache Kafka 是一种分布式音讯零碎,由Scala语言编写而成。 Kafak 基本概念messagemessage 是 Kafka 中最根本的数据单元,它由 key 和 value 两局部形成,KV 都为字节数组。 Kafka 会依照肯定的策略,将音讯依照 key 值路由到指定的 partition 中,从而保障 key 雷同的 message 全副写入同一 partition 中。 value 是 Kafka真正传递的业务数据。 topic、partition、brokertopic 是 Kafka 中的一个逻辑概念,kafka 集群中能够定义多个 topic。 在应用的时候,producer 和 consumer 会约定好一个 topic 名称,producer 产生的 message 会写入到该指定的 topic 中,consumer 会从该指定的 topic 中读取 message。 topic 能够看做为一个 message 通道,连贯多个 producer 和 consumer,如下图所示: 在 topic 这个逻辑概念中,kafka 做了进一步的拆分,将一个 topic 分为一个或多个 partition(一个 topic 至多有一个 partition),如下图所示:从上图能够看出,当 message 在被 producer push 到一个 partition 的时候,都会被调配一个 offset 编号, offset 是这条 message 在这个 partition 中的惟一编号。 ...

May 7, 2021 · 5 min · jiezi

关于kafka:赵强老师Kafka的消息持久化

1、Kafka音讯持久性概述 Kakfa依赖文件系统来存储和缓存音讯。对于硬盘的传统观念是硬盘总是很慢,基于文件系统的架构是否提供优异的性能?实际上硬盘的快慢齐全取决于应用形式。同时 Kafka 基于 JVM 内存有以下毛病: 对象的内存开销十分高,通常是要存储的数据的两倍甚至更高随着堆内数据的减少,GC的速度越来越慢实际上磁盘线性写入的性能远远大于任意地位写的性能,线性读写由操作系统进行了大量优化(read-ahead、write-behind 等技术),甚至比随机的内存读写更快。所以与常见的数据缓存在内存中而后刷到硬盘的设计不同,Kafka 间接将数据写到了文件系统的日志中: 写操作:将数据程序追加到文件中读操作:从文件中读取这样实现的益处: 读操作不会阻塞写操作和其余操作,数据大小不对性能产生影响硬盘空间绝对于内存空间容量限度更小线性拜访磁盘,速度快,能够保留更长的工夫,更稳固2、Kafka的长久化原理解析 一个Topic 被分成多 Partition,每个 Partition 在存储层面是一个 append-only 日志文件,属于一个 Partition 的音讯都会被间接追加到日志文件的尾部,每条音讯在文件中的地位称为 offset(偏移量)。 如下图所示,咱们之前创立了mytopic1,具备三个分区。咱们能够到对应的日志目录下进行查看。 Kafka日志分为index与log(如上图所示),两个成对呈现:index文件存储元数据,log存储音讯。索引文件元数据指向对应log文件中message的迁徙地址;例如2,128指log文件的第2条数据,偏移地址为128;而物理地址(在index文件中指定)+ 偏移地址能够定位到音讯。 咱们能够应用Kafka自带的工具来查看log日志文件中的数据信息:

April 30, 2021 · 1 min · jiezi

关于kafka:数栈产品分享Kafka实时离不开的那个TA

一、前言随着技术一直的成熟及市场需求的日益旺盛,实时开发曾经成为以后大数据开发不可或缺的一部分。在整个实时开发的链路中,数据采集须要写入到Kafka,数据处理也须要应用到Kafka。明天咱们就针对Kafka这个时下支流的消息中间件进行简略的介绍。 二、音讯队列:数据流的归宿在实时开发的场景中,来源于各类行为、事件的数据是随着产生工夫源源不断如同河流个别进入实时工作并一直产出后果的。传统的异构数据源,数据以结构化的模式存储在对应的库表内。那么除了数据自身蕴含的业务工夫属性,要如何找到一个稳固的工夫维度来形容这些数据的先后呢?又要将流式的数据放在哪里去进行解决? 音讯队列就是为了应答大量数据须要传递、剖析场景所波及的。 目前音讯队列的形式分为以下两种: 点对点(point to point,queue):音讯被任一消费者生产后即隐没在点对点零碎中,音讯被保留在队列中,一个或多个消费者能够耗费队列中的音讯,然而特定音讯只能由最多一个消费者生产,一旦消费者读取队列中的音讯,它就从该队列中隐没。公布-订阅(publish/subscribe,topic):音讯可被所有订阅者(组)生产在公布-订阅零碎中,音讯生产者称为发布者,音讯消费者称为订阅者。发布者公布的音讯被保留在 Topic 中,与点对点零碎不同,生产组能够订阅一个或多个主题并应用该主题中的所有音讯,同样,所有公布到Topic的音讯均可被所有订阅组生产。一个订阅组内可能蕴含多个订阅者。为了更好的了解音讯队列的运作形式,咱们先构想如下一个场景:数据是一份快递,数据在不同开发环节之间的流转就是快递的配送过程。1、电视购物:上门配送,客户签收 在10年前电视购物还比拟流行的时代,少数货物是通过邮政等快递公司进行上门配送,往往快递员上门后,会让客户在运单上签字验收。这时候的快递员,只有每一份快递被客户签字验收后,才会再开始下一件货品的运输(此为极其状况下的举例)。 当一个客户存在多个快递,并且多个快递是陆续达到的时候,就会呈现快递员配送-期待签收-客户签收-快递员回到收发点发现新的快递-快递员配送这样一个重复链路,如果存在客户反馈慢,签字速度慢的状况,则会破费更多工夫。 同样,在传统的数据开发场景中,数据传输也遵循这样的法则。上下游的两个服务之间对数据进行传输等同于快递配送的过程,如果一次数据传输须要等到上游服务给到的回执来保证数据失常写入,再开始下一次的进行,那么上游服务处理速度及响应速度会重大影响这一环节的数据从而导致数据提早;如果整条数据传输的链路蕴含了多个这样的过程,整体数据的时效性就无奈失去保障。2、快递物流:对立快递站 随着网络购物的一直倒退,为了提高效率,当初的货物配送形式产生了极大的扭转。当初快递员从收发点拣货登程,将快递配送至相应地区的快递站,由快递站替理论用户进行一次代理签收,此时视作快递配送的过程曾经实现。快递员就能够疾速回到拣货点,后续快递站会以各类模式告诉到具体的用户,有相应的快递须要签收,在“某某工夫点”前来到快递点拿取。对于用户而言,它只须要继续关注快递站的状态(订阅),当有快递时,及时去取就能够。 当咱们相熟了快递从仓库中存储到配送到收件人手中的流转过程时,咱们就可能了解消息中间件是如何在实时开发的过程中运作的。那么在多种消息中间件中,目前利用最宽泛的就属Apache Kafka。 三、Kafka:消息中间件Apache Kafka是一个分布式、反对分区的(partition)、多正本的(replica),基于zookeeper协调的分布式音讯零碎,用于实时处理大量数据,罕用于大数据,数据挖掘等场景。 Kafka中常常会波及到如下基本概念: Zookeeper:用于将独立的Broker配置成Kafka集群;Broker:Kafka集群蕴含一个或多个服务器,这种服务器被称为Broker;Topic:Kafka中的音讯主题,相似于Table的概念,用于辨别不同音讯;Partition:Topic分区,每个topic能够有多个分区,分区的作用是不便拓展,进步并发。为了便于了解,咱们能够简略的将Kafka与快递过程进行类比如下: 1、数据写入 1)确定Topic及Partition 一个Topic下可能存在多个Partition,在向Kafka写入数据时须要先确定Topic及对应的Partition。 2)找到Partition通信地址 因为Kafka实现了高可用,确定写入Partition后,Producer会从ZK中获取到对应Partition的Leader并与其通信。 3)数据传输 Leader接管到Producer的信息并写入本地Log其余Follower从Leader Pull信息,并写入本地log,实现后向Leader发送ACKLeader接管到所有Follower信息,并设置一个HW(High Watermark),而后向Producer发送ACK2、生产形式及调配策略 理论生产数据时Kafka中的消费者——Consumer会以Consumer Group的模式与Topic交互并调配对应的Partition。在生产过程中一个Group内的数据不反复,但多个Group之间的数据可反复生产,这也是公布-订阅制的特点。 开发人员能够利用这一特点实现在不影响主业务流程的状况下,对业务数据进行实时监控等。 一个Group中蕴含至多有一个Consumer,一个Topic下也至多蕴含一个Partiton。一个Consumer Group中的多个Consumer能够并行生产不同的Partition,以此来进步对Kafka数据生产的并行度,从而进步数据处理的速度。然而在生产的过程中,针对于Partition和Consumer数量的不同,会呈现各种状况,Kafka针对于不同的状况有相应的调配策略,可参考如下: 四、实时开发如何应用Kafka在理论生产中,实时开发也是以一个消费者组或生产者组的形式去Kafka中生产相应的数据。 在实时采集工作过程中,采集数据源的数据到Kafka,通过设置不同的写入并发数,能够设置多个Producer向同一个Topic下进行数据写入,进步并发度和数据读取效率;同样,当采集Kafka数据源时,通过设置不同的读取并发数,能够在一个Group内设置多个Consumer同时对Topic内的数据进行生产。 在实时开发工作中,也能够设置Kafka数据源的并行度,从而依据理论业务需要调整并行度来满足生产需要。 五、结语通过明天的介绍,咱们理解到Kafka作为典型“公布-订阅”模式的音讯队列如何通过帮忙用户长期存储流式数据,并通过Consumer Group和Partition的机制实现多并发的读写以进步实时开发相干的效率。后续咱们还会持续介绍跟实时开发相干的内容,敬请期待。 数栈是云原生—站式数据中台PaaS,咱们在github和gitee上有一个乏味的开源我的项目:FlinkX,FlinkX是一个基于Flink的批流对立的数据同步工具,既能够采集动态的数据,也能够采集实时变动的数据,是全域、异构、批流一体的数据同步引擎。大家喜爱的话请给咱们点个star!star!star! github开源我的项目:https://github.com/DTStack/fl... gitee开源我的项目:https://gitee.com/dtstack_dev...

April 28, 2021 · 1 min · jiezi

关于kafka:数栈产品分享基于StreamWorks构建实时大数据处理平台

数栈是云原生—站式数据中台PaaS,咱们在github和gitee上有一个乏味的开源我的项目:FlinkX,FlinkX是一个基于Flink的批流对立的数据同步工具,既能够采集动态的数据,也能够采集实时变动的数据,是全域、异构、批流一体的数据同步引擎。大家喜爱的话请给咱们点个star!star!star! github开源我的项目:https://github.com/DTStack/fl... gitee开源我的项目:https://gitee.com/dtstack_dev... 2020年春节期间,一场从天而降的疫情在全国蔓延开来,突破了大家原有的工作生活节奏。疫情期间,大家宅在家就能随时看到实时的大数据疫情地图,能够随时刷到本人以后感兴趣的抖音视频,这所有背地依赖的最重要的技术,就是实时大数据处理技术。 当初疫情行将过来,国家提出要放慢大数据中心等新型基础设施建设,实时大数据处理平台建设成为企业数智化转型过程中越来越重要的局部。 一、什么是实时计算在大数据处理畛域,通常依据数据的不同性质,将工作划分为实时计算与离线计算,以温度传感器的场景举例:假如某城市装置了大量的温度传感器,每个传感器每隔1min上传一次采集到的温度信息,由气象核心对立汇总,每隔5分钟更新一次各个地区的温度,这些数据是始终源源不断的产生的,且不会进行。实时计算就次要用于“数据源源不断的产生,而且不会进行,须要以最小的提早取得计算结果”的场景,这种最小的提早通常为秒级或分钟级。 为了满足这种数据量很大,而且实时性要求又十分高的场景,通常会采纳实时计算技术,实时计算的“数据源源不断”的特定决定了其数据处理形式与离线是截然不同的。 Figure 1 实时计算和离线计算的区别 离线计算的批量、高延时、被动发动的计算特点不同,实时计算是一种继续、低延时、事件触发的计算工作。离线计算须要先装载数据,而后提交离线工作,最初工作计算返回后果;实时计算首先要提交流式工作,而后等实时流数据接入,而后计算出实时后果流。 Figure 2 实时计算和离线计算的区别(形象图) 形象点能够了解为离线计算是开着船去湖里(数据库)打渔,实时计算为在河流(数据流)上建设大坝发电。进一步发散,湖泊的造成依赖河流,河流确定高低边界就是湖泊;其实,离线计算能够了解为实时计算的一种特例。 二、实时计算能解决的问题Figure 3 实时计算能解决的问题 从技术畛域来看,实时计算次要用于以下场景: 基于Data Pipline的实时数据ETL:目标是实时地把数据从A点传输到B点。在传输的过程中可能增加数据荡涤和集成的工作,例如实时构建搜寻零碎的索引、实时数仓中的ETL过程等。基于Data Analysis的实时数据分析:依据业务指标,从原始数据中抽取对应信息并整合的过程。例如,查看每天销售额排行前10的商品、仓库均匀周转工夫、网页均匀点击率、实时推送关上率等。实时数据分析则是上述过程的实时化,通常在终端体现为实时报表或实时大屏。基于Data Driven的事件驱动利用:对一系列订阅事件进行解决或作出响应的零碎。事件驱动利用通常须要依赖外部状态,例如点击欺诈检测、风控系统、运维异样检测零碎等。当用户的行为触发某些危险控制点时,零碎会捕捉这个事件,并依据用户以后和之前的行为进行剖析,决定是否对用户进行危险管制。三、实时开发的全链路流程Figure 4 实时开发的全链路流程 实时采集——应用流式数据采集工具将数据流式且实时地采集并传输到大数据音讯存储(kafka等),流式数据存储作为实时计算的上游,提供源源不断的数据流去触发流式计算作业的运行。流数据作为实时计算的触发源驱动实时计算运行。因而,一个实时计算作业必须至多应用一个流数据作为源。每一条进入的流数据将间接触发实时计算的一次流式计算解决。数据在实时计算零碎中解决剖析后随机写到上游数据存储,上游数据库个别与业务相干,能够用来做实时报表、实时大屏等数据生产。 四、实时采集---全链路实时开发平台的要害整个全链路的实时开发中,实时采集是实时计算的上游。对于很对企业而言,自身曾经有数据存储系统,然而很大一部分都是离线的关系型数据库。如何将这些离线的关系型数据库的实时增量数据,提供给实时计算去剖析,是一个亟需解决的环节。如下图所示,是袋鼠云实时数据采集工具的性能架构。 Figure 5 实时数据采集工具FlinkX数据流程 袋鼠云实时数据采集作为StreamWorks平台的一个模块,有以下性能特点。 FlinkX反对批量数据抽取,同时反对实时捕获MySQL、Oracle、SQLServer等变动数据,实现批流对立采集。底层基于Flink分布式架构,反对大容量、高并发同步,相比单点同步性能更好,稳定性更高。反对间接读取数据库Binlog的形式实时同步,也反对距离轮询形式实时同步。反对断点续传和脏数据记录,实时数据采集的metric曲线展现。五、StreamWorks实时开发平台介绍袋鼠云实时开发平台(StreamWorks)基于 Apache Flink 构建的云原生一站式大数据流式计算平台,涵盖从实时数据采集到实时数据ETL的全链路流程。亚秒级别的解决延时, Datastream API 作业开发,与已有大数据组件兼容,帮忙企业实时数据智能化转型,助力新型基础设施建设。 在以往的数据开发技术栈中,SQL语言能解决大部分业务场景的问题。StreamWorks的外围性能是主打以SQL语义的流式数据分析能力(FlinkStreamSQL),升高开发门槛。提供Exactly-Once的解决语义保障,保障业务准确统一。 Figure 6 StreamWorks性能架构 如上图所示,StreamWorks蕴含如下几个模块: 实时采集:反对MySQL、SQLServer、Oracle、PolarDB、Kafka、EMQ等数据源实时数据采集,通过速率和并发数管制可帮忙用户更精确的管制采集过程。数据开发:反对FlinkSQL、Flink工作类型,FlinkSQL作业提供可视化存储配置、作业开发、语法查看等性能;Flink工作反对上传jar包的形式运行实时开发作业。工作运维:工作运行状况监控,数据曲线、运行日志、数据延时、CkeckPoint、Failover、属性参数、告警配置等性能。项目管理: 用户治理、角色治理、我的项目整体配置、我的项目成员治理等。六、StreamWorks实时大数据开发平台的劣势Figure 7 StreamWorks平台层级 如上图所示,StreamWorks实时大数据开发平台基于Apache Flink计算引擎,做了一层SQL化的封装,最上层有一个在线开发的IDE平台。平台有以下几个劣势点: 简略易用: 提供在线IDE,定制化适配FlinkSQL的开发工具!可视化DDL:提供可视化建表工具,配置参数即可实现DDL!内置函数:提供丰盛的FlinkSQL内置函数,简化开发工作!高效运维: 提供多达几十个运行指标,解决开源运维难题!实时采集:提供实时采集工具,撑持全链路实时开发平台!FlinkX:自研的批流一体的数据采集工具,曾经开源!Figure 8 传统开发模式 VS StreamWorks开发模式 七、十四行代码搞定实时业务开发讲了这么多,咱们的产品到底如何不便大家进行实时业务逻辑开发的,咱们还是拿最常见的网站流量剖析的例子阐明下。比方,某网站须要对拜访起源进行剖析: 如下图所示,从日志服务读取该站点拜访日志,解析日志中的起源并查看起源是否在感兴趣的网站列表中(相似起源网站的白名单,保留在MySQL中),统计来自各个网站的流量PV,最终后果写出到MySQL。Figure 9 业务逻辑流程图 用StreamSQL代码实现的话非常简单,只须要14行伪代码即可搞定。 CREATE TABLE log_source(dt STRING, …) WITH (type=kafka); CREATE TABLE mysql_dim(url STRING, …, PRIMARY KEY(url))WITH (type=mysql); CREATE TABLE mysql_result(url STRING, …, PRIMARY KEY(url))WITH (type=mysql); INSERT INTO mysql_resultSELECT l.url, count(*) as pv …FROM log_source l JOIN mysql_dim d ON l.url = d.urlgroup by l.url八、基于StreamWorks构建实时举荐零碎个别的举荐零碎都是基于标签来实现的,基于标签的举荐其实利用很广泛,比方头条,比方抖音,都用到了大量的标签,这样的举荐零碎有很多长处,比方实现简略、可解释性好等。如何通过标签来实现实时商品或者内容的举荐呢? ...

April 28, 2021 · 1 min · jiezi

关于kafka:kafka-可视化工具-6-个重要维度-帮你快速了解这-9-款免费-etl-调度工具的应用

ETL,是英文 Extract-Transform-Load 的缩写,用来形容将数据从起源端通过抽取(extract)、转换(transform)、加载(load)至目标端的过程。ETL 是构建数据仓库的重要一环,用户从数据源抽取出所需的数据,通过数据荡涤,最终依照事后定义好的数据仓库模型,将数据加载到数据仓库中去。咱们在下方列出了 7 款开源的 ETL 工具,并探讨了从 ETL 转向“无 ETL”的过程,因为 ELT 正迅速成为古代数据和云环境的终极过程。 ETL,是英文 Extract-Transform-Load 的缩写,用来形容将数据从起源端通过抽取(extract)、转换(transform)、加载(load)至目标端的过程。ETL 是构建数据仓库的重要一环,用户从数据源抽取出所需的数据,通过数据荡涤,最终依照事后定义好的数据仓库模型,将数据加载到数据仓库中去。 我在下方列出了 9 款当初市面上收费且口碑不错的 ETL 调度工具,并列举了在抉择利用这些工具前所要思考的几个维度 优良的 ETL 工具1.Apache Camel Apache Camel 是一个十分弱小的基于规定的路由以及媒介引擎,该引擎提供了一个基于 POJO 的企业应用模式(Enterprise Integration Patterns)的实现,你能够采纳其异样弱小且非常易用的 API (能够说是一种 Java 的畛域定义语言 Domain Specific Language)来配置其路由或者中介的规定。 通过这种畛域定义语言,你能够在你的 IDE 中用简略的 Java Code 就能够写出一个类型平安并具备肯定智能的规定形容文件。 2.Apache Kafka Apache Kafka 是一个开源的音讯零碎,用 Scala 和 Java 写成。该我的项目为解决实时数据提供了一个对立、高通量、低延时的平台。有如下个性: 通过 O(1) 的磁盘数据结构提供音讯的长久化,这种构造对于即便数以 TB 的音讯存储也可能放弃长时间的稳定性能。 高吞吐量:即便是十分一般的硬件 kafka 也能够反对每秒数十万的音讯。 反对通过 kafka 服务器和消费机集群来分区音讯。 反对 Hadoop 并行数据加载。 ...

April 26, 2021 · 1 min · jiezi

关于kafka:Kafka4kafka生产环境规划部署

摘要咱们上一节解说了Kafka架构-底层原理:从根底的partition外面的offset引申到LEO和HW;以及对于Leader partition跟follower partition而言,他们的LEO跟HW是如何更新的的?以及高水位HW在leader选举切换时候,存在的数据失落跟数据不统一问题,以及通过leader epoch版本号的概念引入解决下面问题,因为HW的变更还跟leadder partition外面的ISR列表有关联,又解说了:ISR列表设计的0.9.x之前版本形式以及0.9.x之后的版本通过follower音讯数比leader音讯数目少形式更新LSR列表,以及依据工夫来更新ISR列表。而后这些都解说结束之后,咱们解说了Kafka的日志是如何存储存储到对应目录列表的,而后怎么基于存储日志疾速找到对应offset的数据的二分查找法;这些都解说结束之后,解说了Kafka底层集群外面节点如何通信?以及集群节点如果进行管控,Leader选举,线上解体以及数据清理。 这些理解之后,咱们便可进行Kafka理论线上生产规划以及搭建。次要阐明以下:1、基于理论业务进行kafka集群如何布局?须要思考哪些问题? 2、Kafka集群生产参数配置:包含Kafka本人内核参数、操作系统参数、JVM和GC参数。3、Kafka单点搭建用于测试、Kafka集群搭建4、具备环境之后,咱们须要进行一些运维工作:Kafka的测试。 思维导图 内容1、基于理论业务进行Kafka集群生产规划(电商零碎每日10亿数据量)基于理论生产业务的时候,咱们布局kafka集群的时候,思考方向是:基于每天数据量计算出零碎的大略QPS,依据QPS能够计算出须要多少台物理机器;依据每天数据量预估整体数据量大小,在联合Kafka本身的原理,保留工夫长短,以及多冗余正本机制避免数据失落来预估整体数据量大小来布局机器测硬盘大小。这些都做完之后,就须要具体到一台物理机或者虚拟机了,次要思考:cpu(每台机器的线程数)、内存(Kafka本身底层原理)、磁盘(kafka底层原理剖析)、网络(依据数据量) 1、QPS基于10亿数据量:10亿数据量 依据2-8准则,80%的数据是在非凌晨0-8点的16小时产生,并且其中80%的申请都是在20%的工夫内,所以:100.80.8=6亿数据在:1620%=3小时;QPS=600000000/360*60近似为6万。 2、存储量总存储量=工夫*每天存储量。 每天10亿数据量,咱们假如每条数据大小大略是1kb,其实很多时候均匀是达不到1kb的数据。咱们粗略预计下:假如一个英文字母是1个字节byte,1个中文汉子是2个字节byte,那么1kb能够包容1024个英文字符/512个汉子;10亿数据量,是10亿kb大小数据,kafka假如咱们依照2个正本,数据默认保留7天,则 整体数据量=1027=140亿kb近似依照12TB数据量算。 3、物理机1、物理机数量物理机数量个别依据qps计算,因为qps是6万左右,个别一台机器大略抗并发是3万左右,因为在机器资源短缺状况下,个别为了应答秒杀这种场景,计算的qps=总体qps*30%;所以咱们的最大qps为20万qps左右,所以咱们的机器大略在6-7台机器,这里咱们抉择6台机器。 2、物理机cpu经验值 是状况而定,咱们为了减少kafka的吞吐量的话,咱们将会把解决申请的线程数量调整为默认的2~3倍 Kafka Broker过程运行起来线程数预估依据Kafka多路复用的Reeactor模型解决申请时候,是须要一个Accepptor线程,Processor线程用来将申请写入到申请队列,默认是3个;而后具体进行申请解决的是一个Handler线程池,默认线程数量是8个;以及后盾数据清理线程几controller选举等线程。依照2~3倍准则,咱们的线程数:24-36;而后加上日志清理线程,或者Controller感知线程等,咱们将预估线程忙碌的时候,线程数量为一两百。 cpu核跟线程数的经验值 1、CPU 4核,一般来说几十个线程,在高峰期CPU简直都快打满了,2、CPU 8核,也就可能比拟拮据的撑持几十个线程忙碌的工作,3、个别是倡议16核,靠谱,基本上能够达到一两百线程的工作。 broker个别都会启动几十个甚至上百个线程,大家看过broker端的原理了,各种解决申请的线程,后盾线程,几十个线程频繁工作,个别都倡议是16核CPU,甚至32核CPU 3、物理机内存因为Kafka写数据是:写入os_cache+磁盘程序写,kafka读取数据:零拷贝+页缓冲技术(os_cache)所以咱们发现Kafka是大量依附os_cache,而不是JVM外面的内存;所以咱们布局机器内存的时候,次要是思考os_cache内存大小,辅助思考下机器内存大小。 kafka jvm堆内存,你感觉须要很大吗? 理解了kafka原理之后,kafka并没有在本人的jvm堆内存里放入过多的数据,他跟rabbitmq是不一样的,rabbitmq是数据过去优先写入jvm堆内存里去缓冲一下,肯定工夫之后,rabbitmq再一次性把jvm堆内存里的缓冲一批数据给刷入磁盘中。rabbitmq那种机制跟原理的话会导致jvm堆内存中寄存大量的数据,须要给jvm堆内存开拓比拟大的空间了。 然而kafka正好相同的,他接管到了这个数据之后不是间接写jvm堆内存的,而是采纳本人的二进制紧凑的数据格式,给写入到磁盘文件里去,然而是先写入os cache(操作系统治理的一块内存缓冲空间)kafka并没有应用过多的jvm堆内存空间,所以的话你不须要给kafka jvm堆内存调配过大的空间,基本上来说几个G就够了。 充分利用os_cache进步性能:咱们思考下os_cache调配多大;准则: broker治理的每个parition的最新正在写的日志段文件的数据都能够驻留在os cache中,这样能够保障每个parition正在写的数据,最有可能被生产的数据,就能够间接从os cache里来读了。 剖析:假如整个Kafka的集群外面有100个topic,假如每个topic是6个partition,每个partiton是2个正本,然而其实不会从partition的正本读取数据,你只须要思考的是leader partirion,所以一共100 * 6 =600个leader partition,均匀到6台机器下来,假如每台机器是放100个partition,每个partition的最新正在写的日志段文件的大小是默认的1GB. 所以说单台机器上,最新的正在写的日志段文件的大小100个partition 1GB的日志段文件 = 600GB。如果最佳的状况,单台机器能够有600GB的内存的给os cache的话,就能够每个partiton最新的数据都在os cache里,比如说一个日志段文件有1GB,可能都对应几百万条数据了,这些数据咱们也不会变频繁生产,最多也就是1%-10%数据生产,所以600(1%-10%)也就是6G以上所以咱们大略64G的机器内存即可。 JVM的堆内存kafka本身的jvm是用不了过多堆内存的,因为kafka设计就是躲避掉用jvm对象来保留数据,防止频繁fullgc导致的问题,所以个别kafka本身的jvm堆内存,调配个6G左右就够了,剩下的内存全副留给os cache 4、物理机网络带宽生产环境的机器布局,无论是MySQL、Redis、RocketMQ、Elasticsearch、Kafka、Hadoop、Flink,Yarn,其实布局的思路都是相似的,思考的其实是从技术实质和底层的原理登程来思考:1、申请量有多大、2、数据量有多大、3、内存应该调配多大(须要理解底层工作机制,怎么应用内存的?)、4、线程数量有多少、5、网络数据传输量有多大(个别决定了你的网卡大小抉择) 当初个别就是千兆网卡(1GB / s),还有万兆网卡(10GB / s),网卡决定了什么呢?比方你要计算一下,kafka集群之间,broker和broker之间是会做数据同步的,因为leader要同步数据到follower下来,他们是在不同的broker机器上的,broker机器之间会进行频繁的数据同步,传输大量的数据。 所以在这种状况下,须要计算下每秒两台broker机器之间大略会传输多大的数据量?高峰期每秒大略会涌入6万条数据,假如每一条数据大小是1kb,大略来说每秒就是60mb/s的数据量,每秒60mb/s的湖,他会在broker之间来传输,你就算多估算一些,每秒大略也就传输个几百mb/s的数据,就足够了。 实际上每台机器能用的网卡的带宽还达不到极限,因为kafka只能用其中一部分的带宽资源,比方700mb/s,然而个别不能允许kafka占用这么多带宽,因为防止说占用这么多带宽,万一再多一点,就容易把网卡打满 所以说,个别限度kafka每秒带宽资源就是300mb / s,如果你给物理机应用的千兆网卡,那么其实他每秒最多传输数据是几百mb,是够了,可能也就是几十mb,或者一两百mb,基本上都够了,能够足够传输。 5、物理机磁盘磁盘类型 SSD磁盘的性能相比于机械硬盘的话次要在磁盘随即写下面,在磁盘程序写的状况下,磁盘程序写跟随即写差不多,所以因为Kafka是基于os cahce+磁盘程序写机制,因为磁盘程序写的性能跟写内存差不多,并且SSD的在磁盘随机写上会比机械硬盘成果好,在磁盘程序写上SSD跟机械硬盘差不多,所以咱们应用机械硬盘即可 磁盘大小 总共13T数据,因为很多数据是没有1kb大小的,所以咱们预估是12TB数据,6台机器,则:每台机器加上2快1TB的磁盘,总共2TB。 2、Kafka集群生产参数设置1、内核参数内存参数的话次要是Kafka Broker利用的本身配置文件,上面是一些惯例参数: ...

March 27, 2021 · 1 min · jiezi

关于kafka:Kafka-性能篇为何-Kafka-这么快

『码哥』的 Redis 系列文章有一篇讲透了 Redis 的性能优化 ——《Redis 外围篇:唯快不破的机密》。深刻地从 IO、线程、数据结构、编码等方面分析了 Redis “快”的外部机密。65 哥深受启发,在学习 Kafka 的过程中,发现 Kafka 也是一个性能非常优良的中间件,遂要求『码哥』讲一讲 Kafka 性能优化方面的常识,所以『码哥』决定将这篇性能方面的博文作为 Kafka 系列的开篇之作。 先预报一下 Kafka 系列文章,大家敬请期待哦: 以解说性能作为 Kafka 之旅的开篇之作,让咱们一起来深刻理解 Kafka “快”的外部机密。你不仅能够学习到 Kafka 性能优化的各种伎俩,也能够提炼出各种性能优化的方法论,这些方法论也能够利用到咱们本人的我的项目之中,助力咱们写出高性能的我的项目。 关公战秦琼65: Redis 和 Kafka 齐全是不同作用的中间件,有比拟性吗?是的,所以此文讲的不是《分布式缓存的选型》,也不是《分布式中间件比照》。咱们聚焦于这两个不同畛域的我的项目对性能的优化,看一看优良我的项目对性能优化的通用伎俩,以及在针对不同场景下的特色的优化形式。 很多人学习了很多货色,理解了很多框架,但在遇到理论问题时,却经常会感觉到常识有余。这就是没有将学习到的常识体系化,没有从具体的实现中形象出能够卓有成效的方法论。 学习开源我的项目很重要的一点就是演绎,将不同我的项目的优良实现总结出方法论,而后演绎到自我的实际中去。 码哥寄语感性、主观、审慎是程序员的特点,也是长处,然而很多时候咱们也须要带一点理性,带一点激动,这个时候能够帮忙咱们更快的做决策。「悲观者正确、乐观者胜利。」心愿大家都是一个乐观地解决问题的人。Kafka 性能全景 从高度形象的角度来看,性能问题逃不出上面三个方面: 网络磁盘复杂度对于 Kafka 这种网络分布式队列来说,网络和磁盘更是优化的重中之重。针对于下面提出的形象问题,解决方案高度形象进去也很简略: 并发压缩批量缓存算法晓得了问题和思路,咱们再来看看,在 Kafka 中,有哪些角色,而这些角色就是能够优化的点: ProducerBrokerConsumer是的,所有的问题,思路,优化点都曾经列出来了,咱们能够尽可能的细化,三个方向都能够细化,如此,所有的实现便高深莫测,即便不看 Kafka 的实现,咱们本人也能够想到一二点能够优化的中央。 这就是思考形式。提出问题 > 列出问题点 > 列出优化办法 > 列出具体可切入的点 > tradeoff和细化实现。 当初,你也能够尝试本人想一想优化的点和办法,不必尽如人意,不必管好不好实现,想一点是一点。 65 哥:不行啊,我很笨,也很懒,你还是间接和我说吧,我白嫖比拟行。程序写65 哥:人家 Redis 是基于纯内存的零碎,你 kafka 还要读写磁盘,能比?为什么说写磁盘慢? 咱们不能只晓得论断,而不知其所以然。要答复这个问题,就得回到在校时咱们学的操作系统课程了。65 哥还留着课本吗?来,翻到讲磁盘的章节,让咱们回顾一下磁盘的运行原理。 65 哥:鬼还留着哦,课程还没上到一半书就没了。要不是考试俺眼神好,预计当初还没毕业。看经典大图: ...

March 24, 2021 · 3 min · jiezi

关于kafka:Kafka3kafka架构底层原理

摘要咱们上一节解说了Kafka架构-基本原理,次要是降级了kafka的高性能,高可用,分布式存储,负载平衡故障感知。这一节次要解说下kafka架构-底层原理。 高可用底层实现:Partition中外围offset:LEO、HW;以及LEO跟HW如何更新;HW在0.11.x版本前存在的问题以及前面版本如何解决这个问题的?高性能:Kafka分段日志如何存储,如何疾速定位。负载平衡故障感知: Kafka如何通信?Kafka的Controller如何实现故障转移、Leader选举、创立/删除Topic时候Controkler会做什么操作?Controller如何感知Broker上线以及解体的? 思维导图 内容

March 22, 2021 · 1 min · jiezi

关于kafka:Kafka2kafka架构基本原理

摘要上一解说咱们解说了kafka的具备的一些特点:相比于传统的音讯队列来说,kafka能够做到分布式存储,具备高可用,高性能的特点,咱们这一讲次要解说:Kafka实现高性能、高可用、分布式存储的的基本原理。主线次要从吞吐量到延时引出kafka是高吞吐量、低延时的架构;依据这个高吞吐量低延时原理从而引出kafka如果实现单机几十万并发数据写入、以及如何实现高性能数据读取;而后如何将写入的数据进行极致压缩利用磁盘效率,进而在数据写入读取,以及数据存取形式都晓得的状况下,kafka如何实现分布式存储、分布式负载平衡;分布式数据存储曾经做完之后,怎么保障存储的数据实现高可用,而后如何保障存储进去的数据不会失落;这些都解说结束之后;最初解说下kafka架构外面的服务弹性伸缩以及节点新发现跟故障感知。从简到繁,一步一步层层递进。 思维导图 内容1、吞吐量跟延时1、吞吐量跟延时因为kafka是高吞吐量跟低延时的架构,所以在解说kafka时候须要先理解吞吐量跟延时概念。 如果解决完一条数据须要1毫秒,并且一条数据的大小是1kb;那么1秒中就能够解决1000条数据,1000kb数据大小;下面场景中吞吐量就是:1000条、1000kb; 吞吐量:单位工夫内解决数据大小。延时:Kafka一次申请接管音讯到音讯解决实现所耗费的工夫。 2、Spark Streaming要采取微批处理技术实现流式计算与kafka相似的Spark大数据框架,为什么须要应用微批处理技术实现流式计算? 如果咱们解决完一条数据须要1毫秒,那么咱们的延时是:1ms 零碎的吞吐量是:1000条数据。 咱们采纳微批处理机制,先花9毫秒收集完1000条数据,而后通过1毫秒进行数据流式计算,那么本次一起数据申请执行结束的延时10毫秒 吞吐量是10万条数据。吞吐量量进步了100倍,延时减少了10倍。 因为解决1条或者1000条数据耗时相等,为了节俭每条数据都须要启动新的计算资源:网络开销或者磁盘开销比方解决1条数据须要1毫秒,吞吐量是:1000条数据/s;如果9毫秒收集1000条数据,而后1毫秒解决数据,那么零碎吞吐量10万条;零碎吞吐量增大了100倍数,然而延时减少了10倍。 其实也相似于咱们对数据库进行多条数据插入时候,应用批量插入而不是一次插入一条;次要是节约新资源的网络开销。 3、与Spark Streaming高吞吐量高延时不一样,Kafka如何实现高吞吐量低延时?kafka实现高吞吐量低延时次要是基于kafka的数据写入机制跟数据读取机制。在上面解说。 2、Kafka如何实现单机几十万并发写入后面解说了Spark Streaming技术是应用:batch微批处理,实现高吞吐高提早。然而kafka相同,高吞吐低提早。 常见音讯队列rabbitmq如何写入数据?常见的音讯队列数据数据是间接将数据写入到内存,而后将内存外面的数据再写入到磁盘,这样的花就会耗用机器更多的内存,如果是基于JVM机制的还须要调配更多的对内存空间保证数据写入高效。 kafka数据写入 os cache+磁盘程序写:kafka数据写入是间接写磁盘;写磁盘的时候 实先写入到page cache;page cache是基于os cache。并且数据写入磁盘的时候是磁盘程序写的。逻辑架构图如下: 3、kafka如何实现高效数据读取4、底层数据存储构造5、如何保障TB数据分布式存储6、如何保障kafka的高可用7、如何保障kafka写入数据不失落8、集群数据写入时候如何实现负载平衡成果9、kafka无状态的架构如何实现10、kafka如何实现节点发现跟故障感知

March 20, 2021 · 1 min · jiezi

关于kafka:博文推荐-Apache-Pulsar-延迟消息投递解析

对于 Apache Pulsar Apache Pulsar 是 Apache 软件基金会顶级我的项目,是下一代云原生分布式音讯流平台,集音讯、存储、轻量化函数式计算为一体,采纳计算与存储拆散架构设计,反对多租户、长久化存储、多机房跨区域数据复制,具备强一致性、高吞吐、低延时及高可扩展性等流数据存储个性。 GitHub 地址:http://github.com/apache/pulsar/ Apache Pulsar 是一个多租户、高性能的服务间音讯传输解决方案,反对多租户、低延时、读写拆散、跨地区复制、疾速扩容、灵便容错等个性。腾讯数据平台部 MQ 团队对 Pulsar 做了深刻调研以及大量的性能和稳定性方面优化,目前曾经在腾讯云音讯队列 TDMQ 落地上线。 本文次要介绍 Pulsar 提早音讯投递的实现,心愿与大家一起交换。 什么是提早音讯投递提早音讯投递在 MQ 利用场景中非常广泛,它是指音讯在发送到 MQ 服务端后并不会立马投递,而是依据音讯中的属性提早固定工夫后才投递给消费者,个别分为定时音讯和提早音讯两种: 定时音讯:Producer 将音讯发送到 MQ 服务端,但并不冀望这条音讯立马投递,而是推延到在以后工夫点之后的某一个工夫投递到 Consumer 进行生产。提早音讯:Producer 将音讯发送到 MQ 服务端,但并不冀望这条音讯立马投递,而是提早肯定工夫后才投递到 Consumer 进行生产。目前在业界,腾讯云的 CMQ 和阿里云的 RocketMQ 也都反对提早音讯投递: CMQ:将音讯提早期间定义为”航行状态“,可通过设置 DelaySeconds 配置提早范畴,取值范畴为 0 - 3600 秒,即音讯最长不可见时长为 1 小时。RocketMQ:开源版本提早音讯长期存储在一个外部主题中,反对特定的 level,例如定时 5s,10s,1m 等,商业版本反对任意工夫精度。开源的 NSQ、RabbitMQ、ActiveMQ 和 Pulsar 也都内置了提早音讯的解决能力。尽管每个 MQ 我的项目的应用和实现形式不同,但外围实现思路都一样:Producer 将一个提早音讯发送到某个 Topic 中,Broker 将提早音讯放到长期存储进行暂存,提早跟踪服务(Delayed Tracker Service)会查看音讯是否到期,将到期的音讯进行投递。 提早音讯投递的应用场景提早音讯投递是要暂缓对以后音讯的解决,在将来的某个工夫点再触发投递,理论的利用场景十分多,比方异样检测重试、订单超时勾销、预约揭示等。 服务申请异样,须要将异样申请放到独自的队列,隔 5 分钟后进行重试;用户购买商品,但始终处于未领取状态,须要定期揭示用户领取,超时则敞开订单;面试或者会议预约,在面试或者会议开始前半小时,发送告诉再次揭示;最近所在业务产品有个应用 Pulsar 提早音讯的 Case:业务要对两套零碎的日志音讯进行关联,其中一套零碎因为查问 Hbase 可能会超时或失败,须要将失败的关联工作在集群闲暇的时候再次调度。 ...

March 1, 2021 · 2 min · jiezi

关于kafka:译文-Apache-Pulsar-对现代数据堆栈至关重要的四个原因

本文最后公布于 DataStax 官网博客,经原作者受权由 InfoQ 中文站翻译并分享。本译文公布也已取得受权,较原文有调整。译文链接:https://www.infoq.cn/article/...对于 Apache Pulsar Apache Pulsar 是 Apache 软件基金会顶级我的项目,是下一代云原生分布式音讯流平台,集音讯、存储、轻量化函数式计算为一体,采纳计算与存储拆散架构设计,反对多租户、长久化存储、多机房跨区域数据复制,具备强一致性、高吞吐、低延时及高可扩展性等流数据存储个性。 GitHub 地址:http://github.com/apache/pulsar/ 多年来,DataStax 始终关注音讯畛域。一个十分重要的起因是基于微服务的架构日益遍及。简略来说,微服务架构应用音讯总线来解耦服务之间的通信,并简化重放、错误处理和负载峰值。 有了 Cassandra 和 Astra,开发者和架构师就有了这样一个数据库生态系统: •以开源为根底•非常适合混合云和多云部署•云原生,按生产计价 目前还没有满足这些需要的音讯解决方案,因而咱们打算打造一个。从评估最风行的 Apache Kafka 开始,咱们发现它在四个方面存在有余: 1.跨地区复制2.扩大3.多租户4.队列 然而,针对 Kafka 的不足之处,Apache Pulsar 却解决了所有这些问题。让咱们逐项看下 Pulsar 在这四方面的劣势。 Pulsar 反对跨地区复制Kafka 被设计为在单个区域内运行,不反对跨数据中心的复制。Kafka 部署区域之外的客户端只能忍耐提早减少。有几个我的项目试图在客户端层面向 Kafka 增加跨数据中心的复制,但操作都很艰难,而且容易失败。 Pulsar 在外围服务器上构建了跨地区复制性能,你能够在部署时抉择同步或异步配置,并且能够按主题配置复制机制。生产者能够从任何地区写入共享主题,Pulsar 负责确保这些信息对各地的消费者均可见。 Pulsar 具备高可扩展性在 Kafka 中,存储单元是一个段文件,然而复制单元是一个分区中的所有段文件。每个分区都归一个 leader 代理所有,它会复制给多个 follower。所以,当你须要给 Kafka 集群减少容量时,在新节点分担现有节点的负载之前,有些分区须要复制到新节点上。 这意味着,减少 Kafka 集群的容量会使其变慢,而不是变快。如果你的容量布局恰到好处,这很好,但如果业务需要的变动比你预期的要快,那么这可能会是一个重大的问题。 Pulsar 减少了一个间接层。(Pulsar 也将计算和存储离开,别离由 broker 和 bookie 治理,但这里,最重要的局部是 Pulsar 如何通过 BookKeeper 减少复制的粒度。)在 Pulsar 中,分区被宰割成 ledger,但和 Kafka 段不同,ledger 能够独自复制,互不影响。Pulsar 在 ZooKeeper 中保护着一个 ledger 到分区的映射。因而,当咱们向集群增加一个新的存储节点时,咱们所要做的就是在该节点上启动一个新的 ledger。现有的数据能够保留在原来的地位,不须要集群做额定的工作。 ...

March 1, 2021 · 1 min · jiezi

关于kafka:Kafka-是怎么存储的为什么速度那么快

文章收录地址:Java-Bang 专一于零碎架构、高可用、高性能、高并发类技术分享Kafka 依赖于文件系统(更底层地来说就是磁盘)来存储和缓存音讯。在咱们的印象中,对于各个存储介质的速度认知大体同下图所示的雷同,层级越高代表速度越快。很显然,磁盘处于一个比拟难堪的地位,这不禁让咱们狐疑 Kafka 采纳这种长久化模式是否提供有竞争力的性能。在传统的消息中间件 RabbitMQ 中,就应用内存作为默认的存储介质,而磁盘作为备选介质,以此实现高吞吐和低提早的个性。然而,事实上磁盘能够比咱们料想的要快,也可能比咱们料想的要慢,这齐全取决于咱们如何应用它。 无关测试结果表明,一个由6块 7200r/min 的 RAID-5 阵列组成的磁盘簇的线性(程序)写入速度能够达到 600MB/s,而随机写入速度只有 100KB/s,两者性能相差6000倍。操作系统能够针对线性读写做深层次的优化,比方预读(read-ahead,提前将一个比拟大的磁盘块读入内存)和后写(write-behind,将很多小的逻辑写操作合并起来组成一个大的物理写操作)技术。程序写盘的速度不仅比随机写盘的速度快,而且也比随机写内存的速度快,如下图所示。 页缓存的魅力Kafka 在设计时采纳了文件追加的形式来写入音讯,即只能在日志文件的尾部追加新的音讯,并且也不容许批改已写入的音讯,这种形式属于典型的程序写盘的操作,所以就算Kafka应用磁盘作为存储介质,它所能承载的吞吐量也不容小觑。但这并不是让 Kafka 在性能上具备足够竞争力的惟一因素,咱们无妨持续剖析。 页缓存是操作系统实现的一种次要的磁盘缓存,以此用来缩小对磁盘 I/O 的操作。具体来说,就是把磁盘中的数据缓存到内存中,把对磁盘的拜访变为对内存的拜访。为了补救性能上的差别,古代操作系统越来越“激进地”将内存作为磁盘缓存,甚至会十分乐意将所有可用的内存用作磁盘缓存,这样当内存回收时也简直没有性能损失,所有对于磁盘的读写也将经由对立的缓存。 当一个过程筹备读取磁盘上的文件内容时,操作系统会先查看待读取的数据所在的页(page)是否在页缓存(pagecache)中,如果存在(命中)则间接返回数据,从而防止了对物理磁盘的 I/O 操作;如果没有命中,则操作系统会向磁盘发动读取申请并将读取的数据页存入页缓存,之后再将数据返回给过程。 同样,如果一个过程须要将数据写入磁盘,那么操作系统也会检测数据对应的页是否在页缓存中,如果不存在,则会先在页缓存中增加相应的页,最初将数据写入对应的页。被批改过后的页也就变成了脏页,操作系统会在适合的工夫把脏页中的数据写入磁盘,以保持数据的一致性。 Linux 操作系统中的 vm.dirty_background_ratio 参数用来指定当脏页数量达到零碎内存的百分之多少之后就会触发 pdflush/flush/kdmflush 等后盾回写过程的运行来解决脏页,个别设置为小于10的值即可,但不倡议设置为0。与这个参数对应的还有一个 vm.dirty_ratio 参数,它用来指定当脏页数量达到零碎内存的百分之多少之后就不得不开始对脏页进行解决,在此过程中,新的 I/O 申请会被阻挡直至所有脏页被冲刷到磁盘中。对脏页有趣味的读者还能够自行查阅 vm.dirty_expire_centisecs、vm.dirty_writeback.centisecs 等参数的应用阐明。 对一个过程而言,它会在过程外部缓存解决所需的数据,然而这些数据有可能还缓存在操作系统的页缓存中,因而同一份数据有可能被缓存了两次。并且,除非应用 Direct I/O 的形式,否则页缓存很难被禁止。此外,用过 Java 的人个别都晓得两点事实:对象的内存开销十分大,通常会是实在数据大小的几倍甚至更多,空间使用率低下;Java 的垃圾回收会随着堆内数据的增多而变得越来越慢。基于这些因素,应用文件系统并依赖于页缓存的做法显著要优于保护一个过程内缓存或其余构造,至多咱们能够省去了一份过程外部的缓存耗费,同时还能够通过结构紧凑的字节码来代替应用对象的形式以节俭更多的空间。如此,咱们能够在32GB的机器上应用28GB至30GB的内存而不必放心 GC 所带来的性能问题。 此外,即便 Kafka 服务重启,页缓存还是会放弃无效,然而过程内的缓存却须要重建。这样也极大地简化了代码逻辑,因为保护页缓存和文件之间的一致性交由操作系统来负责,这样会比过程内保护更加平安无效。 Kafka 中大量应用了页缓存,这是 Kafka 实现高吞吐的重要因素之一。尽管音讯都是先被写入页缓存,而后由操作系统负责具体的刷盘工作的,但在 Kafka 中同样提供了同步刷盘及间断性强制刷盘(fsync)的性能,这些性能能够通过 log.flush.interval.messages、log.flush.interval.ms 等参数来管制。 同步刷盘能够进步音讯的可靠性,避免因为机器掉电等异样造成处于页缓存而没有及时写入磁盘的音讯失落。不过笔者并不倡议这么做,刷盘工作就应交由操作系统去调配,音讯的可靠性应该由多正本机制来保障,而不是由同步刷盘这种重大影响性能的行为来保障。 Linux 零碎会应用磁盘的一部分作为 swap 分区,这样能够进行过程的调度:把以后非沉闷的过程调入 swap 分区,以此把内存空进去让给沉闷的过程。对大量应用零碎页缓存的 Kafka 而言,该当尽量避免这种内存的替换,否则会对它各方面的性能产生很大的负面影响。 咱们能够通过批改 vm.swappiness 参数(Linux 零碎参数)来进行调节。vm.swappiness 参数的下限为100,它示意踊跃地应用 swap 分区,并把内存上的数据及时地搬运到 swap 分区中;vm.swappiness 参数的上限为0,示意在任何状况下都不要产生替换(vm.swappiness = 0 的含意在不同版本的 Linux 内核中不太雷同,这里采纳的是变更后的最新解释),这样一来,当内存耗尽时会依据肯定的规定忽然停止某些过程。笔者倡议将这个参数的值设置为1,这样保留了 swap 的机制而又最大限度地限度了它对 Kafka 性能的影响。 ...

February 24, 2021 · 1 min · jiezi

关于kafka:使用dockercompose部署kafka服务

1 装置# 1. 装置docker-compose,须要事后装置好Dockersudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose# 减少可执行权限sudo chmod +x /usr/local/bin/docker-compose# 2. 创立相干文件夹mkdir -p /opt/zookeeper && mkdir -p /opt/kafka# 3. 筹备配置文件echo 'version: '3.7'services: zookeeper: image: wurstmeister/zookeeper volumes: - /opt/zookeeper/data:/data container_name: zookeeper mem_limit: 1024M environment: ZOOKEEPER_CLIENT_PORT: 2181 ZOOKEEPER_TICK_TIME: 2000 ports: - 2181:2181 restart: always kafka_node1: image: wurstmeister/kafka container_name: kafka_node1 mem_limit: 1024M depends_on: - zookeeper ports: - 9092:9092 volumes: - /opt/kafka/data:/kafka environment: KAFKA_CREATE_TOPICS: "test" KAFKA_BROKER_NO: 0 KAFKA_LISTENERS: PLAINTEXT://kafka_node1:9092 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://${kafka_service_public_ip}:${kafka_service_public_port} KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 KAFKA_HEAP_OPTS: "-Xmx512M -Xms16M" restart: always kafka_manager: image: hlebalbau/kafka-manager:stable ports: - 9000:9000 environment: ZK_HOSTS: "zookeeper:2181" depends_on: - zookeeper - kafka_node1 restart: always' > /etc/kafka/kafka.yml# 3. 启动容器服务docker-compose -f /etc/kafka/kafka.yml up -d2 应用Kafka-Mgr治理集群拜访服务所在主机的9000端口,按如下图所示创立集群: ...

February 23, 2021 · 1 min · jiezi

关于kafka:如何开发一个完善的-Kafka-生产者客户端

Kafka 起初是 由 LinkedIn 公司采纳 Scala 语言开发的一个多分区、多正本且基于 ZooKeeper 协调的分布式音讯零碎,现已被募捐给 Apache 基金会。目前 Kafka 曾经定位为一个分布式流式解决平台,它以高吞吐、可长久化、可程度扩大、反对流数据处理等多种个性而被宽泛应用。目前越来越多的开源分布式解决零碎如 Cloudera、Storm、Spark、Flink 等都反对与 Kafka 集成。 Kafka 之所以受到越来越多的青眼,与它所“表演”的三大角色是分不开的: 音讯零碎: Kafka 和传统的音讯零碎(也称作消息中间件)都具备零碎解耦、冗余存储、流量削峰、缓冲、异步通信、扩展性、可恢复性等性能。与此同时,Kafka 还提供了大多数音讯零碎难以实现的音讯程序性保障及回溯生产的性能。存储系统: Kafka 把音讯长久化到磁盘,相比于其余基于内存存储的零碎而言,无效地升高了数据失落的危险。也正是得益于 Kafka 的音讯长久化性能和多正本机制,咱们能够把 Kafka 作为长期的数据存储系统来应用,只须要把对应的数据保留策略设置为“永恒”或启用主题的日志压缩性能即可。流式解决平台: Kafka 不仅为每个风行的流式解决框架提供了牢靠的数据起源,还提供了一个残缺的流式解决类库,比方窗口、连贯、变换和聚合等各类操作。1|0基本概念一个典型的 Kafka 体系架构包含若干 Producer、若干 Broker、若干 Consumer,以及一个 ZooKeeper 集群,如下图所示。其中 ZooKeeper 是 Kafka 用来负责集群元数据的治理、控制器的选举等操作的。Producer 将音讯发送到 Broker,Broker 负责将收到的音讯存储到磁盘中,而 Consumer 负责从 Broker 订阅并生产音讯。 整个 Kafka 体系结构中引入了以下3个术语: Producer: 生产者,也就是发送音讯的一方。生产者负责创立音讯,而后将其投递到 Kafka 中。Consumer: 消费者,也就是接管音讯的一方。消费者连贯到 Kafka 上并接管音讯,进而进行相应的业务逻辑解决。Broker: 服务代理节点。对于 Kafka 而言,Broker 能够简略地看作一个独立的 Kafka 服务节点或 Kafka 服务实例。大多数状况下也能够将 Broker 看作一台 Kafka 服务器,前提是这台服务器上只部署了一个 Kafka 实例。一个或多个 Broker 组成了一个 Kafka 集群。一般而言,咱们更习惯应用首字母小写的 broker 来示意服务代理节点。在 Kafka 中还有两个特地重要的概念—主题(Topic)与分区(Partition)。Kafka 中的音讯以主题为单位进行归类,生产者负责将音讯发送到特定的主题(发送到 Kafka 集群中的每一条音讯都要指定一个主题),而消费者负责订阅主题并进行生产。 ...

January 22, 2021 · 1 min · jiezi

关于kafka:二Kafka命令行操作和架构原理

一.kafka命令行操作1.1 创立topic[v2admin@hadoop10 kafka]$ bin/kafka-topics.sh --zookeeper hadoop10:2181 --create --replication-factor 2 --partitions 1 --topic firstCreated topic first.1.2 查看topic[v2admin@hadoop10 kafka]$ bin/kafka-topics.sh --zookeeper hadoop10:2181 --listdemofirst1.3 删除topic[v2admin@hadoop10 kafka]$ bin/kafka-topics.sh --zookeeper hadoop10:2181 -delete --topic firstTopic first is marked for deletion.Note: This will have no impact if delete.topic.enable is not set to true.1.4 发送音讯[v2admin@hadoop10 kafka]$ bin/kafka-console-producer.sh --broker-list hadoop10:9092 --topic demo>hello>world>haha>women>tintian1.5 生产音讯[v2admin@hadoop11 kafka]$ bin/kafka-console-consumer.sh --bootstrap-server hadoop10:9092 --from-beginning --topic demoworldwomenhellohahatintian1.6 查看某个topic^C[v2admin@hadoop11 kafka]$ bin/kafka-topics.sh --zookeeper hadoop10:2181 --describe --topic demoTopic: demo PartitionCount: 2 ReplicationFactor: 2 Configs: Topic: demo Partition: 0 Leader: 11 Replicas: 11,12 Isr: 12,11 Topic: demo Partition: 1 Leader: 12 Replicas: 12,10 Isr: 10,12二.Kafka架构图 ...

January 7, 2021 · 2 min · jiezi

关于kafka:kafka-入门与进阶

(一)Kafka初辨认更新中

January 6, 2021 · 1 min · jiezi

关于kafka:一Kafka初识别

一.Kafka概述1.1 音讯队列简介音讯队列就是一个寄存音讯的容器(MQ),当咱们须要应用音讯的应用能够从中取出音讯。次要类型有两种,点对点音讯队列和公布-订阅者音讯队列. 1.点对点音讯队列音讯生产者生产音讯发送到音讯队列中,而后音讯消费者从Queue中取出并且生产音讯。音讯被生产当前,Queue中不再有存储,所以音讯消费者不可能生产到曾经被生产的音讯。点对点音讯队列模式反对存在多个消费者,然而对一个音讯而言,只会有一个消费者能够生产。 2.公布-订阅音讯队列音讯生产者(公布)将音讯公布到topic中,同时有多个音讯消费者(订阅)生产该音讯。和点对点形式不同,公布到topic的音讯会被所有订阅者生产。数据被生产后不会立马删除。在公布-订阅音讯零碎中,音讯的生产者称为发布者,消费者称为订阅者。 1.2 kafka介绍Kafka是一个分布式的基于公布/订阅模式的音讯队列,具备高性能、长久化、多正本备份、横向扩大能力。生产者往队列里写音讯,消费者从队列里取音讯进行业务逻辑。个别在架构设计中起到解耦、削峰、异步解决的作用。次要利用场景是:日志收集零碎和音讯零碎。 1.3 Kafka术语在了解kafa之前,先理解下kafka的术语,见下图1)brokerkafka急大众蕴含一个或多个服务器,服务器节点就称之为broker。 2)Topic每条公布到kafk的音讯都有一个类别,这个类别就是topic。物理上不同Topic的音讯离开存储,逻辑上一个Topic的音讯尽管保留于一个或多个broker上但用户只需指定音讯的Topic即可生产或生产数据而不用关怀数据存于何处 3)Partitiontopic中的数据会被宰割为一个或者多个Partition。每个topic至多一个Partition。每个Partition中的数据应用多个segment文件存储。Partition中的数据是有序的,但不同的Partition间的数据失落数据的程序,如果topic有多个Partition,那生产数据时不能保证数据的程序,在须要严格保障音讯程序的场景下,Partition数据须要设置为1. 4)Producer生产者,就数据的发布者,它将数据公布到kafka的topic中。broker承受到发布者发送的音讯数据,将该音讯追加到以后用于追加数据的segment中。发布者发送的音讯,存储到一个Partition中,生产者也能够指定数据存储的Partition。 5)Consumer消费者也就是订阅者,从broker中读取数据,消费者能够读取多个topic中的数据。 6)Consumer Group每个Consumer属于一个特定的Consumer Group。 7)Leader每个Partition有多个正本,其中有且仅有一个作为Leader,Leader负责以后数据读写。 8)FollowerFollower追随Leader,所有读写申请都通过Leader,数据变更会播送给所有Follower,Follower与Leader保持数据同步。如果Leader生效,则从Follower中选举出一个新的Leader。当Follower与Leader挂掉、卡住或者同步太慢,leader会把这个follower从“in sync replicas”(ISR)列表中删除,从新创立一个Follower。 二.为什么应用kafka当然更精确的说,为什么要应用队列?kafka只是咱们抉择的队列。 2.1 解耦举一个例子,咱们有一个A零碎,它要把数据发到B、C两个零碎,这时候来了一个需要,D零碎说“我也须要A零碎的数据,你发过来吧”,负责A零碎的程序员开始改代码,没有费多少力量,批改好了。过了两天,D零碎说“我当初不须要A零碎的数据了。”A:“。。。。”又过了两天,D零碎“A零碎,不行啊,我还是得须要你的数据。”周而复始,负责A零碎的程序员“心态崩了。。。” 那咱们当初引入了Kafka,当然这并不只是Kafka的劣势,其余音讯队列同样能够实现解耦哦,具体依据业务状况来抉择,这里只说kafka。 有了kafka后,当初A的数据只发送到kafka中,其他人想要应用数据从kafka中取就是了。这样A零碎就跟其余零碎解耦了。 2.2 异步通信假设这样一个场景,还是A零碎,从浏览器承受了一个申请,在本人本地写库,速度1ms,之后须要BC两零碎也要写库,但速度要慢,B零碎须要600ms,C零碎须要500ms,这个时候用户从浏览器发动申请到失去相应须要1ms+600ms+800ms,那用户体验必定不好。 但应用音讯队列能够实现异步解耦A零碎取得申请后,发送两条音讯到音讯队列,假设只有2ms实现,之后A就能够响应用户了,总共耗时1ms+2ms,也就是3ms,那用户体验必定不差,这就是异步通信。 2.3 冗余有些状况下,解决数据的过程可能会失败,这时候数据除非被长久化,佛足额就会失落。音讯队列把数据进行长久化,直到他们曾经被齐全解决,通过这种形式躲避了数据失落的危险。 2.4 削峰还是举例,平时A零碎,每秒并发量也就是100左右,这时赶上双11,并发量可是能突增到50k以上,这对系统还有数据库的压力可是极大的,搞不好就把零碎搞解体了。就像咱们mysql,每秒2000多的并发申请就然而双11一过,又回到日常100左右并发。 这时候,我引入音讯队列,申请先进入音讯队列中,假设每秒5k个,A零碎从音讯队列拉取申请,每秒解决3k个,音讯队列以5k个申请进入,3k个申请被拉取出去,这样就能够顶住顶峰期间的拜访压力,不会因为突发的超顶峰负荷导致系统解体。 2.5 可恢复性A零碎把数据发到音讯队列中,B从音讯队列中拉取数据,忽然B挂掉了,但队列中保留的数据还在,所以当B复原后,还能够持续解决之前的数据。 3.罕用MQ介绍3.1 RabbitMQRabbitMQ是应用Erlang编写的一个开源的音讯队列,反对很多的协定:AMQP,XMPP, SMTP, STOMP。它反对多种语言,Python、Java、Ruby、C、PHP等,反对事务、公布确认和音讯长久化。那个很火的Openstack中用到的就是RabbitMQ。 3.2 RedisRedis是一个NoSql数据库,基于k-v对,尽管是一个k-v的NoSql数据,但自身反对MQ性能。同样很多语言都反对Redis,像会话缓存、音讯队列,还有流动排行榜等。对于RabbitMQ和Redis的入队和入列性能测试,对两者出入队操作,各执行100万次,每10万次记录一次执行工夫,测试数据别离为128Bytes、512Bytes、1K和10K四个不同大小的数据。结果表明:入队时,当数据比拟小时Redis的性能要高于RabbitMQ,而如果数据大小超过了10K,Redis则慢的无法忍受;出队时,无论数据大小,Redis都体现出十分好的性能,而RabbitMQ的出队性能则远低于Redis。 在抉择MQ时,要结合实际业务状况来抉择。Redis是轻量级、高并发、提早敏感,在做缓存、即时数据分析等场景能够思考。 3.3 ActiveMQ性能比拟差,版本迭代慢,当初应用的应该不多了。 3.4 RocketMQ阿里出品,Java系开源我的项目,参考文档:http://rocketmq.apache.org/ 3.5 KafkaApache下的一个子项目,这是一个分布式公布/订阅音讯队列零碎,咱们hadoop生态中,就应用kafka。

January 6, 2021 · 1 min · jiezi

关于kafka:kafka-消费者负载均衡实现

语言:java (spring boot),单台kafka场景:同一个组,两个消费者同时生产一个topic 实现过程: 首先批改这个topic的partitions./kafka-topics.sh --bootstrap-server localhost:9092 --alter --partitions 2 --topic topic-name而后批改我的项目配置文件spring: kafka: listener: concurrency: 2生产者代码 @SpringBootTestclass ProducerApplicationTests { @Autowired private KafkaTemplate<String, String> kafkaTemplate; @Test void contextLoads() { for (int i = 1; i <= 1000; i++) { kafkaTemplate.send("test_0105_jcy", String.valueOf(i)); System.out.println(i); } }}消费者代码(X2) @Slf4j@SpringBootApplicationpublic class Customer1Application { @KafkaListener(topics = "test_0105_jcy") public void consumerListener(String msg) throws InterruptedException { log.info(msg); Thread.sleep(1 * 1000); } public static void main(String[] args) { SpringApplication.run(Customer1Application.class, args); }}我的项目构造 ...

January 6, 2021 · 1 min · jiezi

关于kafka:kafka错误之-Topic-xxx-not-present-in-metadata-after-60000-ms

一、背景明天尝试应用 kafka 的 生产者 api 写一下,音讯发送,后果遇到以下问题,Topic xxx not present in metadata after 60000 ms,找了半天后果发现是jar包引入不全导致的,为防当前遗记,在此记录一下。 二、场景还原1、jar包引入<dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>2.6.0</version></dependency>2、jar代码public class KafkaProducerDemo { public static void main(String[] args) { Properties properties = new Properties(); properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "127.0.0.1:9092,127.0.0.1:9093,127.0.0.1:9094"); properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); properties.put(ProducerConfig.ACKS_CONFIG, "all"); properties.put(ProducerConfig.BUFFER_MEMORY_CONFIG, 33554432); properties.put(ProducerConfig.RETRIES_CONFIG, 0); properties.put(ProducerConfig.RETRY_BACKOFF_MS_CONFIG, 300); properties.put(ProducerConfig.BATCH_SIZE_CONFIG, 16384); // KafkaProducer 是线程平安的,能够多个线程应用用一个 KafkaProducer KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(properties); for (int i = 0; i < 100; i++) { ProducerRecord<String, String> record = new ProducerRecord<>("topic-a", "value - (" + i + 1 + ")"); kafkaProducer.send(record, new Callback() { @Override public void onCompletion(RecordMetadata metadata, Exception exception) { if (exception != null) { System.err.println("发送数据到kafka中,产生了异样."); exception.printStackTrace(); return; } System.out.println("topic: " + metadata.topic() + " offset: " + metadata.offset() + " partition: " + metadata.partition()); } }); } System.out.println("音讯发送实现"); kafkaProducer.close(); }}3、运行后果运行下面的代码呈现了 org.apache.kafka.common.errors.TimeoutException: Topic topic-a not present in metadata after 60000 ms 异样。 ...

January 4, 2021 · 1 min · jiezi

关于kafka:kafka的基本概念

一、基本概念1、brokerbroker 指的一个kafka服务器,一个kafka集群是由多个 kafka broker 组成。 2、producerproducer 指的是音讯生产者,即发送音讯到 kafka broker 的客户端。 3、consumerconsumer 指的音讯消费者,即从 kafka broker 获取音讯的客户端。 4、cousumer groupconsumer group 指的是消费者组,领有雷同的 group id 的消费者形成一个消费者组。 消费者组与消费者之间互不影响。消费者组内的每个消费者负责生产不同的分区的数据。一个分区只能有同一个分区中的一个消费者生产。5、topictopic 指的是主题。生产者生产音讯、消费者生产音讯,都须要指定一个topic。 6、partitionpartition 指的是分区。 一个 topic 能够存在多个分区。一个分区,只能被同一个音讯者组中的某一个消费者生产。每个分区上的音讯都是有序的,然而主题(topic)上的音讯不是有序的。每个分区可能存在多个follower,其中负责读/写的是leader。每个kafka broker能够是以后分区的leader,也能够是其它分区的follower。多个分区能够进步程序的并发性,因为一个分区只能一个分区音讯,多个分区能够多个消费者同时生产。7、replicasreplicas 指的是正本。数据冗余,保障集群的可用性。 leader 指的是topic主题的分区中,每个分区的 主 。生产者发送数据、消费者生产数据都是从 leader分区 中操作的。follower 指的是 topic主题的分区中,每个分区的 从。负责从leader分区同步数据,当 leader 宕机时,follower 可能成为新的 leader。默认是从 ISR 中进行选举。设置unclean.leader.election.enable = true能够从非ISR节点中进行选举,这样能够导致失落数据,默认值是false,倡议是false。ISR(in-sync replicas) 与leader放弃同步的follower汇合如果follower在超过 replica.lag.time.max.ms 毫秒,没有与leader进行同步,则踢出ISR。 OSR(out-sync replicas) 落后leader太多的正本AR ISR + OSR是否容许非ISR的正本参加选举。 二、生产者分区策略即生产者,发送发送音讯后,该音讯保留到kafka broker上的topic上的那个partition上。 1、默认分区策略默认的分区策略应用的是 org.apache.kafka.clients.producer.internals.DefaultPartitioner 这个类。即咱们代码中应用org.apache.kafka.clients.producer.ProducerRecord发送音讯时。 在指定了 partition 的状况下,间接应用指定的 分区。没有指定 partition 但指定了key的状况下,将key的hash值与topic的partition数进行取余失去partition值。 ...

January 3, 2021 · 2 min · jiezi

关于kafka:Kafka基本架构和命令

原文地址:https://github.com/WilburXu/b... Kafka体系架构 Broker服务代理节点服务代理节点。对于Kafka而言,Broker能够简略地看作一个独立的Kafka服务节点或Kafka服务实例。大多数状况下也能够将Broker看作一台Kafka服务器,前提是这台服务器上只部署了一个Kafka实例,一个或多个Broker组成了一个Kafka集群。 Producer和Consumer Producer生产者生产者,也就是发送音讯的一方。生产者负责创立音讯,而后将其投递到Kafka中。 一个失常的生产逻辑须要具备以下几个步骤: 创立生产者实例构建待发送的音讯发送音讯到指定的Topic、Partition、Key敞开生产者实例Consumer消费者消费者,也就是接管音讯的一方。消费者连贯到Kafka上并接管音讯,从而进行相应的业务逻辑解决。 生产个别有三种生产模式: 单线程模式 单个线程生产多个Partition 问题: 效率低,并发上不去可用性差,单个线程挂了,将无奈生产多线程模式独立消费者模式 和单线程模式相似,区别就是为每一个Partition独自起一个线程进行生产。 问题: 线程和并发减少了,然而单线程挂了,该线程的分区还是无奈生产。生产组模式 也是目前最罕用的生产模式,咱们能够创立多个生产实例并设置同一个group-id来辨别生产组,同一个生产组能够指定一个或多个Topic进行生产: 生产组自均衡(Rebalance),kafka会依据生产组实例数量和分区数量自均衡调配不会反复生产,同个组内kafka确保一个分区只会发往一个生产实例,防止反复生产高可用,当一个生产实例挂了,kafka会主动调整生产实例和分区的关系Topic主题Kafka中的音讯以主题为单位进行归类(逻辑概念,生产者负责将音讯发送到特定的主题(发送到Kafka集群中的每一条音讯都要指定一个主题),而消费者负责订阅主题并进行生产。 Partition分区物理分区,主题细分为了1或多个分区,一个分区只能属于单个主题,个别也会把分区称为主题分区(Topic-Partition)。 Segment理论存储数据的中央,Segment蕴含一个数据文件和一个索引文件。一个Partition有多个大小雷同的Segment,能够了解为Partition是在Segment之上进行的逻辑形象。 Kafka根本命令zookeeperbroker节点保留在zookeeper,所有须要: 进入zookeeper,而后 ./bin/zkCli.sh执行ls /brokers/ids查看broker详情kafka-log-dirs.sh --describe --bootstrap-server kafka:9092 --broker-list 1 topic查看列表kafka-topics.sh --list --zookeeper zookeeper:2181 创立 kafka-topics.sh --create --zookeeper zookeeper:2181 --replication-factor 1 --partitions 3 --topic [topic_name] 查看详情 kafka-topics.sh --describe --zookeeper zookeeper:2181 --topic [topic_name] 删除kafka-topics.sh --zookeeper zookeeper:2181 --delete --topic [topic_name] topic生产状况topic offset 最小kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list localhost:9092 -topic [topic_name] --time -2 ...

December 30, 2020 · 3 min · jiezi

关于kafka:Kafka基本架构和命令

原文地址:https://github.com/WilburXu/b... Kafka体系架构 Broker服务代理节点服务代理节点。对于Kafka而言,Broker能够简略地看作一个独立的Kafka服务节点或Kafka服务实例。大多数状况下也能够将Broker看作一台Kafka服务器,前提是这台服务器上只部署了一个Kafka实例,一个或多个Broker组成了一个Kafka集群。 Producer和Consumer Producer生产者生产者,也就是发送音讯的一方。生产者负责创立音讯,而后将其投递到Kafka中。 一个失常的生产逻辑须要具备以下几个步骤: 创立生产者实例构建待发送的音讯发送音讯到指定的Topic、Partition、Key敞开生产者实例Consumer消费者消费者,也就是接管音讯的一方。消费者连贯到Kafka上并接管音讯,从而进行相应的业务逻辑解决。 生产个别有三种生产模式: 单线程模式 单个线程生产多个Partition 问题: 效率低,并发上不去可用性差,单个线程挂了,将无奈生产多线程模式独立消费者模式 和单线程模式相似,区别就是为每一个Partition独自起一个线程进行生产。 问题: 线程和并发减少了,然而单线程挂了,该线程的分区还是无奈生产。生产组模式 也是目前最罕用的生产模式,咱们能够创立多个生产实例并设置同一个group-id来辨别生产组,同一个生产组能够指定一个或多个Topic进行生产: 生产组自均衡(Rebalance),kafka会依据生产组实例数量和分区数量自均衡调配不会反复生产,同个组内kafka确保一个分区只会发往一个生产实例,防止反复生产高可用,当一个生产实例挂了,kafka会主动调整生产实例和分区的关系Topic主题Kafka中的音讯以主题为单位进行归类(逻辑概念,生产者负责将音讯发送到特定的主题(发送到Kafka集群中的每一条音讯都要指定一个主题),而消费者负责订阅主题并进行生产。 Partition分区物理分区,主题细分为了1或多个分区,一个分区只能属于单个主题,个别也会把分区称为主题分区(Topic-Partition)。 Segment理论存储数据的中央,Segment蕴含一个数据文件和一个索引文件。一个Partition有多个大小雷同的Segment,能够了解为Partition是在Segment之上进行的逻辑形象。 Kafka根本命令zookeeperbroker节点保留在zookeeper,所有须要: 进入zookeeper,而后 ./bin/zkCli.sh执行ls /brokers/ids查看broker详情kafka-log-dirs.sh --describe --bootstrap-server kafka:9092 --broker-list 1 topic查看列表kafka-topics.sh --list --zookeeper zookeeper:2181 创立 kafka-topics.sh --create --zookeeper zookeeper:2181 --replication-factor 1 --partitions 3 --topic [topic_name] 查看详情 kafka-topics.sh --describe --zookeeper zookeeper:2181 --topic [topic_name] 删除kafka-topics.sh --zookeeper zookeeper:2181 --delete --topic [topic_name] topic生产状况topic offset 最小kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list localhost:9092 -topic [topic_name] --time -2 ...

December 30, 2020 · 3 min · jiezi

关于kafka:kafkaeagle监控界面搭建

一、背景在上一节中,咱们搭建了一个kafka集群,然而kafka集群在运行的过程中会产生各种数据,比方broker信息、集群信息、主题信息、消费者信息等等,而kafka本身没有提供一个图形化的监控界面,此处咱们应用kafka-eagle来搭建一个kafka的治理监控界面。 二 、mac上装置kafka-eagle1、装置JDK略 2、装置eagle1、下载eagle下载链接:http://download.kafka-eagle.org/ 2、解压并配置环境变量1、解压 tar -zxvf kafka-eagle-bin-2.0.3.tar.gz && cd kafka-eagle-bin-2.0.3 && tar -zxvf kafka-eagle-web-2.0.3-bin.tar.gz2、重命名 mv kafka-eagle-web-2.0.3 kafka-eagle 3、配置环境变量 vim /etc/profileexport KE_HOME=/Users/huan/soft/kafka/kafka-eagleexport PATH=$PATH:$KE_HOME/binsource /etc/profilecd ${KE_HOME}/binchomd +x ke.shKE_HOME 为eagle环境变量的名字。 3、启用kafka的JMX此配置是可选的,放开能够看到更多的监控信息。1、cd ${KAFKA_HOME}/bin2、vim kafka-server-start.sh if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then # export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G" export KAFKA_HEAP_OPTS="-server -Xms2G -Xmx2G -XX:PermSize=128m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=8 -XX:ConcGCThreads=5 -XX:InitiatingHeapOccupancyPercent=70" export JMX_PORT="9099"fiJMX_PORT 的端口能够给个没有占用的端口既可。 4、配置eagle1、cd ${KE_HOME}/conf 2、vim system-config.properties ####################################### multi zookeeper & kafka cluster list# 设置kafka的多集群,此处只须要给zk的地址既可######################################kafka.eagle.zk.cluster.alias=cluster1cluster1.zk.list=localhost:2181,localhost:3181,localhost:4181####################################### zookeeper enable acl######################################cluster1.zk.acl.enable=falsecluster1.zk.acl.schema=digestcluster1.zk.acl.username=testcluster1.zk.acl.password=test123####################################### broker size online list######################################cluster1.kafka.eagle.broker.size=20####################################### zk client thread limit######################################kafka.zk.limit.size=25####################################### kafka eagle webui port# kafka eagle 的前端拜访端口######################################kafka.eagle.webui.port=9090####################################### kafka jmx acl and ssl authenticate######################################cluster1.kafka.eagle.jmx.acl=falsecluster1.kafka.eagle.jmx.user=keadmincluster1.kafka.eagle.jmx.password=keadmin123cluster1.kafka.eagle.jmx.ssl=falsecluster1.kafka.eagle.jmx.truststore.location=/Users/dengjie/workspace/ssl/certificates/kafka.truststorecluster1.kafka.eagle.jmx.truststore.password=ke123456####################################### kafka offset storage# kafka集群的offset保留的地位,0.10及当前的kafka集群是保留在kafka中,之前的是保留在zookeeper中######################################cluster1.kafka.eagle.offset.storage=kafka####################################### kafka metrics, 15 days by default# 开启性能监控,数据默认保留的天数######################################kafka.eagle.metrics.charts=truekafka.eagle.metrics.retain=15####################################### kafka sql topic records max######################################kafka.eagle.sql.topic.records.max=5000####################################### delete kafka topic token# 删除kafka topic 时,须要输出的token值######################################kafka.eagle.topic.token=keadmin####################################### kafka sasl authenticate######################################cluster1.kafka.eagle.sasl.enable=falsecluster1.kafka.eagle.sasl.protocol=SASL_PLAINTEXTcluster1.kafka.eagle.sasl.mechanism=SCRAM-SHA-256cluster1.kafka.eagle.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="kafka" password="kafka-eagle";cluster1.kafka.eagle.sasl.client.id=cluster1.kafka.eagle.blacklist.topics=cluster1.kafka.eagle.sasl.cgroup.enable=falsecluster1.kafka.eagle.sasl.cgroup.topics=cluster2.kafka.eagle.sasl.enable=falsecluster2.kafka.eagle.sasl.protocol=SASL_PLAINTEXTcluster2.kafka.eagle.sasl.mechanism=PLAINcluster2.kafka.eagle.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="kafka" password="kafka-eagle";cluster2.kafka.eagle.sasl.client.id=cluster2.kafka.eagle.blacklist.topics=cluster2.kafka.eagle.sasl.cgroup.enable=falsecluster2.kafka.eagle.sasl.cgroup.topics=####################################### kafka ssl authenticate######################################cluster3.kafka.eagle.ssl.enable=falsecluster3.kafka.eagle.ssl.protocol=SSLcluster3.kafka.eagle.ssl.truststore.location=cluster3.kafka.eagle.ssl.truststore.password=cluster3.kafka.eagle.ssl.keystore.location=cluster3.kafka.eagle.ssl.keystore.password=cluster3.kafka.eagle.ssl.key.password=cluster3.kafka.eagle.blacklist.topics=cluster3.kafka.eagle.ssl.cgroup.enable=falsecluster3.kafka.eagle.ssl.cgroup.topics=####################################### kafka sqlite jdbc driver address#######################################kafka.eagle.driver=org.sqlite.JDBC#kafka.eagle.url=jdbc:sqlite:/hadoop/kafka-eagle/db/ke.db#kafka.eagle.username=root#kafka.eagle.password=www.kafka-eagle.org####################################### kafka mysql jdbc driver address# eagle数据保留的数据库,此处应用mysql######################################kafka.eagle.driver=com.mysql.jdbc.Driverkafka.eagle.url=jdbc:mysql://127.0.0.1:3306/ke?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNullkafka.eagle.username=rootkafka.eagle.password=root5、启动 eagleke.sh start ...

December 30, 2020 · 1 min · jiezi

关于kafka:kafka技术原理解析

前言:有好多同学留言说看不懂我之前写的博客——kafka利用实例篇,不明确外面的代码为什么那么写,我找到了本人之前写的对于kafka技术解析的ppt,现将局部重点及相干原理整理出来供大家参考。 1. 音讯队列介绍kafka定义:kafka是一个分布式的基于公布/订阅模式的音讯队列(message queue),次要利用于大数据实时处理畛域。音讯队列的定义两种模式的区别公布订阅模式如何实现实现了负载平衡? 2. 风行队列的模型比拟RabbitMQ生产端发送一条音讯通过路由投递到Queue,只有一个消费者能生产到。当RabbitMQ须要反对多订阅时,发布者发送的音讯通过路由同时写到多个Queue,不同订阅组生产此音讯。Kafka 3. Kafka架构留神1:一个主题中的一个分区中的音讯只能被一个消费者组中的一个消费者生产留神2:但如果是不同的消费者组能够呈现:一个分区中的音讯能够被不同消费者组中的多个消费者同时生产留神3:当一个消费者组中的消费者数大于分区数时:会造成消费者的资源节约留神4:当消费者数小于分区数:一个消费者能够同时生产两个消费者组中的音讯 4. Kafka生产过程剖析1.写入形式--producer采纳推(push)模式将音讯公布到broker 5. Kafka的存储策略文件存储形式

December 28, 2020 · 1 min · jiezi

关于kafka:入门-Kafka-你所需要了解的基本概念和开发模式

团队在日常工作中,个别状况下应用的音讯队列是腾讯云 CKafka。CKafka 提供了高牢靠的开箱即用音讯队列能力,让咱们在日常可能放心使用,缩小花在运维上的投入。不过即便如此,咱们还是须要学习 Kafka 的一些基本概念和性能,从而在理论利用中嗯可能充沛高效、高质量地利用 Kafka 的能力。 业务基本概念本大节次要阐明的是在软件业务层面,咱们应用 Kafka 中会接触到的概念 音讯 Message 对于一个音讯队列零碎,最根底的天然是 “音讯”。在 Kafka 中,“音讯” 就是 Message,是在 Kafka 中数据传输的根本单位。多个音讯会被分批次写入 Kafka 中。这同一批次的音讯,就称为一组音讯。 生产者和消费者 生产者和消费者的概念就很好了解了:产生音讯的服务就称为 “生产者” Producer,也称为 “发布者” Publisher 或 Writer。 而须要获取音讯的服务就称为 “消费者” Consumer,也称为 “订阅者” SubScriber 或 Reader。 主题 Topic 和 分区 Partition 在 Kafka 中,所有的音讯并不是还有一条队列。Kafka 的音讯通过 Topic 进行分类。而一个 Topic 能够被辨别为多个 “分区” Partitions。 这里须要留神的是,在 同一个 partition 外部,音讯的程序是可能保障的。也就是说:如果音讯A达到 partition 的工夫早于音讯B,那么消费者在获取音讯的时候,必然是先取得音讯A之后,才可能获取到音讯B。 然而,如果在多个 partitions 之间,音讯的程序就无奈保障了。比方当消费者监听多个 partitions 时的话,音讯A和音讯B被读取进去的工夫无奈保障。 ...

December 22, 2020 · 3 min · jiezi

关于kafka:异步消息处理机制之KAFKA应用实例

本我的项目采纳的是SpringMvc+原生JDBC开发的Java数据处理过程,用的是oracle数据库。我的项目整体目录如下: 我的项目中用到的消息中间件次要有activeMQ和KAFKA两种,本篇次要介绍KAFKAKAFKA数据的推和取,分为生产者和消费者。生产者定义一个topic,相当于一个数据队列,将数据推送至kafka的该topic下,消费者凭借该topic从kafka中按序列读取数据。实例代码实现如下:首先是oracle数据库配置文件 <?xml version="1.0" encoding="GB18030"?><!-- the proxool configuration can be embedded within your own application's.Anything outside the "proxool" tag is ignored. --><something-else-entirely> <proxool> <alias>gess</alias> <driver-url>jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=135.224.21.131)(PORT=1521))(ADDRESS = (PROTOCOL = TCP)(HOST = 135.224.21.133)(PORT=1521))(LOAD_BALANCE=yes)(FAILOVER=on))(CONNECT_DATA=(SERVICE_NAME=iam)(FAILOVER_MODE=(TYPE=SESSION)(METHOD=BASIC))))</driver-url> <!-- <driver-url>jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=135.224.21.133)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=135.224.21.131)(PORT=1521))(LOAD_BALANCE=yes)(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=iam2)))</driver-url>--> <!-- <driver-url>jdbc:oracle:thin:@//135.224.21.133:1521:iam2</driver-url> --> <driver-class>oracle.jdbc.driver.OracleDriver</driver-class> <driver-properties> <!-- <property name="user" value="c##scott"/> <property name="password" value="StCgzpt@12!qqz;"/> --> <property name="user" value="xjgzk"/> <property name="password" value="Gzk%^1202"/> </driver-properties> <maximum-connection-count>1000</maximum-connection-count> <minimum-connection-count>1</minimum-connection-count> <maximum-active-time>90000</maximum-active-time> <maximum-connection-lifetime>3600000</maximum-connection-lifetime> <house-keeping-test-sql>select CURRENT_DATE from DUAL</house-keeping-test-sql> </proxool></something-else-entirely>程序入口,main办法主体 /** * */package com.ustcinfo.kanms.alarmcollector.main;import java.text.ParseException;import com.ustcinfo.kanms.alarmcollector.framework.GesAlarmAnalysisInDBThreads;import com.ustcinfo.kanms.alarmcollector.framework.GesAlarmInDBThreads;import com.ustcinfo.kanms.alarmcollector.framework.UnusualAlarmAnalysisThreads;import com.ustcinfo.kanms.alarmcollector.kafka.kafkaMessageReceiver;/** * ================================================= <br> * 工程:GessAlarmCollector <br> * 类名:MainProcess <br> * 作者:lt <br> * 工夫:2019-9-18下午02:57:59<br> * 版本:Version 1.0 <br><br> * 形容:零碎入口<br> * ================================================= <br> */public class MainProcess { /** * 零碎入口 * @param args * @throws ParseException */ public static void main(String[] args) throws ParseException { // 初始化零碎配置文件 GlobleConfiguration.getInstance().initSysConfig(); //启动Kafka consumer监督,获取告警数据 new kafkaMessageReceiver(2).start(); //启动数据入库线程(瞬断入库) new GesAlarmInDBThreads(2); //非瞬断告警剖析入库 new GesAlarmAnalysisInDBThreads(3); //异样告警查问对应流动告警 new UnusualAlarmAnalysisThreads(2); }}全局化参数定义 ...

December 18, 2020 · 11 min · jiezi

关于kafka:消息队列简介

音讯队列什么是音讯队列举一个简略的例子:在网上买了海鲜,快递小哥给我送快递的时候我正好在下班,家中无人签收。而快递又不能推延送,可能会造成海鲜腐坏,而快递小哥还须要派送其他人的快递,此时就陷入了僵局。 此时家中楼下正好有一个便利店,快递小哥将快递放入便利店,而我上班后再去便利店中取。这样就防止了僵局的产生。 原来快递小哥和我之间的分割就变成了快递小哥和便利店分割,而我回去后或有工夫了再和便利店分割。便利店成为了中转地。 例子中的便利店便相当于音讯队列,而快递小哥相当于生产者。我相当于消费者。这就是音讯的三个重要组成。而音讯队列有蕴含很多其余的重要组成。 在上边的例子中音讯队列的次要作用是解耦合。 音讯队列的作用还有削峰填谷,异步解决,日志解决,音讯通信等 音讯队列的劣势同异步解决流程比照:同步解决异步解决减少零碎响应速度 削峰填谷: 服务器在接管到用户申请后,首先写入音讯队列。这时如果音讯队列中音讯数量超过最大数量,则间接回绝用户申请或返回跳转到谬误页面;秒杀业务依据秒杀规定读取音讯队列中的申请信息,进行后续解决。日志解决: 日志采集客户端:负责日志数据采集,定时写受写入Kafka队列;Kafka音讯队列:负责日志数据的接管,存储和转发;日志解决利用:订阅并生产kafka队列中的日志数据; Kafka:接管用户日志的音讯队列。Logstash:做日志解析,对立成JSON输入给Elasticsearch。Elasticsearch:实时日志剖析服务的核心技术,一个schemaless,实时的数据存储服务,通过index组织数据,兼具弱小的搜寻和统计性能。Kibana:基于Elasticsearch的数据可视化组件,超强的数据可视化能力是泛滥公司抉择ELK stack的重要起因。音讯通信:点对点通信架构设计中,客户端A和客户端B共用一个音讯队列,即可实现音讯通信性能。客户端A、客户端B、直至客户端N订阅同一音讯队列,进行音讯的公布与接管,即可实现聊天通信计划架构设计。 音讯队列的毛病零碎可用性升高:零碎可用性在某种程度上升高,在退出MQ之前,你不必思考音讯失落或者说MQ挂掉等等的状况,然而,引入MQ之后你就须要去思考了。零碎复杂性进步: 退出MQ之后,你须要保障音讯没有被反复生产、解决音讯失落的状况、保障消息传递的程序性等等问题!一致性问题: 我下面讲了音讯队列能够实现异步,音讯队列带来的异步的确能够进步零碎响应速度。然而,万一音讯的真正消费者并没有正确生产音讯怎么办?这样就会导致数据不统一的状况了!音讯队列的标准规范JMS(JAVA Message Service,java音讯服务)是java的音讯服务,JMS的客户端之间能够通过JMS服务进行异步的音讯传输。JMS(JAVA Message Service,Java音讯服务)API是一个音讯服务的规范或者说是标准,容许应用程序组件基于JavaEE平台创立、发送、接管和读取音讯。它使分布式通信耦合度更低,音讯服务更加牢靠以及异步性。 JMS两种音讯模型①点到点(P2P)模型 应用队列(Queue)作为音讯通信载体;满足生产者与消费者模式,一条音讯只能被一个消费者应用,未被生产的音讯在队列中保留直到被生产或超时。比方:咱们生产者发送100条音讯的话,两个消费者来生产个别状况下两个消费者会依照音讯发送的程序各自生产一半(也就是你一个我一个的生产。) ② 公布/订阅(Pub/Sub)模型 公布订阅模型(Pub/Sub) 应用主题(Topic)作为音讯通信载体,相似于播送模式;发布者公布一条音讯,该音讯通过主题传递给所有的订阅者,在一条音讯播送之后才订阅的用户则是收不到该条音讯的。 JMS 五种不同的音讯注释格局JMS定义了五种不同的音讯注释格局,以及调用的音讯类型,容许你发送并接管以一些不同模式的数据,提供现有音讯格局的一些级别的兼容性。 StreamMessage -- Java原始值的数据流MapMessage--一套名称-值对TextMessage--一个字符串对象ObjectMessage--一个序列化的 Java对象BytesMessage--一个字节的数据流AMQP AMQP,即Advanced Message Queuing Protocol,一个提供对立音讯服务的应用层规范 高级音讯队列协定(二进制应用层协定),是应用层协定的一个凋谢规范,为面向音讯的中间件设计,兼容 JMS。基于此协定的客户端与消息中间件可传递音讯,并不受客户端/中间件同产品,不同的开发语言等条件的限度。 JMS vs AMQP AMQP 为音讯定义了线路层(wire-level protocol)的协定,而JMS所定义的是API标准。在 Java 体系中,多个client均能够通过JMS进行交互,不须要利用批改代码,然而其对跨平台的反对较差。而AMQP人造具备跨平台、跨语言个性。JMS 反对TextMessage、MapMessage 等简单的音讯类型;而 AMQP 仅反对 byte[] 音讯类型(简单的类型可序列化后发送)。因为Exchange 提供的路由算法,AMQP能够提供多样化的路由形式来传递音讯到音讯队列,而 JMS 仅反对 队列 和 主题/订阅 形式两种。音讯队列比照 ActiveMQ 的社区算是比拟成熟,然而较目前来说,ActiveMQ 的性能比拟差,而且版本迭代很慢,不举荐应用。RabbitMQ 在吞吐量方面尽管稍逊于 Kafka 和 RocketMQ ,然而因为它基于 erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。然而也因为 RabbitMQ 基于 erlang 开发,所以国内很少有公司有实力做erlang源码级别的钻研和定制。如果业务场景对并发量要求不是太高(十万级、百万级),那这四种音讯队列中,RabbitMQ 肯定是你的首选。如果是大数据畛域的实时计算、日志采集等场景,用 Kafka 是业内规范的,相对没问题,社区活跃度很高,相对不会黄,何况简直是全世界这个畛域的事实性标准。RocketMQ 阿里出品,Java 系开源我的项目,源代码咱们能够间接浏览,而后能够定制本人公司的MQ,并且 RocketMQ 有阿里巴巴的理论业务场景的实战考验。RocketMQ 社区活跃度绝对较为个别,不过也还能够,文档相对来说简略一些,而后接口这块不是依照规范 JMS 标准走的有些零碎要迁徙须要批改大量代码。还有就是阿里出台的技术,你得做好这个技术万一被摈弃,社区黄掉的危险,那如果你们公司有技术实力我感觉用RocketMQ 挺好的kafka 的特点其实很显著,就是仅仅提供较少的外围性能,然而提供超高的吞吐量,ms 级的提早,极高的可用性以及可靠性,而且分布式能够任意扩大。同时 kafka 最好是撑持较少的 topic 数量即可,保障其超高吞吐量。kafka 惟一的一点劣势是有可能音讯反复生产,那么对数据准确性会造成极其轻微的影响,在大数据畛域中以及日志采集中,这点轻微影响能够疏忽这个个性人造适宜大数据实时计算以及日志收集。转载:https://www.jianshu.com/p/689...转载:https://www.jianshu.com/p/36a... ...

December 17, 2020 · 1 min · jiezi

关于kafka:kafka集群的搭建

一、背景最近在学习 kafka,此处记录一下 mac上 搭建 kafka集群的步骤。 二、装置软件因为 kafka 依赖 zookeeper 因而须要装置 zookeeper,而kafka是基于scala语言编写,scala又是基于 jdk的,因而须要装置 jdk。1、 JDK , 举荐在 jdk8 及以上的版本,此处装置 jdk 略。2、zookeeper , 在本机搭建一个 3 个节点的 zk 伪集群。3、kafka 在本地搭建一个3个节点的 kafka 集群。 三、装置步骤1、搭建一个 3 个节点的 zk 伪集群ip客户端连贯端口集群选举接口集群原子播送接口server.id中id的值节点名,目前没用到,这个配置到hosts文件中127.0.0.1218112888138881zk01127.0.0.1318122888238882zk02127.0.0.1418132888338883zk03留神:1、server.id的中的id的配置是在 zoo.cfg配置文件的 dataDir 配置项指定的目录中 创立 myid文件指定的。 1、下载 zookeeper 安装包get https://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.6.2/apache-zookeeper-3.6.2-bin.tar.gz2、解压三份,并搁置在 zookeeper 目录中 3、批改 zookeeper 配置文件,此处以 zk01 为例子1、批改 conf 目录下的 zoo_sample.cfg 为 zoo.cfg2、编辑 zoo.cfg 配置文件留神:1、此处拿 zk01 为示例编写,因为是本地上启动多个,所以 需要批改端口2、各个服务器上的 myid 文件对应的值 都应该不一样,且惟一。3、dataDir 的门路须要批改。4、其余的配置能够看着批改,看具体的状况。 5、启动3个zk节点别离进入到 zk01/bin,zk02/bin,zk03/bin目录下执行 如下命令 ...

December 13, 2020 · 1 min · jiezi

关于kafka:spring-kafka之如何批量给topic加前缀

前言最近业务开发部门给咱们部门提了一个需要,因为他们开发环境和测试环境共用一套kafka,他们心愿咱们部门能帮他们实现主动给kafka的topic加上环境前缀,比方开发环境,则topic为dev_topic,测试环境,则topic为test_topic,他们kafka客户端是应用spring-kafka。一开始接到这个需要的时候,我心里是回绝的,为啥开发环境和测试环境不别离部署一套kafka,还要那么麻烦。但老大都许可接这个需要了,作为小罗罗也只能接了 实现思路1、生产者端能够通过生产者拦截器,来给topic加前缀 2、实现步骤a、编写一个生产者拦截器@Slf4jpublic class KafkaProducerInterceptor implements ProducerInterceptor<String, MessageDTO> { /** * 运行在用户主线程中,在音讯被序列化之前调用 * @param record * @return */ @Override public ProducerRecord<String, MessageDTO> onSend(ProducerRecord<String, MessageDTO> record) { log.info("原始topic:{}",record.topic()); return new ProducerRecord<String, MessageDTO>(TOPIC_KEY_PREFIX + record.topic(), record.partition(),record.timestamp(),record.key(), record.value()); } /** * 在音讯被应答之前或者音讯发送失败时调用,通常在producer回调逻辑触发之前,运行在produer的io线程中 * @param metadata * @param exception */ @Override public void onAcknowledgement(RecordMetadata metadata, Exception exception) { log.info("理论topic:{}",metadata.topic()); } /** * 清理工作 */ @Override public void close() { } /** * 初始化工作 * @param configs */ @Override public void configure(Map<String, ?> configs) { }b、配置拦截器kafka: producer: # 生产者拦截器配置 properties: interceptor.classes: com.github.lybgeek.kafka.producer.interceptor.KafkaProducerInterceptorc、测试 ...

December 5, 2020 · 2 min · jiezi

关于kafka:从Kafka到NIO

在谈NIO之前,简略回顾下内核态和用户态 内核空间是Linux内核运行的空间,而用户空间是用户程序的运行空间,为了保障内核平安,它们之间是隔离的,即便用户的程序解体了,内核也不受影响。内核空间能够执行任意命令,调用零碎的所有资源,用户空间只能执行简略运算,不能间接调用系统资源(I/O,过程资源,内存调配,外设,计时器,网络通信等),必须通过零碎接口(又称 system call),能力向内核收回指令。 用户过程通过零碎调用拜访系统资源的时候,须要切换到内核态,而这对应一些非凡的堆栈和内存环境,必须在零碎调用前建设好。而在零碎调用完结后,cpu会从内核态切回到用户态,而堆栈又必须复原成用户过程的上下文。而这种切换就会有大量的耗时。 过程缓冲区个别程序在读取文件的时候先申请一块内存数组,称为buffer,而后每次调用read,读取设定字节长度的数据,写入buffer。(用较小的次数填满buffer)。之后的程序都是从buffer中获取数据,当buffer应用完后,在进行下一次调用,填充buffer。这里的buffer咱们称为用户缓冲区,它的目标是为了缩小频繁I/O操作而引起频繁的零碎调用,从而升高操作系统在用户态与外围态切换所消耗的工夫。 内核缓冲区除了在过程中设计缓冲区,内核也有本人的缓冲区。 当一个用户过程要从磁盘读取数据时,内核个别不间接读磁盘,而是将内核缓冲区中的数据复制到过程缓冲区中。 但若是内核缓冲区中没有数据,内核会把对数据块的申请,退出到申请队列,而后把过程挂起,为其它过程提供服务。 等到数据曾经读取到内核缓冲区时,把内核缓冲区中的数据读取到用户过程中,才会告诉过程,当然不同的io模型,在调度和应用内核缓冲区的形式上有所不同。 你能够认为,read是把数据从内核缓冲区复制到过程缓冲区。write是把过程缓冲区复制到内核缓冲区。 当然,write并不一定导致内核的写动作,比方os可能会把内核缓冲区的数据积攒到一定量后,再一次写入。这也就是为什么断电有时会导致数据失落。 所以,咱们进行IO操作的申请过程如下:用户过程发动申请(调用零碎函数),内核接管到申请后(过程会从用户态切换到内核态),从I/O设施中获取数据到内核buffer中,再将内核buffer中的数据copy到用户过程的地址空间,该用户过程获取到数据后再响应客户端。 I/O复用模型JavaNIO应用了I/O复用模型 从图中能够看出,咱们阻塞在select调用,期待数据报套接字变为可读。当select返回套接字可读这一条件的时候,咱们调用recvfrom把所读数据从内核缓冲区复制到利用过程缓冲区。 那么内核态怎么判断I/O流可读可写?内核针对读缓冲区和写缓冲区来判断是否可读可写而java从1.5开始就应用epoll代替了之前的select,它对select有所加强,比拟有特点的是epoll反对程度触发(epoll默认)和边缘触发两种形式。 epoll比select高效次要几种在两点,这个能够参考知乎的这个答复(https://www.zhihu.com/questio... 缩小用户态和内核态之间的文件句柄拷贝缩小对可读可写文件句柄的遍历epoll和NIO的操作形式对应图如下: epoll_ctl 注册事件epoll_wait 轮询所有的socket解决对应的事件epoll中比拟乏味的是程度触发(LT)和边缘触发(ET)。 程度触发(条件触发):读缓冲区只有不为空,就始终会触发读事件;写缓冲区只有不满(发送得速度比写得速度快),就始终会触发写事件。这个比拟合乎编程习惯,也是epoll的缺省模式。 边缘触发(状态触发):读缓冲区的状态,从空转为非空的时候,触发1次;写缓冲区的状态,从满转为非满的时候,触发1次。比方你发送一个大文件,把写缓存区塞满了,之后缓存区能够写了,就会产生一次从满到不满的切换。 通过剖析,咱们能够看出: 对于LT模式,要防止"写的死循环"问题:写缓冲区为满的概率很小,也就是"写的条件"会始终满足,所以如果你注册了写事件,没有数据要写,但它会始终触发,所以在LT模式下,写完数据,肯定要勾销写事件。 对应ET模式,要防止"short read"问题:比方你收到100个字节,它触发1次,但你只读到了50个字节,剩下的50个字节不读,它也不会再次触发,此时这个socket就废了。因而在ET模式,肯定要把"读缓冲区"的数据读完。 验证代码太长了,我就只列出一段服务器端的次要代码,client端的比较简单,写法和server端也相似就不列出来了 Selector selector = Selector.open();// 创立通道ServerSocketChannelServerSocketChannel serverSocketChannel = ServerSocketChannel.open();// 将通道设置为非阻塞serverSocketChannel.configureBlocking(false);ServerSocket serverSocket = serverSocketChannel.socket();serverSocket.bind(new InetSocketAddress(8989));/*** 将通道(Channel)注册到通道管理器(Selector),并为该通道注册selectionKey.OP_ACCEPT事件* 注册该事件后,当事件达到的时候,selector.select()会返回,* 如果事件没有达到selector.select()会始终阻塞。*/serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);// 循环解决while (true) { // 当注册事件达到时,办法返回,否则该办法会始终阻塞 selector.select(); // 获取监听事件 Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); // 迭代解决 while (iterator.hasNext()) { // 获取事件 SelectionKey key = iterator.next(); // 移除事件,防止反复解决 iterator.remove(); // 客户端申请连贯事件,承受客户端连贯就绪 if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel socketChannel = server.accept(); socketChannel.configureBlocking(false); // 给通道设置写事件,客户端监听到写事件后,进行读取操作 socketChannel.register(selector, SelectionKey.OP_WRITE); } else if(key.isWritable()) { System.out.println("write"); handleWrite(key); } }}当client连贯上server的时候就会发现server始终收到写事件,write会始终打印。所以应用条件触发的API 时,如果应用程序不须要写就不要关注socket可写的事件,否则就会有限次的立刻返回一个write ready告诉。大家罕用的select就是属于条件触发这一类,长期关注socket写事件会呈现CPU 100%的故障。所以在应用Java的NIO编程的时候,在没有数据能够往外写的时候要勾销写事件,在有数据往外写的时候再注册写事件。 ...

November 18, 2020 · 1 min · jiezi

关于kafka:史上最全最详细的-kafka-学习笔记

一、为什么须要音讯零碎1.解耦:容许你独立的扩大或批改两边的处理过程,只有确保它们恪守同样的接口束缚。 2.冗余:音讯队列把数据进行长久化直到它们曾经被齐全解决,通过这一形式躲避了数据失落危险。许多音讯队列所采纳的"插入-获取-删除"范式中,在把一个音讯从队列中删除之前,须要你的解决零碎明确的指出该音讯曾经被处理完毕,从而确保你的数据被平安的保留直到你应用结束。 3.扩展性:因为音讯队列解耦了你的处理过程,所以增大音讯入队和解决的频率是很容易的,只有另外减少处理过程即可。 4.灵活性 & 峰值解决能力:在访问量剧增的状况下,利用依然须要持续发挥作用,然而这样的突发流量并不常见。如果为以能解决这类峰值拜访为规范来投入资源随时待命无疑是微小的节约。应用音讯队列可能使要害组件顶住突发的拜访压力,而不会因为突发的超负荷的申请而齐全解体。 5.可恢复性:零碎的一部分组件生效时,不会影响到整个零碎。音讯队列升高了过程间的耦合度,所以即便一个解决音讯的过程挂掉,退出队列中的音讯依然能够在零碎复原后被解决。 6.程序保障:在大多应用场景下,数据处理的程序都很重要。大部分音讯队列原本就是排序的,并且能保证数据会依照特定的程序来解决。(Kafka 保障一个 Partition 内的音讯的有序性) 7.缓冲:有助于管制和优化数据流通过零碎的速度,解决生产音讯和生产音讯的处理速度不统一的状况。 8.异步通信:很多时候,用户不想也不须要立刻解决音讯。音讯队列提供了异步解决机制,容许用户把一个音讯放入队列,但并不立刻解决它。想向队列中放入多少音讯就放多少,而后在须要的时候再去解决它们。 二、kafka 架构2.1 拓扑构造如下图: 图.1 2.2 相干概念如图.1中,kafka 相干名词解释如下: 1.producer: 音讯生产者,公布音讯到 kafka 集群的终端或服务。2.broker: kafka 集群中蕴含的服务器。3.topic: 每条公布到 kafka 集群的音讯属于的类别,即 kafka 是面向 topic 的。4.partition: partition 是物理上的概念,每个 topic 蕴含一个或多个 partition。kafka 调配的单位是 partition。5.consumer: 从 kafka 集群中生产音讯的终端或服务。6.Consumer group: high-level consumer API 中,每个 consumer 都属于一个 consumer group,每条音讯只能被 consumer group 中的一个 Consumer 生产,但能够被多个 consumer group 生产。7.replica: partition 的正本,保障 partition 的高可用。8.leader: replica 中的一个角色, producer 和 consumer 只跟 leader 交互。9.follower: replica 中的一个角色,从 leader 中复制数据。10.controller: kafka 集群中的其中一个服务器,用来进行 leader election 以及 各种 failover。11.zookeeper: kafka 通过 zookeeper 来存储集群的 meta 信息。2.3 zookeeper 节点kafka 在 zookeeper 中的存储构造如下图所示: 图.2 三、producer 公布音讯3.1 写入形式producer 采纳 push 模式将音讯公布到 broker,每条音讯都被 append 到 patition 中,属于程序写磁盘(程序写磁盘效率比随机写内存要高,保障 kafka 吞吐率)。 3.2 音讯路由producer 发送音讯到 broker 时,会依据分区算法抉择将其存储到哪一个 partition。其路由机制为: 指定了 patition,则间接应用;未指定 patition 但指定 key,通过对 key 的 value 进行hash 选出一个 patitionpatition 和 key 都未指定,应用轮询选出一个 patition。附上 java 客户端分区源码,高深莫测: ...

November 15, 2020 · 5 min · jiezi

关于kafka:优雅的使用Kafka-Consumer

如何生产数据咱们曾经晓得了如何发送数据到Kafka,既然有数据发送,那么必定就有数据生产,消费者也是Kafka整个体系中不可短少的一环 public class KafkaConsumerDemo {public static void main(String[] args) throws InterruptedException { Properties props = new Properties(); // 必须设置的属性 props.put("bootstrap.servers", "192.168.239.131:9092"); props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("group.id", "group1"); // 可选设置属性 props.put("enable.auto.commit", "true"); // 主动提交offset,每1s提交一次 props.put("auto.commit.interval.ms", "1000"); props.put("auto.offset.reset","earliest "); props.put("client.id", "zy_client_id"); KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); // 订阅test1 topic consumer.subscribe(Collections.singletonList("test1")); while(true) { // 从服务器开始拉取数据 ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100)); records.forEach(record -> { System.out.printf("topic = %s ,partition = %d,offset = %d, key = %s, value = %s%n", record.topic(), record.partition(), record.offset(), record.key(), record.value()); }); } }}push 还是 pullKafka Consumer采纳的是被动拉取broker数据进行生产的。个别消息中间件存在推送(server推送数据给consumer)和拉取(consumer被动取服务器取数据)两种形式,这两种形式各有优劣。 ...

November 13, 2020 · 2 min · jiezi

关于kafka:Kafka-Producer消息收发设计

前几篇文章剖析了Kafka的发送流程以及NIO的应用形式,然而还是留下了不少坑,这里就对剩下的问题做一个总结。 收到的数据为什么要缓存起来?Kafka中Selector读取从远端回来的数据的时候会先把收到的数据缓存起来 private void attemptRead(SelectionKey key, KafkaChannel channel) throws IOException { //if channel is ready and has bytes to read from socket or buffer, and has no //previous receive(s) already staged or otherwise in progress then read from it if (channel.ready() && (key.isReadable() || channel.hasBytesBuffered()) && !hasStagedReceive(channel) && !explicitlyMutedChannels.contains(channel)) { NetworkReceive networkReceive; while ((networkReceive = channel.read()) != null) { madeReadProgressLastPoll = true; addToStagedReceives(channel, networkReceive); } }}在NetworkClient中,往下传的是一个残缺的ClientRequest,进到Selector,暂存到channel中的,也是一个残缺的Send对象(1个数据包)。但这个Send对象,交由底层的channel.write(Bytebuffer b)的时候,并不一定一次能够齐全发送,可能要调用屡次write,能力把一个Send对象齐全收回去。这是因为write是非阻塞的,不是等到齐全收回去,才会返回。 ...

November 10, 2020 · 1 min · jiezi

关于kafka:Kafka为consumeroffset设置自动清理规则

此法可能有危险,还请读完文章再操作。 本文中的命令能够在Kafka非启动状态下执行。 起因Kafka服务器在运行几个月后,存储空间耗尽了。剖析Kafka的占用空间状况,发现Kafka主动生成的“__consumer_offset”topic,占用了大量空间,它用于记录每个用户topic的生产偏移量。这一topic实用的清理规定与其余topic不同,某些非凡状况下,它可能始终得不到清理,耗尽服务器资源。 查看清理策略因为服务器上的Kafka版本较老,这里应用的参数是--zookeeper,而非−−bootstrap-server参数。 应用以下命令查看清理策略:./kafka-configs.sh --zookeeper zk01:2181,zk02:2181,zk03:2181/kafka --entity-type topics --entity-name __consumer_offsets --describe在这台服务器上,失去了上面后果:Configs for topics:__consumer_offsets are segment.bytes=104857600,cleanup.policy=compact,compression.type=uncompressed翻译一下就是:每个文件块大小100MB,清理策略为压缩,压缩策略为不压缩。那当然服务器空间会被用完了。 解决首先,将解决__consumer_offset的非凡清理策略删除:./kafka-configs.sh --zookeeper zk01:2181,zk02:2181,zk03:2181/kafka --entity-type topics --entity-name __consumer_offsets --alter --delete-config cleanup.policy据说这样曾经能够让这里的清理策略与一般topic统一了,然而以防万一,再手动增加一组清理策略:./kafka-configs.sh --zookeeper zk01:2181,zk02:2181,zk03:2181/kafka --alter --entity-name __consumer_offsets --entity-type topics --add-config retention.ms=604800000./kafka-configs.sh --zookeeper zk01:2181,zk02:2181,zk03:2181/kafka --alter --entity-name __consumer_offsets --entity-type topics --add-config cleanup.policy=delete 这两行命令将__consumer_offset的清理逻辑调整为“清理7天前数据,清理策略为删除” 之后,将Kafka运行起来,就能看见大量数据被标记删除,静静期待一分钟(如果延时参数没被调整的话),Kafka就会主动将7天前的数据删除了。后续也不用操心服务器空间问题。 危险尽管服务器空间问题失去了解决,但也有一个疑难:这是否会导致一些分区的offset记录隐没,导致反复生产?举例来说:一个topic有200条记录,消费者在8天前生产了100条,这8天内无消费者生产,也无生产者生产。那么如果这个消费者在明天去生产,因为之前的生产记录超过7天无变动,很有可能已被删除。那消费者是否会从0号音讯开始生产?目前的环境中,topic保留数据也有7天的限度,躲避了这个问题,但它的确有导致一些问题的可能。

November 9, 2020 · 1 min · jiezi

关于kafka:Kafka-Producer网络层源码分析

上一篇讲了Kafka Producer发送音讯的主体流程,这一篇咱们关注下Kafka的网络层是如何实现的。对于发送音讯而言,Producer是客户端,Broker是服务器端。Kafka应用了JavaNIO向服务器发送音讯,所以在这之前须要理解java nio的基本知识。这次网络层源码剖析从metadata request切入。 开局一张图 下面是Kafka producer网络层的主体流程,先看下有一个大体印象。 Kafka的底层应用的是Java NIO,Kafka中针对NIO的Selector的封装类也叫Selector,对Channel的封装类叫做KafkaChannel。前面如果没有非凡阐明,Selector都是指Kafka中的Selector。 metadata request先来回顾下Kafka 发送音讯的代码 KafkaProducer<String,String> producer = createProducer();for (int i = 0; i < 10;i++) { producer.send(new ProducerRecord<>("codeTest","key" + (i+1),"value" + (i+1)));}下面的代码中首先会初始化KafkaProducer,在初始化KafkaProducer的时候,同时咱们也会初始化Kafka发送音讯的客户端 KafkaClient client = kafkaClient != null ? kafkaClient : new NetworkClient( new Selector(config.getLong(ProducerConfig.CONNECTIONS_MAX_IDLE_MS_CONFIG), this.metrics, time, "producer", channelBuilder, logContext), ...);创立NetworkClient(implements KafkaClient)的同时会创立一个Selector,这个是对java.nio.Selector的封装,发送申请,接管响应,解决连贯实现以及现有的断开连接都是通过它的poll()办法调用实现的。 期待metadata更新咱们都晓得Kafka读写音讯都是通过leader的,只有晓得了leader能力发送音讯到kafka,在咱们的你好,Kafka)一文中,咱们讲了首先会发动metadata request,从中就能够获取到集群元信息(leader,partiton,ISR列表等),那么是在哪里发动metadata request的呢? 调用KafkaProducer的doSend()(send()-->doSend())办法时,第一步就是通过waitOnMetadata期待集群元数据(topic,partition,node等)可用。 Cluster cluster = metadata.fetch();Integer partitionsCount = cluster.partitionCountForTopic(topic);//如果此时曾经有partition的信息了if (partitionsCount != null && (partition == null || partition < partitionsCount)) return new ClusterAndWaitTime(cluster, 0);do { int version = metadata.requestUpdate(); //唤醒Sender()线程,Sender会被poll阻塞(参见java.nio.Channels.Selector.poll()) sender.wakeup(); //期待metadata的更新,会始终阻塞直到以后版本大于最近一次版本 metadata.awaitUpdate(version, remainingWaitMs); cluster = metadata.fetch(); elapsed = time.milliseconds() - begin; remainingWaitMs = maxWaitMs - elapsed; partitionsCount = cluster.partitionCountForTopic(topic);} while (partitionsCount == null);如果metadata中不蕴含对应topic的metadata信息,那么就申请更新metadata,如果没有更新则始终会在这个while循环中,这个循环次要做了以下几件事 ...

November 9, 2020 · 4 min · jiezi

关于kafka:五Kafka的消费者原理及使用详解

消费者和消费者群组1. 一个消费者从一个Topic中生产数据 : 2. 消费者群组 : 当生产者向 Topic 写入音讯的速度超过了现有消费者的处理速度,此时须要对消费者进行横向伸缩,用多个消费者从同一个主题读取音讯,对音讯进行分流。同一个分区不能被一个组中的多个 consumer 生产。 Kafka消费者代码样例读取Kafka音讯只须要创立一个KafkaConsumer,除此之外还须要应用四个根本属性,bootstrap.servers、key.deserializer、value.deserializer和group.id。 import java.util.Arrays;import java.util.Properties;import org.apache.kafka.clients.consumer.ConsumerRecord;import org.apache.kafka.clients.consumer.ConsumerRecords;import org.apache.kafka.clients.consumer.KafkaConsumer;import org.apache.kafka.common.TopicPartition;/** * @Author Natasha * @Description * @Date 2020/11/3 14:14 **/public class ConsumerDemo { public static void main(String[] args) { Properties properties = new Properties(); //bootstrap.servers是broker服务器列表 properties.put("bootstrap.servers", "120.27.233.226:9092"); //group.id是指是消费者的生产组 properties.put("group.id", "test"); //key.deserializer和value.deserializer是用来做反序列化的,也就是将字节数组转换成对象 properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); properties.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); properties.put("enable.auto.commit", "true"); properties.put("auto.commit.interval.ms", "1000"); properties.put("auto.offset.reset", "earliest"); properties.put("session.timeout.ms", "30000"); KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<String, String>(properties); //订阅主题 //kafkaConsumer.subscribe(Collections.singletonList("test")); kafkaConsumer.assign(Arrays.asList(new TopicPartition("test",0))); try{ //有限循环消解决数据 while (true) { //一直调用poll拉取数据,如果进行拉取,那么Kafka会认为此消费者曾经死亡并进行重均衡 //参数值100是一个超时工夫,指明线程如果没有数据会期待多长时间,0示意不期待立刻返回 ConsumerRecords<String, String> records = kafkaConsumer.poll(100); //每条记录蕴含key/value以及主题、分区、位移信息 for (ConsumerRecord<String, String> record : records) { System.out.printf("offset = %d, value = %s\n", record.offset(), record.value()); } } } catch (WakeupException e) { // ignore for shutdown } finally { //此办法会提交位移,同时发送一个退出生产组的音讯到Kafka的组协调者,组协调者收到音讯后会立刻进行重均衡而无需期待此消费者会话过期。 kafkaConsumer.close(); } }}提交偏移量1. 主动提交最简略的提交形式是让消费者主动提交偏移量,如果 enable.auto.commit 被设为 true,那么每过 5s,消费者会主动把从 poll() 办法接管到的最大偏移量提交下来。 ...

November 6, 2020 · 6 min · jiezi

关于kafka:我花了一周读了Kafka-Producer的源码

talk is easy,show me the code,先来看一段创立producer的代码 public class KafkaProducerDemo { public static void main(String[] args) { KafkaProducer<String,String> producer = createProducer(); //指定topic,key,value ProducerRecord<String,String> record = new ProducerRecord<>("test1","newkey1","newvalue1"); //异步发送 producer.send(record); producer.close(); System.out.println("发送实现"); } public static KafkaProducer<String,String> createProducer() { Properties props = new Properties(); //bootstrap.servers 必须设置 props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.239.131:9092"); // key.serializer 必须设置 props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); // value.serializer 必须设置 props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); //client.id props.put(ProducerConfig.CLIENT_ID_CONFIG, "client-0"); //retries props.put(ProducerConfig.RETRIES_CONFIG, 3); //acks props.put(ProducerConfig.ACKS_CONFIG, "all"); //max.in.flight.requests.per.connection props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, 1); //linger.ms props.put(ProducerConfig.LINGER_MS_CONFIG, 100); //batch.size props.put(ProducerConfig.BATCH_SIZE_CONFIG, 10240); //buffer.memory props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, 10240); return new KafkaProducer<>(props); }}生产者的API应用还是比较简单,创立一个ProducerRecord对象(这个对象蕴含指标主题和要发送的内容,当然还能够指定键以及分区),而后调用send办法就把音讯发送进来了。 ...

November 6, 2020 · 3 min · jiezi

关于kafka:你好Kafka

大家好,我是 kafka, 可能很多人都据说过我,晓得我是 2011 年出世在 LinkedIn 的, 从那会儿到当初我的性能越发弱小了。作为一个优良而又残缺的平台,你能够在我下面冗余地存储微小的数据量,我有一个具备高吞吐量 (数百万 / 秒) 的音讯总线,你能够在这上面对通过我的数据进行实时流解决。如果你认为我就只有下面的这些特点的话,那么你真的是太浮浅了。 下面尽管说的很好,然而并未涉及到我的外围,这里我给你几个关键字:分布式,程度可扩大,容错,提交日志。 下面这些形象的词语,我会一一解释它们的含意,并通知你们我是如何工作的。 内心独白: 原本我是想要以第一人称来写这篇文章的,然而我发现我只能写出下面的了,再多的我就憋不进去了,于是我决定不要尴尬本人,还是用用第三人称写吧 (写作的功底依然须要锤炼) 分布式分布式系统由多个运行的计算机系统组成,所有这些计算机在一个集群中一起工作,对终端用户来讲只是一个繁多节点。 kafka也是分布式的,因为它在不同的节点(又被称为broker)上存储,承受以及发送音讯,这样做的益处是具备很高的可扩展性和容错性。 程度可扩展性在这之前,先看看什么是垂直可扩大,比方你有一个传统的数据库服务器,它开始适度负载,解决这个问题的方法就是给服务器加配置(cpu,内存,SSD),这就叫做垂直扩大。然而这种形式存在两个微小的劣势 硬件存在限度,不可能有限的增加机器配置它须要停机工夫,通常这是很多公司无奈容忍的程度可扩大就是通过增加更多的机器来解决同样的问题,增加新机器不须要停机,而且集群中也不会对机器的数量有任何的限度。问题在于并非所有零碎都反对程度可伸缩性,因为它们不是设计用于集群中(集群中工作更加简单)。 容错性非分布式系统中容易最致命的问题就是单点失败,如果你惟一的服务器挂掉了,那么我置信你会很解体。 而分布式系统的设计形式就是能够以配置的形式来答应失败。在5个节点的kafka集群中,你依然能够持续工作即便其中两个节点挂掉了。须要留神的是,容错与性能间接相干,你的零碎容错水平越高,性能就越差。 提交日志(commit log)提交日志(也被称为预写日志或者事物日志)是仅反对附加的长久有序数据结构,你无奈批改或者删除记录,它从左往右读并且保障日志的程序。是不是感觉kafka的数据结构如此简略? 是的,从很多方面来讲,这个数据结构就是kafka的外围。这个数据结构的记录是有序的,而有序的数据能够确保咱们的解决流程。这两个在分布式系统中都是及其重要的问题。 kafka实际上将所有音讯存储到磁盘并在数据结构中对它们进行排序,以便利用程序磁盘读取。 读取和写入都是常量工夫O(1)(当确定了record id),与磁盘上其余构造的O(log N)操作相比是一个微小的劣势,因为每个磁盘搜寻都很耗时。读取和写入不会相互影响,写不会锁住读,反之亦然。这两点有着微小的劣势, 因为数据大小与性能齐全拆散。无论你的服务器上有100KB还是100TB的数据,Kafka都具备雷同的性能 如何工作应用程序(producer)发送音讯(record)到kafka服务器(broker),这些音讯会被其余应用程序(consumer)所解决,这些音讯存储在主题(topic)中,并且消费者订阅该主题以接管新音讯。是不是感觉很像你平时写的代码——生产者消费者模式。 随着主题变得十分大,它们会分成更小的分区(partition),以取得更好的性能和可伸缩性(比方存储了用户互相发送的音讯,你能够依据用户名的第一个字母来进行拆分)。Kafka保障分区内的所有音讯都依照它们的程序排序,辨别特定音讯的形式是通过其偏移量(offset),你能够将其视为一般数组索引,即为分区中的每个新音讯递增的序列号。 kafka恪守着愚昧的broker和聪慧的consumer的准则。这意味着kafka不会跟踪消费者读取了哪些记录并删除它们,而是会将它们存储肯定的工夫(比方1天,以log.retention结尾的来决定日志保留工夫),直到达到某个阈值。消费者本人轮询kafka的新音讯并且通知它本人想要读取哪些记录。这容许它们依照本人的志愿递增/递加它们所处的偏移量,从而可能重放和从新处理事件。 须要留神的是消费者是属于消费者组的,消费者组有一个或多个消费者。为了防止两个过程读取同样的音讯两次,每个partition只能被一个消费者组中的一个消费者拜访。 长久化到硬盘正如我之前提到的,kafka实际上是将所有记录存储到硬盘而不在RAM中保留任何内容。你想晓得这个如何做出这个抉择的,其实这背地有很多优化使得这个计划可行。 kafka有一个将音讯分组的协定,这容许网络申请将音讯组合在一起并缩小网络开销,服务器反过来一次性保留大量音讯,消费者一次获取大量线性块。磁盘上线性读写十分快,古代磁盘十分慢的概念是因为大量磁盘寻址,然而在大量的线性操作中不是问题。操作系统对线性操作进行了大量优化,通过预读(预取大块屡次)和后写(将小型逻辑写入组成大型物理写入)技术。操作系统将磁盘文件缓存在闲暇RAM中。这称为pagecache,而kafka的读写都大量应用了pagecahce 写音讯的时候音讯先从java到page cache,而后异步线程刷盘,音讯从page cache刷入磁盘读音讯的时候先从page cache找,有就间接转入socket,没有就先从磁盘load到page cache,而后间接从socket收回去因为Kafka在整个流程(producer - >broker - >consumer)中以未经批改的标准化二进制格局存储音讯,因而它能够应用零拷贝优化。那时操作系统将数据从pagecache间接复制到socket,无效地齐全绕过了Kafka broker。所有这些优化都使Kafka可能以靠近网络的速度传递音讯。 数据散发和复制咱们来谈谈Kafka如何实现容错以及它如何在节点之间调配数据。 为了使得一个borker挂掉的时候,数据还能得以保留,分区(partition)数据在多个broker中复制。 在任何时候,一个broker领有一个partition,应用程序读取/写入都要通过这个节点,这个节点叫做----partition leader。它将收到的数据复制到N个其余broker,这些接收数据的broker叫做follower,follower也存储数据,一旦leader节点死掉的时候,它们就筹备竞争上岗成为leader。 这能够保障你胜利公布的音讯不会失落,通过抉择更改复制因子,你能够依据数据的重要性来替换性能以取得更强的持久性保障然而你可能会问:producer或者consumer怎么晓得partition leader是谁? 对生产者/消费者对分区的写/读申请,它们须要晓得分区的leader是哪一个,对吧?这个信息必定是能够获取到的,Kafka应用zookeeper来存储这些元数据。 什么是ZooKeeperZookeeper是一个分布式键值存储。它针对读取进行了高度优化,但写入速度较慢。它最罕用于存储元数据和解决群集的机制(心跳,散发更新/配置等)。 它容许服务的客户(Kafka broker)订阅并在产生变更后发送给他们,这就是Kafka如何晓得何时切换分区领导者。ZooKeeper自身保护了一个集群,所以它就有很高的容错性,当然它也应该具备,毕竟Kafka很大水平上是依赖于它的。 zookeeper用于存储所有的元数据信息,包含但不限于如下几项: 消费者组每个分区的偏移量(当初客户端在独自的kafka topic上存储偏移量)ACL —— 权限管制生产者/消费者的流量管制——每秒生产/生产的数据大小。能够参考Kafka-流量管制Quota性能partition leader以及它们的衰弱信息那么produer/consumer是如何晓得谁是partition leader的呢? 生产者和消费者以前经常间接连贯ZooKeeper来获取这些信息,然而Kafka从0.8和0.9版本开始移除了这种强耦合关系。客户端间接从kafka broker间接获取这些元数据,而让kafka broker从zookeeper那里获取这些元数据。 ...

November 6, 2020 · 1 min · jiezi

关于kafka:二Kafka之集群架构原理

原理至关重要,面试的时候不可能问你命令的,都是问原理,懂了原理线上如果应用kafka出了问题才可能疾速定位,而不是一脸蒙圈。必须要明确原理,如果不说原理间接实战,就真成搬砖了。 Topic创立一个TopicA的主题,3个分区别离存储在不同的服务器,留神Topic是一个逻辑上的概念。 Partition & Partition正本Kafka的topic能够划分成一个或多个partition,Partition 是物理上的概念。如果一个topic的正本数设为3,那么每个partition对应还会有3个雷同的正本。下图咱们对TopicA的分区0,1,2别离设置了3个正本,再别离存储在broker0,1,2。 日志分段存储 因为生产者生产的音讯会一直追加到 log 文件开端,为避免 log 文件过大导致数据定位效率低下,Kafka 采取了分片和索引机制。 它将每个 Partition 分为多个 Segment,每个 Segment 对应两个文件:“.index” 索引文件和 “.log” 数据文件。 Leader & Follow而且每个正本都是有角色之分的,它们会选举一个正本作为leader,其余的为follower。生产者在发送数据的时候,是间接发送到 leader partition,而后follower partition自行去leader进行数据同步,消费者生产数据的时候,也是从leader中生产数据。(下图在TopicA-partition-0在broker0是leader,同理其余TopicA-partition-N也有leader) Consumer & Consumer group一个生产组由一个或多个消费者实例组成,便于扩容与容错。一个分区不会让同一个消费者组外面的多个消费者去生产,一个消费者是能够去生产多个分区的数据的。 Kafka的网络设计 客户端将申请发送给Acceptor,broker里有3个processor的线程(默认是3),Acceptor不会对客户端的申请做任何的解决,而是封装成socketChannel,而后发送给3个processor线程,造成一个队列。发送的形式是轮询,就是发送给第一个processor,而后是第二个,第三个...消费者线程会以request申请去生产这些socketChannel;线程池外面默认有8个ReaderThreadPool线程,这些线程是用来解决request的,解析申请,返回响应后果response;processor会从response中读取响应数据,而后再返回给客户端。所以如果咱们须要对kafka进行加强调优,减少processor并减少线程池外面的解决线程,就能够达到成果。request和response那一块局部其实就是起到了一个缓存的成果,是思考到processor们生成申请太快,线程数不够不能及时处理的问题。所以这就是一个加强版的reactor网络线程模型。 Kafka零拷贝传统IO: //读取文件,再用socket发送进来buffer = File.read Socket.send(buffer)1、第一次:将磁盘文件,读取到操作系统内核缓冲区;2、第二次:将内核缓冲区的数据,copy到application应用程序的buffer;3、第三步:将application应用程序buffer中的数据,copy到socket网络发送缓冲区(属于操作系统内核的缓冲区);4、第四次:将socket buffer的数据,copy到网卡,由网卡进行网络传输。 传统形式,读取磁盘文件并进行网络发送,通过的四次数据copy是十分繁琐的。理论IO读写,须要进行IO中断,须要CPU响应中断(带来上下文切换),只管起初引入DMA来接管CPU的中断请求,但四次copy是存在“不必要的拷贝”的。 零拷贝: Kafka应用的zero-copy的应用程序要求内核间接将数据从磁盘文件拷贝到套接字,而无需通过应用程序。零拷贝不仅大大地进步了应用程序的性能,而且还缩小了内核与用户模式间的上下文切换。 zookeeper在kafka集群中的作用1、Broker注册 Broker是分布式部署并且互相独立,然而须要有一个注册零碎可能将整个集群中的Broker治理起来,此时就应用到了Zookeeper。在Zookeeper上会有一个专门用来进行Broker服务器列表记录的节点:/brokers/ids 每个Broker在启动时,都会到Zookeeper上进行注册,即到/brokers/ids下创立属于本人的节点,如/brokers/ids/[0...N]。 Kafka应用了全局惟一的数字ID来指代每个Broker服务器,创立完节点后,每个Broker就会将本人的IP地址和端口信息记录到该节点中去。其中,Broker创立的节点类型是长期节点,一旦Broker宕机,则对应的长期节点也会被主动删除。 2、Topic注册 在Kafka中,Topic的音讯分区与Broker的对应关系也都是由Zookeeper在保护,由专门的节点来记录,如:/borkers/topics Kafka中每个Topic都会以/brokers/topics/[topic]的模式被记录,如 /brokers/topics/login 和 /brokers/topics/search 等。Broker服务器启动后,会到对应Topic节点(/brokers/topics)上注册本人的Broker ID,并写入该Topic的分区总数,如/brokers/topics/login/3->2,这示意Broker ID为3的节点对"login"这个Topic提供了2个分区进行音讯存储。同样,这个分区节点也是长期节点。 3、消费者注册 ①、注册节点到消费者分组。每个消费者服务器启动时,都会到Zookeeper的指定节点下创立一个属于本人的消费者节点,例如/consumers/[group_id]/ids/[consumer_id],实现节点的创立后,消费者就会将本人订阅的Topic信息写入该长期节点。 ②、对消费者分组中的消费者的变动注册监听。每个 消费者都须要关注所属消费者分组 其余消费者服务器的变动状况,即对/consumers/[group_id]/ids节点注册子节点变动的Watcher监听,一旦发现消费者新增或缩小,就触发消费者的负载平衡。 ...

October 31, 2020 · 1 min · jiezi

关于kafka:解惑高深的Kafka时间轮原理原来也就这么回事

【摘要】 Kafka工夫轮是Kafka实现高效的延时工作的根底,它模仿了现实生活中的钟表对工夫的示意形式,同时,工夫轮的形式并不仅限于Kafka,它是一种通用的工夫示意形式,本文次要介绍Kafka中的工夫轮原理。Kafka中存在一些定时工作(DelayedOperation),如DelayedFetch、DelayedProduce、DelayedHeartbeat等,在Kafka中,定时工作的增加、轮转、执行、沦亡等是通过工夫轮来实现的。(工夫轮并不是Kafka独有的设计,而是一种通用的实现形式,Netty中也有用到工夫轮的形式) 1. 工夫轮是什么参考网上的两张图(摘自 https://blog.csdn.net/u013256...) 这两张图就比较清楚的阐明了Kafka工夫轮的构造了:相似事实中的钟表,由多个环形数组组成,每个环形数组蕴含20个工夫单位,示意一个工夫维度(一轮),如:第一层工夫轮,数组中的每个元素代表1ms,一圈就是20ms,当延迟时间大于20ms时,就“进位”到第二层工夫轮,第二层中,每“一格”示意20ms,依此类推… 对于一个提早工作,大体蕴含三个过程:进入工夫轮、降级和到期执行。 进入工夫轮依据延迟时间计算对应的工夫轮“档次”(如钟表中的“小时级”还是“分钟级”还是“秒级”,实际上是一个一直“降级”的过程,直到找到适合的“档次”)计算在该轮中的地位,并插入该地位(每个bucket是一个双向链表,可能蕴含多个提早工作,这也是工夫轮提高效率的一大起因,前面会提到)若该bucket是首次插入,须要将该bucket退出DelayQueue中(DelayQueue的引入是为了解决“空推动”,前面会提到) 降级当工夫“推动”到某个bucket时,阐明该bucket中的工作在以后工夫轮中的工夫曾经走完,须要进行“降级”,即进入更小粒度的工夫轮中,reinsert的过程和进入工夫轮是相似的 到期执行在reinsert的过程中,若发现曾经到期,则执行这些工作 整体过程大抵如下: 2. 工夫的“推动”一种直观的想法是,像事实中的钟表一样,“一格一格”地走,这样就须要有一个线程始终不停的执行,而大多数状况下,工夫轮中的bucket大部分是空的,指针的“推动”就没有本质作用,因而,为了缩小这种“空推动”,Kafka引入了DelayQueue,以bucket为单位入队,每当有bucket到期,即queue.poll能拿到后果时,才进行工夫的“推动”,缩小了 ExpiredOperationReaper 线程空转的开销。 3. 为什么要用工夫轮用到提早工作时,比拟间接的想法是DelayQueue、ScheduledThreadPoolExecutor 这些,而工夫轮相比之下,最大的劣势是在工夫复杂度上: 工夫复杂度比照: 因而,实践上,当工作较多时,TimingWheel的工夫性能劣势会更显著 总结一下Kafka工夫轮性能高的几个次要起因: (1)工夫轮的构造+双向列表bucket,使得插入操作能够达到O(1)的工夫复杂度 (2)Bucket的设计让多个工作“合并”,使得同一个bucket的屡次插入只须要在delayQueue中入队一次,同时缩小了delayQueue中元素数量,堆的深度也减小,delayqueue的插入和弹出操作开销也更小 点击关注,第一工夫理解华为云陈腐技术~

October 29, 2020 · 1 min · jiezi

关于kafka:kafka

kafka:replica正本同步机制[](https://www.jianshu.com/u/897... 1 前言Kafka的风行归功于它设计和操作简略、存储系统高效、充分利用磁盘程序读写等个性、非常适合在线日志收集等高吞吐场景。 Kafka个性之一是它的复制协定。复制协定是保障kafka高可靠性的要害。对于单个集群中每个Broker不同工作负载状况下,如何主动调优Kafka正本的工作形式是比拟有挑战的。它的挑战之一是要晓得如何防止follower进入和退出同步正本列表(即ISR)。从用户的角度来看,如果生产者发送一大批海量音讯,可能会引起Kafka Broker很多正告。这些警报表明一些topics处于“under replicated”状态,这些正本处于同步失败或生效状态,更意味着数据没有被复制到足够数量Broker从而减少数据失落的概率。因而Kafka集群中处于“under replicated”中Partition数要亲密监控。这个正告应该来自于Broker生效,减慢或暂停等状态而不是生产者写不同大小音讯引起的。 2 Kafka的正本机制Kafka中主题的每个Partition有一个预写式日志文件,每个Partition都由一系列有序的、不可变的音讯组成,这些音讯被间断的追加到Partition中,Partition中的每个音讯都有一个间断的序列号叫做offset, 确定它在分区日志中惟一的地位。 image Kafka每个topic的partition有N个正本,其中N是topic的复制因子。Kafka通过多正本机制实现故障主动转移,当Kafka集群中一个Broker生效状况下依然保障服务可用。在Kafka中产生复制时确保partition的预写式日志有序地写到其余节点上。N个replicas中。其中一个replica为leader,其余都为follower,leader解决partition的所有读写申请,与此同时,follower会被动定期地去复制leader上的数据。 如下图所示,Kafka集群中有4个broker, 某topic有3个partition,且复制因子即正本个数也为3: Kafka提供了数据复制算法保障,如果leader产生故障或挂掉,一个新leader被选举并被承受客户端的音讯胜利写入。Kafka确保从同步正本列表中选举一个正本为leader,或者说follower追赶leader数据。leader负责保护和跟踪ISR(In-Sync Replicas的缩写,示意正本同步队列,具体可参考下节)中所有follower滞后的状态。当producer发送一条音讯到broker后,leader写入音讯并复制到所有follower。音讯提交之后才被胜利复制到所有的同步正本。音讯复制提早受最慢的follower限度,重要的是疾速检测慢正本,如果follower“落后”太多或者生效,leader将会把它从ISR中删除。 正本同步队列(ISR)所谓同步,必须满足如下两个条件: 正本节点必须能与zookeeper放弃会话(心跳机制)副本能复制leader上的所有写操作,并且不能落后太多。(卡住或滞后的正本管制是由 replica.lag.time.max.ms 配置)默认状况下Kafka对应的topic的replica数量为1,即每个partition都有一个惟一的leader,为了确保音讯的可靠性,通常利用中将其值(由broker的参数offsets.topic.replication.factor指定)大小设置为大于1,比方3。 所有的正本(replicas)统称为Assigned Replicas,即AR。ISR是AR中的一个子集,由leader保护ISR列表,follower从leader同步数据有一些提早。任意一个超过阈值都会把follower剔除出ISR, 存入OSR(Outof-Sync Replicas)列表,新退出的follower也会先寄存在OSR中。AR=ISR+OSR。 上一节中的HW俗称高水位,是HighWatermark的缩写,取一个partition对应的ISR中最小的LEO作为HW,consumer最多只能生产到HW所在的地位。另外每个replica都有HW,leader和follower各自负责更新本人的HW的状态。对于leader新写入的音讯,consumer不能立即生产,leader会期待该音讯被所有ISR中的replicas同步后更新HW,此时音讯能力被consumer生产。这样就保障了如果leader所在的broker生效,该音讯依然能够从新选举的leader中获取。对于来自外部broKer的读取申请,没有HW的限度。下图具体的阐明了当producer生产音讯至broker后,ISR以及HW和LEO的流转过程: 由此可见,Kafka的复制机制既不是齐全的同步复制,也不是单纯的异步复制。事实上,同步复制要求所有能工作的follower都复制完,这条音讯才会被commit,这种复制形式极大的影响了吞吐率。而异步复制形式下,follower异步的从leader复制数据,数据只有被leader写入log就被认为曾经commit,这种状况下如果follower都还没有复制完,落后于leader时,忽然leader宕机,则会失落数据。而Kafka的这种应用ISR的形式则很好的平衡了确保数据不失落以及吞吐率。 Controller来保护:Kafka集群中的其中一个Broker会被选举为Controller,次要负责Partition治理和正本状态治理,也会执行相似于重调配partition之类的治理工作。在合乎某些特定条件下,Controller下的LeaderSelector会选举新的leader,ISR和新的leader_epoch及controller_epoch写入Zookeeper的相干节点中。同时发动LeaderAndIsrRequest告诉所有的replicas。leader来保护:leader有独自的线程定期检测ISR中follower是否脱离ISR, 如果发现ISR变动,则会将新的ISR的信息返回到Zookeeper的相干节点中。正本不同步的异常情况 慢正本:在肯定周期时间内follower不能追赶上leader。最常见的起因之一是I / O瓶颈导致follower追加复制音讯速度慢于从leader拉取速度。卡住正本:在肯定周期时间内follower进行从leader拉取申请。follower replica卡住了是因为GC暂停或follower生效或死亡。新启动正本:当用户给主题减少正本因子时,新的follower不在同步正本列表中,直到他们齐全赶上了leader日志。3 Follower向leader拉取数据的过程3.1 replica fetcher 线程何时启动broker 调配的任何一个 partition 都是以 Replica 对象实例的模式存在,而 Replica 在 Kafka 上是有两个角色: leader 和 follower,只有这个 Replica 是 follower,它便会向 leader 进行数据同步。 反映在 ReplicaManager 上就是如果 Broker 的本地正本被选举为 follower,那么它将会启动正本同步线程,其具体实现如下所示: image 简略来说,makeFollowers() 的处理过程如下: ...

October 16, 2020 · 3 min · jiezi

关于kafka:Apache-Kafka主题分区副本和ISR

浏览工夫: 6 分钟 在较早的博客中,咱们介绍了Kafka的根本术语,并进一步深刻了Zookeeper。当初,让咱们具体探讨主题分区和正本。 主题分区主题(Topic)或称音讯队列,是您在Kafka中数据的寄存地位。主题的数据进一步分为多个分区(Partition)。每个分区都是有序的,不可变的记录序列,这些记录间断地附加到结构化的提交日志中。 当公布带有密钥的音讯(带密钥的音讯)时,Kafka依据密钥的哈希确定性地将音讯映射到分区。这样能够保障具备雷同密钥的音讯始终被路由到同一分区。对于没有密钥的音讯,Kafka会将其随机映射到任何分区中。 偏移量分区中的每个音讯都有一个称为其偏移量(offset)的标识符 。它是音讯队列的不可被生产者或消费者更改的序号,由Kafka系统维护。消费者能够从特定的偏移量开始读取音讯,并能够从他们抉择的任何偏移量点进行读取,从而容许消费者在他们认为适合的任何工夫点退出集群。 分区越多,吞吐量越高主题分区是Kafka中并行性的单位。在使用者角度来看,Kafka始终将单个分区的数据提供给一个使用者线程。因而,使用者(在使用者组内)的并行度受要应用的分区数限度。因而,通常,Kafka群集中的分区越多,能够实现的吞吐量就越高。 更多分区的陷阱须要更多文件处理程序每个分区都映射到代理中文件系统中的目录。在该日志目录中,每个日志段将有两个文件(一个用于索引,另一个用于理论数据)。对于每个日志段,每个代理都关上蕴含索引文件和数据文件的文件句柄。如果存在大量分区,则关上文件的总数可能十分宏大。尽管这能够通过调整配置来解决。咱们能够应用以下命令查看关上的文件数:lsof | wc -l应用以下命令能够解决此问题:ulimit -n <noOfFiles>**端到端提早**从生产者公布的音讯到消费者读取的音讯之间的工夫称为提早。Kafka仅在提交音讯后(即,将音讯复制到所有同步正本时)才将音讯公开给使用者。因而,提交音讯的工夫可能是端到端提早的重要局部。鉴于默认状况下,对于在两个代理之间共享正本的所有分区,默认状况下,Kafka代理仅应用一个线程从另一个代理复制数据。例如,假设一个代理上有1000个分区领导者,并且它是两个具备复制因子为2的代理的Kafka集群。第二个代理须要从第一个代理中获取500个分区。一个线程负责将这些分区从代理1提取到代理2。这将破费足够的工夫。然而,在大型群集的状况下,这一点不会引起问题,因为每个代理只需累赘大量复本。在Kafka中复制复制(Replication)意思是在集群上保留数据的正本,以便在任何应用程序中晋升可用性功能。Kafka中的复制处于分区级别。每个分区在群集上具备0个或多个正本。 上例中,咱们在代理(Broker)1和2中具备分区0,在代理1和4中具备分区1,在代理3和4中具备分区2。在这些正本中,其中一个分区将充当领导者(主分区),而其余分区将作为跟随者(从分区)。 领导者负责发送和接管该分区的数据。 因而,当咱们说一个主题的复制因子为2时,这意味着其每个分区领有两个正本。当同步正本集(In-Sync Replica set, 简称ISR)中的所有正本均已确认已将记录写入磁盘时,Kafka认为记录已提交。 Kafak 确认机制 生产者能够抉择应用 “acks” 设置来接管对写入分区的数据的确认。 ack-value是Apache Kafka中的生产者配置参数,它定义仅应从同步正本中期待的确认数。能够将其设置为以下值: ACK=0 [NONE] 当ack值设置为0时,生产者将永远不会期待来自代理的确认。无奈保障代理已收到音讯。生产者不会尝试再次发送记录,因为生产者从不晓得记录失落了。此设置提供了较低的提早和较高的吞吐量,但以更高的音讯失落危险为代价。 ACK=1 [LEADER] 将ack值设置为1时,生产者将在领导者收到记录后失去ack。领导者会将记录写入其日志,但会在不期待所有关注者的齐全确认的状况下做出响应。仅当领导者在确认记录之后但在追随者复制它之前立刻失败时,该音讯才会失落。此设置是提早,吞吐量和持久性的两头根据。它比acks = 0慢,但更耐用。 ACK= -1 [ALL] 将ack值设置为all意味着当所有同步正本都收到记录时,生产者将取得ack。领导者将期待全套同步正本确认记录。这意味着发送带有所有ack值的音讯要花费更长的工夫,然而它提供了最强的音讯持久性。 什么是ISR?同步正本是与其领导者(即与领导者具备雷同音讯/或同步信息的跟随者)同步的复制分区ISR数并不强制性要求等于正本数。 “同步”的定义取决于主题配置,然而默认状况下,这意味着正本在最近10秒钟内曾经或曾经齐全与领导者同步。此时间段的设置为:replica.lag.time.max.ms,并具备服务器默认值,能够按每个主题笼罩该服务器默认值。 追随者通过定期发送获取申请(默认状况下每500毫秒发送一次)来将数据从领导者复制到本人。 如果追随者失败,则它将进行发送获取申请,并且在默认值10秒钟之后,将从ISR中删除。同样,如果追随者速度变慢,可能是与网络无关的问题或服务器资源受限,那么一旦它落后于领导者超过10秒钟,就会将其从ISR中删除。 min.insync.replicas 值指定了必须全副确认写入后能力视为写入胜利的最小正本数,因而,它对负责写入的生产方具备影响。此配置参数对生产方没有任何间接影响,这就是为什么它不影响消费者的起因,即便无效经纪人的数量小于的值 min.insync.replicas。 当生产者将acks设置为“ all”(或“ -1”)时,min.insync.replicas指定必须确认写入能力使写入胜利的最小正本数。如果不能满足此最小值,则生产者将引发异样(NotEnoughReplicas或NotEnoughReplicasAfterAppend)。 一起应用时,min.insync.replicas 和 acks 可使您施行更大的可用性保障。典型的状况是创立一个复制因子为3的主题,将min.insync.replicas 设置为 2,并设产生者确认为 “all”。如果未收到大多数正本写入,这将确保生产者引发异样。 有什么益处? 如果任何一个代理解体或因为网络问题而无法访问,其中一个正本将成为领导者。 只有属于同步正本列表的一部分的正本才有资格成为领导者,并且无论何时对其进行任何更改,同步正本的列表都会保留给zookeeper。同样,只有在至多有一个同步正本时,Kafka才会保障不会失落数据。 如果没有此类正本,则此保障不实用。 这就是主题分区,复制和ISR的全部内容。我将在进一步的博客中介绍无关Kafka的更多信息。编码欢快! ...

October 16, 2020 · 1 min · jiezi

关于kafka:kafka-系列-72日志索引

kafka 的索引文件以稠密索引的形式结构音讯的索引,每个 segmentfault 文件,对应 2 个索引文件。偏移量索引文件(xx.index)用于建设音讯偏移量到物理地址之间的映射关系;工夫戳索引文件(xx.timeindex)依据指定的工夫戳查找对应的偏移量信息。 .index、.timeindex 均放弃严格枯燥递增,在查找时,都应用二分查找法,如果查不到,均返回比查找值要小的最大值。 日志切分当日志分段文件满足以下几个条件任意之一,便会切分索引文件 分段文件大小超过 broker 参数 log.segment.bytes 配置的值,默认为 1073741824,即 1G以后分段日志中音讯的最大工夫戳与以后零碎的工夫戳差值大于 log.roll.ms 或 log.roll.hours 参数配置的值。其中前者优先级大于后者,默认配置了 log.roll.hours = 168,即 7 天.index 或 .timeindex 的大小达到 broker 端参数 log.index.size.max.bytes 配置的值,该值默认为 10485760 即10MB追加的音讯的偏移量与以后日志分段的偏移量之间差值大于 Integer.MAX_VALUE偏移量索引(.index).index 每个索引项,占 8 个字节。构造如下图所示: relativeOffset:绝对偏移量,示意音讯绝对于 baseOffset 偏移量,占用 4 个字节position:物理地址,音讯在日志分段文件中对应的物理地位音讯的偏移量(offset)占用 8 个字节,称为相对偏移量。为了节俭空间, relativeoffset 采纳 4 个字节,relativeOffset = offset - baseOffset。因为 relativeOffset 是 4 个字节,因而当 offset - baseOffset 值大于 Integer.MAX_VALUE,则会导致无奈持续存储在以后 .index 文件 工夫戳索引(.timeindex)每个索引项占用 12 个字节,构造如下图: ...

October 10, 2020 · 1 min · jiezi

关于kafka:kafka-系列-71日志存储

1、日志文件布局 __consumer_offset 存储着消费者提交的生产位移 2、日志存储格局V0 音讯格局offset:每一条音讯都有一个 offset 用来标记它在分区中的偏移量,offset 是逻辑值,而非理论物理偏移量 message_size:示意音讯的大小 crc32(4B):crc32 校验值。校验范畴为 magic 至 value 之间 magic(1B):音讯格局版本号,V0 固定为 0 attributes(1B):音讯的属性。总共占1个字节,低 3 位示意压缩类型。0:NONE、1:GZIP、2:SNAPPY;3:LZ4. 其余位保留 key length(4B):-1,示意没有设置 key key:可选 value lengtj(4B):音讯体的长度,-1,示意为空 value:音讯体 V1kafka 从 0.10.0 版本至 0.11.0 版本之前所应用的音讯格局版本为 v1, 比 v0 多了一个 timestamp 字段 音讯格局magic(1B):音讯格局版本号,V0 固定为 1 attributes(1B):前三位同样示意压缩类型。第4位:0-timestamp 类型为 CreateTime, 1-timestap 类型为 LogAppendTimetimestamp 类型由 broker 端参数 log.message.timestamp.type 配置,默认值为 CreateTime V2kafka 版本从 0.11.0 之后都称为 v2. length音讯总长度 attributes弃用 timestamp delta工夫戳增量,保留与 RecordBatch 起始工夫戳的差值 offset delta位移增量,保留与 RecordBatch 起始位移的差值 ...

October 10, 2020 · 1 min · jiezi

关于kafka:揭秘-Apache-Pulsar-如何挑战-Kafka

本专访对 StreamNative 联结创始人兼CTO、Apache Pulsar PMC 翟佳的采访内容。在本采访中,次要介绍了 Apache Pulsar 作为云原生流数据工具在音讯解决畛域的劣势个性、与 Kafka 的一些比照概要以及 StreamNative 公司的介绍和倒退方向。开源流数据公司 StreamNative 近期发表实现数百万美元 Pre-A 轮融资,日前正式退出 CNCF。其开创团队成员是 Apache Pulsar、Apache BookKeeper 我的项目的原生外围开发者,StreamNative 也被称为开源音讯零碎基础设施 Pulsar 背地的公司。(本文中 Pulsar、BookKeeper 别离指代 Apache Pulsar、Apache BookKeeper) StreamNative 是一家基于 Pulsar 的商业公司,提供云原生的实时音讯和流数据处理技术。Pulsar 是 Yahoo 外部在 2012 年为构建对立音讯平台而构建的,采纳分层分片的零碎架构。下层 Pulsar Broker 提供无状态的服务层;底层 BookKeeper 提供高性能、低提早和强一致性的 IO 服务。 在往年 6 月的 Pulsar Summit 中,Splunk 和 Yahoo 做了测试和剖析:Pulsar 帮忙 Splunk 将老本升高了 1.5 - 2 倍,提早升高了 5 - 50 倍,经营老本升高 2 - 3 倍;在 Yahoo 的部署中,Pulsar 反对等同规模的业务量,还在保障更高数据服务质量的状况下,耗费只有 Apache Kafka 的一半的理论硬件资源老本。 ...

September 27, 2020 · 3 min · jiezi

关于kafka:深度剖析-Kafka-Producer-的缓冲池机制图解-源码分析

上次跟大家分享的文章「Kafka Producer 异步发送音讯竟然也会阻塞?」中提到了缓冲池,前面再通过一番浏览源码后,发现了这个缓冲池设计的很棒,被它的设计思维优雅到了,所以忍不住跟大家持续分享一波。 在新版的 Kafka Producer 中,设计了一个音讯缓冲池,在创立 Producer 时会默认创立一个大小为 32M 的缓冲池,也能够通过 buffer.memory 参数指定缓冲池的大小,同时缓冲池被切分成多个内存块,内存块的大小就是咱们创立 Producer 时传的 batch.size 大小,默认大小 16384,而每个 Batch 都会蕴含一个 batch.size 大小的内存块,音讯就是寄存在内存块当中。整个缓冲池的构造如下图所示: 客户端将音讯追加到对应主题分区的某个 Batch 中,如果 Batch 曾经满了,则会新建一个 Batch,同时向缓冲池(RecordAccumulator)申请一块大小为 batch.size 的内存块用于存储音讯。 当 Batch 的音讯被发到了 Broker 后,Kafka Producer 就会移除该 Batch,既然 Batch 持有某个内存块,那必然就会波及到 GC 问题,如下: 以上,频繁的申请内存,用完后就抛弃,必然导致频繁的 GC,造成重大的性能问题。那么,Kafka 是怎么做到防止频繁 GC 的呢? 后面说过了,缓冲池在设计逻辑下面被切分成一个个大小相等的内存块,当音讯发送结束,归还给缓冲池不就能够防止被回收了吗? 缓冲池的内存持有类是 BufferPool,咱们先来看下 BufferPool 都有哪些成员: public class BufferPool { // 总的内存大小 private final long totalMemory; // 每个内存块大小,即 batch.size private final int poolableSize; // 申请、偿还内存的办法的同步锁 private final ReentrantLock lock; // 闲暇的内存块 private final Deque<ByteBuffer> free; // 须要期待闲暇内存块的事件 private final Deque<Condition> waiters; /** Total available memory is the sum of nonPooledAvailableMemory and the number of byte buffers in free * poolableSize. */ // 缓冲池还未调配的闲暇内存,新申请的内存块就是从这里获取内存值 private long nonPooledAvailableMemory; // ...}从 BufferPool 的成员可看出,缓冲池实际上由一个个 ByteBuffer 组成的,BufferPool 持有这些内存块,并保留在成员 free 中,free 的总大小由 totalMemory 作限度,而 nonPooledAvailableMemory 则示意还剩下缓冲池还剩下多少内存还未被调配。 ...

September 14, 2020 · 3 min · jiezi

关于kafka:kafka数据如何被重复消费

近段时间学习极客工夫李玥老师的后端存储实战课时,看到一个很多意思的货色:用kafka存储点击流的数据,并反复解决。在以往的应用中,kafka只是一个音讯传输的载体,音讯被生产后就不能再次生产。新常识与印象相冲突,于是就有了本篇文章:kafka数据如何被反复生产。 后期实践理解首先我先去官网纠正了我对kafka的整体理解。 官网对kafka的形容是:一个分布式流平台。怪本人的学艺不精。 其次,我从新看了一下kafka消费者的生产过程:kafka首先通过push/poll(默认为poll)获取音讯,接管音讯解决实现后手动/主动提交生产胜利,kafka服务器则依据提交状况决定是否挪动以后偏移量。 计划确定kafka消费者读取数据的地位是通过偏移量判断,那如果我能将偏移量手动设置为起始地位,就能实现反复生产?这个有搞头。 如何手动设置偏移量是要害。 show me the code代码的要害次要在于偏移量设置 api 的调用,其余没什么特地。 要留神的是,代码中我别离调用了作用不同的设置偏移量,仅作为展现,可按需取用。 最初消费者音讯音讯时,我只应用默认的拉取条数设置生产一次,可按需进行批改。  /**   * repeat kafka message   * @param host kafka host   * @param groupId kafka consumer group id   * @param autoCommit whether auto commit consume   * @param topic consume topic   * @param consumeTimeOut consume time out  */   private void textResetOffset(String host, String groupId, Boolean autoCommit, String topic, Long consumeTimeOut){   //form a properties to new consumer   Properties properties = new Properties();   properties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, host);   properties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, groupId);   properties.setProperty(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, autoCommit.toString());   properties.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());   properties.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());   KafkaConsumer<String, String> consumer = new KafkaConsumer<>(properties);   //subscribe incoming topic   consumer.subscribe(Collections.singletonList(topic));   //get consumer consume partitions   List<PartitionInfo> partitionInfos = consumer.partitionsFor(topic);   List<TopicPartition> topicPartitions = new ArrayList<>();   for(PartitionInfo partitionInfo : partitionInfos){   TopicPartition topicPartition = new TopicPartition(partitionInfo.topic(), partitionInfo.partition());   topicPartitions.add(topicPartition);   }   // poll data from kafka server to prevent lazy operation   consumer.poll(Duration.ofSeconds(consumeTimeOut));   //reset offset from beginning   consumer.seekToBeginning(topicPartitions);   //reset designated partition offset by designated spot   int offset = 20;   consumer.seek(topicPartitions.get(0), offset);   //reset offset to end   consumer.seekToEnd(topicPartitions);   //consume message as usual   ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(1));   Iterator<ConsumerRecord<String, String>> iterator = records.iterator();   while (iterator.hasNext()){   ConsumerRecord<String, String> record = iterator.next();   log.info("consume data: {}", record.value());   }   }运行后果 ...

September 13, 2020 · 2 min · jiezi