Doris专题9- 行列混存和冷热数据分层
1. 行列混存 (Row Store)
1.1 核心概念与原理
1.2 配置参数详解
-- 1. 基础行存配置
CREATE TABLE `tbl_row_store` (`k` INT NULL,`v1` DECIMAL(27, 9) NULL,`v2` VARCHAR(30) NULL,`v3` VARCHAR(30) NULL
) ENGINE=OLAP
UNIQUE KEY(`k`)
DISTRIBUTED BY HASH(`k`) BUCKETS 1
PROPERTIES (-- 开启行存(必需)"store_row_column" = "true",-- 指定行存列(可选,3.0+)"row_store_columns" = "k,v1,v3",-- 行存页面大小(可选)"row_store_page_size" = "4096",-- Merge-on-Write(高并发点查必需)"enable_unique_key_merge_on_write" = "true",-- 轻量级Schema变更"light_schema_change" = "true"
);-- 2. Duplicate表行存配置
CREATE TABLE `tbl_duplicate` (`k` INT NULL,`v1` STRING NULL
) ENGINE=OLAP
DUPLICATE KEY(`k`)
DISTRIBUTED BY HASH(`k`) BUCKETS 1
PROPERTIES ("store_row_column" = "true","row_store_page_size" = "4096"
);
1.3 行存命中条件分析
1.4 性能优化实践
-- 场景1:高并发主键点查(命中行存)
EXPLAIN SELECT k, v1, v3 FROM tbl_point_query WHERE k = 100;
-- 预期:SHORT-CIRCUIT标记-- 场景2:TOPN查询(命中行存)
EXPLAIN SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10;
-- 预期:FETCH_ROW_STORE + OPT TWO PHASE标记-- 场景3:混合查询(部分命中)
-- 行存包含k,v1,v3,查询包含v2(不在行存)
EXPLAIN SELECT k, v1, v2, v3 FROM tbl_point_query WHERE k = 100;
-- 结果:v1,v3从行存读取,v2从列存读取
1.5 存储成本与性能权衡
2. 冷热数据分层概述
2.1 分层存储策略对比
存储方案 | 适用条件 | 核心特性 | 成本效益 | 性能特点 |
---|---|---|---|---|
存算分离 | 具备部署条件 | • 数据单副本存对象存储 • 本地缓存加速 • 存储计算独立扩展 | 存储成本显著降低 | 热数据缓存加速,冷数据直接访问 |
本地分层 | 存算一体模式 | • SSD→HDD自动迁移 • 利用本地存储层级 | 节省高性能存储成本 | 热数据SSD高性能,冷数据HDD低成本 |
远程分层 | 存算一体模式 | • 冷数据→对象存储/HDFS • 热数据本地存储 | 进一步降低成本 | 热数据本地访问,冷数据远程读取 |
2.2 方案选择决策树
3. 远程存储 (Remote Storage)
3.1 S3兼容存储配置
-- 第一步:创建S3 Resource
CREATE RESOURCE "remote_s3"
PROPERTIES ("type" = "s3","s3.endpoint" = "bj.s3.com","s3.region" = "bj","s3.bucket" = "test-bucket","s3.root.path" = "path/to/root","s3.access_key" = "your_access_key","s3.secret_key" = "your_secret_key","s3.connection.maximum" = "50","s3.connection.request.timeout" = "3000","s3.connection.timeout" = "1000",-- 针对minio等需要path style的存储"use_path_style" = "true"
);-- 第二步:创建Storage Policy
CREATE STORAGE POLICY test_policy
PROPERTIES("storage_resource" = "remote_s3","cooldown_ttl" = "1d" -- 1天后冷却到远程存储
);-- 第三步:建表使用Storage Policy
CREATE TABLE cold_data_table (k1 BIGINT,k2 LARGEINT,v1 VARCHAR(2048)
)
UNIQUE KEY(k1)
DISTRIBUTED BY HASH(k1) BUCKETS 3
PROPERTIES(-- 注意:MOW表不支持远程存储"enable_unique_key_merge_on_write" = "false","storage_policy" = "test_policy"
);
3.2 HDFS存储配置
-- 第一步:创建HDFS Resource
CREATE RESOURCE "remote_hdfs"
PROPERTIES ("type" = "hdfs","fs.defaultFS" = "hdfs://namenode:8020","hadoop.username" = "hive","hadoop.password" = "hive","root_path" = "/my/root/path",-- HA集群配置"dfs.nameservices" = "my_ha","dfs.ha.namenodes.my_ha" = "nn1,nn2","dfs.namenode.rpc-address.my_ha.nn1" = "nn1_host:8020","dfs.namenode.rpc-address.my_ha.nn2" = "nn2_host:8020","dfs.client.failover.proxy.provider.my_ha" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
);-- 第二步:创建Storage Policy
CREATE STORAGE POLICY hdfs_policy
PROPERTIES("storage_resource" = "remote_hdfs","cooldown_ttl" = "300" -- 300秒后冷却
);-- 第三步:使用Storage Policy创建表
CREATE TABLE hdfs_cold_table (k1 BIGINT,k2 LARGEINT,v1 VARCHAR(2048)
)
UNIQUE KEY(k1)
DISTRIBUTED BY HASH(k1) BUCKETS 3
PROPERTIES("enable_unique_key_merge_on_write" = "false","storage_policy" = "hdfs_policy"
);
3.3 存量表冷却管理
-- 1. 整表设置远程存储
ALTER TABLE existing_table SET ("storage_policy" = "test_policy");-- 2. 特定分区设置远程存储
ALTER TABLE partitioned_table MODIFY PARTITION (p202301, p202302)
SET("storage_policy" = "test_policy");-- 3. 所有分区设置远程存储
ALTER TABLE partitioned_table MODIFY PARTITION (*)
SET("storage_policy" = "test_policy");-- 4. 查看分区存储情况
SHOW PARTITIONS FROM partitioned_table;
3.4 性能优化与监控
-- BE配置调优(be.conf)
-- 远程存储Compaction并发
cold_data_compaction_thread_num = 4-- Compaction时间间隔(秒)
cold_data_compaction_interval_sec = 1800-- 垃圾回收间隔(秒)
remove_unused_remote_files_interval_sec = 21600-- 监控远程存储使用情况
-- 方式1:查看BE远程存储用量
SHOW PROC '/backends';
-- 关注:RemoteUsedCapacity字段-- 方式2:查看表级别远程存储
SHOW TABLETS FROM table_name;
-- 关注:RemoteDataSize字段-- 方式3:查看缓存命中率(需开启数据缓存)
SHOW BACKEND;
-- 关注:DataCacheMetrics相关指标
4. SSD/HDD本地分层存储
4.1 动态分区层级配置
-- 创建SSD/HDD分层存储表
CREATE TABLE tiered_table (event_date DATE,user_id BIGINT,event_data STRING
)
PARTITION BY RANGE(event_date)()
DISTRIBUTED BY HASH(user_id) BUCKETS 5
PROPERTIES (-- 动态分区基础配置"dynamic_partition.enable" = "true","dynamic_partition.time_unit" = "DAY","dynamic_partition.start" = "-3","dynamic_partition.end" = "3","dynamic_partition.prefix" = "p","dynamic_partition.buckets" = "5","dynamic_partition.create_history_partition" = "true",-- 分层存储关键配置"dynamic_partition.storage_medium" = "hdd","dynamic_partition.hot_partition_num" = "2"
);
4.2 分层存储原理示例
4.3 分区状态监控
-- 查看分区存储介质分布
SHOW PARTITIONS FROM tiered_table;-- 预期输出示例:
/*
p20210517: ["2021-05-17", "2021-05-18") storage_medium=HDD
p20210518: ["2021-05-18", "2021-05-19") storage_medium=HDD
p20210519: ["2021-05-19", "2021-05-20") storage_medium=SSD
p20210520: ["2021-05-20", "2021-05-21") storage_medium=SSD
p20210521: ["2021-05-21", "2021-05-22") storage_medium=SSD
p20210522: ["2021-05-22", "2021-05-23") storage_medium=SSD
p20210523: ["2021-05-23", "2021-05-24") storage_medium=SSD
*/-- 查看存储介质统计
SELECT storage_medium,COUNT(*) as partition_count,SUM(data_size) as total_size
FROM information_schema.partitions
WHERE table_name = 'tiered_table'
GROUP BY storage_medium;
5. 最佳实践与注意事项
5.1 行列混存使用建议
-
适用场景识别
- 高频点查业务(用户查询、订单查询)
- 宽表SELECT * 场景
- 高并发主键查询
-
成本控制策略
- 使用
row_store_columns
指定关键列 - 根据业务特点调整
row_store_page_size
- 监控存储空间增长
- 使用
-
性能验证方法
- 通过EXPLAIN确认行存命中
- 对比开启前后的查询延迟
- 监控IOPS变化
5.2 冷热分层部署建议
5.3 重要限制与约束
-
行列混存限制
- 存储空间增加2-10倍
- 需要仔细评估业务场景
- 部分查询可能无法命中行存
-
远程存储限制
- 不支持备份功能
- 不支持修改存储位置
- MOW表不支持远程存储
- 一旦设置不能取消
-
分层存储限制
- 必须有SSD设备支持
- 动态分区配置相对复杂
- 冷却策略需要持续优化
5.4 故障排查与优化
-- 常见问题诊断-- 1. 行存未命中检查
EXPLAIN SELECT * FROM tbl WHERE conditions;-- 2. 远程存储连接测试
-- 检查Resource创建是否成功
SHOW RESOURCES;-- 3. 分层存储状态检查
SHOW PARTITIONS FROM table_name;-- 4. 性能问题定位
-- 查看查询Profile
SET enable_profile = true;-- 5. 存储空间监控
SHOW TABLETS FROM table_name;
SHOW PROC '/backends';
6. 总结
通过合理使用行列混存和冷热数据分层技术,可以在Apache Doris中实现:
- 行列混存:优化点查性能,解决宽表IOPS瓶颈
- 远程存储:大幅降低冷数据存储成本,支持存算分离
- 本地分层:在存算一体架构下优化存储成本
- 智能冷却:根据数据热度自动迁移,平衡性能与成本