JAVA复习笔记分布式篇:kafka
前言:第一次使用消息队列是在实在前年的时候,那时候还不了解kafka,用的是阿里的rocket_mq,当时觉得挺好用的,后来听原阿里的同事说rocket_mq是他们看来kafka的源码后自己开发了一套更适合业务的消息队列rocket_mq(kafka更多地适用于日志方面),所以我们从kafka下手去了解一个消息队列也是不错的选择
简介:Apache Kafka是分布式发布-订阅消息系统,在 kafka官网上对 kafka 的定义:一个分布式发布-订阅消息传递系统。 它最初由LinkedIn公司开发,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。Kafka是一种快速、可扩展的、设计内在就是分布式的,分区的和可复制的提交日志服务。
关键字:一个分布式发布-订阅消息传递系统
组件概念:
Broker:Kafka节点,一个Kafka节点就是一个broker,多个broker可以组成一个Kafka集群。
Topic:一类消息,消息存放的目录即主题,例如page view日志、click日志等都可以以topic的形式存在,Kafka集群能够同时负责多个topic的分发。
Partition:topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列
Segment:partition物理上由多个segment组成,每个Segment存着message信息
Producer : 生产message发送到topic
Consumer : 订阅topic消费message, consumer作为一个线程来消费
Consumer Group:一个Consumer Group包含多个consumer
参考以下架构图

基本原理
从上面的架构图发现,kafka还依赖到zookeeper了,那么zookeeper在kafka中扮演上面角色呢?
broken注册:每个broken启动的时候都会向zookeeper注册自己的信息,每个broker都使用不同的brokerId去zookeeper上创建一个临时节点,并保持长连接,创建节点完成后, broker会将自己的IP和端口记录到节点中去。一旦broker宕机,长连接断掉,该节点就会
删除(PS:只会有一个broker会创建成为controller节点,其他的broker就是follwers,follwers会注册watch到这个节点)
topic注册:在Kafka中,同一个Topic的消息会被分成多个分区并将其分布在多个Broker上,这些分区信息及与Broker的对应关系也都是由Zookeeper在维护
消费者注册:
- 注册到消费者分组。每个消费者服务器启动时,都会到Zookeeper的指定节点下创建一个属于自己的消费者节点,完成节点创建后,消费者就会将自己订阅的Topic信息写入该临时节点。
- 对消费者分组中的消费者的变化注册监听。每个消费者都需要关注所属消费者分组中其他消费者服务器的变化情况,一旦发现消费者新增或减少,就触发消费者的负载均衡。
- 对Broker服务器变化注册监听。消费者需要对/broker/ids/[0-N]中的节点进行监听,如果发现Broker服务器列表发生变化,那么就根据具体情况来决定是否需要进行消费者负载均衡。
- 进行消费者负载均衡。为了让同一个Topic下不同分区的消息尽量均衡地被多个消费者消费而进行消费者与消息分区分配的过程,通常,对于一个消费者分组,如果组内的消费者服务器发生变更或Broker服务器发生变更,会发出消费者负载均衡。
生产者负载均衡:由于每个Broker启动时,都会完成Broker注册过程,生产者会通过该节点的变化来动态地感知到Broker服务器列表的变更,这样就可以实现动态的负载均衡机制。
消费者负载均衡:与生产者类似,消费者会把注册信息发送到Zookeeper上,每个消费者分组包含若干消费者,每条消息都只会发送给分组中的一个消费者,不同的消费者分组消费自己特定的Topic下面的消息,互不干扰
消费者与消费组之前的关系:在Zookeeper上记录消息分区与消费者之间的关系,每个消费者一旦确定了对一个消息分区的消费权力,需要将其Consumer ID 写入到对应消息分区的临时节点上/consumers/[group_id]/owners/[topic]/[broker_id-partition_id]
消费进度:在消费者对指定消息分区进行消息消费的过程中,需要定时地将分区消息的消费进度Offset记录到Zookeeper上,以便在该消费者进行重启或者其他消费者重新接管该消息分区的消息消费后,能够从之前的进度开始继续进行消息消费 /consumers/[group_id]/offsets/[topic]/[broker_id-partition_id]

message在segment中的物理存储方式:


从上述图可知这样做的优点,segment index file采取稀疏索引存储方式,它减少索引文件大小,通过mmap可以直接内存操作,稀疏索引为数据文件的每个对应message设置一个元数据指针,它比稠密索引节省了更多的存储空间,但查找起来需要消耗更多的时间
写message
- 消息从java堆转入page cache(即物理内存)。
- 由异步线程刷盘,消息从page cache刷入磁盘。
读message
- 消息直接从page cache转入socket发送出去。
- 当从page cache没有找到相应数据时,此时会产生磁盘IO,从磁
盘Load消息到page cache,然后直接从socket发出去
Kafka高效文件存储设计特点
- Kafka把topic中一个parition大文件分成多个小文件段,通过多个小文件段,就容易定期清除或删除已经消费完文件,减少磁盘占用。
- 通过索引信息可以快速定位message和确定response的最大大小。
- 通过index元数据全部映射到memory,可以避免segment file的IO磁盘操作。
- 通过索引文件稀疏存储,可以大幅降低index文件元数据占用空间大小。
JAVA复习笔记分布式篇:kafka的更多相关文章
- JAVA复习笔记分布式篇:zookeeper
前言:终于到分布式篇,前面把JAVA的一些核心知识复习了一遍,也是一个JAVA程序员最基本要掌握的知识点,接下来分布式的知识点算是互联网行业的JAVA程序员必备的技能: 概念:ZooK ...
- Java 学习笔记提高篇
Java笔记(提高篇)整理 主要内容: 面向对象 异常 数组 常用类 集合 IO流 线程 反射 Socket编程 1. 面向对象 1.1包 用来管理Java中的类, 类似文件夹管理文件一样. 因 ...
- java复习笔记
本笔记(无异常处理与网络编程部分)整理自<java程序设计>-黄岚 王岩 王康平 编著 java数据 UI I/O java线程 数据库操作 Java数 ...
- SQL 复习笔记 MSSQL篇
苦逼得很,一下就失业了,只有好好复习,迎接下一份工作 MSSQL篇: 1.数据库表分为临时表和永久表.临时表又分为全局临时表和局部临时表 全局临时表:表名以##开头.对系统当前 ...
- java学习笔记-JavaWeb篇二
JavaWEB篇二 45 HttpSession概述46 HttpSession的生命周期 47 HttpSession常用方法示例48 HttpSessionURL重写 49 HttpSession ...
- java学习笔记-JavaWeb篇一
JavaWEB篇一 1 Tomcat的安装和配置 2 JavaWeb开发的目录结构 3 使用Eclipse开发JavaWeb项目 4 第一个Servlet程序 5 Servlet 的配置及生命周期方法 ...
- java学习笔记-基础篇
Java基础篇 1—12 常识 13 this关键字 14参数传递 16 继承 17 访问权限 28—31异常 1—12 常识 1.文件夹以列表展示,显示扩展名,在地址栏显示全路径 2.javac编译 ...
- 【私人向】Java复习笔记
此笔记学习于慕课网:Java入门第一季-第三季,想学的可以点击链接进行学习,笔记仅为私人收藏 建议学习时间:2-3天(极速版) 数据类型 基本数据类型存的是数据本身 引用类型变量(class.inte ...
- Java学习笔记——基础篇
Tips1:eclipse中会经常用到System.out.println方法,可以先输入syso,然后eclipse就会自动联想出这个语句了!! 学习笔记: *包.权限控制 1.包(package) ...
随机推荐
- 解题:洛谷4314 CPU监控
题面 线段树·二重标记(什么鬼 用(a,b)标记表示先执行+a操作,然后对b取max,维护历史/当前最大值和历史/当前标记.然后我们发现区间加$x$就是$(x,-inf)$,区间赋$x$就是$(-in ...
- L. Twice Equation ACM Nanning 2017
https://nanti.jisuanke.com/t/19978 acm提交:类 Main 使用java:高精度 BigInteger import java.math.BigInteger; i ...
- springboot中如何添加第三方的jar包或者说如何配置本地jar
首先推荐博客: spring-boot-maven-plugin 安装本地jar 包 http://www.cnblogs.com/acm-bingzi/p/mavenSpringBootPlugin ...
- C++中的空类,编译器默认可以产生哪些成员函数
C++中的空类,编译器默认可以产生哪些成员函数 C++中创建一个空类:class Empty {};默认会生成4个函数,其函数的原型如下: public: Empty() { ... } Empty( ...
- Python【datetime】模块
import datetimeprint("==============date类================")#创建一个date对象:datetime.date(year, ...
- Java质数求解
质数概念 质数,又称素数,指在一个大于1的自然数中,除了1和此整数自身外,无法被其他自然数整除的数(也可定义为只有1和本身两个因数的数).最小的素数是2,也是素数中唯一的偶数:其他素数都是奇数.质数有 ...
- ZeroMQ API(八) 异常&属性
1.错误处理 1.1 zmq_errno() 1.1.1 名称 zmq_errno - 为调用线程检索errno的值 1.1.2 概要 int zmq_errno(void); 1.1.3 描述 zm ...
- Jmeter javaRequest插件开发
1. 适用场景 Jmeter工具当前支持的协议或协议所支持的传输方式及传输内容不能满足当前项目的测试要求时,就需要根据实际要求手动编写java测试代码(实现对应的Jmeter规范),以插件方式加载到J ...
- 简易jQuery插件
之前写过jQuery插件的笔记 如何用jQuery封装插件 我一直觉得前面讲了一大堆闭包和三种插件封装模式有点冗余,那篇笔记我直到记录到后面才发现这事情很简单,想来想去还是觉得网上的一些文章把事情搞复 ...
- jQuery中的text(),html(),val()的区别
一.jquery中HTML 1. 无参html() 方法用来获取任意元素的HTML内容,如果你调用多个选定元素的.html()方法,那么其读取的只是第一个元素,换句话说:如果选择器匹配多于一个的元素, ...