1.概述

Kafka是一个分布式消息中间件系统,里面存储着实际场景中的数据。Kafka原生是不支持点查询的,如果我们想对存储在Topic中的数据进行查询,可能需要对Topic中的数据进行消费落地,然后构建索引(或者数据落地到自带所以的存储系统中,例如HBase、Hive等)。今天,笔者就为大家来介绍如何实现Kafka分布式查询引擎。

2.内容

对于点查询,我们可以总结为两个要点。其一,有数据供我们查询;其二,对待查询的数据构建索引。在Kafka中,Topic存储数据,满足了第一点,虽然Kafka有索引的概念,但是它的索引是基于Offset的稀疏索引,并不是对每条Message都会构建一个索引。并且,这个Offset索引对于实际情况查询场景来说,也帮助不大。比如,你查询Topic01下的Partition_0,但是,也仅仅只是查下到某个Topic中分区下的Offset对应的一条记录,但是这条记录是啥,你并不知道。真实查询的情况,可能是你需要查询某个ID,或者模糊查询某个Name是否存在。

2.1 索引

其实有一种方式,是可行的。就是对Kafka源代码进行改造,在Broker落地每条数据的时候,构建一条索引(其实,这种方式与在原始的Kafka外面加一层Proxy类似,由Proxy充当与Client交互的角色,接收Client的数据存储并构建索引)。这样的实现方式如下图:

如果对Kafka源代码熟悉,有能力改造其源代码,可以在Kafka中添加对每条数据构建索引的逻辑。如果,觉得怕对Kafka的性能有影响,或者改造有难度。上述流程图的方式,也可以实现这种点查询。

改造Kafka源代码添加索引,或者是Proxy的方式存储数据并构建索引,这种两种方式来说,数据上都会要冗余一倍左右的的存储容量。

2.2 单节点查询

基于上述的问题,我们对这种方案进行升级改造一下。因为很多情况下,生产环境的数据已经是运行了很长时间了,加Proxy或者改造Kafka源代码的方式适合构建一个Kafka的新集群的时候使用。对于已有的Kafka集群,如果我们要查询Topic中的数据,如何实现呢。

Kafka-Eagle中,我对Topic数据查询实现了基于SQL查询的实现方案。逻辑是这样的,编写SQL查询语句,对SQL进行解析,映射出一个Topic的Schema以及过滤条件,然后根据过滤条件消费Topic对应的数据,最后拿到数据集,通过SQL呈现出最后的结果。流程图如下:

但是,这样是由局限性的。由于,单节点的计算能力有限,所以对每个Partition默认查询5000条数据,这个记录是可以增加或者减少的。如果在配置文件中对这个属性增大,比如设置为了50000条,那么对应的ke.sh脚本中的内存也需要增加,因为每次查询需要的内存增加了。不然,频繁若干用户同时查询,容易造成OOM的情况。

但是,通常一个Topic中存储的数据一般达到上亿条数据以上,这种方式要从上亿条或者更多的数据中查询我们想要的数据,可能就满足不了了。

2.3 分布式查询

基于这种情况,我们可以对这中单节点查询的方式进行升级改造,将它变为分布式查询。其实,仔细来看,单节点查询的方式,就是一个分布式查询的缩版。那我们需要实现这样一个分布式查询的Kafka SQL引擎呢?

首先,我们可以借助Hadoop的MapReduce思想,“化繁为简,分而治之”。我们将一个Topic看成一个比较大的数据集,每次我们需要对这个数据集进行查询,可以将待查询的数据进行拆分若干份Segment,然后,充分利用服务器的CPU,进行多线程消费(这样就可以打破Kafka中一个线程只能消费一个分区的局限性)。实现流程图如下:

上图可知,由客户端发起请求,提交请求到Master节点,然后Master节点解析客户端的请求,并生成待执行策略。比如上述有三个工作节点,按照客户端的情况,Master会将生成的执行策略下发给三个工作节点,让其进行计算。

这里以其中一个工作节点为例子,比如WorkNode1接收到了Master下发的计算任务,接收到执行指令后,结合工作节点自身的资源情况(比如CPU和内存,这里CPU较为重要),将任务进行拆解为若干个子任务(子任务的个数取决于每个批次的BatchSize,可以在属性中进行配置),然后让生成好的若干个子任务并行计算,得到若干个子结果,然后将若干个子结果汇总为一个最终结果作为当前工作节点的最终计算结果,最后将不同的工作节点的结果进行最后的Merge作为本次查询的结果返回给Master节点(这里需要注意的是,多个工作节点汇总在同一个JobID下)。然后,Master节点收到工作节点返回的结果后,返回给客户端。

3.结果预览

查询10条Topic中的数据,工作节点执行如下:

select * from ke1115 where `partition` in (0) limit 10

上图显示了,同一WorkNode节点下,同一JobID中,不同线程子任务的计算进度日志。

KSqlStrategy显示了Master节点下发的待执行策略,msg表示各个工作节点返回的最终结果。

4.待优化

目前Kafka分布式查询引擎基础功能已实现可以用,任务托管、子任务查询内存优化等还有优化的空间,计划正在考虑集成到KafkaEagle系统中。

5.结束语

这篇博客就和大家分享到这里,如果大家在研究学习的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!

另外,博主出书了《Kafka并不难学》和《Hadoop大数据挖掘从入门到进阶实战》,喜欢的朋友或同学, 可以在公告栏那里点击购买链接购买博主的书进行学习,在此感谢大家的支持。关注下面公众号,根据提示,可免费获取书籍的教学视频。

Kafka分布式查询引擎的更多相关文章

  1. Presto 来自Facebook的开源分布式查询引擎

    Presto是一个分布式SQL查询引擎, 它被设计为用来专门进行高速.实时的数据分析.它支持标准的ANSI SQL,包括复杂查询.聚合(aggregation).连接(join)和窗口函数(windo ...

  2. Presto: 可以处理PB级别数据的分布式SQL查询引擎

    2012年秋季Facebook启动了Presto,Presto的目的是在几百PB级别数据量上面进行准实时分析.在摒弃了一些外部项目以后,Facebook准备开发他们自己的分布式查询引擎.Presto的 ...

  3. Spark 分布式SQL引擎

    SparkSQL作为分布式查询引擎:两种方式 SparkSQL作为分布式查询引擎:Thrift JDBC/ODBC服务 SparkSQL作为分布式查询引擎:Thrift JDBC/ODBC服务 Spa ...

  4. Spark SQL概念学习系列之分布式SQL引擎

    不多说,直接上干货! parkSQL作为分布式查询引擎:两种方式 除了在Spark程序里使用Spark SQL,我们也可以把Spark SQL当作一个分布式查询引擎来使用,有以下两种使用方式: 1.T ...

  5. 大数据系列之分布式大数据查询引擎Presto

    关于presto部署及详细介绍请参考官方链接 http://prestodb-china.com PRESTO是什么? Presto是一个开源的分布式SQL查询引擎,适用于交互式分析查询,数据量支持G ...

  6. 带你玩转Flink流批一体分布式实时处理引擎

    摘要:Apache Flink是为分布式.高性能的流处理应用程序打造的开源流处理框架. 本文分享自华为云社区<[云驻共创]手把手教你玩转Flink流批一体分布式实时处理引擎>,作者: 萌兔 ...

  7. DRDS分布式SQL引擎—执行计划介绍

    摘要: 本文着重介绍 DRDS 执行计划中各个操作符的含义,以便用户通过查询计划了解 SQL 执行流程,从而有针对性的调优 SQL. DRDS分布式SQL引擎 — 执行计划介绍 前言 数据库系统中,执 ...

  8. Kafka分布式消息队列

    基本架构 Kafka分布式消息队列的作用: 解耦:将消息生产阶段和处理阶段拆分开,两个阶段互相独立各自实现自己的处理逻辑,通过Kafka提供的消息写入和消费接口实现对消息的连接处理.降低开发复杂度,提 ...

  9. HBase高性能复杂条件查询引擎

    转自:http://blog.csdn.net/bluishglc/article/details/31799255 mark 写在前面 本文2014年7月份发表于InfoQ,HBase的PMC成员T ...

随机推荐

  1. Java关键字——break和continue、this等

    想知道break用于if和while的区别是什么? break是跳出最近的循环.if是逻辑判断,不是循环,所以会跳出if最近的循环: break:终止退出,用于do-while.while.for中时 ...

  2. 卸载联软UniAccess,删除UniAccess Agent记录

    UniAccess 卸载 事情起因: 公司假以安全上网为由,让公司员工安装所谓的"XX上网助手",实则是内嵌了联软的UniAccess监控系统. 有关这个软件的用途就不用多介绍了, ...

  3. DTU是什么 常见的DTU有哪些

    DTU也叫数据传输终端,它的主要功能是把远端设备的数据通过无线的方式传送回后台中心,想要完成数据的传输就需要建立一套完整的数据传输系统.DTU是一种现代物联网行业广泛使用的无线数据终端,利用公用运营商 ...

  4. Django中间件(Middleware)处理请求

    关注公众号"轻松学编程"了解更多. 1.面向切面编程 切点(钩子) 切点允许我们动态的在原有逻辑中插入一部分代码 在不修改原有代码的情况下,动态注入一部分代码 默认情况,不中断传播 ...

  5. .netcore3.1使用log4net/nlog记录日志

    .netcore3.1使用log4net/nlog记录日志 .netcore3.1与2.x之间很是有不少差异的.本来想通过ctrl+c,ctrl+v将在2.2中实现的简单日志记录搬到.netcore3 ...

  6. Reactor:深入理解reactor core

    目录 简介 自定义Subscriber Backpressure处理 创建Flux 使用generate 使用create 使用push 使用Handle 简介 上篇文章我们简单的介绍了Reactor ...

  7. KOA2 笔记

    KOA2 基于ES7开发,完全使用Promise并配合async来实现异步的node框架 核心是对node的HTT模块P进行了封装,用多个async函数组成处理链,来不断地接收HTTP请求(ctx对象 ...

  8. Redis基础—了解Redis是如何做数据持久化的

    之前的文章介绍了Redis的简单数据结构的相关使用和底层原理,这篇文章我们就来聊一下Redis应该如何保证高可用. 数据持久化 我们知道虽然单机的Redis虽然性能十分的出色, 单机能够扛住10w的Q ...

  9. windows端口占用和进程定位

    问题:Error was Port already in use: 40001 1. netstat -ano|findstr "40001" TCP 127.0.0.1:1404 ...

  10. 第05组 Alpha冲刺(4/6)

    .th1 { font-family: 黑体; font-size: 25px; color: rgba(0, 0, 255, 1) } #ka { margin-top: 50px } .aaa11 ...