前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >从零到千百万并发:数据架构师必知的事务处理秘籍

从零到千百万并发:数据架构师必知的事务处理秘籍

作者头像
一臻数据
发布2024-12-24 16:19:05
发布2024-12-24 16:19:05
6300
代码可运行
举报
文章被收录于专栏:一臻数据一臻数据
运行总次数:0
代码可运行

数据如果是流动的现金,那么每一笔交易都需要万分谨慎。 在Data+AI驱动的时代,如何确保数据的准确性和一致性?这让我想起了一个有趣的场景: 假如你是一家银行的出纳员,每天要处理成百上千笔交易。突然停电了,你正在处理的那笔百万转账进行到一半...冷汗瞬间就下来了!如果是你,你最担心什么?没错,就是数据一致性! 今天,我们就来聊聊数据世界里的"保险箱"——事务机制,基于Doris带你深入理解这套精妙的数据保护机制,让你在处理数据时不再提心吊胆。 无论你是刚接触数据的魔芋手,还是经验丰富的资深数据架构师,相信都能从中获得独特的启发。

Doris事务:数据一致性的守护者

"又丢数据了!"架构师小华深夜接到一个紧急电话,运维反馈生产环境出现数据不一致问题。

而作为一个经验丰富的Apache Doris技术内核专家,小勇知道这种问题往往与事务处理有关。

让我们一起走进Doris 2.1版本后的事务世界,看看它如何保护数据一致性。

事务魔法:保护数据的盾牌

在Doris中,事务好比盾牌,守护数据的完整性和一致性。这个盾牌有两种形态:显式事务和隐式事务。目前 Doris 不支持嵌套事务。

显式事务需要我们主动操控,就像驾驶一辆手动挡汽车。通过BEGIN指令启动事务,执行一系列数据操作,最后通过COMMIT确认提交或ROLLBACK撤销更改。这种方式让我们能够精确控制数据变更的边界。

隐式事务则像自动挡汽车,它在每个独立的查询和DDL操作中自动开启和结束。这种无感知的事务处理让我们能够专注于业务逻辑,而不用过多关注事务细节。

代码语言:javascript
代码运行次数:0
复制
-- 悄无声息的隐式事务
SELECT * FROM user_table WHERE age > 25;

-- 明明白白的显式事务
BEGIN;
INSERT INTO sales_2024 SELECT * FROM sales_2023 WHERE region = 'East';
UPDATE sales_summary SET total = total + 1 FROM sales_2024);
COMMIT;

隔离级别:数据读写的交通规则

Doris 当前支持的唯一隔离级别是 READ COMMITTED。在 READ COMMITTED 隔离级别下,语句只能看到在该语句开始执行之前已经提交的数据,它不会看到未提交的数据。

好比方,在繁忙的数据高速公路上,READ COMMITTED隔离级别就像智能交通灯。每个查询语句开始执行时,都会获得一个数据快照,只能看到该时刻之前已经提交的数据。这就像是给每个司机一张实时路况图,保证他们看到的是确定无误的路况信息。

小王遇到过这样一个场景:一个报表查询在执行过程中,另一个实时写入任务修改了源数据。多亏了READ COMMITTED隔离级别,报表查询使用的是开始时刻的数据快照,不会受到并发写入的影响,保证了数据的一致性。

不丢不重:数据的身份证

Doris 有两个机制支持写入的不重不丢,使用 Label 机制提供了单个事务的不重,使用两阶段提交提供了协调多事务不重的能力。

Label机制

Doris 的事务或者写入可以设置一个 Label,而Label就像是数据的身份证。每个事务都可以带有一个独特的标签,通常采用"业务名称_时间戳"的格式,不设置时内部会生成一个 UUID 字符串。这个标签不仅能帮助我们追踪数据的来源,还能防止重复导入。

设想在2024年11月19日22:00:00,业务系统产生了一批数据。我们可以为这批数据赋予一个标签:"my_business1_20241119_220000"。如果这批数据的导入因为网络问题中断,我们可以用相同的Label重试。

通过这种 Label 设定,业务上可以通过 Label 查询导入任务状态,来明确地获知该时间点批次的数据是否已经导入成功。如果没有成功,则可以使用这个 Label 继续重试导入。

StreamLoad 2PC

两阶段提交(2PC)机制让Doris能够优雅地处理跨系统的数据同步。对于数据同步任务,每个导入都像一场精心策划的音乐会:第一阶段是彩排,确保所有准备就绪;第二阶段才是正式演出。这种机制主要用于支持 Flink 写入 Doris 时的 EOS 语义,确保数据能够准确无误地从源系统同步到Doris。

小华最近就在设计一个实时数据同步方案,源系统数据变更需要实时同步到Doris。通过Stream Load的2PC机制,他成功实现了数据的精准同步,即使在网络抖动的情况下也能保证数据的一致性。

代码语言:javascript
代码运行次数:0
复制
# 1. 在 HTTP Header 中设置 two_phase_commit:true 启用两阶段提交。
curl  --location-trusted -u user:passwd -H "two_phase_commit:true" -T test.txt http://fe_host:http_port/api/{db}/{table}/_stream_load
{
    "TxnId": 18036,
    "Label": "my_business1_20241119_220000",
    "TwoPhaseCommit": "true",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 100,
    "NumberLoadedRows": 100,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 1031,
    "LoadTimeMs": 77,
    "BeginTxnTimeMs": 1,
    "StreamLoadPutTimeMs": 1,
    "ReadDataTimeMs": 0,
    "WriteDataTimeMs": 58,
    "CommitAndPublishTimeMs": 0
}

# 2. 对事务触发 commit 操作(请求发往 FE 或 BE 均可)
# 例如使用 label 指定事务
curl -X PUT --location-trusted -u user:passwd  -H "label:my_business1_20241119_220000" -H "txn_operation:commit"  http://fe_host:http_port/api/{db}/{table}/_stream_load_2pc
{
    "status": "Success",
    "msg": "label [55c8ffc9-1c40-4d51-b75e-f2265b3602ef] commit successfully."
}

# 3. 对事务触发 abort 操作(请求发往 FE 或 BE 均可)
curl -X PUT --location-trusted -u user:passwd  -H "label:my_business1_20241119_220000" -H "txn_operation:abort"  http://fe_host:http_port/api/{db}/{table}/_stream_load_2pc
{
    "status": "Success",
    "msg": "label [55c8ffc9-1c40-4d51-b75e-f2265b3602ef] abort successfully."
}

让我们回到开篇小华遇到的问题。通过深入了解Doris的事务机制,问题的根源找到了:原来是某些同步任务没有正确使用Label机制,导致数据重复写入。修复后,数据一致性得到了保障,生产环境也不再半夜"惊醒"运维团队了。

最后,来句结语:数据世界的演进永无止境,Doris事务机制也在不断完善,多多关注支持~

下期,我们将一起探讨Doris其它更有趣有用有价值的内容,敬请期待!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-11-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一臻数据 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Doris事务:数据一致性的守护者
  • 事务魔法:保护数据的盾牌
  • 隔离级别:数据读写的交通规则
  • 不丢不重:数据的身份证
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档