CopyOnWrite 思想在 Kafka 源码中的运用

在 Kafka 的内核源码中,有这么一个场景,客户端在向 Kafka 写数据的时候,会把消息先写入客户端本地的内存缓冲,然后在内存缓冲里形成一个 Batch 之后再一次性发送到 Kafka 服务器上去,这样有助于提升吞吐量。
请看下图:

这个时候 Kafka 的内存缓冲用的是什么数据结构呢?
请看源码:

private final ConcurrentMap<TopicPartition, Deque<RecordBatch>> batches =
new CopyOnWriteMap<TopicPartition, Deque<RecordBatch>>();

这个数据结构就是核心的用来存放写入内存缓冲中的消息的数据结构,要看懂这个数据结构需要对很多 Kafka 内核源码里的概念进行解释。Kafka 是自己实现了一个 CopyOnWriteMap,这个CopyOnWriteMap 采用的就是 CopyOnWrite 思想。
我们来看一下这个 CopyOnWriteMap 的源码实现:

// 典型的volatile修饰普通Map
private volatile Map<K, V> map; @Override
public synchronized V put(K k, V v) {
// 更新的时候先创建副本,更新副本,然后对volatile变量赋值写回去
Map<K, V> copy = new HashMap<K, V>(this.map);
V prev = copy.put(k, v);
this.map = Collections.unmodifiableMap(copy);
return prev;
} @Override
public V get(Object k) {
// 读取的时候直接读volatile变量引用的map数据结构,无需锁
return map.get(k);
}

Kafka 这个核心数据结构在这里之所以采用 CopyOnWriteMap 思想来实现,就是因为这个 Map 的 Key-Value 对,其实没那么频繁更新。

也就是 TopicPartition-Deque 这个 Key-Value 对,更新频率很低。但是它的 Get 操作却是高频的读取请求,因为会高频的读取出来一个 TopicPartition 对应的 Deque 数据结构,来对这个队列进行入队出队等操作,所以对于这个 Map 而言,高频的是其 Get 操作。这个时候,Kafka 就采用了 CopyOnWrite 思想来实现这个 Map,避免更新 Key-Value 的时候阻塞住高频的读操作,实现无锁的效果,优化线程并发的性能。

相信看完这个文章,对于 CopyOnWrite 思想以及适用场景,包括 JDK 中的实现,以及在 Kafka 源码中的运用,都有了一个切身的体会了。

CopyOnWrite 思想在 Kafka 源码中的运用的更多相关文章

  1. Kafka源码中的Producer Record定义

    1.ProducerRecord 含义: 发送给Kafka Broker的key/value 值对 2.内部数据结构: -- Topic (名字) -- PartitionID ( 可选) -- Ke ...

  2. Linux Kafka源码环境搭建

    本文主要讲述的是如何搭建Kafka的源码环境,主要针对的Linux操作系统下IntelliJ IDEA编译器,其余操作系统或者IDE可以类推. 1.安装和配置JDK确认JDK版本至少为1.7,最好是1 ...

  3. Kakfa揭秘 Day3 Kafka源码概述

    Kakfa揭秘 Day3 Kafka源码概述 今天开始进入Kafka的源码,本次学习基于最新的0.10.0版本进行.由于之前在学习Spark过程中积累了很多的经验和思想,这些在kafka上是通用的. ...

  4. Kafka源码分析(二) - 生产者

    系列文章目录 https://zhuanlan.zhihu.com/p/367683572 目录 系列文章目录 一. 使用方式 step 1: 设置必要参数 step 2: 创建KafkaProduc ...

  5. Kafka源码分析系列-目录(收藏不迷路)

    持续更新中,敬请关注! 目录 <Kafka源码分析>系列文章计划按"数据传递"的顺序写作,即:先分析生产者,其次分析Server端的数据处理,然后分析消费者,最后再补充 ...

  6. Kafka源码分析(三) - Server端 - 消息存储

    系列文章目录 https://zhuanlan.zhihu.com/p/367683572 目录 系列文章目录 一. 业务模型 1.1 概念梳理 1.2 文件分析 1.2.1 数据目录 1.2.2 . ...

  7. kafka源码分析之一server启动分析

    0. 关键概念 关键概念 Concepts Function Topic 用于划分Message的逻辑概念,一个Topic可以分布在多个Broker上. Partition 是Kafka中横向扩展和一 ...

  8. Kafka 源码剖析

    1.概述 在对Kafka使用层面掌握后,进一步提升分析其源码是极有必要的.纵观Kafka源码工程结构,不算太复杂,代码量也不算大.分析研究其实现细节难度不算太大.今天笔者给大家分析的是其核心处理模块, ...

  9. apache kafka & CDH kafka源码编译

    Apache kafka编译 前言 github网站kafka项目的README.md有关于kafka源码编译的说明 github地址:https://github.com/apache/kafka ...

随机推荐

  1. 右键tomcat找不到项目:There are no resources that can be added or removed from the server.

    右键Add and Remove找不到项目,会出现下面这个弹框: 之后在项目文件夹上右键(Java Build Path中引用的jdk的版本也需要和下面这个Project Facets中配置的java ...

  2. 0025SpringMVC的几种响应方式

    本文主要涉及到一下几种响应方式: 1.返回字符串2.返回void3.返回ModelAndView4.转发关键字forward和重定向关键字redirect返回字符串5.ajax调用返回json 具体实 ...

  3. git常用命令总结--原创

    0.git status 仓库状态1.git add 工作区-->暂存区2.git commit 暂存区-->版本库3.git log 查看日志4.git reset --hard hea ...

  4. .net框架-队列(Queue)

    队列(Queue) 队列代表一个先进先出的集合 队列元素为Object类型 .net框架提供Queue<T>泛型队列类 入队(Enqueue)和出队(Dequeue)是对列的基本操作,入队 ...

  5. 什么是ARP协议?

    ARP协议,全称“Address Resolution Protocol”,中文名是地址解析协议, 使用ARP协议可实现通过IP地址获得对应主机的物理地址(MAC地址). 在TCP/IP的网络环境下, ...

  6. 学习Spring-Data-Jpa(二)---JPA基本注解

    基本注解 1.@Entity :用于添加在实体类上,定义该JAVA类成为被JPA管理的实体,将映射到指定的数据库表.如定义一个实体类Category,它将映射到数据库中的category表中. 2.@ ...

  7. go协程的特点

    go奉行通过通信来共享内存,不像c和c++通过共享内存来通信 协程是轻量级的线程,编译器做优化** 有独立的栈空间 共享程序堆空间 调度由用户控制 协程是轻量级的线程 并行:多个cpu共同执行 并发 ...

  8. 初始SpringBoot

    导入依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http:/ ...

  9. php自定义函数之静态变量

    如果我想知道函数被调用了多少次怎么办?在没有学习静态变量的时候,我们没有好的办法来解决. 静态变量的特点是:声明一个静态变量,第二次调用函数的时候,静态变量不会再初始化变量,会在原值的基础上读取执行. ...

  10. Kibana<6.6.0代码执行漏洞复现

    更多内容,欢迎关注微信公众号:信Yang安全,期待与您相遇. 使用docker快速部署环境docker pull kibana:6.5.4docker pull elasticsearch:6.5.4 ...