Apache Doris 学习文档(面向开发人员)

一、Doris 是什么?为什么你需要它?

数据库类型典型代表特点适用场景
OLTP(事务型)MySQL, PostgreSQL强一致性、高并发写、行存订单、用户信息等业务系统
OLAP(分析型)Apache Doris, ClickHouse, StarRocks高吞吐查询、列存、MPP 架构报表、BI、日志分析、用户行为分析

Apache Doris 是一个开源的、高性能、实时的 MPP 分析型数据库,采用列式存储,兼容 MySQL 协议,专为 OLAP(在线分析处理) 场景设计。

1、为什么你需要它?

 快:TB 级数据秒级查询(聚合、多维分析)
 实时:支持 Kafka/HTTP 秒级写入,数据即时可见
 简单:无 Hadoop 依赖,部署运维轻量
 易用:标准 SQL + BI 工具直连(如 Tableau、Superset)
 省成本:开源免费,高压缩比降低存储开销

 适用场景:实时数仓、日志分析、BI 报表、用户行为分析。
 不适用:高频点查、强事务、全文检索(这类需求选 MySQL 或 Elasticsearch)。


2、Apache Doris 整体架构图

graph TD
    subgraph "客户端层"
        A[MySQL Client] -->|SQL| B(FE)
        C[JDBC/MyBatis] -->|SQL| B
        D[Stream Load] -->|HTTP| B
        E[Routine Load] -->|Kafka| B
    end

    subgraph "计算与协调层 (FE - Frontend)"
        B --> B1[SQL Parser]
        B --> B2[Planner]
        B --> B3[Scheduler]
        B --> B4[Metadata Manager]
        B4 -->|持久化| B5[(BDBJE<br/>doris-meta/)]
    end

    subgraph "存储与执行层 (BE - Backend)"
        B --> F[BE Node 1]
        B --> G[BE Node 2]
        B --> H[BE Node N]

        F --> F1[Tablet 1]
        F --> F2[Tablet 2]
        F --> F3[Storage Engine]
        F3 --> F4[(Data Files<br/>storage_root_path/)]

        G --> G1[Tablet 3]
        G --> G2[Tablet 4]
        G --> G3[Storage Engine]
        G3 --> G4[(Data Files)]

        H --> H1[...]
        H --> H2[Storage Engine]
        H2 --> H3[(Data Files)]
    end

    subgraph "数据源"
        I[Kafka] -->|Routine Load| B
        J[Local File] -->|Stream Load| B
        K[HDFS/S3] -->|Broker Load| B
    end

    classDef fe fill:#4CAF50,stroke:#388E3C,color:white;
    classDef be fill:#2196F3,stroke:#0D47A1,color:white;
    classDef storage fill:#FFC107,stroke:#FF8F00;
    classDef client fill:#9E9E9E,stroke:#616161,color:white;

    class B,B1,B2,B3,B4,B5 fe;
    class F,G,H,F3,G3,H2 be;
    class F4,G4,H3 storage;
    class A,C,D,E,I,J,K client;

只需记住两个角色:
组件作用类比理解是否需要你关心?
FE (Frontend)接收 SQL、管理元数据、调度查询≈ MySQL Server 层(部署好就不用管)
BE (Backend)真正存数据 + 执行计算≈ InnoDB + 分布式计算引擎(扩容加 BE 节点即可)

 关键特点:

  • FE 无状态:可多节点部署,自动选主

  • BE 自动均衡:加机器后数据自动分片

  • 你只用连 FE:像连 MySQL 一样简单


二、Doris 核心能力(开发者最关心的)

1、常用写入方式

1)Broker Load(推荐用于大文件批量导入)
  • 原理:通过 Doris 内置的 Broker 进程(如 HDFS、S3、OSS、BOS 等)从外部存储系统并行拉取数据。

  • 支持格式:CSV、Parquet、ORC

  • 特点:

    • 异步导入,适合 GB~TB 级大文件

    • 自动分片、并行处理

    • 支持断点续传(部分失败可重试)

  • 适用场景:

    • 从 HDFS/S3 导入历史数据

    • 每天一次的 T+1 批量同步

  • 示例:

LOAD LABEL broker_load_2022_04_01
(
    DATA INFILE("s3://your_bucket_name/brokerload_example.csv")
    INTO TABLE test_brokerload
    COLUMNS TERMINATED BY ","
    FORMAT AS "CSV"
    (user_id, name, age)
)
WITH S3
(
    "provider" = "S3",
    "AWS_ENDPOINT" = "s3.us-west-2.amazonaws.com",
    "AWS_ACCESS_KEY" = "<your-ak>",
    "AWS_SECRET_KEY"="<your-sk>",
    "AWS_REGION" = "us-west-2",
    "compress_type" = "PLAIN"
)
PROPERTIES
(
    "timeout" = "3600"
);


2)Stream Load(推荐用于实时/小批量 HTTP 推送)
  • 原理:通过 HTTP 协议将本地文件或内存数据直接推送到 Doris。

  • 支持格式:CSV、JSON(支持多行 JSON)

  • 特点:

    • 同步返回结果(成功/失败)

    • 低延迟(秒级可见)

    • 支持 实时流式写入

    • 可通过 Nginx 负载均衡到多个 BE 节点

  • 适用场景:

    • 日志采集(Filebeat → Stream Load)

    • Flink/Spark 实时写入

    • 应用程序直接推送数据

  • 示例(curl):

curl --location-trusted -u <doris_user>:<doris_password> 
    -H "label:124" 
    -H "Expect:100-continue" 
    -H "format:json" -H "strip_outer_array:true" 
    -H "jsonpaths:["$.userid", "$.username", "$.userage"]" 
    -H "columns:user_id,name,age" 
    -T streamload_example.json 
    -XPUT >:<fe_http_port>/api/testdb/test_streamload/_stream_load

3)Routine Load(推荐用于 Kafka 实时持续消费)
  • 原理:Doris 自动创建后台任务,持续从 Kafka 消费数据并导入。

  • 支持格式:CSV、JSON

  • 特点:

    • 自动容错:Kafka offset 自动管理,失败自动重试

    • Exactly-Once 语义(通过 label 去重)

    • 支持 Kafka 多分区并行消费

  • 适用场景:

    • 实时数仓(Kafka → Doris)

    • 用户行为日志、交易流水实时入库

  • 示例:

SHOW ROUTINE LOAD FOR tbl_name;

CREATE ROUTINE LOAD example_db.kafka_load ON tbl1
PROPERTIES(
    "desired_concurrent_number"="3",
    "max_batch_interval" = "20",
    "max_batch_rows" = "200000"
)
FROM KAFKA(
    "kafka_broker_list" = "host:9092",
    "kafka_topic" = "topic1",
    "property.kafka_default_offsets" = "OFFSET_BEGINNING"
);


4)Insert Into(适合小量数据或 ETL 中转)
  • 原理:类似 MySQL 的 INSERT INTO ... SELECT ...

  • 特点:

    • 同步执行,适合 < 100 万行 的小数据量

    • 可用于 Doris 内部表间数据转换(如 DWD → DWS)

  • 限制:

    • 不适合高频写入(会触发小文件问题)

    • 性能远低于 Stream/Broker Load

  • 示例:

INSERT INTO tbl_agg
SELECT user_id, sum(pv) FROM tbl_detail GROUP BY user_id;
5)各导入方式对比总结
导入方式实时性吞吐量数据源适用场景
Stream Load秒级HTTP(本地/程序)实时日志、Flink 写入
Routine Load秒级Kafka持续实时消费
Broker Load分钟级极高HDFS/S3/OSS 等T+1 批量导入、大文件
Insert Into秒级Doris 内部表小量数据、ETL 中转
6)最佳实践建议
  1. 实时场景 → 优先选 Routine Load(Kafka) 或 Stream Load(Flink/日志)

  2. 批量离线导入 → 用 Broker Load(HDFS/S3)

  3. 避免高频 Insert Into → 会导致小文件过多,影响查询性能

  4. 开启 Routine Load 监控 → 通过 SHOW ROUTINE LOAD 查看消费状态

  5. 合理设置 Label → 避免重复导入(Doris 通过 label 保证幂等)

方式适用场景吞吐延迟是否推荐生产
JDBC INSERT小量测试、调试低(几千/秒)(会出多版本问题!)
Stream Load (HTTP)Kafka 消费、日志导入高(10w+/秒)秒级 强烈推荐
Routine Load自动消费 Kafka秒级(适合简单场景)

 血泪教训:
生产环境禁止直接用 JDBC INSERT 写 Doris!
原因:每次 INSERT 生成新版本 → 多版本堆积 → 查询结果混乱


2、表模型:选对模型,性能翻倍

模型适用场景特点示例
Duplicate Key日志、事件流保留所有明细,不聚合用户点击日志
Unique Key需要更新的明细表主键去重,最新覆盖用户画像表
Aggregate Key预聚合指标自动 SUM/COUNT/MAXPV/UV 汇总表

 推荐:

  • 日志分析 → Duplicate Key

  • 用户行为宽表 → Unique Key

  • 报表指标 → Aggregate Key


3、兼容性:零学习成本

  • 协议兼容:直接用 mysql-connector-java

  • SQL 兼容:支持 JOIN、子查询、窗口函数

  • 工具兼容:Navicat、DBeaver、DataGrip 直接连

 你不需要学新语法,就像操作 MySQL 一样!


三、Spring Boot 整合实战(避坑版)

1、依赖配置

xml<!-- 核心:用 MySQL 驱动连 Doris -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>

<!-- 连接池(推荐 Druid) -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.16</version>
</dependency>

<!-- MyBatis -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

<!-- Stream Load 需要 HTTP 客户端 -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

2、多数据源配置(主库 + Doris)

spring:
  datasource:
    # 主业务库(MySQL)
    primary:
      url: jdbc:mysql://mysql:3306/order_db
      username: root
      password: xxx
    
    # Doris 分析库
    doris:
      url: jdbc:mysql://doris-fe:9030/analysis_db  # 注意:端口是 9030!
      username: root
      password: ""  # 默认无密码

3、Java 配置(手动控制,避免自动配置冲突)

// 主启动类:排除 MyBatis 自动配置
@SpringBootApplication(exclude = MybatisAutoConfiguration.class)
public class Application { /* ... */ }
主数据源(MySQL)
@Configuration
@MapperScan(basePackages = "com.example.mapper.mysql", 
           sqlSessionTemplateRef = "mysqlSqlSessionTemplate")
public class PrimaryDataSourceConfig {

    @Bean 
    @Primary
    @ConfigurationProperties("spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean 
    @Primary
    public SqlSessionFactory mysqlSqlSessionFactory(DataSource ds) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(ds);
        return bean.getObject();
    }

    @Bean 
    @Primary
    public SqlSessionTemplate mysqlSqlSessionTemplate(SqlSessionFactory sf) {
        return new SqlSessionTemplate(sf);
    }
}
Doris 数据源
@Configuration
@MapperScan(basePackages = "com.example.mapper.doris",
           sqlSessionTemplateRef = "dorisSqlSessionTemplate")
public class DorisDataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.doris")
    public DataSource dorisDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    public SqlSessionFactory dorisSqlSessionFactory(DataSource ds) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(ds);
        return bean.getObject();
    }

    @Bean
    public SqlSessionTemplate dorisSqlSessionTemplate(SqlSessionFactory sf) {
        return new SqlSessionTemplate(sf);
    }
}

 关键规则:

  1. 两个 @MapperScan 包路径必须不同

  2. 只有主数据源加 @Primary

  3. 方法名与 @Qualifier 保持一致

四、最佳实践清单(直接抄作业)

1、表设计

  • 分区:按天/月分区(PARTITION BY RANGE(event_date)

  • 分桶:按高基数列(如 user_id)分桶,桶数 = BE 节点数 × 10

  • 模型选择:

    • 日志 → Duplicate Key

    • 宽表 → Unique Key

    • 指标 → Aggregate Key

2、写入规范

场景推荐方式
Kafka 消费Stream Load(批量)
文件导入Broker Load
调试/小量JDBC(仅限测试环境)

3、查询优化

  • 避免 SELECT * → 只查需要的列

  • 大表 JOIN 小表 → 小表用 BROADCAST Hint

  • 时间范围必加 → 利用分区裁剪

4、 监控告警

  • 关键指标:

    • Tablet Version Count > 100 → 告警

    • Stream Load 失败率 > 1% → 告警

    • 查询 P99 > 5s → 优化

五、总结:Doris 使用口诀

“一兼容、二模型、三写入、四分片”

步骤要点
一兼容用 MySQL 驱动直连,SQL 零学习成本
二模型Duplicate(日志)、Unique(宽表)、Aggregate(指标)
三写入生产只用 Stream Load,禁用 JDBC INSERT
四分片按时间分区 + 按用户分桶,性能翻倍

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com