本文详细介绍Apache Doris(原Palo)实时分析数据库与Hadoop生态的集成实战,包括Doris概述、架构原理、集群部署、数据导入、SQL查询、性能优化等内容,风哥教程参考Doris官方文档Getting Started、Deployment、SQL Reference等内容,适合大数据工程师使用。学习交流加群风哥微信: itpux-com
Part01-基础概念与理论知识
1.1 Doris概述与核心特性
Apache Doris是一个基于MPP架构的高性能实时分析数据库,支持海量数据的实时分析查询。更多视频教程www.fgedu.net.cn
- MPP架构:分布式并行计算
- 实时导入:支持秒级数据延迟
- 高性能查询:亚秒级响应
- 多种数据模型:Duplicate、Aggregate、Unique
- Rollup物化视图:预聚合加速查询
- Schema Change:在线变更表结构
1.2 Doris架构与数据模型
Doris采用FE+BE架构:
FE(Frontend):
– 元数据管理
– 查询解析和优化
– 客户端接入
– 可以配置多个FE(Master+Follower)
BE(Backend):
– 数据存储
– 查询执行
– 数据导入
– 可以配置多个BE
# 数据模型
Duplicate Key:
– 保留原始数据
– 适合日志分析
– 允许重复数据
Aggregate Key:
– 自动聚合
– 适合报表统计
– 按维度聚合指标
Unique Key:
– 保证主键唯一
– 适合数据更新
– 自动去重
1.3 Doris表类型介绍
Doris表类型:
- Duplicate表:重复表,保留所有数据
- Aggregate表:聚合表,自动聚合数据
- Unique表:唯一表,保证主键唯一
- Rollup:物化视图,预聚合数据
Part02-生产环境规划与建议
2.1 Doris集群规划
Doris集群规划要点:
FE节点:
– 数量:3个(1Master+2Follower)
– 配置:16核32GB
– 磁盘:SSD 500GB
BE节点:
– 数量:3-100个
– 配置:16核64GB-32核128GB
– 磁盘:SSD 2TB-4TB
# 目录规划
安装目录:/bigdata/app/doris
数据目录:/bigdata/fgdata/doris
日志目录:/bigdata/fgdata/logs/doris
2.2 Doris核心配置
Doris核心配置建议:
meta_dir=/bigdata/fgdata/doris/meta
http_port=8030
rpc_port=9020
query_port=9030
edit_log_port=9010
# BE配置
storage_root_path=/bigdata/fgdata/doris/storage
be_port=9060
webserver_port=8040
heartbeat_service_port=9050
brpc_port=8060
# JVM配置
JAVA_OPTS=”-Xmx8192m -XX:+UseG1GC”
2.3 资源配置建议
资源配置建议:
- 小型集群:3个BE,每台16核64GB
- 中型集群:10个BE,每台32核128GB
- 大型集群:30个BE,每台32核256GB
更多学习教程公众号风哥教程itpux_com
Part03-生产环境项目实施方案
3.1 Doris集群安装部署
3.1.1 下载安装Doris
cd /bigdata/app
wget https://apache-doris-releases.oss-accelerate.aliyuncs.com/apache-doris-2.0.3-bin-x64.tar.xz
tar -xvf apache-doris-2.0.3-bin-x64.tar.xz
ln -s apache-doris-2.0.3-bin-x64 doris
# 2. 创建目录
mkdir -p /bigdata/fgdata/doris/meta
mkdir -p /bigdata/fgdata/doris/storage
mkdir -p /bigdata/fgdata/logs/doris
# 3. 配置FE
cat > /bigdata/app/doris/fe/conf/fe.conf << ‘EOF’
meta_dir = /bigdata/fgdata/doris/meta
http_port = 8030
rpc_port = 9020
query_port = 9030
edit_log_port = 9010
EOF
# 4. 启动FE
/bigdata/app/doris/fe/bin/start_fe.sh –daemon
# 5. 验证FE
jps | grep PaloFe
curl http://localhost:8030
# 6. 配置BE
cat > /bigdata/app/doris/be/conf/be.conf << ‘EOF’
storage_root_path = /bigdata/fgdata/doris/storage
be_port = 9060
webserver_port = 8040
heartbeat_service_port = 9050
brpc_port = 8060
EOF
# 7. 添加BE到FE
mysql -h 127.0.0.1 -P 9030 -uroot
mysql> ALTER SYSTEM ADD BACKEND “fgedu-be01:9050”;
mysql> ALTER SYSTEM ADD BACKEND “fgedu-be02:9050”;
mysql> ALTER SYSTEM ADD BACKEND “fgedu-be03:9050”;
# 8. 启动BE
/bigdata/app/doris/be/bin/start_be.sh –daemon
# 9. 验证集群
mysql -h 127.0.0.1 -P 9030 -uroot
mysql> SHOW PROC ‘/backends’;
3.2 Doris表创建与数据导入
3.2.1 创建表并导入数据
mysql -h fgedu-fe -P 9030 -uroot
# 创建数据库
mysql> CREATE DATABASE IF NOT EXISTS fgedu_db;
mysql> USE fgedu_db;
# 创建Duplicate表(用户行为日志)
mysql> CREATE TABLE IF NOT EXISTS fgedu_user_log (
dt DATE,
ts DATETIME,
user_id BIGINT,
event_type STRING,
page STRING,
duration INT
)
DUPLICATE KEY(dt, ts, user_id)
PARTITION BY RANGE(dt) (
PARTITION p202404 VALUES LESS THAN (‘2024-05-01’)
)
DISTRIBUTED BY HASH(user_id) BUCKETS 32
PROPERTIES (
“replication_num” = “3”
);
# 创建Aggregate表(销售报表)
mysql> CREATE TABLE IF NOT EXISTS fgedu_sales_agg (
dt DATE,
city STRING,
category STRING,
sales_cnt BIGINT SUM,
sales_amt DECIMAL(18,2) SUM
)
AGGREGATE KEY(dt, city, category)
PARTITION BY RANGE(dt) (
PARTITION p202404 VALUES LESS THAN (‘2024-05-01’)
)
DISTRIBUTED BY HASH(city) BUCKETS 16
PROPERTIES (
“replication_num” = “3”
);
# Stream Load导入数据
curl –location-trusted -u root: \
-H “label:fgedu_label_$(date +%Y%m%d_%H%M%S)” \
-H “column_separator:,” \
-T /bigdata/fgdata/user_log.csv \
http://fgedu-fe:8030/api/fgedu_db/fgedu_user_log/_stream_load
# Broker Load从HDFS导入
mysql> LOAD LABEL fgedu_db.label_001 (
DATA INFILE(‘hdfs://fgedu-nn:8020/bigdata/fgdata/hive/warehouse/fgedu_user/*’)
INTO TABLE fgedu_user_log
COLUMNS TERMINATED BY ‘,’
)
WITH BROKER hdfs_broker (
‘username’=’hdfs’,
‘password’=”
)
PROPERTIES (
‘timeout’=’3600’
);
3.3 HDFS数据同步到Doris
3.3.1 使用Spark同步数据
<dependency>
<groupId>org.apache.doris</groupId>
<artifactId>doris-spark-connector_2.12</artifactId>
<version>1.2.0</version>
</dependency>
# Spark写入Doris
import org.apache.spark.sql.SparkSession
object FgeduSpark2Doris {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder()
.appName(“FgeduSpark2Doris”)
.enableHiveSupport()
.getOrCreate()
val df = spark.read.table(“hive_db.fgedu_user_table”)
df.write
.format(“doris”)
.option(“doris.fenodes”, “fgedu-fe:8030”)
.option(“doris.table.identifier”, “fgedu_db.fgedu_user_table”)
.option(“user”, “root”)
.option(“password”, “”)
.option(“sink.batch.size”, “100000”)
.option(“sink.max-retries”, “3”)
.mode(“append”)
.save()
spark.stop()
}
}
# 提交Spark任务
spark-submit –class FgeduSpark2Doris \
–master yarn \
–deploy-mode cluster \
–jars doris-spark-connector_2.12-1.2.0.jar \
fgedu-spark-doris.jar
Part04-生产案例与实战讲解
4.1 Doris SQL查询实战
4.1.1 基础SQL查询
mysql -h fgedu-fe -P 9030 -uroot -Dfgedu_db
# 基础查询
mysql> SELECT COUNT(*) FROM fgedu_user_log WHERE dt = ‘2024-04-08’;
+———-+
| count(*) |
+———-+
| 5000000 |
+———-+
# 聚合查询
mysql> SELECT
dt,
event_type,
COUNT(*) AS pv,
COUNT(DISTINCT user_id) AS uv
FROM fgedu_user_log
WHERE dt BETWEEN ‘2024-04-01’ AND ‘2024-04-07’
GROUP BY dt, event_type
ORDER BY dt, pv DESC;
# Join查询
mysql> SELECT
u.user_id,
u.name,
l.event_type,
COUNT(*) AS event_cnt
FROM fgedu_user u
JOIN fgedu_user_log l ON u.user_id = l.user_id
WHERE l.dt = ‘2024-04-08’
GROUP BY u.user_id, u.name, l.event_type
ORDER BY event_cnt DESC
LIMIT 100;
# 窗口函数
mysql> SELECT
dt,
city,
category,
sales_amt,
RANK() OVER (PARTITION BY dt ORDER BY sales_amt DESC) AS city_rank
FROM fgedu_sales_agg
WHERE dt = ‘2024-04-08’
QUALIFY RANK() OVER (PARTITION BY dt ORDER BY sales_amt DESC) <= 10;
# 查看执行计划
mysql> EXPLAIN SELECT * FROM fgedu_user_log WHERE dt = ‘2024-04-08’;
4.2 Doris性能优化实战
4.2.1 查询优化技巧
# 不推荐
SELECT * FROM fgedu_user_log WHERE DATE_FORMAT(dt, ‘%Y-%m’) = ‘2024-04’;
# 推荐
SELECT * FROM fgedu_user_log WHERE dt BETWEEN ‘2024-04-01’ AND ‘2024-04-30’;
# 优化2:创建Rollup物化视图
mysql> ALTER TABLE fgedu_user_log ADD ROLLUP rollup_dt_event (dt, event_type, user_id);
# 优化3:使用内存表
mysql> CREATE TABLE fgedu_dim_city (
city_id INT,
city_name STRING,
province STRING
)
UNIQUE KEY(city_id)
DISTRIBUTED BY HASH(city_id) BUCKETS 1
PROPERTIES (
“replication_num” = “3”,
“in_memory” = “true”
);
# 优化4:调整并行度
mysql> SET parallel_fragment_exec_instance_num = 8;
# 优化5:调整批次大小
mysql> SET batch_size = 4096;
# 优化6:启用谓词下推
mysql> SET enable_pushdown_predicate = true;
# 优化7:数据压缩
PROPERTIES (
“compression” = “LZ4”
)
4.3 Doris监控与运维
4.3.1 Web UI监控
FE: http://fgedu-fe:8030
BE: http://fgedu-be:8040
# 主要监控页面
– 首页:集群概览
– Query:查询分析
– Backends:BE节点状态
– Logs:日志查看
# Prometheus监控
# FE配置
enable_metric_calculator = true
# Prometheus配置
scrape_configs:
– job_name: ‘doris_fe’
static_configs:
– targets: [‘fgedu-fe:8030’]
metrics_path: ‘/metrics’
– job_name: ‘doris_be’
static_configs:
– targets: [‘fgedu-be01:8040’, ‘fgedu-be02:8040’]
metrics_path: ‘/metrics’
# Grafana Dashboard
# 关键指标:
– 查询QPS
– 查询延迟(P50/P95/P99)
– BE节点状态
– 数据导入速率
– 存储空间使用
– CPU/内存使用
Part05-风哥经验总结与分享
5.1 Doris生产最佳实践
Doris生产最佳实践:
- 数据模型:根据场景选择合适的数据模型
- Rollup:合理创建Rollup加速查询
- 分区设计:按时间分区,定期管理分区
- 分桶设计:合理设置分桶数量
- 数据导入:选择合适的导入方式
- 监控告警:实时监控集群状态
5.2 常见问题处理
– 检查BE日志
– 检查网络连接
– 检查磁盘空间
– 重启BE节点
# 常见问题2:查询慢
– 检查是否使用分区裁剪
– 创建Rollup物化视图
– 查看执行计划
– 增加BE节点
# 常见问题3:导入失败
– 检查数据源格式
– 检查权限配置
– 查看Load日志
– 调整导入参数
# 常见问题4:数据不一致
– 检查Duplicate Key设计
– 使用Unique模型
– 检查导入任务状态
– 重新导入数据
# 常见问题5:OOM问题
– 调整JVM内存
– 减少查询并发
– 优化SQL查询
– 增加BE节点
5.3 运维检查清单
– [ ] FE节点状态
– [ ] BE节点状态
– [ ] 查询状态
– [ ] 导入任务状态
– [ ] 查询延迟
– [ ] 存储空间使用
– [ ] 内存使用
– [ ] CPU使用
– [ ] 副本状态
– [ ] 分区状态
– [ ] 告警规则检查
– [ ] 日志检查
# 日常巡检内容
1. 检查Web UI集群状态
2. 查看失败查询
3. 检查导入任务
4. 检查节点状态
5. 检查资源使用
6. 查看错误日志
7. 检查磁盘空间
8. 管理分区
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
