浅谈分布式消息中间件----kafka

分布式消息中间件----kafka

人家的理解

简介

KafKa是一款分布式消息发送和订阅系统,具有高性能,高吞吐量的特点而被广泛运用于大数据传输场景。它是由Linkedln公司开发,使用纯Scala语言编写的,之后成为Apache的一个顶级项目。

为什么要用kafka

互联网公司在营销方面逐步要做到精细化运营需求,这样就能够针对不同的用户喜好推送不同的产品,而这个过程需要收集和分析用户的行为数据,而通过传统的ActiveMQ这类消息中间件在处理大数据传输的时候存在实效性、性能、消息堆积等问题。kafka早期设计的目的是作为linkln活动流和运营数据处理管道,它天然的具备了高吞吐量、内置分区、复制等能力而非常适合处理大规模的消息,因此很多的大数据传输场景都选用kafka,比如应用日志收集分析、消息系统、用户行为分析、运营指标(服务器性能数据)、流式处理(spark、storm)。

kafka的架构组件

(kafka的broker和zookeeper组成天然的集群)
在这里插入图片描述

Kafka的架构图

在这里插入图片描述

  • zookeeper:消息的生产者和消息的消费者都将会注册到zookeeper中
  • KafkaTopic(消息逻辑上的抽象存储):一个topic可以由多个broker组成,消息生产者将消息发送到一个topic上面去,消息的消费者消费某个topic上面的消息。
  • partition(消息物理上的具体存储):物理上消息的最小存储单元。
  • consummer group:消费者分组,假如说有三个consummer,分为两个组,groupA/groupB,那么当生产者发送一条消息的时候,groupA/groupB的组内成员只会有一台机器收到消息(每个消息只会被非分配到一个consummer上面去消费)。

kafka的安装部署

kafka的实现细节

  • 消息:消息由key-value组成,key【可选】和value都是byte数组;消息批量发送。
  • topic(逻辑概念)&partition(物理概念):
    topic是一个用来存储消息的逻辑概念。可以理解成一个消息集合。一个topic上面可以有任意多个produce&consummer。任意一个produce可以向topic上面去发送消息,任意一个consummer也可以从topic上面去获取消息消费。

**形象的说明:**假设有一个1000w数据的表,现在要分为十张表,每一张存储10w的数据,那么存储这个分表映射关系的表就好比topic,而具体存储10w数据的表就好比一个个partition,从而可以看出topic只是一个逻辑存储结构,具体的物理存储是由一个个具体的parttion去存储物理数据。

  • 问题来了,消息的发送者发送的消息是如何指定到某个partition中的呢?
    前面也说了,发送的消息是由key+value组成的,produce在向topic中发送消息的时候,kafka可以根据消息的key去映射到某个partitionb中去。
  • topic中的partition格局分布

在这里插入图片描述

值得注意的几点:

  1. 每个partition中都是独立有序的,顺序不会跨分区有序。
  2. 图中的0,1,2,3…这些实际上就是offset值,consummer在从topic中获取消息的时候就是通过offset值去获取到相应的消息,读取消息之后offset会自增。

kafka的高吞吐量的因素

  1. 顺序写的方式存储数据(随机写的主要开销就是寻道开销);频繁IO(网络IO,磁盘IO)
  2. 批量发送:kafka的消息发送有同步和异步发送两种机制,在异步发送的时候,kafka允许批量发送,produce在向broker发送消息的时候,并不是第一时间发送到topic上面,而是先发送到broker的内存缓存中,决定发送的两个因素batch.size/lnger.ms 当消息缓存数量达到临界值,或者缓存时间达到临界时间后,就会批量发送到topic中.
  3. 零拷贝(利用java.nio.channels.FileChannel 中的 transferTo() ,可以避免从磁盘读取数据到应用环境,然后直接发送给socket,这样少了一个上下文切换。因此耗时也就少了不少。)
    在这里插入图片描述在这里插入图片描述

日志策略

  • 日志保留策略(时间,大小)
  • 日志压缩策略:合并相同key的消息,只保留每个key对应的最新的消息(value)

partition的概念

创建topic命令中的partitions决定了当前要创建的topic有几个分区,如果指点为三个,那么在每个broker的logs目录下面都会创建一个third-x的目录。

sudo …/bin/./kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 3 --topic third

kafka的可靠性机制

消息发送可靠性:生产者发送消息到broker,有三种确认方式(request,required,acks)

  1. acks=0:producer不会等待broker(leader)发送ack,因为发送消息网络超时或broker crash(1.leader还没有commit消息;2.Leader和Follower数据不同步),即有可能丢失,又有可能会重发。
  2. acks=1:leader接收到消息后发送ack(给producer确认消息收到),丢失会重发,丢的概率很小。
  3. acks=-1:当所有的follower都同步消息成功后发送ack(个体producer确认消息收到)。丢失消息可能性比较低。

消息存储的可靠性:可以设置Partition的规则,通过Partition的规则分配路由,那么消息在partiton上面存储就会比较规则,这样就实现了消息存储的水平扩展(分片)。

  1. kafka提供了一个高可靠性的副本机制,通过副本去保存每个partition中的消息数据。

sudo …/bin/./kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 3 --topic third
命令中的–replication-factor参数就指定了副本数,如果是3 然后分区数为3的话,那么在所有的broker节点的logs目录下面总共会创建9个相应的topic分区,从而实现交叉备份,这样就降低了某个broker宕机智斗导致改broker节点上分区中的消息无法消费的问题。

副本机制:
在这里插入图片描述
如图,在设置副本机制后,broker之间会两两复制,假设replicatin-factor 设置为3,每个分区将有两个副本,攻共计三个,这三个分区中也有leader和follower的概念。

a.leader选举,leader选举是从isr(副本同步队列中去选举的)
sudo …/bin/./kafka-topics.sh --describe --zookeeper localhost:2181 --topic myReplicatedTopic
可以查看到isr队列,其中维护的是follower(有资格被选举成leader:1.副本的所有节点要和zookeeper保存链接,2.副本的最后一条消息offset和leader副本的最后一条消息的offset之间的差值不能超过指定的阈值,这个阈值是可以指定的(replicat.lag.max.message 实际上就是保证你这个broker的消息与之前的leade的消息差别不能太大)。)

2.副本同步细节分析(HW&&LEO)
HW:hightWater,高水位,表示当前能被消费的最新一条数据。
LEO:log offset,表示leader的最新消息的offset
在这里插入图片描述

总结:

  • broker的集群搭建只是为了保存kafka的连接的高可用,并不能保证消息消费的高可用。
  • partition分区能够提高消息存储消费的性能,配合broker集群使用可以提高消息消费的可用性,但是挂掉某个机器还是可能导致改机器上面的分区消息无法被消费
  • 副本机制,副本机制是为了提交消息消费的可靠/可用性,多个副本之间partition选举leader,leader挂了之后还能重新选举出leader,保持消息消费的高可用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值