找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1585

积分

0

好友

228

主题
发表于 2025-12-17 04:57:34 | 查看: 15| 回复: 0

深入了解所选数据库的核心功能与能力边界,是避免技术选型失误的关键。例如,一个刚刚决定采用Doris的团队,在业务上面临着一个典型挑战:如何高效地将来自多张不同业务表的数据进行“打宽”处理。

他们最初的想法是借助ETL工具,对来自上游MySQL等数据源,通过SQL的Join操作将多表字段合并后,再写入Doris。这种方法在技术上固然可行,但实现复杂度较高。对于追求敏捷的团队,我们建议尝试一种更轻量的方案:利用Doris自2.x版本开始支持的Partial Update(部分列更新)功能。

官方文档的描述固然清晰,但实际应用效果如何?本文将通过实战测试,为你揭示细节。先说结论:功能可用,但在使用上有诸多注意事项。

功能定位对比

在测试Doris之前,我们曾深度测评过Apache Paimon的Partial Update功能,其在“数据打宽”场景下表现不错。通读两者文档后发现,其功能定位存在差异:

  • Paimon:将其定位为“主键表下的一种Merge策略”。
    Paimon Partial Update定位
  • Doris:则将其定位为“主键表模型下的一种更新策略”。
    Doris Partial Update定位

不过,对于使用者而言,定位差异并非关键。重要的是,Paimon的文档指引更为直观,而Doris的Partial Update功能则需要仔细研读文档,才能避开其中的一些“弯弯绕绕”。

启用前置条件

经过实测,要使Doris的Partial Update功能正常工作,必须满足以下三个条件:

  1. 表类型限制:必须创建主键模型表(Unique Key)聚合模型表(Aggregate Key)
  2. 开启功能开关:必须通过会话变量开启功能:SET enable_unique_key_partial_update=true;。经验证,此设置无法写入建表属性中。
  3. 关闭严格模式:同样需要通过会话变量关闭严格写入模式:SET enable_insert_strict=false;,否则数据无法插入。

官网提及的其他条件多为默认设置,此处不再赘述。从条件看,Doris的启用方式与Paimon有较大区别。

主键模型表的实践与限制

尽管Doris官方文档大量使用主键模型表举例,但从实测来看,其用于Partial Update场景并不便捷,主要存在以下限制:

1. Sequence Column类型限制
尝试创建一个类似Paimon用法的普通主键模型表,意图让每个字段只有在值大于旧值时才会更新(通过设置sequence column实现):

CREATE TABLE doris_partial_update01 (
    id BIGINT,
    age INT,
    name STRING,
    address STRING
)
UNIQUE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 3
PROPERTIES (
    "function_column.sequence_col" = "age",
    "function_column.sequence_col" = "name",
    "function_column.sequence_col" = "address"
);

执行将报错:

ERROR 1105 (HY000): errCode = 2, detailMessage = errCode = 2, detailMessage = Sequence type only support integer types and date types

这表明Doris的sequence column仅支持整型或日期类型。因此,上述表中仅有age字段有资格作为sequence column。

2. Sequence Column更新限制
修改建表语句,仅指定age为sequence column:

PROPERTIES (
    "function_column.sequence_col" = "age"
);

写入数据测试:

mysql> insert into doris_partial_update01 (id,age) values(1,11);
Query OK, 1 row affected

mysql> select * from doris_partial_update01;
+------+------+------+---------+
| id   | age  | name | address |
+------+------+------+---------+
|    1 |   11 | NULL | NULL    |
+------+------+------+---------+

mysql> insert into doris_partial_update01 (id,name) values(1,'A');
ERROR 1105 (HY000): Table doris_partial_update01 has sequence column, need to specify the sequence column

可见,一旦建表时指定了sequence column,后续每次数据写入都必须包含该列,否则会执行失败。这与Paimon的灵活处理方式不同。

3. 难以添加聚合列
在之前测试Paimon时,我们喜欢添加一个用于记录每行更新次数的字段,这有助于监控数据质量。但在Doris的主键模型表中,暂时未找到简便的实现方法。

更优解:聚合模型表实践

很多时候,官方推荐并非唯一路径。尝试换用聚合模型表(Aggregate Key),反而能更优雅地实现所有需求,且效果更佳。

创建聚合模型表如下:

CREATE TABLE doris_partial_update02 (
    id BIGINT,
    age INT MAX,
    name varchar(50) REPLACE_IF_NOT_NULL ,
    address varchar(100) REPLACE_IF_NOT_NULL ,
    update_cnt INT SUM DEFAULT 1
)
AGGREGATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 3

此表设计巧妙实现了全部预期功能:

  • age 字段:每次更新取最大值MAX聚合)。
  • nameaddress 字段:每次取最新写入且非空的值REPLACE_IF_NOT_NULL聚合)。
  • update_cnt 字段:自动累加,用于统计每行执行Partial Update的总次数SUM聚合,默认值1)。

以下是实战效果演示:

-- 第一次插入,只更新age
mysql> insert into doris_partial_update02 (id,age) values(1,10);
Query OK, 1 row affected
mysql> select * from doris_partial_update02;
+------+------+------+---------+------------+
| id   | age  | name | address | update_cnt |
+------+------+------+---------+------------+
|    1 |   10 | NULL | NULL    |          1 |
+------+------+------+---------+------------+

-- 第二次部分更新,只更新address
mysql> insert into doris_partial_update02 (id,address) values(1,'China');
Query OK, 1 row affected
mysql> select * from doris_partial_update02;
+------+------+------+---------+------------+
| id   | age  | name | address | update_cnt |
+------+------+------+---------+------------+
|    1 |   10 | NULL | China   |          2 |
+------+------+------+---------+------------+

-- 第三次部分更新,更新age和name(age新值更小,未被采纳)
mysql> insert into doris_partial_update02 (id,age,name) values(1,9,'A');
Query OK, 1 row affected
mysql> select * from doris_partial_update02;
+------+------+------+---------+------------+
| id   | age  | name | address | update_cnt |
+------+------+------+---------+------------+
|    1 |   10 | A    | China   |          3 |
+------+------+------+---------+------------+

-- 第四次部分更新,更新age和name(age新值更大,被采纳)
mysql> insert into doris_partial_update02 (id,age,name) values(1,15,'A');
Query OK, 1 row affected
mysql> select * from doris_partial_update02;
+------+------+------+---------+------------+
| id   | age  | name | address | update_cnt |
+------+------+------+---------+------------+
|    1 |   15 | A    | China   |          4 |
+------+------+------+---------+------------+

整个过程清晰展示了基于聚合模型的Partial Update如何灵活工作,并且自动完成了更新次数的统计。

总结

虽然Doris Partial Update的配置过程略显曲折,但最终通过聚合模型表找到了一个效果良好的解决方案,完全满足了数据打宽场景的需求。这也再次印证,相同的功能在不同的大数据组件中,其实现与最佳实践可能大相径庭。关于该功能在大数据量下的性能表现,我们将在后续文章中继续进行测试。




上一篇:高并发秒杀系统设计:消息队列异步解耦与流量削峰实战
下一篇:Python网络爬虫与信息提取 Requests、BeautifulSoup、Scrapy实战解析
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-25 02:41 , Processed in 0.160271 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表