Kafka 的生产者优秀架构设计( 五 )
2
这个 Kafka 生产者面临的是一个高并发的场景 , 大量的消息会涌入这个这个数据结构 , 所以这个数据结构需要保证线程安全 , 这样我们就不能使用 HashMap 这样的数据结构了 。
3
这个数据结构需要支持的是读多写少的场景 。 读多是因为每条消息过来都会根据 key 读取 value 的信息 , 假如有 1000 万条消息 , 那么就会读取 batches 对象 1000 万次 。 写少是因为 , 比如我们生产者发送数据需要往一个主题里面去发送数据 , 假设这个主题有 50 个分区 , 那么这个 batches 里面就需要写 50 个 key-value 数据就可以了(大家要搞清楚我们虽然要写 1000 万条数据 , 但是这 1000 万条是写入 queue 队列的 batch 里的 , 并不是直接写入 batches所以就我们刚刚说的这个场景 , batches 里只需要最多写 50 条数据就可以了) 。
根据第二和第三个场景我们总结出来 , Kafka 这儿需要一个能保证线程安全的 , 支持读多写少的 Map 数据结构 。 但是 Java 里面并没有提供出来的这样的一个数据 , 唯一跟这个需求比较接近的是 CopyOnWriteArrayList , 但是偏偏它又不是 Map 结构 , 所以 Kafka 这儿模仿 CopyOnWriteArrayList 设计了 CopyOnWriteMap 。 采用了读写分离的思想解决了线程安全且支持读多写少等问题 。 高效的数据结构保证了生产者的性能 。 (CopyOnWriteArrayList 不熟悉的同学 , 可以尝试百度学习) 。 这儿笔者建议大家可以去看看 Kafka 生产者往 batches 里插入数据的源码 , 生产者为了保证插入数据的高性能 , 采用了多线程 , 又为了线程安全 , 使用了分段加锁等多种手段 , 源码非常精彩 。 02 生产者高级设计之内存池设计 刚刚我们看到 batches 里面存储的是批次 , 批次默认的大小是 16K , 整个缓存的大小是 32M , 生产者每封装一个批次都需要去申请内存 , 正常情况下如果一个批次发送出去了以后 , 那么这 16K 的内存就等着 GC 来回收了 。 但是如果是这样的话 , 就可能会频繁的引发 FullGC , 故而影响生产者的性能 , 所以在缓存里面设计了一个内存池(类似于我们平时用的数据库的连接池) , 一个 16K 的内存用完了以后 , 把数据清空 , 放入到内存池里 , 下个批次用的时候直接从里面获取就可以 。 这样大大的减少了 GC 的频率 , 保证了生产者的稳定和高效(Java 的 GC 问题是一个头疼的问题 , 所以这种设计也非常值得我们去积累) 。 结尾 Kafka 的设计之中精彩的地方有很多 , 今天我们截取了一部分跟大家分享 。 之前我看到过 Kafka 的源码以后 , 就想以后如果我要去当老师 , 去培养架构师的话 , 那么我一定得跟学生分享 Kafka 的源码 , 通过学习 Kafka 源码提升系统架构能力 , 再次建议大家有空可以研究研究 Kafka 的源码 , 大家加油!! 推荐阅读 钉钉跃居 App Store 榜首背后 , 全民云办公时代来临?远程办公 4 大坑 , 坑坑“致命”!揭秘阿里、腾讯、字节跳动在家办公的区别2020年区块链和分布式账本技术的5大趋势 你点的每一个在看 , 我认真当成了喜欢推荐阅读
- 精灵宝可梦|《宝可梦》人称神兽版本“秃鹰娜”,伽勒尔火焰鸟的表现多优秀?
- 单机|游戏《原神》,算是挺优秀的游戏了,就是获取资源有些慢
- 狄仁杰|狄仁杰是现在的T0射手?强度稳定,技能机制优秀
- 阴阳师|外媒评有史以来最优秀的10款恐怖游戏,谁是你的童年阴影
- |被埋没的优秀大作,还没有走向热榜,却已经过时了
- 剑网3|几部优秀的游戏类文!虚拟!现实!
- fate grand order|fgo四星骑阶灰姑娘龙娘强度初评公开 骑阶金时的优秀替代打手
- 伐木工|《明日之后》萌新学院:末世优秀伐木工都是怎么炼成的?
- 三国杀|三国杀:不是神将的神将!这些武将堪称强大,每一个都是那么优秀
- 冒险游戏|一款质量优秀的动作冒险游戏