设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 数据 手机
当前位置: 首页 > 运营中心 > 网站设计 > 教程 > 正文

Apache Kafka快速入门指南(2)

发布时间:2019-11-13 17:23 所属栏目:48 来源:AiChinaTech
导读:前面已经介绍了Kafka如何进行有效的存储,以及了解了Producer和Consumer如何工作。接下来讨论的是Kafka如何确保消息在Producer和Consumer之间传输。有以下三种可能的传输保障(delivery guarantee): At most once:

前面已经介绍了Kafka如何进行有效的存储,以及了解了Producer和Consumer如何工作。接下来讨论的是Kafka如何确保消息在Producer和Consumer之间传输。有以下三种可能的传输保障(delivery guarantee):

  • At most once: 消息可能会丢,但绝不会重复传输
  • At least once:消息绝不会丢,但可能会重复传输
  • Exactly once:每条消息肯定会被传输一次且仅传输一次

Kafka的消息传输保障机制非常直观。当Producer向Broker发送消息时,一旦这条消息被commit,由于副本机制(replication)的存在,它就不会丢失。但是如果Producer发送数据给Broker后,遇到的网络问题而造成通信中断,那producer就无法判断该条消息是否已经提交(commit)。虽然Kafka无法确定网络故障期间发生了什么,但是Producer可以retry多次,确保消息已经正确传输到Broker中,所以目前Kafka实现的是At least once。

Consumer从Broker中读取消息后,可以选择Commit,该操作会在Zookeeper中存下该Consumer在该Partition下读取的消息的offset。该Consumer下一次再读该Partition时会从下一条开始读取。如未commit,下一次读取的开始位置会跟上一次commit之后的开始位置相同。当然也可以将consumer设置为autocommit,即Consumer一旦读取到数据立即自动commit。如果只讨论这一读取消息的过程,那Kafka是确保了exactly once, 但是如果由于前面Producer与Broker之间的某种原因导致消息的重复,那么这里就是At least once。

考虑这样一种情况,当Consumer读完消息之后先commit再处理消息,在这种模式下,如果consumer在commit后还没来得及处理消息就crash了,下次重新开始工作后就无法读到刚刚已提交而未处理的消息,这就对应于At most once了。读完消息先处理再commit。这种模式下,如果处理完了消息在commit之前Consumer crash了,下次重新开始工作时还会处理刚刚未commit的消息,实际上该消息已经被处理过了,这就对应于at least once。

要做到exactly once就需要引入消息去重机制。Kafka文档中提及GUID(Globally Unique Identifier)的概念,通过客户端生成算法得到每个消息的unique id,同时可映射至broker上存储的地址,即通过GUID便可查询提取消息内容,也便于发送方的幂等性保证,需要在broker上提供此去重处理模块,目前版本尚不支持。

针对GUID, 如果从客户端的角度去重,那么需要引入集中式缓存,必然会增加依赖复杂度,另外缓存的大小难以界定。不只是Kafka, 类似RabbitMQ以及RocketMQ这类商业级中间件也只保障at least once, 且也无法从自身去进行消息去重。所以我们建议业务方根据自身的业务特点进行去重,比如业务消息本身具备幂等性,或者借助Redis等其他产品进行去重处理。

Kafka作为消息队列:

传统的消息有两种模式:队列和发布订阅。 在队列模式中,消费者池从服务器读取消息(每个消息只被其中一个读取); 发布订阅模式:消息广播给所有的消费者。这两种模式都有优缺点,队列的优点是允许多个消费者瓜分处理数据,这样可以扩展处理。但是,队列不像多个订阅者,一旦消息者进程读取后故障了,那么消息就丢了。而发布和订阅允许你广播数据到多个消费者,由于每个订阅者都订阅了消息,所以没办法缩放处理。

Kafka中的Consumer Group有两种形式:

a、队列:允许同名的消费者组成员共同处理。

b、发布订阅:广播消息给多个消费者组。

Kafka的每个topic都具有这两种模式。

传统的消息系统按顺序保存数据,如果多个消费者从队列消费,则服务器按存储的顺序发送消息,但是,尽管服务器按顺序发送,多个并行请求将会是异步的,因此消息可能乱序到达。这意味着只要消息存在并行消费的情况,顺序就无法保证。消息系统常常通过仅设1个消费者来解决这个问题,但是这意味着没用到并行处理。

Kafka有比传统的消息系统更强的顺序保证。通过并行Topic的Parition,Kafka提供了顺序保证和负载均衡。每个Partition仅由同一个消费者组中的一个消费者消费到。并确保消费者是该Partition的唯一消费者,并按顺序消费数据。每个topic有多个分区,则需要对多个消费者做负载均衡,但请注意,相同的消费者组中不能有比分区更多的消费者,否则多出的消费者一直处于空等待,不会收到消息。

Kafka作为存储系统

所有发布消息到消息队列和消费分离的系统,实际上都充当了一个临时存储系统。Kafka还是一个非常高性能的存储系统。写入到Kafka的数据将写到磁盘并复制到集群中保证容错性。并允许生产者等待消息应答,直到消息完全写入。Kafka的存储结构保证无论服务器上有50KB或50TB数据,执行效率是相似的,因此可达到水平扩展的目标。还可以认为Kafka是一种专用于高性能,低延迟,提交日志存储,复制,和传播特殊用途的分布式文件系统。

Kafka流处理

Kafka的更高目标是实时流处理。在Kafka中,流处理持续获取输入topic的数据,进行处理加工,然后写入输出topic。例如,一个零售APP,接收销售和出货的输入流,统计数量或调整价格后输出。

简单的需求可以直接使用Producer和Consumer API进行处理。对于复杂的转换,Kafka提供了更强大的Streams API,可构建聚合计算或连接流到一起的复杂应用程序。

综上所述,Kafka 的设计可以帮助我们解决很多架构上的问题。但是想要用好 Kafka 的高性能、低耦合、高可靠性等特性,我们需要非常了解 Kafka,以及我们自身的业务需求,综合考虑应用场景。

【本文是51CTO专栏机构“AiChinaTech”的原创文章,微信公众号( id: tech-AI)”】

戳这里,看该作者更多好文

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读