使用 SQL 的方式查询消息队列数据以及踩坑指南
背景
为了让业务团队可以更好的跟踪自己消息的生产和消费状态,需要一个类似于表格视图的消息列表,用户可以直观的看到发送的消息;同时点击详情后也能查到消息的整个轨迹。
消息列表
点击详情后查看轨迹
原理介绍
由于 Pulsar
并没有关系型数据库中表的概念,所有的数据都是存储在 Bookkeeper
中,为了模拟使用 SQL 查询的效果 Pulsar 提供了 Presto
(现在已经更名为 Trino
)的插件。
Trino 是一个分布式的 SQL 查询引擎,它也提供了插件能力,如果我们想通过 SQL 从自定义数据源查询数据时,基于它的 SPI 编写一个插件是很方便的。
这样便可以类似于查询数据库一样查询 Pulsar
数据:
Pulsar 插件的运行流程如上图所示:
-
启动的时候通过
Pulsar-Admin
接口获取一些元数据,比如 Scheme,topic 分区信息等。 -
然后会创建一个只读的 Bookkeeper 客户端,用于获取数据。
-
之后根据 SQL 条件过滤数据即可。
相关代码:
使用 Pulsar-SQL
image.png
使用起来也很简单,官方提供了两个命令:
-
sql-worker: 会启动一个 trino 服务端同时运行了 Pulsar 插件
-
sql: 就是一个 SQL 命令行终端。
遇到的问题
自己在本地运行的时候自然是没问题,可是一旦想在生产运行,同时如果你的 Pulsar
集群是运行再 k8s
环境中时就会碰到一些问题。
无法使用现有 Trino 集群
首先第一个问题是如果生产环境已经有了一个 Trino
集群想要复用的时候就会碰到问题,常规流程是将 Pulsar
的插件复制到 Trino
的 Plugin
目录,然后重启 Trino
后就能使用该插件。
当然社区也是支持这么做的:
但是当我将 Pulsar-plugin 复制到 Trino 中运行的时候却失败了,整体的流程可以参考这个 issue:https://github.com/apache/pulsar/discussions/20941
简单来说 Trino
的官方镜像和 pulsar-plugin
并不能兼容,这个问题直接影响到我们是否可以在生产环境使用它。
但是手动编译出来的 Trino
服务和插件是兼容的,可以直接运行。
image.png
因此我只能在本地编译出 Trino 服务端和 pulsar-plugin
然后打包成一个镜像来运行了,当然这样的坏处就是无法利用到我们现有的 Trino
集群,又得重新部署一个了。
image.png
流程也比较麻烦:
-
首先是本地编译
Pulsar-SQL
模块 -
将生成物复制到当前目录
-
执行
make docker
打出 docker 镜像并上传到私服 -
再执行
kubectl
将 trino 部署到k8s
环境中
整个流程做下来加上和社区的沟通,更加确定这个功能应该是很少有人在生产环境使用的,毕竟第一个坑就很麻烦,更别提后续的问题了😂。
Presto 插件不支持 AuthToken
第二个问题也是个深坑,当我把 Trino 部署好查询数据的时候直接抛了一个调用 pulsar-admin
接口连接超时的异常。
结果排查了半天发现原来是 pulsar-plugin
里没有提供 JWT
的验证方式,而我们的 Pulsar 集群恰好是打开了 JWT
验证的。
为此我只能先在本地修复了这个问题,同时也提交了 PR,预计会在下一个大版本合并吧:https://github.com/apache/pulsar/pull/20860
新创建的 topic 查询失败
第二个问题是当查询一个新创建的 topic 时,客户端会直接 block,相关的复现流程在这里:https://github.com/apache/pulsar/issues/20910
image.png
这个问题还好,不是很致命,是我在本地测试的时候无意间发现的。
本地我已经修复了,后面也提交了一个 PR,目前还在讨论中:https://github.com/apache/pulsar/pull/20911
查询消息会丢失最后一条
这个问题也不是很严重,数据量少的时候会发现,就是在指定了消息发送时间的查询条件时,最后一条消息会被过滤掉,相关 issue 在这里:https://github.com/apache/pulsar/issues/20919
这个我只是定位到了原因,但不太清楚 为什么要这么做(-1),影响也不是很大,就放在这里搁置了。
Schema 不兼容
最后发现的一个问题是我们线上某些 topic 查询数据的时候会抛出 Not a record: "string"
的异常,但只是部分 topic,也排查了很久,整个源码中没有任何一个地方有这个异常。
https://github.com/apache/pulsar/issues/20945
image.png
根本原因是生产者生成的 schema 有问题,类型已经是 JSON 了,但是 schema 却是 string,这样导致 pulsar-plugin
在反序列化 schema 的时候抛出了异常,由于是 pb 反序列化抛出的异常,所以源码中都搜索不到。
没有问题的 topic 使用了正确的 schema
后续我也在本地修复了这个问题,当抛出异常后就将 schema 降级为基本类型进行解析。
不过本质问题还是客户端使用有误,如果对 schema
理解不准确的话还是建议使用 byte[]
吧,这样至少兼容性不会有问题。相关 PR:https://github.com/apache/pulsar/pull/20955
总结
Pulsar-SQL
是一个非常有用的功能,只是我们使用过程中确实发现了一些问题,大部分都已经修复了;希望对后续使用该功能的朋友有所帮助。
相关文章:

使用 SQL 的方式查询消息队列数据以及踩坑指南
背景 为了让业务团队可以更好的跟踪自己消息的生产和消费状态,需要一个类似于表格视图的消息列表,用户可以直观的看到发送的消息;同时点击详情后也能查到消息的整个轨迹。 消息列表 点击详情后查看轨迹 原理介绍 由于 Pulsar 并没有关系型数…...

拿下国家级信创认证 中科驭数KPU SWIFT-2200N成为国内首款满足金融业严苛要求的DPU产品
近日,中科驭数KPU SWIFT-2200N低时延DPU卡,在中国人民银行旗下金融信创生态实验室完成测试并取得测试报告,这意味着中科驭数低时延网络代表性产品的应用领域从证券进一步拓展到了银行业,成为国内首款满足金融行业严苛要求的DPU产品…...
centos怎么禁用和关闭selinux
要禁用和关闭SELinux(Security-Enhanced Linux)在CentOS上,请按照以下步骤进行: 请注意:禁用SELinux会减少系统的安全性,因此只有在确切知道自己在做什么并且出于特定目的时才应该这样做。 1.打开终端并以超级用户(root)身份登录&…...

【LeetCode刷题日志】88.合并两个有序数组
🎈个人主页:库库的里昂 🎐C/C领域新星创作者 🎉欢迎 👍点赞✍评论⭐收藏✨收录专栏:LeetCode 刷题日志🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,…...

计算机考研 | 2013年 | 计算机组成原理真题
文章目录 【计算机组成原理2013年真题43题-9分】【第一步:信息提取】【第二步:具体解答】 【计算机组成原理2013年真题44题-14分】【第一步:信息提取】【第二步:具体解答】 【计算机组成原理2013年真题43题-9分】 某32位计算机&a…...

[Unity][VR]透视开发系列4-解决只看得到Passthrough但看不到Unity对象的问题
【视频资源】 视频讲解地址请关注我的B站。 专栏后期会有一些不公开的高阶实战内容或是更细节的指导内容。 B站地址: https://www.bilibili.com/video/BV1Zg4y1w7fZ/ 我还有一些免费和收费课程在网易云课堂(大徐VR课堂): https://study.163.com/provider/480000002282025/…...
电气工程 自动化 机械工科学生来看看
PLC 类 基于PLC的机械手控制系统设计 基于PLC的机械手控制系统设计 PLC与变频器在综采设备上的应用 PLC与步进电机的运动控制编程9000 PLC应用数字电子钟设计 三菱FX系列PLC与三菱变频器通讯应用实例 基于plc拉杆箱振动与噪音检测平台设计 基于PLC的船舶空压机控制系统设计 基…...

NewStarCTF2023week4-midsql(利用二分查找实现时间盲注攻击)
大致测试一下,发现空格被过滤了 使用内联注释/**/绕过,可行 1/**/-- 使用%a0替代空格,也可以 1%a0-- 再次测试发现等号也被过滤,我们使用 like 代替 (我最开始以为是and被过滤,并没有,如果是…...
null,undefined的区别?
在 JavaScript 中,null 和 undefined 都表示没有值或缺失值的状态,但它们之间有一些区别。 null: null 是一个表示空值的特殊关键字。它是一个表示变量未赋值的值,可以将其赋给任何变量,表示该变量为空。使用 null 可以明确地将一个变量设置为空。 示例: let myVaria…...

2.flink编码第一步(maven工程创建)
概述 万里第一步,要进行flink代码开发,第一步先整个 flink 代码工程 flink相关文章链接 flink官方文档 两种方式 一种命令行 mvn 创建,另一种直接在 idea 中创建一个工程,使用 mvn 的一些配置 mvn命令行创建 mvn 创建flink工程&…...

Unit1_1:分治问题之时间复杂度求解
文章目录 背景递归树法案例一案例二局限性 代入法/替代法主方法(重点) 背景 当碰到形如 T ( n ) a T ( ⌈ n b ⌉ ) O ( n d ) T(n)aT(\lceil \frac{n}{b} \rceil)O(n^d) T(n)aT(⌈bn⌉)O(nd)的递推式,本质上就是将问题转化为规模更小的…...
React hooks的闭包陷阱
react hooks 陷阱 hooks必须放在函数顶层, 不能在条件分支和方法内 1、useState陷阱 异步陷阱 function Index() {const [count, setCount] useState(0)function add(){setCount( count 1 )console.log(count); // 0}return (<div><span>{count}…...

20.3 OpenSSL 对称AES加解密算法
AES算法是一种对称加密算法,全称为高级加密标准(Advanced Encryption Standard)。它是一种分组密码,以128比特为一个分组进行加密,其密钥长度可以是128比特、192比特或256比特,因此可以提供不同等级的安全性…...

一文详解防御DDoS攻击的几大有效办法
伴随互联网的飞速发展,网络安全问题变得越来越突出,其中最常见的就是DDoS攻击,也就是分布式拒绝服务攻击。DDoS攻击者利用计算机或其他设备的协作,以发送大量请求的方式导致目标超负荷,导致不能正常运转或“宕机”。以…...

Python二级 每周练习题24
练习一: 体重比较器 要求: 请编程实现如下功能: (1)程序开始运行时,提醒用户输入三个人的名字和体重 (可以分开输入,每次输入名字或者体重) (2) 程序自动比较,找出最重的一个人的名字和体重输出 的格式不限,但是要有最重人的姓名…...
MySQL - Buffer Pool
Buffer Pool 主要用于缓存数据库表的数据页,以提高数据库的读取性能: 缓存数据页:Buffer Pool 是 MySQL 中用于缓存数据页的内存区域。数据页通常包含数据库表的数据,如行记录等。当查询或读取数据时,MySQL会首先查看…...
c++ 拆分函数返回值和参数类型
在c中,函数参数类型和返回值类型通常是一个比较明确的信息,好像确实无需在这个上面费周折。然而,硬编码数据类型会让代码复用性下降,如果能够通过某种方式自动获取函数参数和返回值类型,对于代码的可复用性,…...
Ubuntu 23.10安装TeXlive并安装CTEX中文支持
连接上互联网,打开SHELL命令行界面, 1. sudo apt install texlive texstudio texlive-lang-chinese 就可以安装好了。texlive-lang-chinese 是TEXLIVE对CTEX中文的支持。 2. Tex源文件必须采用UTF-8编码格式,编译器采用xelatex。这样对中文…...

SpringBoot中CommandLineRunner详解(含源码)
文章目录 前言实例导入库application.yamlRunnerSpringBootCommandLineRunnerApplication执行结果 先后顺序示例OrderRunner1OrderRunner2执行结果 通常用法加载初始化数据示例 启动后打印应用信息示例 启动异步任务示例 接口健康检查示例 外部服务调用示例 参数校验示例 动态设…...
通信基础(一):数据传输基础
一、波特率与比特率关系 比特率(信息传输速率、信息速率):指单位时间内在信道上传 送的数据量(即比特数),单位为比特每秒 (bit/s), 简记为b/s或bps。 波特率与比特率有如下换算关系: bitbaud *log 2(N) 其中, N是码元总类数。 特别注意ÿ…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...