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. Flask之基础

    一,flask Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求 ...

  2. thinkphp概述

    thinkphp框架是一个免费的,开源,快速,简单的面向对象的轻量级PHP开发框架. 了解什么是thinkphp概述,thinkphp项目目录结构,thinkphp的控制器,视图,thinkphp项目 ...

  3. Flink原理(五)——容错机制

    本文是博主阅读Flink官方文档以及<Flink基础教程>后结合自己理解所写,若有表达有误的地方欢迎大伙留言指出. 1.  前言 流式计算分为有状态和无状态两种情况,所谓状态就是计算过程中 ...

  4. ISCC之Re2

    硬核rust逆向 首先去学了一天rust...我TMD IDA打开,跟踪主函数 看一下伪代码,发现有一串密文 跟进去发现一串数据,猜测有可能是flag的加密数据,于是回头去分析算法 发现一个关键点 i ...

  5. js select 默认回显判断

    <select id="dataselect" class="input-medium" style="width: 20%"> ...

  6. python关于字典嵌套字典,列表嵌套字典根据值进行排序

    python 对于字典嵌套字典, 列表嵌套字典排序 例:列表嵌套自字典:d = [{"name": '张三', 's': 68}, {'name': '李四', 's': 97}] ...

  7. bzoj 4128: Matrix ——BSGS&&矩阵快速幂&&哈希

    题目 给定矩阵A, B和模数p,求最小的正整数x满足 A^x = B(mod p). 分析 与整数的离散对数类似,只不过普通乘法换乘了矩阵乘法. 由于矩阵的求逆麻烦,使用 $A^{km-t} = B( ...

  8. httpclient: 设置连接池及超时配置,请求数据:PoolingHttpClientConnectionManager

    public static void main(String[] args) throws Exception{ //httpclient连接池 //创建连接池 PoolingHttpClientCo ...

  9. LightOJ - 1282 - Leading and Trailing(数学技巧,快速幂取余)

    链接: https://vjudge.net/problem/LightOJ-1282 题意: You are given two integers: n and k, your task is to ...

  10. 洛谷 P3372 【模板】线段树 1 题解

    Analysis 新学了一种很骚气的线段树写法,就是把整个线段树放到一个struct里面,然后可以直接调用里面的函数 #include<iostream> #include<cstd ...