【kafka学习记录】1 - 为什么学习kafka

2019.10.04 学习记录1     极客时间 - 《kafka核心技术与实战》

 

一、为什么学习kafka

就拿数据量激增来说,Kafka能够有效隔离上下游业务,将上游突增的流量缓存起来,以平滑的方式传导到下游子系统中,避免了流量的不规则冲击。

Apache Kafka是一款开源的消息引擎系统。

 

“消息传递”

官方:消息引擎系统是一组规范。企业利用这组规范在不同系统之间传递语义准确的消息,实现松耦合的异步式数据传递。

平语:系统A发送消息给消息引擎系统,系统B从消息引擎系统中读取A发送的消息。

 

消息传递格式:使用的是纯二进制的字节序列。

设定传输协议,即我用什么方法把消息传输出去,有两种方式:1、点对点,即A对B; 2、发布/订阅:主题topic,多对多

kafka同时支持这两种方式,为什么呢?  JMS一组API

 

 

“削峰填谷”

为什么要使用kafka?

所谓的“削峰填谷”就是指缓冲上下游瞬时突发流量,使其更平滑。另一大好处在于发送方和接收方的松耦合,这也在一定程度上简化了应用的开发,减少了系统间不必要的交互。

 

类似于秒杀这样的业务时,上游订单流量会瞬时增加,可能出现的结果就是直接压跨下游子系统服务。

可以对上游系统限速,但问题不出现它这里,更常见的方式是引入kafka这样的消息引擎系统对抗上下游TPS的错配以及瞬时峰值流量。

 

还是这个例子,当引入了Kafka之后。上游订单服务不再直接与下游子服务进行交互。当新订单生成后它仅仅是向Kafka Broker发送一条订单消息即可。类似地,下游的各个子服务订阅Kafka中的对应主题,并实时从该主题的各自分区(Partition)中获取到订单消息进行处理,从而实现了上游订单服务与下游订单处理服务的解耦。这样当出现秒杀业务时,Kafka能够将瞬时增加的订单流量全部以消息形式保存在对应的主题中,既不影响上游服务的TPS,同时也给下游子服务留出了充足的时间去消费它们。这就是Kafka这类消息引擎系统的最大意义所在。

 

 

问题解答:

  • 怎么解决实时结果响应问题呢?比如秒杀商品,生产者产生订单,消费者处理订单结果,那这结果如何实时返回给用户呢?

这个场景使用Kafka Streams比较适合,它就是为read-process-write场景服务的

  • RabbitMQ和kafka的区别

RabbitMQ属于比较传统的消息队列系统,支持标准的消息队列协议(AMQP, STOMP,MQTT等),如果你的应用程序需要支持这些协议,那么还是使用RabbitMQ。另外RabbitMQ支持比较复杂的consumer Routing,这点也是Kafka不提供的。

  • Flink + Kafka套餐

 

  • mq和rpc的区别

往大了说属于数据流模式(dataflow mode)的问题。

我们常见的数据流有三种:1. 通过数据库;2. 通过服务调用(REST/RPC); 3. 通过异步消息传递(消息引擎,如Kafka)

RPC和MQ是有相似之处的,毕竟我们远程调用一个服务也可以看做是一个事件,但不同之处在于:

1. MQ有自己的buffer,能够对抗过载(overloaded)和不可用场景

2. MQ支持重试

3. 允许发布/订阅模式

当然它们还有其他区别。应该这样说RPC是介于通过数据库和通过MQ之间的数据流模式。

 

  • 我们公司用kafka通过埋点,日志分析,做链路监控,某个业务接口出现问题,预警系统发送消息给处理人。很及时有效,不用等运维那么慢的反馈了。合作方对比处理效率也很满意。

  • 使用kafka做不同数据库之间的准实时同步,这种通信方式一般是异步且是单向的,如果你需要这种回馈机制,最好使用服务调用的方式

  • 要是kafka突然宕机或者临时停止服务进行更新,上游服务的消息该怎么正确更好处理呢?怎么保证消息的能够在kafka恢复工作的时候正确传递?

  • 如果是升级Kafka这种主动停机,应该采用rolling upgrade来做,不至于服务中断。如果是大面积突然宕机,快速处理反而是最重要的。如果在乎上游系统的消息delivery语义,增加retries的同时试试幂等producer吧

 

  • 想要了解kafka和其他消息中间件的优劣点,系统选型时需要考虑什么?

如果是以实现高吞吐量为主要目标,Kafka是不错的首选;如果是以实现业务系统为主要目标,特别是金融类业务,可以考虑应用Kafka的流处理组件Kafka Streams。不过坦率说目前将Kafka应用于纯业务系统的并不多

 

  • 消息的重复消费问题有什么解决方案吗?可以业务去重

  • Kafka依赖ZooKeeper实现集群成员管理、领导者选举等。从架构上来说,目前所有Kafka Broker启动时都需要向ZooKeeper注册

 

 

二、术语

客户端:生产者和消费者

服务端:Kafka的服务器端由被称为Broker的服务进程构成,即一个Kafka集群由多个Broker组成,Broker负责接收和处理客户端发送过来的请求,以及对消息进行持久化。虽然多个Broker进程能够运行在同一台机器上,但更常见的做法是将不同的Broker分散运行在不同的机器上,会实现高可用。

 

备份机制

Kafka定义了两类副本:领导者副本(Leader Replica)和追随者副本。

前者对外提供服务,这里的对外指的是与客户端程序进行交互;而后者只是被动地追随领导者副本而已,不能与外界进行交互。

副本的工作机制:

    生产者总是向领导者副本写消息;而消费者总是从领导者副本读消息。至于追随者副本,它只做一件事:向领导者副本发送请求,请求领导者把最新生产的消息发给它,这样它能保持与领导者的同步。

 

虽然有了副本机制可以保证数据的持久化或消息不丢失,但没有解决伸缩性的问题。

领导者副本积累了太多的数据以至于单台Broker机器都无法容纳了,此时应该怎么办呢?一个很自然的想法就是,能否把数据分割成多份保存在不同的Broker上?即分区。

Kafka中的分区机制指的是将每个主题划分成多个分区(Partition),每个分区是一组有序的消息日志。生产者生产的每条消息只会被发送到一个分区中

 

即时总结:

副本机制可以保证数据持久化或消息不丢失

但不能保证伸缩性

分区可以保证伸缩性

 

“消息层次”

 

 

 

Kafka Broker是如何持久化数据的?

使用消息日志log来保存数据,只能追加写,避免了IO操作,这是kafka实现高吞吐量的一个重要手段;

但也要定期删除消息以回收磁盘,可以通过日志段机制

 

在Kafka底层,一个日志又近一步细分成多个日志段,消息被追加写到当前最新的日志段中,当写满了一个日志段后,Kafka会自动切分出一个新的日志段,并将老的日志段封存起来。Kafka在后台还有定时任务会定期地检查老的日志段是否能够被删除,从而实现回收磁盘空间的目的。

 

点对点:指的是同一条消息只能被下游的一个消费者消费,其他消费者则不能染指。

  • 消费者组(Consumer Group)

指的是多个消费者实例共同组成一个组来消费一组主题。这组主题中的每个分区都只会被组内的一个消费者实例消费,其他消费者实例不能消费它。为什么要引入消费者组呢?主要是为了提升消费者端的吞吐量。多个消费者实例同时消费,加速整个消费端的吞吐量(TPS)。

  • 重平衡:

       消费者组内某个消费者实例挂掉后,其他消费者实例自动重新分配订阅主题分区的过程。Rebalance是Kafka消费者端实现高可用的重要手段。

 

 

 

比较好的总结:

 

  • Kafka体系架构=M个producer +N个broker +K个consumer+ZK集群

  • producer:生产者

  • Broker:服务代理节点,Kafka服务实例。

    n个组成一个Kafka集群,通常一台机器部署一个Kafka实例,一个实例挂了其他实例仍可以使用,体现了高可用

  • consumer:消费者

    消费topic 的消息, 一个topic 可以让若干个consumer消费,若干个consumer组成一个 consumer group ,一条消息只能被consumer group 中一个consumer消费,若干个partition 被若干个consumer 同时消费,达到消费者高吞吐量

  • topic :主题

  • partition: 一个topic 可以拥有若干个partition(从 0 开始标识partition ),分布在不同的broker 上, 实现发布与订阅时负载均衡。producer 通过自定义的规则将消息发送到对应topic 下某个partition,以offset标识一条消息在一个partition的唯一性。

    一个partition拥有多个replica,提高容灾能力。

  • replica 包含两种类型:leader 副本、follower副本,

    leader副本负责读写请求,follower 副本负责同步leader副本消息,通过副本选举实现故障转移。

    partition在机器磁盘上以log 体现,采用顺序追加日志的方式添加新消息、实现高吞吐量

 

为什么 Kafka 不像 MySQL 那样允许追随者副本对外提供读服务?

  • 因为mysql一般部署在不同的机器上一台机器读写会遇到瓶颈,Kafka中的领导者副本一般均匀分布在不同的broker中,已经起到了负载的作用。即:同一个topic的已经通过分区的形式负载到不同的broker上了,读写的时候针对的领导者副本,但是量相比mysql一个还实例少太多,个人觉得没有必要在提供度读服务了。(如果量大还可以使用更多的副本,让每一个副本本身都不太大)

 

  • 不从follower读几个原因:1,kafka的分区已经让读是从多个broker读从而负载均衡,不是MySQL的主从,压力都在主上;2,kafka保存的数据和数据库的性质有实质的区别就是数据具有消费的概念,是流数据,kafka是消息队列,所以消费需要位移,而数据库是实体数据不存在这个概念,如果从kafka的follower读,消费端offset控制更复杂;3,生产者来说,kafka可以通过配置来控制是否等待follower对消息确认的,如果从上面读,也需要所有的follower都确认了才可以回复生产者,造成性能下降,如果follower出问题了也不好处理

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值