地牢速攻无限金牙
31.22 MB · 2026-02-13
| 数据库类型 | 典型代表 | 特点 | 适用场景 |
|---|---|---|---|
| OLTP(事务型) | MySQL, PostgreSQL | 强一致性、高并发写、行存 | 订单、用户信息等业务系统 |
| OLAP(分析型) | Apache Doris, ClickHouse, StarRocks | 高吞吐查询、列存、MPP 架构 | 报表、BI、日志分析、用户行为分析 |
Apache Doris 是一个开源的、高性能、实时的 MPP 分析型数据库,采用列式存储,兼容 MySQL 协议,专为 OLAP(在线分析处理) 场景设计。
快:TB 级数据秒级查询(聚合、多维分析)
实时:支持 Kafka/HTTP 秒级写入,数据即时可见
简单:无 Hadoop 依赖,部署运维轻量
易用:标准 SQL + BI 工具直连(如 Tableau、Superset)
省成本:开源免费,高压缩比降低存储开销
适用场景:实时数仓、日志分析、BI 报表、用户行为分析。
不适用:高频点查、强事务、全文检索(这类需求选 MySQL 或 Elasticsearch)。
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 内置的 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"
);
原理:通过 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
原理: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"
);
原理:类似 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;
| 导入方式 | 实时性 | 吞吐量 | 数据源 | 适用场景 |
|---|---|---|---|---|
| Stream Load | 秒级 | 高 | HTTP(本地/程序) | 实时日志、Flink 写入 |
| Routine Load | 秒级 | 高 | Kafka | 持续实时消费 |
| Broker Load | 分钟级 | 极高 | HDFS/S3/OSS 等 | T+1 批量导入、大文件 |
| Insert Into | 秒级 | 低 | Doris 内部表 | 小量数据、ETL 中转 |
实时场景 → 优先选 Routine Load(Kafka) 或 Stream Load(Flink/日志)
批量离线导入 → 用 Broker Load(HDFS/S3)
避免高频 Insert Into → 会导致小文件过多,影响查询性能
开启 Routine Load 监控 → 通过 SHOW ROUTINE LOAD 查看消费状态
合理设置 Label → 避免重复导入(Doris 通过 label 保证幂等)
| 方式 | 适用场景 | 吞吐 | 延迟 | 是否推荐生产 |
|---|---|---|---|---|
| JDBC INSERT | 小量测试、调试 | 低(几千/秒) | 高 | (会出多版本问题!) |
| Stream Load (HTTP) | Kafka 消费、日志导入 | 高(10w+/秒) | 秒级 | 强烈推荐 |
| Routine Load | 自动消费 Kafka | 高 | 秒级 | (适合简单场景) |
血泪教训:
生产环境禁止直接用 JDBC INSERT 写 Doris!
原因:每次 INSERT 生成新版本 → 多版本堆积 → 查询结果混乱
| 模型 | 适用场景 | 特点 | 示例 |
|---|---|---|---|
| Duplicate Key | 日志、事件流 | 保留所有明细,不聚合 | 用户点击日志 |
| Unique Key | 需要更新的明细表 | 主键去重,最新覆盖 | 用户画像表 |
| Aggregate Key | 预聚合指标 | 自动 SUM/COUNT/MAX | PV/UV 汇总表 |
推荐:
日志分析 → Duplicate Key
用户行为宽表 → Unique Key
报表指标 → Aggregate Key
协议兼容:直接用 mysql-connector-java
SQL 兼容:支持 JOIN、子查询、窗口函数
工具兼容:Navicat、DBeaver、DataGrip 直接连
你不需要学新语法,就像操作 MySQL 一样!
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>
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: "" # 默认无密码
// 主启动类:排除 MyBatis 自动配置
@SpringBootApplication(exclude = MybatisAutoConfiguration.class)
public class Application { /* ... */ }
@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);
}
}
@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);
}
}
关键规则:
两个 @MapperScan 包路径必须不同
只有主数据源加 @Primary
方法名与 @Qualifier 保持一致
分区:按天/月分区(PARTITION BY RANGE(event_date))
分桶:按高基数列(如 user_id)分桶,桶数 = BE 节点数 × 10
模型选择:
日志 → Duplicate Key
宽表 → Unique Key
指标 → Aggregate Key
| 场景 | 推荐方式 |
|---|---|
| Kafka 消费 | Stream Load(批量) |
| 文件导入 | Broker Load |
| 调试/小量 | JDBC(仅限测试环境) |
避免 SELECT * → 只查需要的列
大表 JOIN 小表 → 小表用 BROADCAST Hint
时间范围必加 → 利用分区裁剪
关键指标:
Tablet Version Count > 100 → 告警
Stream Load 失败率 > 1% → 告警
查询 P99 > 5s → 优化
“一兼容、二模型、三写入、四分片”
| 步骤 | 要点 |
|---|---|
| 一兼容 | 用 MySQL 驱动直连,SQL 零学习成本 |
| 二模型 | Duplicate(日志)、Unique(宽表)、Aggregate(指标) |
| 三写入 | 生产只用 Stream Load,禁用 JDBC INSERT |
| 四分片 | 按时间分区 + 按用户分桶,性能翻倍 |
31.22 MB · 2026-02-13
36.6G · 2026-02-13
108.01M · 2026-02-13