八总结

Posted jingdy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了八总结相关的知识,希望对你有一定的参考价值。

1、Kafka的设计时什么样的呢?

  Kafka将消息以topic为单位进行归纳

  将向Kafka topic发布消息的程序成为producers

  将预订topics并消费消息的程序成为consumer.

  Kafka以集群的方式运行,可以由一个或多个服务组成,每个服务叫做一broker.producers通过网络将消息发送到Kafka集群,集群向消费者提供消息

2、数据传输的事物定义有哪三种?

  数据传输的事务定义通常有以下三种级别:

  (1)最多一次:消息不会被重复发送,最多被传输一次,但也有可能一次不传输

  (2)最少一次:消息不会被漏发送,最少被传输一次,但也有可能被重复传输.

  (3)精确的一次(Exactlyonce):不会漏传输也不会重复传输,每个消息都传输被一次而且仅仅被传输一次,这是大家所期望的。

3、Kafka判断一个节点是否还活着有那两个条件?

(1)节点必须可以维护和ZooKeeper的连接,Zookeeper通过心跳机制检查每个节点的连接

(2)如果节点是个follower,他必须能及时的同步leader的写操作,延时不能太久

4、producer是否直接将数据发送到broker的leader(主节点)?

  producer直接将数据发送到broker的leader(主节点),不需要在多个节点进行分发,为了帮助producer做到这点,所有的Kafka节点都可以及时的告知:哪些节点是活动的,目标topic目标分区的leader在哪。这样producer就可以直接将消息发送到目的地了

5、Kafka consumer是否可以消费指定分区消息?

  Kafaconsumer消费消息时,向broker发出"fetch"请求去消费特定分区的消息,consumer指定消息在日志中的偏移量(offset),就可以消费从这个位置开始的消息,customer拥有了offset的控制权,可以向后回滚去重新消费之前的消息,这是很有意义的

6、Kafka消息是采用Pull模式,还是Push模式?

  Kafka最初考虑的问题是,customer应该从brokes拉取消息还是brokers将消息推送到consumer,也就是pull还push。在这方面,Kafka遵循了一种大部分消息系统共同的传统的设计:producer将消息推送到broker,consumer从broker拉取消息一些消息系统比如Scribe和ApacheFlume采用了push模式,将消息推送到下游的consumer。这样做有好处也有坏处:由broker决定消息推送的速率,对于不同消费速率的consumer就不太好处理了。消息系统都致力于让consumer以最大的速率最快速的消费消息,但不幸的是,push模式下,当broker推送的速率远大于consumer消费的速率时,consumer恐怕就要崩溃了。最终Kafka还是选取了传统的pull模式Pull模式的另外一个好处是consumer可以自主决定是否批量的从broker拉取数据。Push模式必须在不知道下游consumer消费能力和消费策略的情况下决定是立即推送每条消息还是缓存之后批量推送。如果为了避免consumer崩溃而采用较低的推送速率,将可能导致一次只推送较少的消息而造成浪费。Pull模式下,consumer就可以根据自己的消费能力去决定这些策略Pull有个缺点是,如果broker没有可供消费的消息,将导致consumer不断在循环中轮询,直到新消息到t达。为了避免这点,Kafka有个参数可以让consumer阻塞知道新消息到达(当然也可以阻塞知道消息的数量达到某个特定的量这样就可以批量发

7.Kafka存储在硬盘上的消息格式是什么?

  消息由一个固定长度的头部和可变长度的字节数组组成。头部包含了一个版本号和CRC32校验码。

  • 消息长度:4bytes(value:1+4+n)

  • 版本号:1byteCRC校验码:4bytes

  • 具体的消息:nbytes

8.Kafka高效文件存储设计特点:

  (1).Kafka把topic中一个parition大文件分成多个小文件段,通过多个小文件段,就容易定期清除或删除已经消费完文件,减少磁盘占用。

  (2).通过索引信息可以快速定位message和确定response的最大大小。

  (3).通过index元数据全部映射到memory,可以避免segmentfile的IO磁盘操作。

  (4).通过索引文件稀疏存储,可以大幅降低index文件元数据占用空间大小。

9.Kafka与传统消息系统之间有三个关键区别

  (1).Kafka持久化日志,这些日志可以被重复读取和无限期保留

  (2).Kafka是一个分布式系统:它以集群的方式运行,可以灵活伸缩,在内部通过复制数据提升容错能力和高可用性

  (3).Kafka支持实时的流式处理

10.Kafka创建Topic时如何将分区放置到不同的Broker中

  • 副本因子不能大于Broker的个数;

  • 第一个分区(编号为0)的第一个副本放置位置是随机从brokerList选择的;

  • 其他分区的第一个副本放置位置相对于第0个分区依次往后移。也就是如果我们有5个Broker,5个分区,假设第一个分区放在第四个Broker上,那么第二个分区将会放在第五个Broker上;第三个分区将会放在第一个Broker上;第四个分区将会放在第二个Broker上,依次类推;

  • 剩余的副本相对于第一个副本放置位置其实是由nextReplicaShift决定的,而这个数也是随机产生的。

11.Kafka新建的分区会在哪个目录下创建

  在启动Kafka集群之前,我们需要配置好log.dirs参数,其值是Kafka数据的存放目录,这个参数可以配置多个目录,目录之间使用逗号分隔,通常这些目录是分布在不同的磁盘上用于提高读写性能。当然我们也可以配置log.dir参数,含义一样。只需要设置其中一个即可。如果log.dirs参数只配置了一个目录,那么分配到各个Broker上的分区肯定只能在这个目录下创建文件夹用于存放数据。但是如果log.dirs参数配置了多个目录,那么Kafka会在哪个文件夹中创建分区目录呢?答案是:Kafka会在含有分区目录最少的文件夹中创建新的分区目录,分区目录名为Topic名+分区ID。注意,是分区文件夹总数最少的目录,而不是磁盘使用量最少的目录!也就是说,如果你给log.dirs参数新增了一个新的磁盘,新的分区目录肯定是先在这个新的磁盘上创建直到这个新的磁盘目录拥有的分区目录不是最少为止。

12.partition的数据如何保存到硬盘

  topic中的多个partition以文件夹的形式保存到broker,每个分区序号从0递增,且消息有序Partition文件下有多个segment(xxx.index,xxx.log)segment文件里的大小和配置文件大小一致可以根据要求修改默认为1g如果大小大于1g时,会滚动一个新的segment并且以上一个segment最后一条消息的偏移量命名

13.kafka的ack机制

request.required.acks有三个值01-1

  • 0:生产者不会等待broker的ack,这个延迟最低但是存储的保证最弱当server挂掉的时候就会丢数据

  • 1:服务端会等待ack值leader副本确认接收到消息后发送ack但是如果leader挂掉后他不确保是否复制完成新leader也会导致数据丢失

  • -1:同样在1的基础上服务端会等所有的follower的副本受到数据后才会受到leader发出的ack,这样数据不会丢失,重复消费

14.Kafka的消费者如何消费数据

  消费者每次消费数据的时候,消费者都会记录消费的物理偏移量(offset)的位置等到下次消费时,他会接着上次位置继续消费

15.消费者负载均衡策略

  一个消费者组中的一个分片对应一个消费者成员,他能保证每个消费者成员都能访问,如果组中成员太多会有空闲的成员

16.数据有序

  一个消费者组里它的内部是有序的消费者组与消费者组之间是无序的 17.kafaka生产数据时数据的分组策略

  生产者决定数据产生到集群的哪个partition中每一条消息都是以(key,value)格式Key是由生产者发送数据传入所以生产者(key)决定了数据产生到集群的哪个partition

  新建topic 副本数不能超过机器数。分区可以大于机器数。

18、kafka 维护消费状态跟踪的方法

  大部分消息系统在 broker 端的维护消息被消费的记录: 一个消息被分发到

  consumer 后 broker 就马上进行标记或者等待 customer 的通知后进行标记。这样也可以在消息在消费后立马就删除以减少空间占用。

  但是这样会不会有什么问题呢? 如果一条消息发送出去之后就立即被标记为消费过的, 一旦 consumer 处理消息时失败了( 比如程序崩溃) 消息就丢失了。为了解决这个问题, 很多消息系统提供了另外一个个功能: 当消息被发送出去之后仅仅被标记为已发送状态, 当接到 consumer 已经消费成功的通知后才标记为已被消费的状态。这虽然解决了消息丢失的问题,但产生了新问题,首先如果 consumer 处理消息成功了但是向 broker 发送响应时失败了,这条消息将被消费两次。第二个问题时, broker 必须维护每条消息的状态, 并且每次都要先锁住消息然后更改状态然后释放锁。这样麻烦又来了, 且不说要维护大量的状态数据, 比如如果消息发送出去但没有收到消费成功的通知, 这条消息将一直处于被锁定的状态, Kafka 采用了不同的策略。Topic 被分成了若干分区,每个分区在同一时间只被一个 consumer 消费。这意味着每个分区被消费的消息在日志中的位置仅仅是一个简单的整数:offset。这样就很容易标记每个分区消费状态就很容易了,仅仅需要一个整数而已。这样消费状态的跟踪就很简单了。

  这带来了另外一个好处: consumer 可以把 offset 调成一个较老的值, 去重新消费老的消息。这对传统的消息系统来说看起来有些不可思议, 但确实是非常有用的, 谁规定了一条消息只能被消费一次呢?

19、Zookeeper 对于Kafka 的作用是什么?

  Zookeeper 是一个开放源码的、高性能的协调服务,它用于 Kafka 的分布式应用。Zookeeper 主要用于在集群中不同节点之间进行通信

  在 Kafka 中, 它被用于提交偏移量, 因此如果节点在任何情况下都失败了, 它都可以从之前提交的偏移量中获取

  除此之外,它还执行其他活动,如: leader 检测、分布式同步、配置管理、识别新节点何时离开或连接、集群、节点实时状态等等。

20、消费者故障,出现活锁问题如何解决?

  出现“ 活锁” 的情况, 是它持续的发送心跳, 但是没有处理。为了预防消费者在这种情况下一直持有分区,我们使用 max.poll.interval.ms 活跃检测机制。 在此基础上, 如果你调用的 poll 的频率大于最大间隔, 则客户端将主动地离开组, 以便其他消费者接管该分区。 发生这种情况时, 你会看到 offset 提交失败( 调用commitSync() 引发的 CommitFailedException)。这是一种安全机制, 保障只有活动成员能够提交 offset。所以要留在组中, 你必须持续调用 poll。

消费者提供两个配置设置来控制 poll 循环:

  • max.poll.interval.ms:增大 poll 的间隔,可以为消费者提供更多的时间去处理返回的消息( 调用 poll(long)返回的消息,通常返回的消息都是一批)。缺点是此值越大将会延迟组重新平衡。
  • max.poll.records: 此设置限制每次调用 poll 返回的消息数, 这样可以更容易的预测每次 poll 间隔要处理的最大值。通过调整此值,可以减少 poll 间隔,减少重新平衡分组的

  对于消息处理时间不可预测地的情况,这些选项是不够的。 处理这种情况的推荐方法是将消息处理移到另一个线程中,让消费者继续调用 poll。 但是必须注意确保已提交的 offset 不超过实际位置。另外, 你必须禁用自动提交, 并只有在线程完成处理后才为记录手动提交偏移量( 取决于你)。 还要注意,你需要 pause 暂停分区, 不会从 poll 接收到新消息, 让线程处理完之前返回的消息( 如果你的处理能力比拉取消息的慢, 那创建新线程将导致你机器内存溢出)。

21、如何控制消费的位置

  kafka 使用 seek(TopicPartition, long)指定新的消费位置。用于查找服务器保留的最早和最新的 offset 的特殊的方法也可用( seekToBeginning(Collection) 和seekToEnd(Collection))

  Kafka 分布式的单位是 partition,同一个 partition 用一个 write ahead log 组织,所以可以保证 FIFO 的顺序。不同 partition 之间不能保证顺序。但是绝大多数用户都可以通过 message key 来定义, 因为同一个 key 的 message 可以保证只发送到同一个 partition。

  Kafka 中发送 1 条消息的时候, 可以指定(topic, partition, key) 3 个参数。

  partiton 和 key 是可选的。如果你指定了 partition,那就是所有消息发往同 1 个 partition,就是有序的。并且在消费端,Kafka 保证,1 个 partition 只能被1 个 consumer 消费。或者你指定 key( 比如 order id),具有同 1 个 key 的所有消息, 会发往同 1 个 partition。

以上是关于八总结的主要内容,如果未能解决你的问题,请参考以下文章

作业八总结

总结八

作业八 总结

八月份总结

罗振宇[长谈]罗永浩八小时总结

八Kafka总结