一、表结构优化性能的基石表结构设计是Doris性能优化的起点不合理的表结构会导致后续所有优化事倍功半。核心在于通过合理的数据划分、索引选择和模型匹配从源头减少数据处理量和计算开销。1.1 分区分桶策略数据划分的艺术Doris采用两层数据划分机制第一层是分区Partition实现数据的逻辑隔离和范围裁剪第二层是分桶Bucket实现数据在BE节点间的均匀分布。分区最佳实践优先使用时间维度作为分区列如dt、create_time这是最常用的查询过滤条件能实现高效的分区裁剪推荐使用2.1版本引入的Auto Partition自动分区功能避免手动创建分区的繁琐和遗漏分区粒度根据数据量调整日分区适合每天数据量10GB的场景月分区适合数据量较小的历史表对于有历史数据删除需求的场景分区机制能实现秒级的分区删除远优于DELETE语句分桶最佳实践分桶列选择区分度高的列如user_id、order_id避免数据倾斜单Tablet分桶压缩后的数据量控制在1-10GB之间计算公式分桶数单分区总数据量/(1-10GB)分桶数建议为BE节点数的整数倍确保数据均匀分布避免分桶数过多过多分桶会增加FE元数据压力和BE的Compaction开销示例合理的分区分桶表创建CREATE TABLE user_behavior ( dt DATEV2 NOT NULL COMMENT 日期, user_id BIGINT NOT NULL COMMENT 用户ID, item_id BIGINT NOT NULL COMMENT 商品ID, behavior_type TINYINT NOT NULL COMMENT 行为类型1-点击2-收藏3-加购4-购买, behavior_time DATETIMEV2 NOT NULL COMMENT 行为时间, amount DECIMAL(10,2) COMMENT 交易金额 ) AUTO PARTITION BY RANGE (DATE_TRUNC(dt, DAY)) -- 自动按天分区 DISTRIBUTED BY HASH(user_id) BUCKETS 32 -- 按用户ID分桶32个桶 PROPERTIES ( replication_num 3, storage_medium SSD, enable_segcompaction true -- 开启Segment Compaction2.1默认开启 );1.2 索引优化加速数据检索Doris提供多种索引类型合理使用索引能大幅提升查询性能但需注意索引会增加导入开销和存储成本。Bloom Filter索引适用场景高基数列如user_id、order_id的等值查询不适用范围查询、低基数列创建方式ALTER TABLE user_behavior ADD INDEX bf_item_id(item_id) USING BLOOM_FILTER;Bitmap索引适用场景低基数列如性别、状态、行为类型的等值过滤和组合过滤不适用高基数列、更新频繁的列创建方式ALTER TABLE user_behavior ADD INDEX bitmap_behavior(behavior_type) USING BITMAP;1.3 数据模型选择匹配业务场景Doris提供三种核心数据模型需根据业务需求选择最合适的模型错误的模型选择会导致性能和功能问题。数据模型核心特点适用场景Aggregate模型导入时自动按Key聚合相同行报表统计、数据汇总、预计算场景Unique模型保证主键唯一性支持更新订单表、用户表等需要主键约束的场景Duplicate模型不做任何聚合保留所有原始数据原始日志、明细数据、无聚合需求的场景注意Unique模型在2.0版本引入了Merge-on-Write实现更新性能较之前的Merge-on-Read提升了数十倍推荐优先使用。二、数据导入优化打通入仓高速通道数据导入是Doris数据链路的入口导入性能直接影响数据的实时性和系统稳定性。Doris提供多种导入方式需根据数据源类型、数据量和实时性要求选择合适的导入方式。2.1 导入方式选择按需匹配Broker Load适用场景TB级以上大规模批量数据导入数据源为HDFS、S3、OSS等外部存储优势支持分布式并行导入吞吐量大适合离线数据同步示例LOAD LABEL db.user_behavior_label_20240611 ( DATA INFILE(hdfs://namenode:8020/data/user_behavior/20240611/*.parquet) INTO TABLE user_behavior FORMAT AS PARQUET ) WITH BROKER broker_name PROPERTIES ( timeout 3600, max_filter_ratio 0.01 );Stream Load适用场景GB级以下小文件导入、实时数据写入、程序接口导入优势同步导入实时返回结果无需部署Broker示例curl --location-trusted -u user:password \ -T user_behavior_20240611.csv \ -H label:user_behavior_20240611_stream \ -H format:csv \ http://fe_host:8030/api/db/user_behavior/_stream_loadRoutine Load适用场景从Kafka持续消费实时数据优势支持Exactly-Once语义自动容错无需人工干预是实时数据入仓的首选方式Insert Into适用场景小批量数据导入、Doris内部表之间的数据转换、ETL作业2.1版本引入了MemTable前移优化使得INSERT INTO…SELECT的导入性能提升了100%以上2.2 并行度与参数调优导入并行度是影响导入性能的关键因素合理调整并行度能充分利用集群的CPU和IO资源。全局参数调优-- 开启全局运行时过滤提升大表Join性能 SET GLOBAL global_runtime_filter_mode GLOBAL; -- 设置每个查询的并行实例数建议为BE节点CPU核心数的1/4-1/2 SET GLOBAL parallel_fragment_exec_instance_num 8;Broker Load专项调优WITH BROKER broker_name PROPERTIES ( load_parallelism 16, -- 导入并行度建议为BE节点数的2-4倍 send_batch_parallelism 5, -- 发送批次并行度 exec_mem_limit 21474836480, -- 单个导入任务的内存限制20GB timeout 7200 )高频小批量导入优化开启Group Commit功能将短时间内的多个小事务合并为一个大事务减少Edit Log写入次数和MemTable刷盘频率减轻Compaction压力特别适合日志、IoT等高频小数据量写入场景2.3 文件预处理从源头提升效率文件格式和大小对导入性能有显著影响预处理好文件能大幅提升导入效率。小文件合并避免导入大量小于100MB的小文件小文件会导致FE元数据膨胀和BE Compaction压力剧增文件格式优先使用Parquet或ORC列式存储格式比CSV格式导入速度快3-5倍且占用更少的存储空间压缩算法使用Snappy或LZ4压缩算法平衡压缩比和压缩/解压速度数据类型匹配确保导入文件的数据类型与表结构一致避免类型转换带来的性能开销三、集群配置优化释放硬件潜能合理的集群配置是Doris高性能运行的基础需根据硬件规格和业务负载调整FE和BE的配置参数。3.1 FE配置优化元数据与调度核心FE是Doris集群的大脑负责元数据管理、查询调度和导入协调其性能直接影响整个集群的稳定性和响应速度。JVM堆内存配置FE堆内存建议设置为16GB以上对于大规模集群10个BE建议设置为32GB-Xmx和-Xms设置为相同值避免JVM堆内存动态调整带来的GC停顿示例JAVA_OPTS-Xmx32g -Xms32g -XX:UseG1GC元数据管理优化# 元数据检查点间隔单位秒减少元数据恢复时间 metadata_checkpoint_threshold_sec3600 # 编辑日志滚动数量控制Edit Log文件大小 edit_log_roll_num50000 # 元数据备份数量 max_bdbje_txn_logs100并发控制优化# FE最大连接数 qe_max_connection4096 # 查询最大重试次数 max_query_retry_time3 # 导入任务最大并发数 max_running_txn_num_per_db1003.2 BE配置优化存储与计算引擎BE是Doris集群的存储和计算节点所有的数据导入和查询操作都在BE上执行BE配置对性能影响最大。存储优化# 存储页缓存大小建议设置为BE节点内存的40%-50% storage_page_cache_limit32G # 禁用存储页缓存会导致查询性能大幅下降生产环境切勿关闭 disable_storage_page_cachefalse # 每个存储目录的刷盘线程数 flush_thread_num_per_store4导入优化# 导入进程最大内存限制字节 load_process_max_memory_limit_bytes107374182400 # 100GB # 导入进程内存占BE总内存的最大比例 load_process_max_memory_limit_percent30 # 单个导入任务的默认内存限制 default_load_mem_limit2147483648 # 2GB压缩与IO优化# 默认压缩算法 compression_codecsnappy # 磁盘IO调度算法建议使用deadline或noop disk_io_schedulerdeadline # 最大并发IO请求数 max_disk_io_thread_num163.3 资源组管理负载隔离与优先级在多业务共享集群的场景下不同业务的查询负载可能会互相干扰导致核心业务性能下降。Doris 2.1版本引入了增强的Workload Group资源组功能支持CPU硬限制和内存限制实现严格的负载隔离。示例创建资源组并分配给用户-- 创建核心业务资源组CPU硬限制为60%内存限制为60% CREATE RESOURCE GROUP core_business_rg PROPERTIES ( cpu_hard_limit 60%, memory_limit 60%, query_timeout 300 ); -- 创建普通业务资源组CPU硬限制为30%内存限制为30% CREATE RESOURCE GROUP normal_business_rg PROPERTIES ( cpu_hard_limit 30%, memory_limit 30%, query_timeout 600 ); -- 将用户分配到对应的资源组 ALTER USER core_user% SET RESOURCE_GROUP core_business_rg; ALTER USER normal_user% SET RESOURCE_GROUP normal_business_rg;四、查询优化提升检索响应速度查询优化是提升用户体验的关键通过合理的SQL编写、物化视图和统计信息收集能显著降低查询延迟。4.1 SQL编写最佳实践**避免SELECT ***只查询需要的列减少数据扫描和内存占用强制分区裁剪WHERE条件中必须包含分区列避免全表扫描合理使用过滤条件将过滤条件尽量下推减少后续处理的数据量避免大表全量Join优先使用Broadcast Join小表广播到大表所在节点大表Join使用Shuffle Join避免在WHERE条件中对列进行函数操作会导致索引失效和分区裁剪失效反例与正例对比-- 反例对分区列使用函数导致分区裁剪失效 SELECT * FROM user_behavior WHERE DATE_FORMAT(dt, %Y-%m-%d) 2024-06-11; -- 正例直接使用分区列进行过滤 SELECT * FROM user_behavior WHERE dt 2024-06-11;4.2 物化视图预聚合用空间换时间物化视图是Doris的核心优化特性之一通过预计算常用的聚合结果将复杂查询转化为简单的物化视图扫描能提升查询性能数十倍甚至上百倍。示例创建用户行为统计物化视图CREATE MATERIALIZED VIEW mv_user_behavior_daily AS SELECT dt, user_id, COUNT(*) AS behavior_cnt, SUM(amount) AS total_amount FROM user_behavior GROUP BY dt, user_id;注意事项物化视图不是越多越好过多的物化视图会增加导入开销和存储成本只针对高频、高消耗的查询创建物化视图物化视图会自动与查询匹配无需修改原SQL语句4.3 统计信息收集优化器的眼睛Doris的查询优化器基于统计信息生成最优执行计划不准确或缺失的统计信息会导致优化器生成错误的执行计划严重影响查询性能。统计信息收集命令-- 同步收集表的所有列统计信息 ANALYZE TABLE user_behavior WITH SYNC MODE; -- 收集指定列的统计信息 ANALYZE TABLE user_behavior (user_id, item_id) WITH SYNC MODE; -- 查看统计信息 SHOW COLUMN STATS user_behavior;最佳实践导入大量数据后及时更新统计信息定期如每周全量收集一次统计信息对于数据分布变化大的表增加统计信息收集频率五、监控与诊断快速定位瓶颈建立完善的监控和诊断体系能及时发现性能问题并快速定位瓶颈是保障Doris集群稳定运行的关键。5.1 导入状态监控-- 查看所有导入任务 SHOW LOAD ORDER BY CreateTime DESC LIMIT 10; -- 查看指定Label的导入任务 SHOW LOAD WHERE LABEL user_behavior_label_20240611; -- 查看正在运行的导入任务 SHOW LOAD WHERE STATE LOADING ORDER BY CreateTime DESC; -- 查看BE端导入详情定位慢节点 SHOW LOAD TRACKING user_behavior_label_20240611;导入瓶颈排查步骤检查网络ping FE和BE节点查看网络延迟和丢包率检查磁盘IO使用iostat -x 1命令查看BE节点磁盘IO使用率检查内存使用free -h命令查看BE节点内存使用情况检查CPU使用top -H -p be_pid命令查看BE进程CPU使用率查看BE日志在be.INFO日志中搜索load job查看导入错误和耗时信息5.2 系统运行监控-- 查看BE节点状态 SHOW BACKENDS\G -- 查看FE节点状态 SHOW FRONTENDS\G -- 查看当前运行的查询 SHOW PROC /current_queries; -- 查看BE实例状态 SHOW PROC /current_backend_instances; -- 查看集群资源使用情况 SHOW PROC /cluster_health;5.3 性能分析工具EXPLAIN和PROFILE使用EXPLAIN sql查看查询执行计划检查分区裁剪、Join算法选择是否合理使用EXPLAIN ANALYZE sql执行查询并返回详细的执行计划和耗时信息开启Profile功能查看每个节点的详细耗时和资源消耗Perf工具用于分析BE进程的CPU热点定位性能瓶颈示例perf record -p be_pid -g -- sleep 30然后使用perf report查看分析结果导入Profile开启导入Profile功能查看导入各阶段的耗时信息示例SET is_report_success true; -- 执行导入语句 LOAD LABEL ...; -- 然后在FE日志中查看导入Profile信息六、高级优化与常见问题6.1 Compaction调优解决小文件问题Doris基于LSM树存储结构每次导入都会生成新的数据文件。后台的Compaction进程会定期合并小文件为大文件以提升查询性能。不合理的Compaction策略会导致版本堆积、查询性能下降甚至导入失败。Compaction参数调优# 每个磁盘的累积Compaction线程数 cumulative_compaction_num_threads_per_disk4 # 每个磁盘的基础Compaction线程数 base_compaction_num_threads_per_disk2 # Compaction检查间隔单位秒 cumulative_compaction_check_interval_seconds2 # 单个Compaction任务的最大内存限制 compaction_max_memory_limit_bytes21474836480 # 20GB2.1版本Compaction优化Segment Compaction在导入过程中合并同一批次内的多个Segment减少小文件数量默认开启Vertical Compaction按列组进行合并大幅减少宽表Compaction的内存占用内存使用仅为原有算法的1/106.2 内存管理避免OOM内存不足是Doris集群最常见的问题之一会导致查询失败、BE进程OOM退出等严重问题。内存优化措施调整会话级内存限制SET exec_mem_limit 8589934592;8GB开启Spill to disk功能SET spill_mode auto;当内存不足时自动将数据写入磁盘优化SQL语句减少大查询的内存消耗合理设置BE的导入和Compaction内存限制6.3 冷热数据分离成本与性能平衡对于时间跨度大的业务数据通常最近的数据查询频率高热数据而历史数据查询频率低冷数据。通过冷热数据分离将热数据存储在SSD上保证性能冷数据存储在HDD上降低成本能在保证性能的同时大幅降低存储成本。示例设置冷热数据分离策略ALTER TABLE user_behavior SET ( storage_policy hot_cold, storage_cooldown_time 30d -- 数据写入30天后自动迁移到冷存储 );6.4 快速优化检查清单在遇到性能问题时可以按照以下清单进行快速排查分区字段是否在WHERE条件中分区裁剪是否生效分桶数是否合适单Tablet大小是否在1-10GB之间是否存在数据倾斜分桶列选择是否合理是否使用了Parquet/ORC文件格式是否存在大量小文件导入并发是否达到瓶颈是否开启了Group Commit统计信息是否最新查询执行计划是否合理BE节点的CPU、内存、磁盘IO是否存在瓶颈Compaction是否正常运行是否存在版本堆积