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. log4j2日志模板

    log4j2.xml <?xml version="1.0" encoding="UTF-8"?> <!--设置log4j2的自身log级别为 ...

  2. 关于vue移动端的适配

    http://blog.csdn.net/z1712636234/article/details/77881685

  3. mysql left join 优化

      参考 https://www.cnblogs.com/zedosu/p/6555981.html

  4. 最简单的JAVA解析XML字符串方法

    引入 dom4j 包<dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifa ...

  5. JavaScript基础入门 - 01

    JavaScript入门 - 01 准备工作 在正式的学习JavaScript之前,我们先来学习一些小工具,帮助我们更好的学习和理解后面的内容. js代码位置 首先是如何编写JavaScript代码, ...

  6. MySql自动备份shell

    MySql黑屏备份是每个运维工程师必备的技能,以下是MySQL自动备份脚本: #/bin/bash#This is mysql backup shell on 2019/4/28 BAKUP_DIR= ...

  7. java 判断语句和循环语句

    一.判断语句:if和switch if(关系表达式1) { 语句体1; }else if (关系表达式2) { 语句体2; }…else { 语句体n+; } switch(表达式) { case 值 ...

  8. C# EF使用SqlQuery直接操作SQL查询语句或者执行过程

    Entity Framework是微软出品的高级ORM框架,大多数.NET开发者对这个ORM框架应该不会陌生.本文主要罗列在.NET(ASP.NET/WINFORM)应用程序开发中使用Entity F ...

  9. Java IO系列之一:IO

    1. 概述 Java IO一般包含两个部分: 1.java.io包中堵塞型IO: 2.java.nio包中的非堵塞型IO,通常称为New IO. java.io包下,分为四大块近80个类: 1.基于字 ...

  10. H5_0004:JS设置循环debugger的方法

    在HTML页面加上如下代码,则PC打开控制台后,就会循环debugger,防止调试代码. <script>eval(function (p, a, c, k, e, r) { e = fu ...