Kafka network Processor

SocketServer.Processor

  1. override def run() {
  2. startupComplete()
  3. try {
  4. while (isRunning) {
  5. try {
  6. // 从connetions queue 中取出 New connection 配置相关信息(register OP_READ),初始化配置
  7. configureNewConnections()
  8. //处理所有响应client的 io write
  9. //(request -> process -> response queue -> queue poll -> record metrics
  10. // -> write NetworkInterface)
  11. processNewResponses()
  12. //查询就绪的Channel OP_READ 事件
  13. poll()
  14. //处理客户端请求,添加到request task 到queue
  15. processCompletedReceives()
  16. //处理已经完成的发送
  17. processCompletedSends()
  18. //处理client 断开
  19. processDisconnected()
  20. } catch {
  21. case e: Throwable => processException("Processor got uncaught exception.", e)
  22. }
  23. }
  24. } finally {
  25. debug("Closing selector - processor " + id)
  26. swallowError(closeAll())
  27. shutdownComplete()
  28. }
  29. }
  1. client request process
  1. class KafkaRequestHandler(id: Int,
  2. brokerId: Int,
  3. val aggregateIdleMeter: Meter,
  4. val totalHandlerThreads: Int,
  5. val requestChannel: RequestChannel,
  6. apis: KafkaApis,
  7. time: Time) extends Runnable with Logging {
  8. this.logIdent = "[Kafka Request Handler " + id + " on Broker " + brokerId + "], "
  9. private val latch = new CountDownLatch()
  10.  
  11. def run() {
  12. while(true) {
  13. val startSelectTime = time.nanoseconds
  14. //从request queue 取出 task
  15. val req = requestChannel.receiveRequest()
  16. val endTime = time.nanoseconds
  17. val idleTime = endTime - startSelectTime
  18. aggregateIdleMeter.mark(idleTime / totalHandlerThreads)
  19.  
  20. req match {
  21. case RequestChannel.ShutdownRequest =>
  22. debug(s"Kafka request handler $id on broker $brokerId received shut down command")
  23. latch.countDown()
  24. return
  25.  
  26. //client reqeust
  27. case request: RequestChannel.Request =>
  28. try {
  29. request.requestDequeueTimeNanos = endTime
  30. trace(s"Kafka request handler $id on broker $brokerId handling request $request")
  31. //KafkaApis api handle, client 请求处理逻辑
  32. apis.handle(request)
  33. } catch {
  34. case e: FatalExitError =>
  35. latch.countDown()
  36. Exit.exit(e.statusCode)
  37. case e: Throwable => error("Exception when handling request", e)
  38. } finally {
  39. request.releaseBuffer()
  40. }
  41.  
  42. case null => // continue
  43. }
  44. }
  45. }

index file

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

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

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

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

index file 采用 mmap 提升效率:

  1. abstract class AbstractIndex[K, V](@volatile var file: File, val baseOffset: Long,
  2. val maxIndexSize: Int = -, val writable: Boolean) extends Logging {
  3. @volatile
  4. protected var mmap: MappedByteBuffer = {
  5. val newlyCreated = file.createNewFile()
  6. val raf = if (writable) new RandomAccessFile(file, "rw") else new RandomAccessFile(file, "r")
  7. try {
  8. /* 是否预先分配 memeory */
  9. if(newlyCreated) {
  10. if(maxIndexSize < entrySize)
  11. throw new IllegalArgumentException("Invalid max index size: " + maxIndexSize)
  12. raf.setLength(roundDownToExactMultiple(maxIndexSize, entrySize))
  13. }
  14.  
  15. /* 内存映射文件 */
  16. val len = raf.length()
  17. val idx = {
  18. if (writable)
  19. raf.getChannel.map(FileChannel.MapMode.READ_WRITE, , len)
  20. else
  21. raf.getChannel.map(FileChannel.MapMode.READ_ONLY, , len)
  22. }
  23. /* 设置 position 位置 */
  24. if(newlyCreated)
  25. idx.position()
  26. else
  27. idx.position(roundDownToExactMultiple(idx.limit(), entrySize))
  28. idx
  29. } finally {
  30. CoreUtils.swallow(raf.close())
  31. }
  32. }
  33. }

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

  1. @nonthreadsafe
  2. class LogSegment(val log: FileRecords,
  3. val index: OffsetIndex,
  4. val timeIndex: TimeIndex,
  5. val txnIndex: TransactionIndex,
  6. val baseOffset: Long,
  7. val indexIntervalBytes: Int,
  8. val rollJitterMs: Long,
  9. time: Time) extends Logging {
  10. @nonthreadsafe
  11. def append(firstOffset: Long,
  12. largestOffset: Long,
  13. largestTimestamp: Long,
  14. shallowOffsetOfMaxTimestamp: Long,
  15. records: MemoryRecords): Unit = {
  16.  ...
  17. // 计算是否将索引写入index文件
  18. if(bytesSinceLastIndexEntry > indexIntervalBytes) {
  19. index.append(firstOffset, physicalPosition)
  20. timeIndex.maybeAppend(maxTimestampSoFar, offsetOfMaxTimestamp)
  21. bytesSinceLastIndexEntry =
  22. }
  23. bytesSinceLastIndexEntry += records.sizeInBytes
  24. }
  25. }
  26. }

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. codeforces476D

    Dreamoon and Sets CodeForces - 476D Dreamoon likes to play with sets, integers and .  is defined as ...

  2. grafana备份

    #!/bin/bash #自动备份grafana数据库并上传到云盘 NOWDATE=`date +%Y-%m-%d` YUNPAN_USER=xxxx YUNPAN_PASSWD=XXXXXXXXXX ...

  3. mac与windows共享键盘鼠标(synergy)

    桌面上有两台电脑, 一台mac一台windows, 由于桌面空间紧张, 放两套键盘鼠标有点浪费空间, 如果能让mac和windows共享键盘鼠标就好了, 经过一番搜寻, 找到了一款名为synergy的 ...

  4. 洛谷P4389 付公主的背包--生成函数+多项式

    题目链接戳这里 题目描述 有\(n\)件不同的商品,每件物品都有无限个,输出总体积为\([1,m]\)的方案数 思路 直接跑背包有\(30\) 考虑把每个物品的生成函数设出来,对于一件体积为\(v\) ...

  5. axios设置请求拦截和响应拦截

    首先我们先创建axios实例 const service = axios.create({ baseURL: url, //是用于请求的服务器 URL timeout: 5000, // 请求超时时间 ...

  6. iis7设置ftp

    目前是所有网站一个域下.ftp登录后可看到所有网站,目前想ftp一个网站,查看了下服务器,貌似只有serv-u这么个东西,还不能再创建第二个域.不得其解.百度发现两篇文章正好: http://blog ...

  7. react项目后台及上线步骤

    应同学要求,本人将react项目创建后台及上线流程书写如下: 前端部分 略…… 后台部分 (注:这里的后台是用的nodejs搭建的,使用的是express框架+ejs模板) 首先通过express快速 ...

  8. file 自定义上传附件并展示缩略图

    效果图镇楼..   写的有点乱.上传一个实例供大家参考--附件下载地址如何下: https://files.cnblogs.com/files/fchx91/uploadFiles.rar 2019- ...

  9. Axis2 WebService客户端Axis2调用

    第一RPC方式,不生成客户端代码 第二,document方式,不生成客户端代码 第三,用wsdl2java工具,生成客户端方式调用 package samples.quickstart.client; ...

  10. nodejs学习以及SSJS漏洞

    0x01 简介 什么是nodejs,it's javascript webserver! JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充当了解析器的角色.而对 ...