重庆专业网站建设首页排名,网站模板广告去除,重庆网站制作一般需要多少钱,专业北京网站建设过去#xff0c;TiDB 由于不支持存储过程、大事务的使用也存在一些限制#xff0c;使得在 TiDB 上进行一些复杂的数据批量处理变得比较复杂。
TiDB 在面向这种超大规模数据的批处理场景#xff0c;其能力也一直在演进#xff0c;其复杂度也变得越来越低#xff1a;
○ 从…过去TiDB 由于不支持存储过程、大事务的使用也存在一些限制使得在 TiDB 上进行一些复杂的数据批量处理变得比较复杂。
TiDB 在面向这种超大规模数据的批处理场景其能力也一直在演进其复杂度也变得越来越低
○ 从 TiDB 5.0 开始TiFlash 支持 MPP 并行计算能力在大批量数据上进行聚合、关联的查询性能有了极大的提升
○ 到了 TiDB 6.1 版本引入了 BATCH DML ( https://docs.pingcap.com/zh/tidb/stable/non-transactional-dml ) 功能该功能可以将一个大事务自动拆成多个批次去处理在单表基础上进行大批量更新、删除、写入时能够大幅提升处理效率同时避免了大事务所产生的一些影响。
○ 而到了 7.1 LTS 版本正式 GA 了 TiFlash 查询结果物化 ( https://docs.pingcap.com/zh/tidb/stable/tiflash-results-materialization#tiflash-查询结果物化 ) 的功能使得 insert/replace into ... select ... 这种操作中的复杂 select 能够利用 TiFlash MPP 并行处理的能力大幅提升了这种操作的处理性能。
○ 前不久刚发布的 7.5 LTS正式 GA 了一个 IMPORT INTO ( https://docs.pingcap.com/zh/tidb/stable/sql-statement-import-into#import-into ) 的功能该功能将原本 tidb-lightning 的物理导入能力集成到 TiDB 计算节点上使用一条 SQL 语句就可以完成大批量数据的导入大幅简化了超大规模数据写入时的复杂度。
TiDB 上之前有哪些批处理方案
INSERT INTO ... SELECT 完成查询和写入
● 现状适用于小批量数据处理性能较高
● 挑战大批量数据写入时会产生大事务消耗内存较高
● 说明写入单表查询场景可使用 BATCH DML 功能自动拆批
针对 INSERT INTO/INSERT INTO ... ON DUPLICATE .../REPLACE INTO 这些 SQL 使用批量接口执行降低应用与数据库之间的交互次数提升批量写入时的性能
● 现状在合适的拆批方案、表结构设计上处理性能非常高
● 挑战编码不合理、表结构设计不合理时可能会遇到热点问题导致性能不佳
通过 ETL 和调度平台提供的数据读取和写入能力实现大批量数据的处理
● 现状主流的 ETL 平台如 datax、spark、kettle 等在合理表结构设计时性能也比较高
● 挑战多线程并行写入时也有可能会遇到热点问题
针对上游传过来的 csv 文件的数据使用 LOAD DATA 来完成批量数据的写入提升批量写入时的性能
● 现状在对文件进行拆分多线程并行后处理性能非常高
● 挑战当 LOAD DATA 一个大文件时此时是大事务导致性能不佳多线程处理时也有可能遇到热点问题导致性能不佳
针对以上几种批处理方案以及最新推出的 IMPORT INTO 功能我们开展了一次测试探索哪种批处理方案效率最高消耗资源更低以及使用上更加简单。
TiDB 中不同批处理方案的测试
1 测试环境
TiDB 资源3 台 16VC/64GB 虚拟机 500GB SSD 云盘3500 IOPS 250MB/S 读写带宽
a. TiDB 版本TiDB V7.5.0 LTS
b. TiDB 组件TiDB/PD/TiKV/TiFlash混合部署
存储资源8C/64GB 虚拟机 500GB SSD 云盘3500 IOPS 250MB/S 读写带宽
● 存储服务NFS 服务、Minio 对象存储
测试资源8C/64GB 虚拟机 500GB SSD 云盘3500 IOPS 250MB/S 读写带宽
● datax Dolphin 调度/java 程序/dumpling、tidb-lightning 工具以及 MySQL 客户端 2 测试场景
将大批量查询结果快速写入到目标表既考验查询性能同时也考验批量写入的性能。
2.1 查询部分多表关联聚合
基于 TPCH 100GB 数据扩展 Q10 查询中的字段和查询范围返回 8344700 行数据。
select c_custkey,c_name,sum(l_extendedprice * (1 - l_discount)) as revenue,c_acctbal,n_name,c_address,c_phone,c_comment,min(C_MKTSEGMENT),min(L_PARTKEY), min(L_SUPPKEY,min(L_LINENUMBER),min(L_QUANTITY), max(L_TAX), max(L_LINESTATUS), min(L_SHIPDATE), min(L_COMMITDATE), min(L_RECEIPTDATE), min(L_SHIPINSTRUCT), max(L_SHIPMODE), max(O_ORDERSTATUS), min(O_TOTALPRICE), min(O_ORDERDATE), max(O_ORDERPRIORITY), min(O_CLERK), max(O_SHIPPRIORITY), hostname as etl_host,current_user() as etl_user,current_date() as etl_date
fromtpch.customer,tpch.orders,tpch.lineitem,tpch.nation
wherec_custkey o_custkey and l_orderkey o_orderkeyand o_orderdate date 1993-10-01 and o_orderdate date 1994-10-01and l_returnflag R and c_nationkey n_nationkey
group byc_custkey,c_name,c_acctbal,c_phone,n_name,c_address,c_comment
order by c_custkey;
源表数据量 2.2 写入29 列1 个主键2 个索引
CREATE TABLE tpch_q10 (c_custkey bigint(20) NOT NULL,c_name varchar(25) DEFAULT NULL,revenue decimal(15,4) DEFAULT NULL,...etl_host varchar(64) DEFAULT NULL,etl_user varchar(64) DEFAULT NULL,etl_date date DEFAULT NULL,PRIMARY KEY (c_custkey) /*T![clustered_index] CLUSTERED */,KEY idx_orderdate (o_orderdate),KEY idx_phone (c_phone)
) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_bin;
3 测试结果 4 测试分析
4.1 JAVA 程序使用 SQL 进行批处理
使用 JAVA 处理时StreamingResult 流式读取多并发写入方式能够获得非常好的性能。 强烈不建议使用 limit 分页这种形式拆批 这种逻辑数据库将执行 844 条查询 SQL效率极低消耗的资源极高。同时 StreamingResult 这种流式读取还可以使用于数据导出的场景对比使用 limit 分页处理效率也更高。
在程序 4 中将原本查询 SQL 里的 order by c_custkey 换成了 order by revenue desc 后对性能也有一定影响原因主要是多线程写入时 RPC 开销严重放大。
在程序 5 中将原本查询 SQL 中的 c_phone 换成 132-0399-0111 as c_phone模拟索引热点。 4.2 LOAD DATA 方式
如果使用 LOAD DATA 要获得比较高的性能建议对单个文件进行拆分同时 csv 中文件的顺序建议与目标表主键顺序一致如一个 CSV 文件存储 20000 行再通过多线程并行来写入此时写入性能也比较高。
如果仅 LOAD DATA 导入单个大文件那么性能较低且消耗内存较高。
4.3 ETL调度平台方式
● 作业类型datax(mysqlreader mysqlwriter)简单效率一般
调度平台执行 datax 作业使用 mysqlreader 方式读取时默认就使用流式读取但是对于多表查询的 query 时写入时无法并发
● 作业类型shell datax(txtfileread mysqlwriter)较复杂效率较高
○ 调度平台执行 shell使用 dumpling 导出成多个 csv 文件
○ 再调度 datax 作业使用 txtfilereader mysqlwriter此时可以多线程并发写入效率较高
● 作业类型**SQL简单高效**
○ 调度平台执行 SQLselect ... into outfile
○ 调度平台执行 SQLimport into
4.4 SELECT ... INTO OUTFILE 导出查询结果当前仅支持导出到文件系统
该功能大家平时可能使用比较少但该功能非常有价值它可以高效的将数据一批导出、并且数据是完全一致的状态可以用于
a. 批量数据处理JAVA 程序可直接执行该 SQL 完成结果的导出
b. 在简单的数据导出场景使用导出 csv 替换原本 limit 处理逻辑应用将查询结果导出到一个共享 NFS/S3 对象存储中再读取 NFS/S3 对象存储中的 CSV进行结果的处理极大的降低了数据库的压力同时性能将比之前使用 limit 分批处理更高。
4.5 IMPORT INTO 导入 CSV当前支持 S3 协议对象存储以及文件系统
该功能 7.5.0 引入极大的简化了数据导入的难度JAVA 程序可直接执行该 SQL 完成 CSV 数据的导入在进行批处理时应用节点几乎不需要消耗 CPU/内存资源。以下是使用示例
IMPORT INTO test.tpch_q10 FROM /mnt/nfs/test.tpch_q10.csv with FIELDS_TERMINATED_BY\t,split_file,thread8;
需要注意的是IMPORT INTO 导入过程中不会产生日志所以针对需要 CDC 同步或 Kafka 分发的场景该方案不适用。
5 测试小结 部分测试代码示例 https://github.com/Bowen-Tang/batch-samples
总结与展望
TiDB 7.5.0 引入的 IMPORT INTO 功能结合 SELECT ... INTO OUTFILE、以及 NFS/对象存储让 TiDB 上增加了一种更加简单且非常高效的批处理方案JAVA 应用程序处理时更加简单ETL 调度也更简单。
以下是 TiDB 使用 IMPORT INTO、SELECT ... INTO OUTFILE 的架构示例 I MPORT INTO 功能当前仅支持 CSV 导入未来 TiDB 8.x 版本中 IMPORT INTO 将直接集成 IMPORT INTO ... SELECT ... 功能极致简化批处理操作性能也更进一步提升187 秒敬请大家期待