解开Kafka神秘的面纱(五):kafka优雅应用

2023-10-17 11:40

本文主要是介绍解开Kafka神秘的面纱(五):kafka优雅应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、前言
  • 二、kafka的offset存储演变
  • 三、kafka的持久化
    • 3.1 kafka读写操作
    • 3.2 kafka中的Segment段
  • 四、kafka集群topic和partition数量设置
  • 五、kafka可视化监控
  • 六、尾声

一、前言

本文主要介绍kafka的offset存储演变、kafka的持久化、kafka集群topic和partition数量设置、kafka可视化监控。

二、kafka的offset存储演变

在kafka版本演进过程中,对于消费者offset的存储位置是发生了改变的。

对于kafka版本小于 0.9 的,此时消费者offset存放在 zookeeper 中,默认目录是 /consumers/[group_id]/offsets/[topic]/[broker_id-partition_id] -> offset_counter_value,如果想要查看,可以通过本地使用 zkTools、ZooKeeper Assistant 这些可视化工具查看。

现在最新版本的kafka都已经到2.8.0了,基本上不会再将offset存放到zookeeper,所以这种方式了解即可。

对于kafka版本大于 0.9 的,此时消费者offset存放在 kafka 中,需要做第一次消费,kafka会在内部维护一个__comsumer_offset 的topic,这个topic是第一次消费kafka自动创建的,用来存放消费者offset,默认50个partition,每个partition保存一个副本。那么,offset存放在哪个partition,是如何确定的呢?答案是使用 Utils.abs(grupId.hashCode) % numPattitions 计算,offset存放的位置取决group的hash值,numPattitions的数量默认是50,可以通过 offsets.topic.num.partionts 参数指定。

因为kafka设计的时候向下兼容,所以高版本的client api适配了低版本。

__comsumer_offset 和程序员手工创建的 topic 放在 “kafka解压目录/conf/server.properties” 指定目录下,但是两种 topic 相互独立。

小结:新版本中,message和offset都存放在kafka;旧版本中,message存放在kafka,offset存放在zookeeper。其实,新版本可以也可以将 offset 存放在zookeeper,保证写操作/生产消息时候指定zookeeper,同时读操作/消费消息的时候指定zookeeper,即可实现将offset存放到zookeeper。

三、kafka的持久化

3.1 kafka读写操作

kafka读写文件速度都是极快的,可以完成适用高并发的场景。

写:采用文件追加写,将随机写变为顺序写,将随机IO变为顺序io,砍掉了寻址时间,让廉价的机械硬盘写入速度 接近固态硬盘。

读:因为有了消费者offset,告诉kafka上次读到了什么位置,直接从文件中读,也是顺序读。

kafka中,消息实体和offset归根结底都存放在kafka的topic的partition上面,但是,消息存放到自己创建的topic上面,消费者offset存放到第一次消费自动创建的__consumer_offset_ 上面,两种topic虽然是同一个目录下,但是相互独立。

3.2 kafka中的Segment段

在kafka中,一个index+多个log文件构成了segment,index文件存储的的是position位置,log文件存储的是message,如下图:
在这里插入图片描述

如上图,index文件中存放的是 offset,partition,log文件中存放的是position和message的映射关系,如果需要查找某个message,首先提供offset。例如查找497,则
第一步,查找index文件,根据offset找物理偏离地址position 497;
第二步,查找log文件,根据position找到message,就可以找到497。

查询顺序是offset -> position -> message位置,其中,offset -> position 使用二分查找,position -> message位置 使用线性查找。即先找到段,然后找到文件:就是因为有了index文件,所以可以先大概定位到message在什么地方,然后再次精确查找,所以说,index文件的存在,加快了查找速度。

注意,这个消息存储的offset和消费者consumer offset没任何关系。

问题:分辨两种topic?
回答:自己创建的topic test和kafka消费时自动创建的topic __consumer_offset_,没有任何关系。自己创建的topic test存储的是完整的kafka segment段,即index+log+timestamp组成的消息,kafka消费时自动创建的topic __consumer_offset_,里面存储的是消费者消费消息的offset(存储在kafka上面)。

问题:分辨两种topic中的offset?
回答:test中的offset是topic的offset,不是消费者consumer的offset,消费者consumer的offset在__consumer_offset_上,是完全两个不同的概念,在两个不同的topic里面,test0中的offset是为了加快kafka读写速度,__consumer_offset_ 是为了保存消费者的消费位置,两种topic相互独立,毫无相关。

命令截图:

(1) 仅查看index文件:
./bin/kafka-run-class.sh kafka.tools.DumpLogSegments --files /tmp/kafka-logs/test2-0/00000000000000000000.log --verify-index-only

(2) 查看index和log文件:
./bin/kafka-run-class.sh kafka.tools.DumpLogSegments --files /tmp/kafka-logs/test2-0/00000000000000000000.log --print-data-log

在这里插入图片描述
存放的消息体就是payload,如下:
在这里插入图片描述

注意,kafka中,如果要查看log,必须像上面这样,因为是dump文件,直接cat命令无法查看的。

四、kafka集群topic和partition数量设置

问题:kafka中能够创建多少个topic?
回答:一个kafka集群中,topic数量是由实际业务单元来决定的,而且topic理论数量不超过2000个,超过会有性能问题。

问题:每个topic创建多少个partition用来存储topic?
回答:partition是kafka中存储数据的最小单位,对数据的读写都是通过操作partition来完成的,partition越多越好,最多broker数字个,理论上限是最多不超过30000个,全部宕机了才会丢(如果一个broker宕机,该机器上的parititon都无法使用了),但是如此,磁盘成本+网络同步成本会大大增加。因为partition数量越多,需要的磁盘存储空间越多,更重要的网络同步成本,任何一个topic,都是 1个主partition 和 (N-1) 个从partition,客户端对topic读写消息实际只是操作主partition,从partition需要不断同步主partition的数据。

kafka官网给出一个partition数量计算公式,即 partition数 = max(t/p,t/c) ,其中,p表示生产吞吐量,c表示消费吞吐量,t表示系统想要的最大吞吐量,有了这三个数字,可以算出一个最合适的partition。例如,目标是需要1000吞吐量,使用 1个机器broker,上面只有一个topic,副本数也是1(生产者topic和消费者topic),因为生产者和消费者很少,所以在这个一个机器上需要1000个partition才可以满足1000个吞吐量。

五、kafka可视化监控

kafka的可视化监控,掌握一种就好,这里介绍雅虎的CMAK,直接到 http://github.com/yahoo/CMAK/releases 下载,可以选择最新的版本下载,注意下载压缩包,而不是源码
在这里插入图片描述

上传到centos并解压,如下:

在这里插入图片描述

注意:cmak需要jdk11才可以运行。

修改application.conf文件,如下:
在这里插入图片描述

进入到cmak解压目录,执行这条命令

./bin/cmak -Dconfig.file=conf/application.conf -java-home /root/jdk11

cmk最新3.0.0.5版本,需要安装jdk11才可以运行,否则报错:
java.lang.UnsupportedClassVersionError: controllers/routes has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0

启动之后,可以用 ps -ef|grep cmak 查询,也可以用 netstat -aplt | grep 9000 查询。

在这里插入图片描述

刚启动的时候,cmak还没有任何节点,如下:
在这里插入图片描述
新建一个节点,添加上zookeeper的ip:port,也可以是zookeeper集群,用英文逗号分隔,如下:
在这里插入图片描述
有了节点,就可以查看节点的信息了,这个zookeeper上关联了kafka,可以直接看kafka上的topics的信息,如下:
在这里插入图片描述
继续点进去,可以查看每个topic的详情,如下:
在这里插入图片描述
特殊地,segment_types是可以修改的,如下:
在这里插入图片描述

上图中有一个 delete topic 的蓝色的按钮,其实页面上默认无法删除topic,需要配置kafka的conf/server.properties 文件

# 删除topic
delete.topic.enable=true

在这里插入图片描述

在这里插入图片描述

注意:kafka如果生产消息的时候不会自动创建topic,所以如果topic不存在会报错,建议在server.properties文件中配置上

# 自动创建不存在的topic
auto.create.topics.enable=true

六、尾声

本文主要介绍了kafka的offset存储演变、kafka的持久化、kafka集群topic和partition数量设置、kafka可视化监控。

天天打码,天天进步!!

这篇关于解开Kafka神秘的面纱(五):kafka优雅应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/225134

相关文章

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

Java Kafka消费者实现过程

《JavaKafka消费者实现过程》Kafka消费者通过KafkaConsumer类实现,核心机制包括偏移量管理、消费者组协调、批量拉取消息及多线程处理,手动提交offset确保数据可靠性,自动提交... 目录基础KafkaConsumer类分析关键代码与核心算法2.1 订阅与分区分配2.2 拉取消息2.3

PostgreSQL简介及实战应用

《PostgreSQL简介及实战应用》PostgreSQL是一种功能强大的开源关系型数据库管理系统,以其稳定性、高性能、扩展性和复杂查询能力在众多项目中得到广泛应用,本文将从基础概念讲起,逐步深入到高... 目录前言1. PostgreSQL基础1.1 PostgreSQL简介1.2 基础语法1.3 数据库

Python利用PySpark和Kafka实现流处理引擎构建指南

《Python利用PySpark和Kafka实现流处理引擎构建指南》本文将深入解剖基于Python的实时处理黄金组合:Kafka(分布式消息队列)与PySpark(分布式计算引擎)的化学反应,并构建一... 目录引言:数据洪流时代的生存法则第一章 Kafka:数据世界的中央神经系统消息引擎核心设计哲学高吞吐

Python中的filter() 函数的工作原理及应用技巧

《Python中的filter()函数的工作原理及应用技巧》Python的filter()函数用于筛选序列元素,返回迭代器,适合函数式编程,相比列表推导式,内存更优,尤其适用于大数据集,结合lamb... 目录前言一、基本概念基本语法二、使用方式1. 使用 lambda 函数2. 使用普通函数3. 使用 N

Python中yield的用法和实际应用示例

《Python中yield的用法和实际应用示例》在Python中,yield关键字主要用于生成器函数(generatorfunctions)中,其目的是使函数能够像迭代器一样工作,即可以被遍历,但不会... 目录python中yield的用法详解一、引言二、yield的基本用法1、yield与生成器2、yi

Python多线程应用中的卡死问题优化方案指南

《Python多线程应用中的卡死问题优化方案指南》在利用Python语言开发某查询软件时,遇到了点击搜索按钮后软件卡死的问题,本文将简单分析一下出现的原因以及对应的优化方案,希望对大家有所帮助... 目录问题描述优化方案1. 网络请求优化2. 多线程架构优化3. 全局异常处理4. 配置管理优化优化效果1.

详解Java中三种状态机实现方式来优雅消灭 if-else 嵌套

《详解Java中三种状态机实现方式来优雅消灭if-else嵌套》这篇文章主要为大家详细介绍了Java中三种状态机实现方式从而优雅消灭if-else嵌套,文中的示例代码讲解详细,感兴趣的小伙伴可以跟... 目录1. 前言2. 复现传统if-else实现的业务场景问题3. 用状态机模式改造3.1 定义状态接口3

从基础到高阶详解Python多态实战应用指南

《从基础到高阶详解Python多态实战应用指南》这篇文章主要从基础到高阶为大家详细介绍Python中多态的相关应用与技巧,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、多态的本质:python的“鸭子类型”哲学二、多态的三大实战场景场景1:数据处理管道——统一处理不同数据格式