设为首页收藏本站

小牛社区-大数据学习交流社区|大数据免费学习资源

 找回密码
 立即注册!

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 68|回复: 0

Java开发大型互联网-深入理解Kafka消息系统架构应用与实现 ...

[复制链接]

80

主题

0

帖子

34

积分

吃土小白

Rank: 1

积分
34
发表于 2017-12-6 16:18:30 | 显示全部楼层 |阅读模式
Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消费。
Kafka架构


我们先宏观的看看Kafka的架构,Producer集群通过zookeeper(实际中写的是broker list)获取所写topic对应的partition列表,然后顺序发送消息(支持自己实现分发策略),broker集群负责消息的存储和传递,支持Master Slaver模型,可分布式扩展;Consumer集群从zookeeper上获取topic所在的partition列表,然后消费,一个partition只能被一个consumer消费。Name Server集群(一般是zookeeper)提供名称服务等协调信息。至于什么是topic,什么是partition,我们接下来看。
Topic
Topic是生产者生产、消费者消费的队列标识。一个Topic由一个或多个partition组成,每个partition可以单独存在一个broker上,消费者可以往任一partition发送消息,以此实现生产的分布式,任一partition都可以被且只被一个消费者消息,以此实现消费的分布式;因此partition的设计提供了分布式的基础。

同时,从上图我们也能发现这种设计还有一个优点,因为每个partition内的消息是有序的,而一个partition只能被一个消费者消费,因此Kafka能提供partition层面的消息有序,而传统的队列在多个consumer的情况下是完全无法保证有序的。
消息传递模型
传统的消息队列最少提供两种消息模型,一种P2P,一种PUB/SUB,而Kafka并没有这么做,巧妙的,它提供了一个消费者组的概念,一个消息可以被多个消费者组消费,但是只能被一个消费者组里的一个消费者消费,这样当只有一个消费者组时就等同与P2P模型,当存在多个消费者组时就是PUB/SUB模型。

消息持久化
很多系统、组件为了提升效率一般恨不得把所有数据都扔到内存里,然后定期flush到磁盘上;可实际上,现代操作系统也是这样,所有的现代操作系统都乐于将空闲内存转作磁盘缓存(页面缓存),想不用都难;对于这样的系统,他的数据在内存中保存了一份,同时也在OS的页面缓存中保存了一份,这样不但多了一个步骤还让内存的使用率下降了一半;因此,Kafka决定直接使用页面缓存;但是随机写入的效率很慢,为了维护彼此的关系顺序还需要额外的操作和存储,而线性的写入可以避免这些,实际上,线性写入(linear write)的速度大约是300MB/秒,但随即写入却只有50k/秒,其中的差别接近10000倍。这样,Kafka以页面缓存为中间的设计在保证效率的同时还提供了消息的持久化,每个消费者自己维护当前读取数据的offser(也可委托给zookeeper),以此可同时支持在线和离线的消费。
Push vs. Pull
对于消息的消费,ActiveMQ使用PUSH模型,而Kafka使用PULL模型,两者各有利弊,对于PUSH,broker很难控制数据发送给不同消费者的速度,而PULL可以由消费者自己控制,但是PULL模型可能造成消费者在没有消息的情况下盲等,这种情况下可以通过long polling机制缓解,而对于几乎每时每刻都有消息传递的流式系统,这种影响可以忽略。
可靠性
刚刚说Kafka牺牲了一些可靠性来提升吞吐量,很多同学可能担心消息的丢失,那么我们现在来看看各种情况下的可靠性。

对于如上的模型,我们分开来看,
先来看消息投递可靠性,一个消息如何算投递成功,Kafka提供了三种模式,第一种是啥都不管,发送出去就当作成功,这种情况当然不能保证消息成功投递到broker;第二种是对于Master Slave模型,只有当Master和所有Slave都接收到消息时,才算投递成功,这种模型提供了最高的投递可靠性,但是损伤了性能;第三种模型,即只要Master确认收到消息就算投递成功;实际使用时,根据应用特性选择,绝大多数情况下都会中和可靠性和性能选择第三种模型。
我们再来看消息在broker上的可靠性,因为消息会持久化到磁盘上,所以如果正常stop一个broker,其上的数据不会丢失;但是如果不正常stop,可能会使存在页面缓存来不及写入磁盘的消息丢失,这可以通过配置flush页面缓存的周期、阈值缓解,但是同样会频繁的写磁盘会影响性能,又是一个选择题,根据实际情况配置。
接着,我们再看消息消费的可靠性,Kafka提供的是“At least once”模型,因为消息的读取进度由offset提供,offset可以由消费者自己维护也可以维护在zookeeper里,但是当消息消费后consumer挂掉,offset没有即时写回,就有可能发生重复读的情况,这种情况同样可以通过调整commit offset周期、阈值缓解,甚至消费者自己把消费和commit offset做成一个事务解决,但是如果你的应用不在乎重复消费,那就干脆不要解决,以换取最大的性能。
最后,我们再来看zookeeper的可靠性,很明显,他要挂了,一切都完了,地球就毁灭了,人类就灭绝了,星级穿越也挽救不了了……所以增强可靠性的方式就是把zookeeper也部署成集群。
性能
好了,说了那么多,我们实际来测试下Kafka在各种情况下的性能,为了对比我也测了下单机模式下ActiveMQ的性能,不过由于懒,没有搭建ActiveMQ集群进行测试,但是基于其恶心的Forwarding Bridge模型,我也持悲观态度。
首先,测试环境如下:
Kafka:3 broker;8核/32G;默认配置
ActiveMQ:1 broker;8核/32G;默认配置
Producer: 一台机器通过多线程模拟多producer;8核/32G;默认配置,异步发送
Consumer: 一台机器通过多线程模拟多consumer;8核/32G;默认配置
除了特殊说明,生产和消费同时进行。
然后,我使用如下字符表示各种测试条件:
1T-1P3C-1P1C-1KW-1K:
1T:1个toipc
1P3C:1个partition 3个replication
1P1C:1个producer 1个consumer
1KW:1千万条消息
1K:每个消息1K
我先对ActiveMQ在单机多Producer、多consumer的情况下的测试,结果比我想象中的好,官方的给出的一个数据是1-2K的数据,每秒10-20K个,这样算下来大概30-40MB/S,而测试的结果在多线程的情况下会更好些。

然后我又对Kafka进行了相应的测试,用一个partition模拟单机模式,结果和预想的一样,在单机模型下,两者差异不大;而官方给的数据说生产者能达到50MB/S,消费者能达到100MB/S,生产者符合官方数据,而消费者我始终没有压到那么高的速度。

接下来的对于Kafka集群,我想同样数量的消息会不会因为topic数目的增多而影响,测试结果如下,表明topic越多,速度会有所下降,也符合预期。

然后为了测试partition对性能的影响,进行了如下测试,可以看到partition数量越多,总的生产和消费速度越快;但是意外的是Only produce情况下生产效率没有明显提升反而略慢,这里怀疑和page cache有关,没有深入研究。

综合上面所说,我们可以看到Kafka的性能和吞吐是可以扩展的。
风险点
对于我们来说,Kafka主要有两个风险点,第一,要深入使用必须要熟读源码,而kafka源码是用scala写的,我们并没有相应的技术储备,需要学习;第二,kafka技术较新,目前的版本是0.8.1.1,看起来还不太成熟。
总结
以 上就是我对Java开发大型互联网-深入理解Kafka消息系统架构应用与实现问题及其优化总结,分享给大家,希望大家知道什么是Java开发大型互联网-深入理解Kafka消息系统架构应用与实现问题及其优化。觉得收获的话可以点个关注收藏转发一波喔,谢谢大佬们支持!

  • 1、多写多敲代码,好的代码与扎实的基础知识一定是实践出来的
  • 2、可以去百度搜索腾讯课堂图灵学院的视频来学习一下java架构实战案例,还挺不错的。
  • 最后,每一位读到这里的网友,感谢你们能耐心地看完。希望在成为一名更优秀的Java程序员的道路上,我们可以一起学习、一起进步!都能赢取白富美,走向架构师的人生巅峰!
  • 3丶想了解学习以上课程内容可加群:469717771 验证码头条(06 必过)欢迎大家的加入哟!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册!

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册!

本版积分规则

快速回复 返回顶部 返回列表