Kafka 源代码分析.
这里记录kafka源代码笔记.(代码版本是0.8.2.1)
kafka的源代码如何下载.这里简单说一下.
git clone https://git-wip-us.apache.org/repos/asf/kafka.git kafka
通过官网给出的链接clone项目代码之后.一般只能得到trunk版本的代码.想要之前的版本代码需要自己checkout下来.
git branch -a 能看见所有的分支.或者用git tag --list 也可以看见所有的tag标签.
想得到其中一个的源代码的方法就是用git checkout -t xxxx(分支名称或者标签名称).完成之后就能在git branch下看见各个分支了.
之后使用git checkout 0.8.2就可以切换到对应的版本上去了.
这里简单说一下源代码目录:
源代码目录下的clients目录下是javaapi的源代码.
core目录下的源代码是server端的所有实现.包含一下目录和文件.
admin #一些管理功能的代码.topiccommand也在这下面.
api #跟client通信协议定义的地方
client #客户端工具
cluster #集群的相关实现
common #常用库
consumer #消费端管理的实现
controller #中央控制器的实现
javaapi #javaapi的实现
Kafka.scala #kafka入口库
log #log管理的相关实现
message #消息相关
metrics #...
network #...
producer
serializer
server #server相关的实现.kafkaServer就在这里.
tools
utils
这里不再从kafka启动顺序说起.网上已经一堆kafka启动顺序和框架上的文章了.这里不再罗嗦了,主要详细说一下代码细节部分.细节部分会一直读一直补充.如果想看看kafka 框架及启动顺序之类的文章推荐下面这个链接.
http://www.cnblogs.com/davidwang456/p/5173486.html
这个链接作者贴上了框架图和代码.比较清晰.
配置文件解析等工作都在KafkaConfig.scala中实现.这个类文件在server目录下.下文使用的配置文件项都是由这个类提供.这个类继承ZKConfig类实现.ZKConfig在Utils.scala文件中.功能是将zookeeper相关参数分离出来.
1,首先从kafkaScheduler.start()启动说起.
KafkaScheduler是同名类的实例对象.类源文件在源代码目录的utils目录下.这个对象的初始化是在KafkaServer 类的开头部分.实例化参数是config.backgroundThreads.这个参数对应的是配置文件中的background.threads参数.默认是4.
KafkaScheduler的是封装了ScheduldThreadPoolExecutor,在这个类的start函数里实例化stpe类.并设置了在执行器关闭的时候不再执行现有和周期性任务.通过setThreadFactory 设置了自己的工厂函数.工厂函数里调用了utils目录下的Utils类中的newThread方法.做了一些记录性工作.
KafkaScheduler类同时实现了scheduler方法.这个方法是封装了stpe的scheduler的方法.用来传递需要执行的方法.
shutdown函数也是封装了stpe的shutdown和awaitshutdown方法实现的.
这个对象通过createlogmanager函数传递到LogManager类中.在这个类中的start方法里调用scheduler方法将logmanager的任务放入线程池中.logmanager具体任务是log保留,log刷新,log检查这三个.这三个任务的详细情况将在LogManager部分解释.
2,之后是通过Zkinit()建立了zkclient对象.
zkinit()函数做的就是通过ZkClient初始化zkclient对象,并且做一些kafka在zookeeper里路径设置的工作.
首先检查config.Zkconnect是否指定了zookeeper中的根路径.ZKconnect就是配置文件中的zookeeper.connect参数.这个参数可以在ip_list后面加上/xxx/xxx这种指定的zookeeper工作路径.如:192.168.1.100,127.0.0.1:2181/kafka/dir,代码中直接使用substr(index('/'))的方式截取chroot.如果未设置则直接使用ZkUtils.setupCommonPaths(zkClient)来创建kafka的所有应用目录.具体应用目录可以见ZkUtils.scala文件中.这个文件在utils目录下.
不过这个函数代码有点小疑问,这个疑问先暂时保留.也可能是我未看完全部代码导致的.
private def initZk(): ZkClient = {
info("Connecting to zookeeper on " + config.zkConnect)
//一般配置zookeeper.connect选项的时候很少会在后面跟路径.但是当跟路径之后chroot就会是追加的路径.
val chroot = {
if (config.zkConnect.indexOf("/") > 0)
config.zkConnect.substring(config.zkConnect.indexOf("/"))
else
""
}
//chroot是追加路径的时候.会执行下面这段代码.
if (chroot.length > 1) { //疑问在这个地方.
val zkConnForChrootCreation = config.zkConnect.substring(0, config.zkConnect.indexOf("/"))//这是取出zookeeper ip list
val zkClientForChrootCreation = new ZkClient(zkConnForChrootCreation, config.zkSessionTimeoutMs, config.zkConnectionTimeoutMs, ZKStringSerializer)//然后建立zkclient对象.
ZkUtils.makeSurePersistentPathExists(zkClientForChrootCreation, chroot)//之后通过这个方法创建这个路径.
info("Created zookeeper path " + chroot)//打印一个create info
zkClientForChrootCreation.close()//这里清理这个追加路径的zkclient对象.
}
//做完这些事之后.又正常的用zkconnect来建立一个zkClient对象........如果chroot.length>1的话.这个时候zkconnect应该是跟if块里的一样需要提取ip list才对.
//如果一开始就没有追加路径的话.这里是没有任何问题的.
val zkClient = new ZkClient(config.zkConnect, config.zkSessionTimeoutMs, config.zkConnectionTimeoutMs, ZKStringSerializer)
ZkUtils.setupCommonPaths(zkClient) //这个函数是调用ZkUtils.makeSurePersistentPathExists函数来建立kafka路径.
zkClient }
def setupCommonPaths(zkClient: ZkClient) { //可以看见这个函数是如何工作的
for(path <- Seq(ConsumersPath, BrokerIdsPath, BrokerTopicsPath, TopicConfigChangesPath, TopicConfigPath, DeleteTopicsPath))
makeSurePersistentPathExists(zkClient, path) //以上这些路径是提前定义好的.定义如下.
}
val ConsumersPath = "/consumers" //这些路径是在ZkUtils类开头定义的.可以看见这个定义里无论你是否追加了chroot.也没有任何影响.
val BrokerIdsPath = "/brokers/ids"
val BrokerTopicsPath = "/brokers/topics"
val TopicConfigPath = "/config/topics"
val TopicConfigChangesPath = "/config/changes"
val ControllerPath = "/controller"
val ControllerEpochPath = "/controller_epoch"
val ReassignPartitionsPath = "/admin/reassign_partitions"
val DeleteTopicsPath = "/admin/delete_topics"
val PreferredReplicaLeaderElectionPath = "/admin/preferred_replica_election"
因为是版本0.8.2.1的代码所以我又去对照trunk版本的代码看了一下.这个函数变了.不是直接调用zkclient实现是调用zkutils实现得了.
后续的日志管理,socket服务,副本管理,中央控制等等分析都会在后续篇章里继续分析.
Kafka 源代码分析.的更多相关文章
- Kafka 源代码分析之LogManager
这里分析kafka 0.8.2的LogManager logmanager是kafka用来管理log文件的子系统.源代码文件在log目录下. 这里会逐步分析logmanager的源代码.首先看clas ...
- kafka 源代码分析之Message(v0.10)
这里主要更新一下kafka 0.10.0版本的message消息格式的变化. message 的格式在0.10.0的版本里发生了一些变化(相对于0.8.2.1的版本)这里把0.10.0的message ...
- Kafka 源代码分析之FileMessageSet
这里主要分析FileMessageSet类 这个类主要是管理log消息的内存对象和文件对象的类.源代码文件在log目录下.这个类被LogSegment类代理调用用来管理分片. 下面是完整代码.代码比较 ...
- Kafka 源代码分析之LogSegment
这里分析kafka LogSegment源代码 通过一步步分析LogManager,Log源代码之后就会发现,最终的log操作都在LogSegment上实现.LogSegment负责分片的读写恢复刷新 ...
- Kafka 源代码分析之ByteBufferMessageSet
这里分析一下message的封装类ByteBufferMessageSet类 ByteBufferMessageSet类的源代码在源代码目录message目录下.这个类主要封装了message,mes ...
- Kafka 源代码分析之Log
这里分析Log对象本身的源代码. Log类是一个topic分区的基础类.一个topic分区的所有基本管理动作.都在这个对象里完成.类源代码文件为Log.scala.在源代码log目录下. Log类是L ...
- Kafka 源代码分析之Message
这里主要分析一下message的格式. 一条message的构成由以下部分组成 val CrcOffset = 0 //crc校验部分和字长 val CrcLength = 4 val MagicOf ...
- Kafka 源代码分析之MessageSet
这里分析MessageSet类 MessageSet是一个抽象类,定义了一条log的一些接口和常量,FileMessageSet就是MessageSet类的实现类.一条日志中存储的log完整格式如下 ...
- Kafka 源代码分析之log框架介绍
这里主要介绍log管理,读写相关的类的调用关系的介绍. 在围绕log的实际处理上.有很多层的封装和调用.这里主要介绍一下调用结构和顺序. 首先从LogManager开始. 调用关系简单如下:LogMa ...
随机推荐
- ssm框架整合+maven项目创建
在引入外部maven插件后就可以创建一个maven项目了,这篇文章主要介绍ssm框架的整合和如何创建一个maven项目 1.在开发工具的项目空白区单击右键,依次选择New.Other,会出现如下界面, ...
- 史上最全的njRAT通信协议分析
Njrat,又称Bladabindi,该木马家族使用.NET框架编写,是一个典型的RAT类程序,通过控制端可以操作受控端的文件.进程.服务.注册表内容,也可以盗取受控端的浏览器的保存的密码信息等内容. ...
- (jquery+ajax)省市区三级联动(封装和不封装两种方式)-----2017-05-14
首先,要实现如下图效果, 1.要理清思路: 先做出三个下拉菜单----根据第一个下拉菜单的value值获取第二个下拉列表的内容,第三个同理. 2.用到的数据库表:Chinastates表 规律:根据国 ...
- React入门---开始前的准备(上)-2
开始前准备: 1.安装配置nodeJs(nodeJS官网) 检查安装成功: node -v npm -v 2.使用NPM配置React开发环境 (1). 创建项目文件夹(创建文件夹时,文件夹名不要起为 ...
- Windows下安装Nodejs步骤
最近打算把我们的微信端用Vue.js重构,为什么选择Vue.js,一是之前使用的是传统的asp.net mvc,多页面应用用户体验比单页面要差.二是使用过Angular.js,感觉对开发人员要求较 ...
- textView布局的一点体会
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- JDBC与JNDI的区别
程序员开发时,知道要开发访问MySQL数据库的应用,于是将一个对 MySQL JDBC 驱动程序类的引用进行了编码,并通过使用适当的 JDBC URL 连接到数据库. 就像以下代码这样: Connec ...
- 【面向对象设计原则】之依赖倒置原则(DIP)
依赖倒转原则(Dependency Inversion Principle, DIP):抽象不应该依赖于细节,细节应当依赖于抽象.换言之,要针对抽象(接口)编程,而不是针对实现细节编程. 开闭原则( ...
- 实现分布式队列ZooKeeper的实现
一.背景 有一些时候,多个团队需要共同完成一个任务,比如,A团队将Hadoop集群计算的结果交给B团队继续计算,B完成了自己任务再交给C团队继续做.这就有点像业务系统的工作流一样,一环一环地传下去,直 ...
- React 读书笔记
序言: 领导安排部门同事本月内看一本跟自己职业相关的书籍, 根基类的书籍已经看过了,重复阅读的意义不大,所以我平时看的都是视频,也许是视频作者没有出书的条件,也许是现在出书看的人越来越少了,也许有其他 ...