Doris部分列更新

部分列更新最佳实践

一、使用场景

部分列更新的使用场景主要包括以下几个方面:

  1. 实时动态更新:在需要频繁更新某些字段的场景中,例如用户标签表中的行为信息更新,以支持广告或推荐系统的实时分析和决策。

  2. 大宽表拼接:将多张源表的数据合并成一张大宽表,可以通过部分列更新来实现。

  3. 数据修正:在需要修正某些数据的场景中,部分列更新可以有效减少更新的开销。

  4. 高频并发写入:部分列更新支持高频的并发写入,适用于需要实时更新大量行但仅涉及少数列的场景。

  5. 性能优化:在更新少数列时,部分列更新可以显著提高性能,尤其是在涉及大量行的情况下。

这些场景中,部分列更新通过减少不必要的数据写入和锁定,提升了系统的整体性能和响应速度。

注意事项

  1. 2.0 版本仅在 Unique Key 的 Merge-on-Write 实现中支持了部分列更新能力

  2. 从 2.0.2 版本开始,支持使用 INSERT INTO 进行部分列更新

  3. 不支持在有同步物化视图的表上进行部分列更新

二、实践

  • doris建表

CREATE TABLE `test_partial_update` (
  `id` int(11) NULL,
  `value` varchar(20) NULL,
  `date_time` datetime(6) not NULL DEFAULT CURRENT_TIMESTAMP,
  `dt` datetime(6) default current_timestamp(6) on update current_timestamp(6)
) ENGINE=OLAP
unique KEY(`id`)
COMMENT '部分列更新'
DISTRIBUTED BY HASH(`id`) BUCKETS 3
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);

on update current_timestamp

是否在该行有列更新时将该列的值更新为当前时间 (current_timestamp)。该特性只能在开启了 Merge-on-Write 的 Unique 表上使用,开启了这个特性的列必须声明默认值,且默认值必须为 current_timestamp。如果此处声明了时间戳的精度,则该列默认值中的时间戳精度必须与该处的时间戳精度相同。

  • 首先插入一条数据:

mysql> insert into test_partial_update(id, value) values(1, "doris");
Query OK, 1 row affected (0.04 sec)
{'label':'label_3ed18eb2142c42a6_b02373286719ab46', 'status':'VISIBLE', 'txnId':'60072'}
​
mysql> select * from test_partial_update;
+------+-------+----------------------------+----------------------------+
| id   | value | date_time                  | dt                         |
+------+-------+----------------------------+----------------------------+
|    1 | doris | 2024-10-13 10:45:22.000000 | 2024-10-13 10:45:22.257000 |
+------+-------+----------------------------+----------------------------+
1 row in set (0.01 sec)

2.1 insert

如果只想更改value值,并且保留数据的插入时间,可以开启insert的部分列更新功能并指定插入的列名:

set enable_unique_key_partial_update=true;

mysql> insert into test_partial_update(id, value) values(1, "SelectDB");
Query OK, 1 row affected (0.03 sec)
{'label':'label_6a1e2c7306e84c81_a3ba841f7b302bb3', 'status':'VISIBLE', 'txnId':'60074'}
​
mysql> select * from test_partial_update;
+------+----------+----------------------------+----------------------------+
| id   | value    | date_time                  | dt                         |
+------+----------+----------------------------+----------------------------+
|    1 | SelectDB | 2024-10-13 10:45:22.000000 | 2024-10-13 10:48:12.619000 |
+------+----------+----------------------------+----------------------------+
1 row in set (0.01 sec)

可以看出此时date_time字段记录了数据的插入时间,dt字段记录了数据的更新时间。

2.2 stream load

  • 新建一份数据

vim test_partial_update.csv

1, "SelectDB"
  • 在columns处指定key列(必须包含所有 key 列,不然无法更新)以及要更新的value列,设置header:"partial_columns:true":

curl --location-trusted -u root:123456 -T test_partial_update.csv -H "format:csv" -H "column_separator:," -H "partial_columns:true"  -H "columns:id, value" http://10.16.10.6:8030/api/demo/test_partial_update/_stream_load
  • 查询数据可知date_time字段记录了数据的插入时间,dt字段记录了数据的更新时间。

mysql> select * from test_partial_update;
+------+-------------+----------------------------+----------------------------+
| id   | value       | date_time                  | dt                         |
+------+-------------+----------------------------+----------------------------+
|    1 |  "SelectDB" | 2024-10-13 10:45:22.000000 | 2024-10-13 11:11:51.795000 |
+------+-------------+----------------------------+----------------------------+
1 row in set (0.01 sec)

2.3 Flink Connector

  • mysql建表,插入数据:

CREATE TABLE `test_partial_update` (
  `id` INT(11) NULL,
  `value` VARCHAR(20) NULL,
  `date_time` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  `dt` DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
);
​
mysql> insert into test_partial_update(id, value) values(1, "SelectDB");
Query OK, 1 row affected (0.00 sec)
​
mysql> select * from test_partial_update;
+------+----------+----------------------------+----------------------------+
| id   | value    | date_time                  | dt                         |
+------+----------+----------------------------+----------------------------+
|    1 | SelectDB | 2024-10-14 16:08:14.058728 | 2024-10-14 16:08:14.058728 |
+------+----------+----------------------------+----------------------------+
1 row in set (0.00 sec)
  • 进入flink

./bin/sql-client.sh embedded
  • 开启Checkpoint

Flink作业周期性执行checkpoint,记录Binlog位点,当作业发生Failover时,便会从之前记录的Binlog位点继续处理。

Flink SQL> SET execution.checkpointing.interval = 3s;
  • 创建MySQL CDC表和Dois sink表,并设置'sink.properties.partial_columns' = 'true'

CREATE TABLE cdc_mysql_source (
    id INT,
    `value` STRING,
    date_time TIMESTAMP,
    dt TIMESTAMP
) WITH (
    'connector' = 'mysql-cdc',
    'hostname' = '10.16.10.6',
    'port' = '3326', 
    'username' = 'root',
    'password' = '123456',
    'database-name' = 'test',
    'scan.incremental.snapshot.chunk.key-column'='id',
    'table-name' = 'test_partial_update'
);
​
CREATE TABLE doris_sink (
    id INT,
    `value` STRING,
    date_time TIMESTAMP,
    dt TIMESTAMP
) 
WITH (
  'connector' = 'doris',
  'fenodes' = '127.0.0.1:8030',
  'table.identifier' = 'demo.test_partial_update',
  'username' = 'root',
  'password' = '123456',
  'sink.properties.format' = 'json',
  'sink.properties.read_json_by_line' = 'true',
  'sink.properties.columns' = 'id,name,bank,age',
  'sink.properties.partial_columns' = 'true' -- 开启部分列更新
);
​
​
insert into doris_sink(id, `value`) select id,`value` from cdc_mysql_source;
  • 去 doris 查询数据可知date_time字段记录了数据的插入时间,dt字段记录了数据的更新时间。

mysql> select * from test_partial_update;
+------+-------------+----------------------------+----------------------------+
| id   | value       | date_time                  | dt                         |
+------+-------------+----------------------------+----------------------------+
|    1 |  "SelectDB" | 2024-10-13 10:45:22.000000 | 2024-10-14 16:11:23.546000 |
+------+-------------+----------------------------+----------------------------+
1 row in set (0.01 sec)

常见问题FAQ

  1. 如果开启了部分列更新之后插入报错"errCode = 2, detailMessage = Insert has filtered data in strict mode"

  • 原因:控制 insert 语句是否开启严格模式的会话变量enable_insert_strict的默认值为 true,即 insert 语句默认开启严格模式,而在严格模式下进行部分列更新不允许更新不存在的 key。所以,在使用 insert 语句进行部分列更新的时候如果希望能插入不存在的 key,需要在enable_unique_key_partial_update设置为 true 的基础上同时将enable_insert_strict设置为 false。

解决方法: set enable_insert_strict=false;

  1. MySQL CDC表数据同步失败。

  • 原因1:mysql未开启binlog

解决办法:

可以通过以下命令检查 binlog 是否已启用:

SHOW VARIABLES LIKE 'log_bin';

如果 log_bin 的值是 OFF,需要在 MySQL 配置文件中启用 binlog:

[mysqld]
log_bin = mysql-bin
binlog_format = ROW
server_id = 1

重启 MySQL 服务后生效。

  • 原因2:检查 MySQL 表 test_partial_update 的字段类型与 Flink 表 DDL 是否匹配。字段类型不匹配可能会导致数据读取问题。

  • 原因3:flink 任务报错 MySQL server has a timezone offset (0 seconds ahead of UTC) which does not match the configured timezone Asia/Shanghai. Specify the right server-time-zone to avoid inconsistencies for time-related fields. 解决方法:

    set time_zone='+8:00';
    #或者
    set persist time_zone='+8:00';

    关注公众号 “数据微光”,拉你进 doris 技术交流群。

03-12
<think>好的,我现在需要处理用户关于Apache Doris的查询。首先,用户提供了两个引用链接,我需要仔细查看这些资料,确保回答准确。用户希望了解Apache Doris数据库介绍和使用场景,所以得从这两个方面入手。 先看引用[1],里面提到Apache Doris的前身是百度Doris团队开发的,后来部分成员离职创业,基于之前的版本做了DorisDB,也就是StarRocks的前身。这可能涉及Doris的起源和发展历程,需要在介绍部分提到。同时,引用中还提到了Doris的使用场景,比如实时数据分析、多维度查询等,这些是用户关心的重点,需要详细说明。 引用[2]是关于单机部署流程的,里面提到了下载二进制安装包、传输到Linux系统,以及具体的wget命令。这部分内容可能需要放在使用部分,比如部署步骤,但用户的问题主要是介绍和使用场景,所以可能需要简要提及部署方法,或者作为使用的一部分。 接下来,我需要组织回答结构。根据用户的要求,回答需要结构清晰,分点说明。先介绍Apache Doris的基本情况,包括定义、特点和适用场景。然后说明其使用场景,具体举几个例子,比如实时数据分析、日志分析、数据仓库等,每个场景可以简要说明Doris的优势所在。最后,可能需要提到如何部署或使用,但根据用户的问题,可能不需要太详细的步骤,而是概括性的描述,比如支持标准SQL、高并发查询等。 需要注意的是,用户要求使用中文回答,并且行内数学公式用$...$,独立公式用$$...$$。不过当前问题涉及数据库技术,可能数学公式较少,但如果有性能指标或算法,可能需要用LaTeX表达。例如,如果提到查询延迟在毫秒级,可以写成$<100ms$。不过目前资料中没有涉及太多数学内容,可能需要根据情况处理。 另外,用户要求生成相关问题,需要根据回答内容提出几个相关问题,比如技术架构、性能优化、应用案例等。需要确保问题与Doris相关,并且能够引导用户进一步探索。 检查是否有遗漏的信息。引用[1]中提到Doris适用于实时分析、多维度查询和高并发场景,这些都需要在回答中体现。引用[2]中的部署步骤可能作为使用部分的一个小点,但用户可能更关注应用场景而非具体安装步骤,所以可能简要提及部署简便即可。 最后,确保回答符合格式要求,没有使用markdown,分点清晰,正确引用来源。引用标识要放在相关句子的末尾,例如在介绍使用场景时引用[^1],在部署方法时引用[^2]。 总结回答结构: 1. Apache Doris简介:定义、起源、特点。 2. 核心特点:式存储、MPP架构、易用性、高性能。 3. 使用场景:实时分析、日志分析、数据仓库、即席查询。 4. 使用方式:部署、数据导入、查询。 5. 相关问题。 现在需要将这些内容用中文流畅表达,并自然插入引用标识。确保技术术语准确,比如MPP架构、OLAP等。同时,避免使用复杂术语时适当解释,比如说明式存储的优势,提高查询效率。</think>### Apache Doris 数据库介绍 Apache Doris 是一款高性能、实时的分析型数据库,适用于在线分析处理(OLAP)场景。其前身是百度 Doris 团队开发的分布式数据库系统,后成为 Apache 顶级项目。Doris 采用**式存储**和**MPP(大规模并行处理)架构**,支持高并发查询、实时数据更新和多维分析,具备低延迟(毫秒级响应)和高吞吐量的特点[^1]。 #### 核心特点 1. **式存储与压缩**:数据按存储,减少 I/O 开销,并通过压缩算法降低存储成本。 2. **分布式 MPP 架构**:支持水平扩展,节点间并行计算,适用于 PB 级数据分析。 3. **易用性**:兼容 MySQL 协议,支持标准 SQL,提供与 BI 工具无缝集成。 4. **实时性**:支持数据实时写入与查询,适用于流批一体场景。 ### 使用场景 1. **实时数据分析** - 例如:电商实时订单分析、广告点击率统计,支持在数据写入后 $<1s$ 内查询[^1]。 2. **日志分析** - 快速分析海量日志数据,如用户行为日志、系统监控日志。 3. **数据仓库加速** - 作为查询加速层,提升传统数据仓库(如 Hive)的响应速度。 4. **即席查询(Ad-hoc)** - 支持复杂多维度查询,满足业务灵活分析需求。 ### 如何使用 1. **部署** - 通过二进制安装包快速部署单机或集群环境,支持 Linux 系统(参考命令): ```bash wget https://apache-doris-releases.oss-accelerate.aliyuncs.com/apache-doris-2.1.7-bin-x64.tar.gz ``` [^2] 2. **数据导入** - 支持 Kafka、MySQL、HDFS 等多种数据源,通过 Broker Load 或 Stream Load 实现实时/批量导入。 3. **查询** - 使用标准 SQL 或 BI 工具(如 Tableau)直接连接 Doris 进行数据分析。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据微光a

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值