Kafka network Processor

SocketServer.Processor

override def run() {
startupComplete()
try {
while (isRunning) {
try {
// 从connetions queue 中取出 New connection 配置相关信息(register OP_READ),初始化配置
configureNewConnections()
//处理所有响应client的 io write
//(request -> process -> response queue -> queue poll -> record metrics
// -> write NetworkInterface)
processNewResponses()
//查询就绪的Channel OP_READ 事件
poll()
//处理客户端请求,添加到request task 到queue
processCompletedReceives()
//处理已经完成的发送
processCompletedSends()
//处理client 断开
processDisconnected()
} catch {
case e: Throwable => processException("Processor got uncaught exception.", e)
}
}
} finally {
debug("Closing selector - processor " + id)
swallowError(closeAll())
shutdownComplete()
}
}
client request process
class KafkaRequestHandler(id: Int,
brokerId: Int,
val aggregateIdleMeter: Meter,
val totalHandlerThreads: Int,
val requestChannel: RequestChannel,
apis: KafkaApis,
time: Time) extends Runnable with Logging {
this.logIdent = "[Kafka Request Handler " + id + " on Broker " + brokerId + "], "
private val latch = new CountDownLatch() def run() {
while(true) {
val startSelectTime = time.nanoseconds
//从request queue 取出 task
val req = requestChannel.receiveRequest()
val endTime = time.nanoseconds
val idleTime = endTime - startSelectTime
aggregateIdleMeter.mark(idleTime / totalHandlerThreads) req match {
case RequestChannel.ShutdownRequest =>
debug(s"Kafka request handler $id on broker $brokerId received shut down command")
latch.countDown()
return //client reqeust
case request: RequestChannel.Request =>
try {
request.requestDequeueTimeNanos = endTime
trace(s"Kafka request handler $id on broker $brokerId handling request $request")
//KafkaApis api handle, client 请求处理逻辑
apis.handle(request)
} catch {
case e: FatalExitError =>
latch.countDown()
Exit.exit(e.statusCode)
case e: Throwable => error("Exception when handling request", e)
} finally {
request.releaseBuffer()
} case null => // continue
}
}
}

index file

文件i/o的读操作,会先向文件设备发起读请求,然后驱动把请求要读的数据读取到文件的缓冲区中,这个缓冲区位于内核,然后再把这个缓冲区中的数据复制到程序虚拟地址空间中的一块区域中。

文件i/o的写操作,会向文件设备发起写请求,驱动把要写入的数据复制到程序的缓冲区中,位于用户空间,然后再把这个缓冲区的数据复制到文件的缓冲区中。

内存映射文件,是把位于硬盘中的文件看做是程序地址空间中一块区域对应的物理存储器,文件的数据就是这块区域内存中对应的数据,读写文件中的数据,直接对这块区域的地址操作,就可以,减少了内存复制的环节。

内存映射文件比起文件I/O操作,效率要高,而且文件越大,体现出来的差距越大。

index file 采用 mmap 提升效率:

abstract class AbstractIndex[K, V](@volatile var file: File, val baseOffset: Long,
val maxIndexSize: Int = -, val writable: Boolean) extends Logging {
@volatile
protected var mmap: MappedByteBuffer = {
val newlyCreated = file.createNewFile()
val raf = if (writable) new RandomAccessFile(file, "rw") else new RandomAccessFile(file, "r")
try {
/* 是否预先分配 memeory */
if(newlyCreated) {
if(maxIndexSize < entrySize)
throw new IllegalArgumentException("Invalid max index size: " + maxIndexSize)
raf.setLength(roundDownToExactMultiple(maxIndexSize, entrySize))
} /* 内存映射文件 */
val len = raf.length()
val idx = {
if (writable)
raf.getChannel.map(FileChannel.MapMode.READ_WRITE, , len)
else
raf.getChannel.map(FileChannel.MapMode.READ_ONLY, , len)
}
/* 设置 position 位置 */
if(newlyCreated)
idx.position()
else
idx.position(roundDownToExactMultiple(idx.limit(), entrySize))
idx
} finally {
CoreUtils.swallow(raf.close())
}
}
}

index采用稀疏索引,减少占用空间:

@nonthreadsafe
class LogSegment(val log: FileRecords,
val index: OffsetIndex,
val timeIndex: TimeIndex,
val txnIndex: TransactionIndex,
val baseOffset: Long,
val indexIntervalBytes: Int,
val rollJitterMs: Long,
time: Time) extends Logging {
@nonthreadsafe
def append(firstOffset: Long,
largestOffset: Long,
largestTimestamp: Long,
shallowOffsetOfMaxTimestamp: Long,
records: MemoryRecords): Unit = {
 ...
// 计算是否将索引写入index文件
if(bytesSinceLastIndexEntry > indexIntervalBytes) {
index.append(firstOffset, physicalPosition)
timeIndex.maybeAppend(maxTimestampSoFar, offsetOfMaxTimestamp)
bytesSinceLastIndexEntry =
}
bytesSinceLastIndexEntry += records.sizeInBytes
}
}
}

kafka Network的更多相关文章

  1. kafka.network.AbstractServerThread中的线程协作机制

    这个虚类是kafka.network.Acceptor和kafka.network.Processor的父类,提供了一个抽象的Sever线程. 它的有趣之处在于为子类的启动和停止提供了线程间的协作机制 ...

  2. Kafka Network层解析,还是有人把它说清楚了

    我们知道kafka是基于TCP连接的.其并没有像很多中间件使用netty作为TCP服务器.而是自己基于Java NIO写了一套. 几个重要类 先看下Kafka Client的网络层架构. 本文主要分析 ...

  3. kafka.network.SocketServer分析

    当Kafka启动时,会启动这个SocketServer来接收客户端的连接,处理客户端请求,发送响应. 这个类的注释说明了这个socket server的结构 /** * An NIO socket s ...

  4. kafka集群安装部署

    kafka集群安装 使用的版本 系统:centos6.5 centos6.7 jdk:1.7.0_79 zookeeper:3.4.9 kafka:2.10-0.10.1.0 一.环境准备[只列,不具 ...

  5. Kafka设计解析(三)- Kafka High Availability (下)

    本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/06/08/KafkaColumn3 摘要 本文在上篇文章基础上,更加深入讲解了Kafka的HA机 ...

  6. 【原创】Kakfa network包源代码分析

    kafka.network包主要为kafka提供网络服务,通常不包含具体的逻辑,都是一些最基本的网络服务组件.其中比较重要的是Receive.Send和Handler.Receive和Send封装了底 ...

  7. Flume+Kafka+Strom基于伪分布式环境的结合使用

    目录: 一.Flume.Kafka.Storm是什么,如何安装? 二.Flume.Kafka.Storm如何结合使用? 1) 原理是什么? 2) Flume和Kafka的整合  3) Kafka和St ...

  8. kafka监控系统

    Metrics-Java版的指标度量工具之一 Metrics-Java版的指标度量工具之二 JAVA Metrics 度量工具使用介绍1 JAVA Metrics度量工具 - Metrics Core ...

  9. kafka单节点部署无法访问问题解决

    场景:在笔记本安装了一台虚拟机, 在本地的虚拟机上部署了一个kafka服务: 写了一个测试程序,在笔记本上运行测试程序,访问虚拟机上的kafka,报如下异常: 2015-01-15 09:33:26 ...

随机推荐

  1. webpack4 学习 --- 处理静态资源

    webpack 是利用loader 来处理各种资源的,wepback的配置基本上就是为各种资源文件,指定不同类型的loader. 1,处理css 最基本的css 处理loader 是css-loade ...

  2. Hadoop系列(二):Hadoop单节点部署

    环境:CentOS 7 JDK: 1.7.0_80 hadoop:2.8.5 hadoop(192.168.56.101) 配置基础环境 1. 测试环境可以直接关闭selinux和防火墙 2. 主机添 ...

  3. 【THUSC2017】【LOJ2977】巧克力 斯坦纳树

    题目大意 有一个网格(或者你可以认为这是一个图),每个点都有颜色 \(c_i\) 和点权 \(a_i\). 求最小的连通块,满足这个连通块内点的颜色数量 \(\geq k\).在满足点数最少的前提下, ...

  4. 科学地增加postgresql最大连接数

    PG配置文件路径 /etc/postgresql/9.3/main/postgresql.conf 首先如何查看最大连接数 This SQL will help you select max_conn ...

  5. beego框架开发投票网站(1) beego基础之运行逻辑

    本文档需结合beego官方文档食用 博主也仅仅是边学边记录,不保证内容的正确性,请当做通俗读物来看待 首先 beego是一个基于go语言的框架 其次 beego是一个mvc框架 框架可以理解为对底层又 ...

  6. BZOJ 1010: 玩具装箱toy (斜率优化dp)

    Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...

  7. 利用java内部静态类实现懒汉式单例

    /** * @Description: 利用键值模式控制service * @Author: zhanglifeng * @Date: 2019年 04月 28日 14:41 **/ public c ...

  8. WebDriver下载地址

    http://chromedriver.storage.googleapis.com/index.html https://blog.csdn.net/ccggaag/article/details/ ...

  9. python之路(10)类的内置函数

    目录 isinstance()和issubclass() __setitem__.__getitem__和__delitem__ __str__和__reper__ __format__ __slot ...

  10. SpringBoot项目打成jar包后上传文件到服务器 目录与jar包同级问题

    看标题好像很简单的样子,但是针对使用jar包发布SpringBoot项目就不一样了.当你使用tomcat发布项目的时候,上传文件存放会变得非常简单,因为你可以随意操作项目路径下的资源.但是当你使用Sp ...