列存即列式存储,是一种将数据按列进行存储和处理的数据管理方式。Lindorm计算引擎支持将半结构化、结构化数据以列存方式进行存储,相较于行式存储,列式存储的查询响应时间更短,消耗IO更少。本文介绍如何通过计算引擎访问Lindorm列存数据。
背景信息
Lindorm列存是面向海量半结构化、结构化数据设计的列格式分布式存储服务,适用于车联网、物联网、订单、日志等大规模存储场景,核心能力包括:
计算分析
Lindorm计算引擎可以访问列存数据,完成海量数据的交互式分析和离线计算。列存提供丰富的索引能力和数据分布特征,可以有效加速计算过程中的数据定位与排布,通过SQL即可完成海量主键数据的增删改查。
高吞吐
列存引擎吞吐能力支持水平扩展,提供每分钟TB级数据的读写能力。适用于车联网数据快速导入、模型训练数据集存取和大规模报表分析生产等高吞吐数据场景。
低成本
通过列格式高压缩比算法、高密度低成本介质、冷热分离、多压缩编码和数据冷归档等技术,Lindorm列存相比自建系统存储成本显著降低,满足海量数据归档留存等低成本存储需求。
高可用
通过纠删码等技术,Lindorm列存保证了分布式数据集的高可用性,同时保证了数据访问无单点。
开源兼容
兼容Iceberg开源标准接口,与Spark、Flink等多种计算引擎互联互通,无缝对接主流数据生态。
前提条件
已阅读使用须知。
根据不同的作业形态,请确保已经完成了以下操作:
JDBC开发实践:JDBC开发实践。
JAR作业开发实践:JAR作业开发实践。
Python作业开发实践:Python作业开发实践。
功能说明
DDL
命名空间
表
分区
DML
表
分区整理
在列存分区写入数据,经过一段时间后,您可以执行rewrite_data_files或rewrite_manifest命令,整理分区数据,减少数据或元数据冗余,提升数据查询性能。详细语法信息请参见rewrite_data_files语法和rewrite_manifest语法。
示例一:
USE lindorm_columnar; CALL lindorm_columnar.system.rewrite_data_files(table => 'mydb.mytable');
示例二:
USE lindorm_columnar; CALL lindorm_columnar.system.rewrite_data_files(table => 'mydb.mytable', where => 'city=\"beijing\"');
示例三:
USE lindorm_columnar; CALL lindorm_columnar.system.rewrite_manifest('mydb.mytable');
最佳实践
您可以通过以下方案,加速数据查询或计算。
主键数据查询
如果表中存储了海量数据集,查询时可以指定通过主键过滤条件,实现加速效果。查询时,主键的数据范围设置得越小,加速效果越好。
假设表结构如下:
USE lindorm_columnar;
CREATE TABLE orders (
o_orderkey INT NOT NULL,
o_custkey INT,
o_orderstatus STRING,
o_totalprice DOUBLE,
o_orderdate STRING,
o_orderpriority STRING,
o_clerk STRING,
o_shippriority INT,
o_comment STRING)
PARTITIONED BY (bucket(1024,o_orderkey))
TBLPROPERTIES(
'primary-key' = 'o_orderkey');
示例一:
USE lindorm_columnar; SELECT * FROM orders WHERE o_orderkey=18394;
示例二:
USE lindorm_columnar; SELECT count(*) FROM orders WHERE o_orderkey>100000 AND o_orderkey<200000;
示例三:
USE lindorm_columnar; SELECT count(*) FROM orders WHERE o_orderkey>100000;
添加分区过滤
Lindorm列存引擎中不同分区之间彼此物理隔离,因此,通过添加分区过滤条件,可以加速数据查询。
假设表结构如下:
USE lindorm_columnar;
CREATE TABLE orders (
o_orderkey INT NOT NULL,
o_custkey INT,
o_orderstatus STRING,
o_totalprice DOUBLE,
o_orderdate STRING NOT NULL,
o_orderpriority STRING,
o_clerk STRING,
o_shippriority INT,
o_comment STRING)
PARTITIONED BY (o_orderdate, bucket(1024,o_orderkey))
TBLPROPERTIES(
'primary-key' = 'o_orderdate,o_orderkey');
示例一:
USE lindorm_columnar; SELECT o_orderdate, count(*) FROM orders WHERE o_orderdate='2022-01-01' GROUP BY o_orderdate;
示例二:
USE lindorm_columnar; SELECT o_orderdate, count(*) FROM orders WHERE o_orderdate>='2022-01-01' AND o_orderdate<='2022-01-07' GROUP BY o_orderdate;
查询加速
对指定表或者表中的指定分区进行数据整理(Rewrite),可以增强数据的有序性或紧凑性,从而提升数据扫描性能。
假设表结构如下:
CREATE TABLE mydb.mytable (
id INT NOT NULL,
city STRING NOT NULL,
name STRING,
score INT)
partitioned by (city, bucket(4, id))
tblproperties('primary-key' = 'id,city');
示例一:对mydb.mytable全表进行数据整理。
CALL lindorm_columnar.system.rewrite_data_files(table => 'mydb.mytable');
示例二:对指定分区进行数据整理。
CALL lindorm_columnar.system.rewrite_data_files(table => 'mydb.mytable', where => 'city=\"beijing\"');
完成数据整理后,如果想要进一步提升后续查询的效率,可以执行以下语句设置表的相关参数来加速后续查询:
ALTER TABLE mydb.mytable SET TBLPROPERTIES ('read.scan-major-rewritten-files-only' = true);
参数说明
read.scan-major-rewritten-files-only:指定数据查询范围。数据类型为BOOLEAN。取值如下:
true:只查询已完成数据整理的数据,忽略增量写入且未完成数据整理的数据。
false:默认值。查询所有数据。
非主键条件查询
针对分区整理过程,列存表默认按主键排序,可以在建表后按需配置排序键,从而加速非主键条件查询。
自定义排序键加速查询效果需要在配置排序键后进行分区整理,且只扫描已进行分区整理的数据,不再扫描增量数据。
假设表结构如下:
USE lindorm_columnar;
CREATE TABLE orders (
o_orderkey INT NOT NULL,
o_custkey INT,
o_orderstatus STRING,
o_totalprice DOUBLE ,
o_orderdate STRING ,
o_orderpriority STRING,
o_clerk STRING,
o_shippriority INT,
o_comment STRING)
PARTITIONED BY (bucket(1024,o_orderkey))
TBLPROPERTIES(
'primary-key' = 'o_orderkey',
'read.scan-major-rewritten-files-only' = 'true');
执行以下语句配置排序键:
ALTER TABLE orders WRITE ORDERED BY o_shippriority,o_totalprice;
执行以下语句整理分区:
CALL lindorm_columnar.system.rewrite_data_files(table => 'orders');
您可以使用以下SQL语句查询已完成分区整理的表中的数据。
示例一:
USE lindorm_columnar; SELECT count(*) FROM orders WHERE o_shippriority=0;
示例二:
USE lindorm_columnar; SELECT count(*) FROM orders WHERE o_shippriority=0 AND o_totalprice>999.9;