kafka消息发送者

Kafka起初是由LinkedIn公司采用Scala语言开发的一个多分区、多副本且基于ZooKeeper协调的分布式消息系统,现已被捐献给Apache基金会。目前Kafka已经定位为一个分布式流式处理平台,它以高吞吐、可持久化、可水平扩展、支持流数据处理等多种特性而被广泛使用。目前越来越多的开源分布式处理系统如Cloudera、Storm、Spark、Flink等都支持与Kafka集成。

前言浅见

kafka 不仅仅可以作为MQ消息系统来使用, 也可以作为存储系统和流式处理平台使用。

kafka使用磁盘顺序写入的基本机制来实现海量消息的处理和消息的有序性,同时也保证了消息不会丢失。

kafka也是分布式的系统,使用zookeeper(2.8已经移除)来协调各个部分。 分布式系统可以显著的提高系统的可用性,但是同时也为系统引入了数据一致性的挑战。

为了达到高度的数据一致性, kafka又引入了副本备份的概念,保证在分布系统中某个模块出现问题而不会导致数据丢失。

而引入副本的功能,自然又会降低性能, 感觉这是鱼和熊掌不可兼得的难题,为此必须要做出一定的取舍, kakfa的取舍就是满足高性能和可用性, 对于一致性有所取舍。 同时为了满足高性能, 也丢了一些作为MQ系统的灵活性。

kafka作为消息系统,无法100%保证消息的发送和接受不会重复,作为开发者要在程序中自己实现消息的消费幂等。

而RocketMQ刚好相反, 他优先满足了一致性和可用性,对于性能有一定的损耗, 但是对于大部分的业务来说,RocketMQ已经满足业务需求了, 如果不满足就粗暴的加机器就可以了。

k

概念:

  • broker服务器: 可以简单理解成kafka的服务节点,当然有多个broker协同工作的。
  • Topic: 主题, MQ消息中的重要理念,可以简单理解成消息的分类, broker中也是根据一个个主题来进行处理的
  • Partition: 分区, 主题中下一级小分类,分区也可以看成broker中的一个log文件,分区中的消息都是有序的, 消费这就是消费分区中的存储的内容
  • Consumer:消费者
  • Producer:生产者
  • Replica:副本,分区的备份,可以配置副本数,与分区中的数据同步

生产者

kafka中的生成这是线程安全的,多个线程可以共用一个生产者,可以池化维护生产者,kafka中发现消息的流程大致如下图:
在这里插入图片描述
其中ProducerRecord 就是消息体, 消息体中的主要成员变量如下: 在这里插入图片描述

序列化

两个系统之间通信, 肯定要涉及到最重要的序列化问题, kakfa中有默认的有org.apache.kafka.common.serialization.StringSerializer; 当然也可以自己定义序列化器只要实现org.apache.kafka.common.serialization.Serializer接口就可以。

消息发送流程

消息在发送前会经过拦截器,序列化器和分区器。这三个器的作用通过名称就可以看出来,发送流程大致如下:
在这里插入图片描述

分区器:

每个主题的消息在发送前都需要确认消息要发往那个分区,一般都是根据ProducerRecord中的key值来确定的,

发送线程

主要有两个线程,主线程和发送线程,其中主线程中主要负责消息的创建和三个器的作用, 而发送只有一个作用,发送消息到broker的对应分区。

为了实现高性能,发送线程会缓存消息,等到消息达到一定量后, 再批量发送到broker中。 缓存的消息量可以配置,达到最大的缓存量后继续发送消息会阻塞。

发送线程对于每个分区都维护了一个有限容量的双端队列RecordAccumulator ,一端写入数据,一端取出数据发送,当队列满了后就会阻塞。

发送线程还会维护一个待确认队列InFlightRequests,消息发送到broker后还没有收到回复的消息会放入这个队列中, 这个队列也是可配置大小的。

通过待确认队列InFlightRequests中消息数量的多少,发送端可以得出负载最小的broker,这样发送端就可以优先和这个broker进行通信了(不一定是发送消息)。

元数据的更新

发送端一般都是从负载最小的broker中获取元数据的, 元数据中包含的信息有:

  1. 集群中包含哪些主题,
  2. 主题都有哪些分区,分区分布在那些broker中
  3. 每个分区都有哪些副本,副本分布在哪些broker中
  4. leader broker是哪一个。

当客户端没有元数据和元数据超过一定时间后,就会向broker发起请求更新。 元数据的过期时间可以配置, 元数据的获取也是通过发送线程来完成的,并且获取的数据会同步给主线程使用。

重要参数

  • acks 设置多少个副本收到消息后发送者才会任务消息发送成功,默认值1表示只要leader分区收到消息则认为消息发送成功。 值为0表示发送者不关心broker是否收到,慎用。值-1或者all表示需要所有的副本收到消息才是发送成功, 这个值需要根据情况谨慎选择。
  • max.request.size 设置消息的大小, 默认1MB;这个值不要轻易改,会极大的影响性能,并且1MB的大小已经基本够用了。broker也有关于消息体的大小限制,所以不建议轻易修改。
  • retriesretry.backoff.ms设置重试次数和重试间隔。网络不可避免有抖动的问题,分布系统中leader也有可能碰到选举问题, 所以重试还是有必要的。 retries默认值为0, 如果是重要的业务系统,建议还是设置一个大于0的值。
  • compression.type 消息的压缩, 默认nono, 可选“gzip”“snappy”和“lz4”; 压缩的好处不多说了,开启有一定的性能损耗,我建议开启。
  • linger.ms 发送端会在收到消息后先放入缓存中,等待一定时间后批量发送, 这个就是设置等待的时间
  • request.timeout.ms 发送消息后,会等待服务端确认消息接收成功,这个就是设置等待时间,默认值为30000(ms)。broker端也有一个相似的参数replica.lag.time.max.ms,这个值最好笔broker端的值要大, 这样可以减少重试的次数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值