Doris 介绍
Apache Doris 是一个基于 MPP 架构的高性能、实时的分析型数据库,以极速易用的特点被人们所熟知,仅需亚秒级响应时间即可返回海量数据下的查询结果,不仅可以支持高并发的点查询场景,也能支持高吞吐的复杂分析场景。基于此,Apache Doris 能够较好的满足报表分析、即席查询、统一数仓构建、数据湖联邦查询加速等使用场景,用户可以在此之上构建用户行为分析、AB 实验平台、日志检索分析、用户画像分析、订单分析等应用。
Doris整体架构如下图所示,Doris 架构非常简单,只有两类进程
-
Frontend(FE),主要负责用户请求的接入、查询解析规划、元数据的管理、节点管理相关工作。
-
Backend(BE),主要负责数据存储、查询计划的执行。
在使用接口方面,Doris 采用 MySQL 协议,高度兼容 MySQL 语法,支持标准 SQL,用户可以通过各类客户端工具来访问 Doris,并支持与 BI 工具的无缝对接。
在存储引擎方面,Doris 采用列式存储,按列进行数据的编码压缩和读取,能够实现极高的压缩比,同时减少大量非相关数据的扫描,从而更加有效利用 IO 和 CPU 资源。
(以上内容来自于Doris官方网:https://doris.apache.org/)
也就是说,Doirs可以直接通过mysql的驱动简单的实现远程连接,mysql的兼容是由FE去实现,doris自身维护了一套sql语句的解析,与mysql语法很类似,但是有很多细节会有出入,这也是使用者需要去仔细学习的地方。
数据模型
Doris的列可以分为两大类:Key列 和 Value列。从业务角度看,Key 和 Value 可以分别对应维度列和指标列。Doris的key列是建表语句中指定的列,建表语句中的关键字'unique key'或'aggregate key'或'duplicate key'后面的列就是 Key 列,除了 Key 列剩下的就是 Value 列。Unique key 和aggregate key类似于关系型数据库中的主键或者联合主键。
根据不同的Key类型Doris 的数据模型可以分为3类:
- Aggregate
- Unique
- Duplicate
Aggregate 模型
该模型下,在数据导入时,当Key列相同时,Value列会根据建表时设置的AggregateType去做一个聚合处理,其中AggregateType有4中:
- SUM:求和,多行的 Value 进行累加。
- REPLACE:替代,下一批数据中的 Value 会替换之前导入过的行中的 Value。
- MAX:保留最大值。
- MIN:保留最小值。
官方文档建表sql样例:
CREATE TABLE IF NOT EXISTS example_db.example_tbl
(
`user_id` LARGEINT NOT NULL COMMENT "用户id",
`date` DATE NOT NULL COMMENT "数据灌入日期时间",
`city` VARCHAR(20) COMMENT "用户所在城市",
`age` SMALLINT COMMENT "用户年龄",
`sex` TINYINT COMMENT "用户性别",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "用户最后一次访问时间",
`cost` BIGINT SUM DEFAULT "0" COMMENT "用户总消费",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "用户最大停留时间",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用户最小停留时间"
)
AGGREGATE KEY(`user_id`, `date`, `city`, `age`, `sex`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
Unique 模型
unique模式其实就是特殊的aggregate模型,甚至在doris的1.2.0版本之前,unique的实现就是aggregate模型,value列的aggregateType都设置为REPLACE。但是由于aggregate模型是使用读时合并(merge on read)的方式实现的,所以性能上有瓶颈。在1.2.0之后,Doris引入了Unique模型新的实现方式,写时合并(merge on write),通过在写入时做一些额外的工作,实现了最优的查询性能。
写时合并通过设置PROPERTIES开启:"enable_unique_key_merge_on_write" = "true"
官方文档建表sql样例:
CREATE TABLE IF NOT EXISTS example_db.example_tbl
(
`user_id` LARGEINT NOT NULL COMMENT "用户id",
`username` VARCHAR(50) NOT NULL COMMENT "用户昵称",
`city` VARCHAR(20) COMMENT "用户所在城市",
`age` SMALLINT COMMENT "用户年龄",
`sex` TINYINT COMMENT "用户性别",
`phone` LARGEINT COMMENT "用户电话",
`address` VARCHAR(500) COMMENT "用户地址",
`register_time` DATETIME COMMENT "用户注册时间"
)
UNIQUE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1",
"enable_unique_key_merge_on_write" = "true"
);
Duplicate 模型
在某些多维分析场景下,数据既没有主键,也没有聚合需求。因此,我们引入 Duplicate 数据模型来满足这类需求。Duplicate模型没有聚合要求,所以它的查询速度最快。duplicate模型的sql语句中可以不设置key列,doris的fe会默认把前两列设置为key列。duplicate key用于数据存储时的排序。
官方文档建表sql样例:
CREATE TABLE IF NOT EXISTS example_db.example_tbl
(
`timestamp` DATETIME NOT NULL COMMENT "日志时间",
`type` INT NOT NULL COMMENT "日志类型",
`error_code` INT COMMENT "错误码",
`error_msg` VARCHAR(1024) COMMENT "错误详细信息",
`op_id` BIGINT COMMENT "负责人id",
`op_time` DATETIME COMMENT "处理时间"
)
DUPLICATE KEY(`timestamp`, `type`, `error_code`)
DISTRIBUTED BY HASH(`type`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
建表SQL
doris的建表sql有一些必填和规则:
- DISTRIBUTED BY HASH(`column1`) BUCKETS num,doris表的分桶设置,必填
- DUPLICATE/AGGREGATE/UNIQUE KEY(`column1`, `column2`) key类型设置,决定数据模型,非必填,不填时默认使用DUPLICATE KEY,并且前两列为Key列;
- PROPERTIES:Doris表其他属性,非必填,不填时会使用doris默认的值比如副本数设置"replication_allocation" = "tag.location.default: 1",默认值为3;
- PARTITION BY RANGE/HASH (`column1`, ...):设置分区,非必填,但是doris表是必须有存储分区,不填时是默认使用一个大分区去存储数据。