kafka基础

参考文献:
初探kafka
大数据开发面试指南

Kafka基本概念

Kafka 是一个 “数据流” 平台,能够帮助开发者更好地专注于核心业务。Kafka 支持发布和订阅数据(消息),能够将其保存,并进行处理。

  1. 关键 “术语”
    • 消息(message):Kafka 的数据单元,称为 “消息”。消息由键(key)、值(value)组成,键作为元数据,是可选的,值即为消息的内容。消息写入到 Kafka 时,按照主题和分区分组,以批次(batch)的形式写入。需要根据时间延迟和吞吐量,权衡批次的 “大小”:批次越大,单位时间内处理的消息越多,单个消息的传输时间越长。
    • 主题(topic) & 分区(partition): Kafka 的消息通过 “主题” 进行分类。主题能够被划分为若干 “分区”。消息以追加的方式写入分区,并以 FIFO 的方式读取,保证了消息在单个分区内的顺序。
      Kafka 支持分区的 “复制机制”,以提供消息冗余,分区的 “实例” 称为 “副本”(replica),其中之一作为 “首领副本”(leader replica)。
    • broker:Kafka 服务器通常被称为 broker,broker 负责 “消息保留策略”:当消息超过保留时间,或者消息的总量达到大小限制,旧的消息将过期并且被删除。
      多个 broker 能够组成 Kafka 集群,其中之一作为 “集群管理器”。单个分区的副本必须位于不同的 broker。
  2. kafka的优势
    • 生产者与消费者完全独立,特别的,Kafka 支持多个消费者独立地读取相同的数据 “流”
    • 持久性,消息由磁盘存储,并支持自定义的保留规则
    • 伸缩性 & 高性能,能够以集群的方式水平扩展,并具备故障容错能力

数据丢失

重复消费和数据丢失问题主要分三种情况:

1、生产者弄丢消息

生产者发送消息成功后不等 Kafka 同步完成的确认继续发送下一条消息,在发的过程中如果 Leader Kafka 宕机了,但 Producer 并不知情,发出去的信息 Broker 就收不到导致数据丢失。解决方案是将 request.required.acks 设置为 -1,表示 Leader 和 Follower 都收到消息才算成功。

request.required.acks=0 表示发送消息即完成发送,不等待确认(可靠性低,延迟小,最容易丢失消息)
request.required.acks=1 表示当 Leader 收到消息返回确认后才算成功

2、消费者弄丢消息:

消费者有两种情况,一种是消费的时候自动提交偏移量导致数据丢失:拿到消息的同时将偏移量加一,如果业务处理失败,下一次消费的时候偏移量已经加一了,上一个偏移量的数据丢失了。
另一种是手动提交偏移量导致重复消费:等业务处理成功后再手动提交偏移量,有可能出现业务成功,偏移量提交失败,那下一次消费又是同一条消息。怎么解决呢?
这是一个 or 的问题,偏移量要么手动提交要么自动提交,对应的问题是要么数据丢失要么重复消费。如果消息要求实时性高,丢个一两条没关系的话可以选择自动提交偏移量。如果消息一条都不能丢的话可以将业务设计成幂等(redis分布式锁实现幂等),不管消费多少次都一样。

3、Kafka 弄丢了数据

这块比较常见的一个场景,就是 Kafka 某个 broker 宕机,然后重新选举 partition 的 leader。大家想想,要是此时其他的 follower 刚好还有些数据没有同步,结果此时 leader 挂了,然后选举某个 follower 成 leader 之后,不就少了一些数据?这就丢了一些数据啊。

生产环境也遇到过,我们也是,之前 Kafka 的 leader 机器宕机了,将 follower 切换为 leader 之后,就会发现说这个数据就丢了。

所以此时一般是要求起码设置如下 4 个参数:

给 topic 设置 replication.factor 参数:这个值必须大于 1,要求每个 partition 必须有至少 2 个副本。
在 Kafka 服务端设置 min.insync.replicas 参数:这个值必须大于 1,这个是要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系,没掉队,这样才能确保 leader 挂了还有一个 follower 吧。
在 producer 端设置 acks=all:这个是要求每条数据,必须是写入所有 replica 之后,才能认为是写成功了。
在 producer 端设置 retries=MAX(很大很大很大的一个值,无限次重试的意思):这个是要求一旦写入失败,就无限重试,卡在这里了。

我们生产环境就是按照上述要求配置的,这样配置之后,至少在 Kafka broker 端就可以保证在 leader 所在 broker 发生故障,进行 leader 切换时,数据不会丢失。

kafka事物

Kafka 事务性的使用方法也非常简单,用户只需要在 Producer 的配置中配置 transactional.id,通过 initTransactions() 初始化事务状态信息,再通过 beginTransaction() 标识一个事务的开始,然后通过 commitTransaction() 或 abortTransaction() 对事务进行 commit 或 abort

Properties props = new Properties();
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("client.id", "ProducerTranscationnalExample");
props.put("bootstrap.servers", "localhost:9092");
props.put("transactional.id", "test-transactional");
props.put("acks", "all");
KafkaProducer producer = new KafkaProducer(props);
producer.initTransactions();

try {
    String msg = "matt test";
    producer.beginTransaction();
    producer.send(new ProducerRecord(topic, "0", msg.toString()));
    producer.send(new ProducerRecord(topic, "1", msg.toString()));
    producer.send(new ProducerRecord(topic, "2", msg.toString()));
    producer.commitTransaction();
} catch (ProducerFencedException e1) {
    e1.printStackTrace();
    producer.close();
} catch (KafkaException e2) {
    e2.printStackTrace();
    producer.abortTransaction();
}
producer.close(); 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值