当前位置: 首页 > news >正文

【Phoenix】phoenix实现每个Primarykey主键保留N版本数据,CDC数据记录为Changelog格式

一、背景:

CDC数据中包含了,数据的变更过程。当CDC写入传统数据库最终每一个primary key下会保存一条数据。当然可以使用特殊手段保存多分记录但是显然造成了数据膨胀。
另外数据湖Hudi(0.13.1)是不支持保存所有Changelog其Compaction机制会清除所有旧版本的内容。Iceberg支持TimeTravel,能查到某个时间点的数据状态,但是不能列举的单条记录的Change过程。
所以目前只能手动实现。
其实,实现思路很简单,将原PrimaryKey+Cdc的 ts_ms 一起作为新表的 PrimaryKey就可以了。但需要注意的是一条数据可能变更很多次,但一般需要保存近几次的变更,所以就需要删除部分旧变更记录。ts_ms 就是CDC数据中记录的日志实际产生的时间,具体参见debezium 。如果原表primarykey是联合主键,即有多个字段共同组成,则最好将这些字段拼接为一个字符串,方便后续关联。

本文思路
CDC --写入-> Phoenix + 定期删除旧版本记录

CDC数据写入略过,此处使用SQL模拟写入。

二、Phoenix旧版记录删除(DEMO)

phoenix doc

bin/sqlline.py www.xx.com:2181
-- 直接创建phoenix表
create table TEST.TEST_VERSION(
ID VARCHAR NOT NULL,
TS TIMESTAMP NOT NULL,
NAME VARCHAR,
CONSTRAINT my_pk PRIMARY KEY (ID,TS)
) VERSIONS=5;

再去hbase shell中查看,hbase 关联表已经有phoenix创建了。

hbase(main):032:0> desc "TEST:TEST_VERSION"
Table TEST:TEST_VERSION is ENABLED
TEST:TEST_VERSION, {TABLE_ATTRIBUTES => {coprocessor$1 => '|org.apache.phoenix.coprocessor.ScanRegionObserver|805306366|', coprocessor$2 => '|org.apache.phoenix.coprocessor.UngroupedAggregateRe
gionObserver|805306366|', coprocessor$3 => '|org.apache.phoenix.coprocessor.GroupedAggregateRegionObserver|805306366|', coprocessor$4 => '|org.apache.phoenix.coprocessor.ServerCachingEndpointImpl|80
5306366|', coprocessor$5 => '|org.apache.phoenix.hbase.index.Indexer|805306366|index.builder=org.apache.phoenix.index.PhoenixIndexBuilder,org.apache.hadoop.hbase.index.codec.class=org.apache.phoenix
.index.PhoenixIndexCodec', METADATA => {'OWNER' => 'dcetl'}}
COLUMN FAMILIES DESCRIPTION
{NAME => '0', VERSIONS => '5', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODING => 'FAST_DIFF', T
TL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'NONE', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPE
N => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
-- 在phoenix中向表插入数据
UPSERT INTO TEST.TEST_VERSION(ID,TS,NAME) VALUES('rk001',TO_TIMESTAMP('2020-01-01 10:00:00'),'zhangsan');
UPSERT INTO TEST.TEST_VERSION(ID,TS,NAME) VALUES('rk001',TO_TIMESTAMP('2020-01-01 11:00:00'),'lisi');
UPSERT INTO TEST.TEST_VERSION(ID,TS,NAME) VALUES('rk001',TO_TIMESTAMP('2020-01-01 12:00:00'),'wangwu');
UPSERT INTO TEST.TEST_VERSION(ID,TS,NAME) VALUES('rk001',TO_TIMESTAMP('2020-01-01 13:00:00'),'zhaoliu');
UPSERT INTO TEST.TEST_VERSION(ID,TS,NAME) VALUES('rk001',TO_TIMESTAMP('2020-01-01 14:00:00'),'liuqi');
UPSERT INTO TEST.TEST_VERSION(ID,TS,NAME) VALUES('rk001',TO_TIMESTAMP('2020-01-01 15:00:00'),'sunba');
UPSERT INTO TEST.TEST_VERSION(ID,TS,NAME) VALUES('rk002',TO_TIMESTAMP('2020-01-01 07:00:00'),'sunyang');
UPSERT INTO TEST.TEST_VERSION(ID,TS,NAME) VALUES('rk002',TO_TIMESTAMP('2020-01-01 08:00:00'),'chaoyang');
UPSERT INTO TEST.TEST_VERSION(ID,TS,NAME) VALUES('rk002',TO_TIMESTAMP('2020-01-01 09:00:00'),'xuri');
UPSERT INTO TEST.TEST_VERSION(ID,TS,NAME) VALUES('rk002',TO_TIMESTAMP('2020-01-01 09:30:00'),'chenxi');
-- OK再查询一下数据插入情况
SELECT * FROM TEST.TEST_VERSION;

以下假设每个PrimaryKey需要保留最新的3版本数据。所以红色框内是需要删除的数据。
在这里插入图片描述

现在需要使用row_number的函数给每个primarykey的不通version数据标识。但是phoenix并没有开窗函数。只有agg聚合函数。
phoenix对SQL的限制还是比较多的如:
(1)join 非等值连接不支持,如on a.id>s.id 是不支持的,也不支持数组比较连接,如on a.id = ARRAY[1,2,3]。 会报错:Error: Does not support non-standard or non-equi correlated-subquery conditions. (state=,code=0)
(2)where exists 格式的非等值连接不支持。select ... from A where exists (select 1 from B where A.id>B.id) 是不支持的。会报错:Error: Does not support non-standard or non-equi correlated-subquery conditions. (state=,code=0)
(2)没有开窗window函数
(3)DELETE FROM不支持JOIN

最终发下有一下函数可用
(1)NTH_VALUE 获取分组排序的第N个值。 返回原值的类型。
(2)FIRST_VALUESLAST_VALUES 获取分区排序后的前、后的N个值,返回ARRAY类型。
此三个函数官网doc中,案例是这样的 FIRST_VALUES( name, 3 ) WITHIN GROUP (ORDER BY salary DESC) 是全局分组,而实际使用中是需要搭配 GROUP BY 使用的。

所以可以获取到

-- 方案一:使用NTH_VALUE获取阈值
SELECT A.ID,A.TS FROM TEST.TEST_VERSION A 
INNER JOIN (
SELECT ID,NTH_VALUE(TS,3) WITHIN GROUP (ORDER BY TS DESC) THRES FROM TEST.TEST_VERSION GROUP BY ID) Z ON A.ID=Z.ID
WHERE A.TS < Z.THRES-- 方案二:使用FIRST_VALUES获取到一个ARRAY 
SELECT A.ID,A.TS FROM TEST.TEST_VERSION A 
INNER JOIN (
SELECT ID,FIRST_VALUES(TS,3) WITHIN GROUP (ORDER BY TS DESC) TSS FROM TEST.TEST_VERSION GROUP BY ID) Z ON A.ID=Z.ID
WHERE A.TS < ALL(Z.TSS);

由于phoenix支持行子查询,以下是官方案例。这样就能绕过不使用DELETE … JOIN了。

Row subqueries
A subquery can return multiple fields in one row, which is considered returning a row constructor. The row constructor on both sides of the operator (IN/NOT IN, EXISTS/NOT EXISTS or comparison operator) must contain the same number of values, like in the below example:
SELECT column1, column2
FROM t1
WHERE (column1, column2) IN(SELECT column3, column4FROM t2WHERE column5 = ‘nowhere’);
This query returns all pairs of (column1, column2) that can match any pair of (column3, column4) in the second table after being filtered by condition: column5 = ‘nowhere’.

最终实现删除 除N个较新的以外的所有旧版本数据, SQL如下:

-- NTH_VALUE方式
DELETE FROM TEST.TEST_VERSION
WHERE (ID,TS) IN (
SELECT A.ID,A.TS FROM TEST.TEST_VERSION A 
INNER JOIN (
SELECT ID,NTH_VALUE(TS,3) WITHIN GROUP (ORDER BY TS DESC) THRES FROM TEST.TEST_VERSION GROUP BY ID) Z ON A.ID=Z.ID
WHERE A.TS < Z.THRES
);-- FIRST_VALUES方式
DELETE FROM TEST.TEST_VERSION
WHERE (ID,TS) IN (
SELECT A.ID,A.TS FROM TEST.TEST_VERSION A 
INNER JOIN (
SELECT ID,FIRST_VALUES(TS,3) WITHIN GROUP (ORDER BY TS DESC) TSS FROM TEST.TEST_VERSION GROUP BY ID) Z ON A.ID=Z.ID
WHERE A.TS < ALL(Z.TSS)
);

删除后效果:
在这里插入图片描述

相关文章:

【Phoenix】phoenix实现每个Primarykey主键保留N版本数据,CDC数据记录为Changelog格式

一、背景&#xff1a; CDC数据中包含了&#xff0c;数据的变更过程。当CDC写入传统数据库最终每一个primary key下会保存一条数据。当然可以使用特殊手段保存多分记录但是显然造成了数据膨胀。 另外数据湖Hudi(0.13.1)是不支持保存所有Changelog其Compaction机制会清除所有旧版…...

阿里云服务器开放的一个新端口,重启防火墙,端口未启动

问题&#xff1a; 阿里云网页开放的一个新端口后&#xff0c;重启防火墙&#xff0c;端口未启动&#xff0c;之前配置的也都停止了。 解决&#xff1a; 原因可能是阿里的服务控制了&#xff0c;只能一个个端口开启了。把新配置新端口也单独启用。 开启80端口指令 firewall-cm…...

【PHPCUSTOM】打包PHP程序为EXE

目录 一、下载PHPCUSTOM 二、PHP网站打包 1、打开PHPCUSTOM 2、配置参数 3、生成exe文件 网上很多PHP程序打包成EXE的文章&#xff0c;但是都不能用&#xff0c;最后找到了PHPCUSTOM&#xff0c;使用PHPCUSTOM可以把PHP程序打包成exe。我们都知道PHP是服务端语言&#xff…...

药品咨询报告合集整理平台打包(一共36597份)【专题推荐】

<医药行业从业者必看>笔者今天分享高价值医药行业报告36500余份的获取/下载方法&#xff0c;报告涵盖了医药细分领域研究报告药品报告&#xff08;所有上市药品&#xff09;医药行业分析报告医药环境观察报告药品市场调研报告药品靶点研究报告医药白皮书&#xff1b;数据…...

数字化管理新革命,AI数字人CEO登场引领变革!

王一博老板乐华娱乐CEO杜华推出了她的双生数字人华华子&#xff0c;专门替自己直播卖货。在没有任何宣传的情况下&#xff0c;仅仅在短短的10分钟直播时间内&#xff0c;观众人数就飙升至30万人&#xff01;同时&#xff0c;“杜华AI华华子直播”更是迅速登上了微博热搜榜。这一…...

FPGA/数字IC(芯海科技2022)面试题 2(解析版)

以下仅为学习参考(非原创)&#xff0c;如有疑惑欢迎评论区指出&#xff01; 一、单选题&#xff08;共20题&#xff0c;每题3分&#xff0c;共60分&#xff09; 1. D触发器&#xff1a;Tsetup3ns&#xff0c;Thold1ns&#xff0c;Tck2q1ns&#xff0c; 该D触发器最大可运行时…...

SpringMVC之JSON数据返回与异常处理机制---全方面讲解

一&#xff0c;JSON数据返回的理解 在Spring MVC中&#xff0c;当需要将数据以JSON格式返回给客户端时&#xff0c;可以使用ResponseBody注解或RestController注解将Controller方法的返回值直接转化为JSON格式并返回。这使得开发者可以方便地将Java对象转换为JSON&#xff0c;并…...

信息化发展53

数据标准化 1 、数据标准化是实现数据共享的基础。 2 、数据标准化的主要内容包括元数据标准化、数据元标准化、数据模式标准化、数据分类与编码标准化和数据标准化管理。 元数据标准化 1 、元数据是关于数据的数据&#xff08; Data About Data &#xff09;。其实质是用于…...

Java学习笔记——字符/字符串

在 Java 语言中&#xff0c;字符串都被设计成「不可变」的类型&#xff0c;即无法直接修改字符串的某一位字符&#xff0c;需要新建一个字符串实现 StringBuilder 字符 字符是用单引号括起来的单个字母&#xff0c;在Java中&#xff0c;表示字符的数据类型为char。一个字符…...

数据结构与算法基础-(1)

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…...

华为云云耀云服务器L实例评测|轻量级应用服务器对决:基于 STREAM 深度测评华为云云耀云服务器L实例的内存性能

本文收录在专栏&#xff1a;#云计算入门与实践 - 华为云 专栏中&#xff0c;本系列博文还在更新中 相关华为云云耀云服务器L实例评测文章列表如下&#xff1a; 华为云云耀云服务器L实例评测 | 从零开始&#xff1a;云耀云服务器L实例的全面使用解析指南华为云云耀云服务器L实…...

Windows安装Neo4j

图数据库概述 图数据库是基于图论实现的一种NoSQL数据库&#xff0c;其数据存储结构和数据查询方式都是以图论&#xff08;它以图为研究对象图论中的图是由若干给定的点及连接两点的线所构成的图形&#xff09;为基础的&#xff0c; 图数据库主要用于存储更多的连接数据。 Neo…...

vue3开发必备核心要点

1、route/router的区别 ● $route 表示当前激活的路由的状态信息&#xff0c;包含了当前URL解析得到的信息&#xff0c;包含当前的path路径&#xff0c;params参数&#xff0c;query对象&#xff0c;name路径名等属性 ● r o u t e r 路由器对象&#xff08; n e w 的路由器对…...

针对敏感数据的安全转录服务

即便在新冠肺炎疫情期间&#xff0c;继续保持了最高级别的机密性 新冠肺炎疫情带来的各种限制向所有服务提供商提出了挑战&#xff0c;促使提供商们想方设法采取更富想象力的新方法来满足客户的需求。澳鹏采用了一种由两种方案组成的工作机制&#xff0c;服务于客户机密材料的…...

leetcode 10. 正则表达式匹配

2023.9.20 感觉是目前做过dp题里最难的一题了... 本题首要的就是需要理解题意&#xff0c;翻了评论区我才发现之前一直理解的题意是错的。 我原来理解的 “ *匹配0次” 是指&#xff1a;*直接消失&#xff0c;不会影响到前面的字符。 但是*和前一个字符其实是连体的&#xff0…...

Vue前端开发中的输入限制与输入规则探究

前言 在Vue前端开发中&#xff0c;我们经常需要对用户的输入进行限制和规范&#xff0c;以确保数据的准确性和安全性。本文将介绍如何使用Vue的el-input组件来实现输入限制和输入规则&#xff0c;并提供相应的代码示例。 一、输入限制 最大长度限制 我们可以使用maxlength属…...

自己封装 vue3+ts 组件库并且发布到 NPM

自己封装 vue3ts 组件库并且发布到 NPM 创建项目 pnpm create vite配置 package.json 按照提示创建好项目&#xff0c;然后再 package.json 中进行如下配置&#xff1a; {"name": "tribiani-vue-tools","private": false,"version"…...

MySQL学习系列(6)-每天学习10个知识

目录 1. 管理和维护大量的数据库表和数据2. 检测和修复MySQL性能瓶颈3. MySQL的视图缓存4. 处理MySQL并发问题5. 函数索引和全文索引6. UNION ALL 和 UNION 的区别7. 存储引擎的选择8. 存储过程和触发器9. 数据表管理和优化10. 数据库安全性和一致性 &#x1f44d; 点赞&#x…...

“毛细血管”的进化:华为分销业务如何让伙伴也有“高能级”

作者 | 曾响铃 文 | 响铃说 数字化蓬勃发展的大时代&#xff0c;除了那些中、大型企业&#xff0c;数量更为庞大的小微企业同样有借助数字化产品、服务来提升企业经营的需求&#xff0c;由此也带来了广袤的数字化分销市场。 这里处在聚光灯之外&#xff0c;很少被数字化时代…...

警惕!多本SCI/SSCI被剔除,9月SCI/SSCI期刊目录已更新~(附下载)

【SciencePub学术】 2023年9月20日&#xff0c;科睿唯安更新了Web of Science核心期刊目录。 继上次SCI期刊目录和SSCI期刊目录更新之后&#xff0c;本次9月更新共有9本期刊发生变动&#xff1a; • SCIE&#xff1a;有3本期刊不再被SCIE期刊目录收录(Editorial De-listing/Pr…...

Switch手柄玩转Windows:JoyCon-Driver开源驱动全攻略

Switch手柄玩转Windows&#xff1a;JoyCon-Driver开源驱动全攻略 【免费下载链接】JoyCon-Driver A vJoy feeder for the Nintendo Switch JoyCons and Pro Controller 项目地址: https://gitcode.com/gh_mirrors/jo/JoyCon-Driver 还在为Switch Joy-Con手柄无法在Windo…...

nnUNet学习率调度器改造日记:如何用余弦退火替代线性衰减提升模型收敛?

nnUNet学习率调度器改造实战&#xff1a;从线性衰减到余弦退火的性能跃迁 在医学图像分割领域&#xff0c;nnUNet以其开箱即用的优秀表现成为众多研究者和工程师的首选框架。但当我们面对特定数据集时&#xff0c;默认的训练配置可能并非最优选择。本文将带您深入探索如何通过改…...

M2LOrder模型揭秘AI原理:从卷积神经网络到Transformer

M2LOrder模型揭秘AI原理&#xff1a;从卷积神经网络到Transformer 最近和几个刚入行的朋友聊天&#xff0c;发现他们对AI模型的理解还停留在“很厉害但很神秘”的阶段。一提到卷积神经网络&#xff08;CNN&#xff09;&#xff0c;就觉得是图像处理的“黑魔法”&#xff1b;说…...

个人项目复习-云盘Day03

考点13&#xff1a;大文件上传需求和常见问题普遍需求&#xff1a;在云存储、视频分享、在线教育等领域&#xff0c;用户上传大文件的需求日益普遍。核心挑战&#xff1a;网络波动、不稳定性及客户端资源限制&#xff0c;常给用户带来不佳体验&#xff1b;传统整文件上传易因中…...

机器人爱好者疑问:DreamZero跨具身适应为何领先两倍?

机器人爱好者疑问&#xff1a;DreamZero跨具身适应为何领先两倍&#xff1f; 想象一下&#xff0c;你作为机器人工程师&#xff0c;在实验室调试机械臂&#xff0c;输入指令后&#xff0c;它却总在陌生环境中卡壳。效率低下&#xff0c;项目延期。 这不是个案——传统机器人模型…...

18 Byte Buddy 进阶指南:解锁 `@Pipe` 注解,实现灵活的方法转发

在 Java 字节码增强的世界里&#xff0c;Byte Buddy 以其简洁的 API 和强大的功能成为了开发者手中的利器。我们通常使用 MethodDelegation 配合 SuperCall 来调用父类逻辑&#xff0c;或者使用 This 操作当前实例。 但你是否遇到过这样的场景&#xff1a;你想拦截一个方法&am…...

CarouselView扩展实战:实现无限轮播与网络图片加载

CarouselView扩展实战&#xff1a;实现无限轮播与网络图片加载 【免费下载链接】carouselview A simple library to add carousel view in android app. 项目地址: https://gitcode.com/gh_mirrors/ca/carouselview CarouselView是一个简单易用的Android轮播图库&#x…...

【2026 最新】最好用必备笔记软件 Obsidian 的下载安装与使用教程(Mac 版)

Obsidian采用markdown文档编辑器&#xff0c;提供强大的笔记链接功能&#xff0c;支持单向链接、反向链接和双向链接&#xff0c;可以自由地链接文档、文本内容块。它拥有丰富的插件&#xff0c;例如阅读PDF文档时随手标记、标记视频播放时间&#xff08;在观看视频课程时&…...

重装系统后快速恢复CasRel模型开发环境:镜像与依赖一键还原

重装系统后快速恢复CasRel模型开发环境&#xff1a;镜像与依赖一键还原 重装系统&#xff0c;对开发者来说&#xff0c;简直是场噩梦。辛辛苦苦搭建好的Python环境、CUDA驱动、各种深度学习框架&#xff0c;还有那个调了无数参数才跑起来的CasRel模型项目&#xff0c;一夜之间…...

ebmap Tour 智慧节目时间表功能预览

ebmap Tour 最近新增了节目时间表功能&#xff0c;为景区 / 园区打造实时化、场景化的演艺活动管理与展示体系&#xff0c;让游客清晰掌握节目动态、合理规划游览路线&#xff0c;同时帮助运营方高效编排、精准触达游客&#xff0c;提升景区服务体验与活动曝光。安装扩展&#…...