Doris简介、部署、功能介绍以及架构设计
Apache Doris 是一个基于 MPP 架构的高性能、实时的分析型数据库,以极速易用的特点被人们所熟知,仅需亚秒级响应时间即可返回海量数据下的查询结果,不仅可以支持高并发的点查询场景,也能支持高吞吐的复杂分析场景。基于此,Apache Doris 能够较好的满足报表分析、即席查询、统一数仓构建、数据湖联邦查询加速等使用场景,用户可以在此之上构建用户行为分析、AB 实验平台、日志检索分析、用
Doris简介、部署、功能介绍以及架构设计
1. Doris简介
Doris 中文官方文档:https://doris.apache.org/zh-CN/docs/dev/summary/basic-summary
1.1 Doris概述
Apache Doris 是一个基于 MPP 架构的高性能、实时的分析型数据库,以极速易用的特点被人们所熟知,仅需亚秒级响应时间即可返回海量数据下的查询结果,不仅可以支持高并发的点查询场景,也能支持高吞吐的复杂分析场景。基于此,Apache Doris 能够较好的满足报表分析、即席查询、统一数仓构建、数据湖联邦查询加速等使用场景,用户可以在此之上构建用户行为分析、AB 实验平台、日志检索分析、用户画像分析、订单分析等应用
Apache Doris 最早是诞生于百度广告报表业务的 Palo 项目,2017 年正式对外开源,2018 年 7 月由百度捐赠给 Apache 基金会进行孵化,之后在 Apache 导师的指导下由孵化器项目管理委员会成员进行孵化和运营。目前 Apache Doris 社区已经聚集了来自不同行业数百家企业的 400 余位贡献者,并且每月活跃贡献者人数也超过 100 位。 2022 年 6 月,Apache Doris 成功从 Apache 孵化器毕业,正式成为 Apache 顶级项目(Top-Level Project,TLP)
Apache Doris 如今在中国乃至全球范围内都拥有着广泛的用户群体,截止目前, Apache Doris 已经在全球超过 2000 家企业的生产环境中得到应用,在中国市值或估值排行前 50 的互联网公司中,有超过 80% 长期使用 Apache Doris,包括百度、美团、小米、京东、字节跳动、腾讯、网易、快手、微博、贝壳等。同时在一些传统行业如金融、能源、制造、电信等领域也有着丰富的应用
1.2 Doris使用场景
Doris数据库是一个分布式列式存储和查询系统,主要用于实时分析和查询海量数据。它适用于以下场景:
- 实时分析:Doris数据库可以快速查询和分析海量数据,支持实时查询和聚合操作,可以帮助企业快速做出决策并调整业务策略。
- 大数据仓库:Doris数据库可以作为企业的数据仓库,存储大规模的数据,并提供高效的查询和分析能力,帮助企业更好地理解和利用数据。
- 日志存储和分析:Doris数据库可以快速存储和分析实时生成的日志数据,支持实时查询和聚合操作,帮助企业及时发现和解决问题。
- 金融数据分析:Doris数据库可以存储和分析金融相关的大规模数据,如证券交易数据、客户信息等,帮助金融机构更好地理解市场趋势、客户需求等信息。
总之,Doris数据库适用于需要处理海量数据、需要实时查询和分析数据的场景。
1.3 Doris架构
Doris整体架构如下图所示,Doris 架构非常简单,只有两类进程
-
Frontend(FE),主要负责用户请求的接入、查询解析规划、元数据的管理、节点管理相关工作,并将请求转发给对应的Backend进行处理。Frontend还负责了Doris集群的负载均衡和故障转移等功能
主要有三个角色:
(1)Leader 和Follower:主要是用来达到元数据的高可用,保证单节点宕机的情况下,元数据能够实时地在线恢复,而不影响整个服务。
(2)Observer:用来扩展查询节点,同时起到元数据备份的作用。如果在发现集群压力非常大的情况下,需要去扩展整个查询的能力,那么可以加 observer 的节点。observer 不参与任何的写入,只参与读取。
-
Backend(BE),主要负责数据存储、查询计划的执行
数据的可靠性由 BE 保证,BE 会对整个数据存储多副本或者是三副本。副本数可根据需求动态调整
Frontend(FE)和 Backend(BE)这两类进程都是可以横向扩展的,单集群可以支持到数百台机器,数十 PB 的存储容量。并且这两类进程通过一致性协议来保证服务的高可用和数据的高可靠。这种高度集成的架构设计极大的降低了一款分布式系统的运维成本
除了
- MySQL Client
Doris借助MySQL协议,用户使用任意MySQL的ODBC/JDBC以及MySQL的客户端,都可以直接访问Doris
- broker
Broker 是 Doris 集群中一种可选进程,主要用于支持 Doris 读写远端存储上的文件和目录,如 HDFS、BOS 和 AFS 等
2. Doris安装和部署
2.1 Doris安装环境要求
2.1.1 Linux 操作系统版本需求
Linux 系统 | 版本 |
---|---|
CentOS | 7.1 及以上 |
2.1.2 软件需求
软件 | 版本 |
---|---|
Java | 1.8 及以上 |
GCC | 4.8.2 及以上 |
2.1.3 Linux文件系统
ext4和xfs文件系统均支持
2.1.4 机器配置( 生产环境 )
模块 | CPU | 内存 | 磁盘 | 网络 | 实例数量(最低要求) |
---|---|---|---|---|---|
Frontend | 16核+ | 64GB+ | SSD 或 RAID 卡,100GB+ * | 万兆网卡 | 1-3 * |
Backend | 16核+ | 64GB+ | SSD 或 SATA,100G+ * | 万兆网卡 | 3 * |
如只是部署调试,熟悉了解或是简单测试环境,配置可以低
2.1.5 端口预留
实例名称 | 端口名称 | 默认端口 | 通讯方向 | 说明 |
---|---|---|---|---|
BE | be_prot | 9060 | FE–>BE | BE上thrift server的端口用于接收来自FE 的请求 |
BE | webserver_port | 8040 | BE<–>FE | BE上的http server端口 |
BE | heartbeat_service_port | 9050 | FE–>BE | BE上心跳服务端口用于接收来自FE的心跳 |
BE | brpc_prot* | 8060 | FE<–>BEBE<–>BE | BE上的brpc端口用于BE之间通信 |
FE | http_port | 8030 | FE<–>FE用户<–> FE | FE上的http_server端口 |
FE | rpc_port | 9020 | BE–>FEFE<–>FE | FE上thirt server端口号 |
FE | query_port | 9030 | 用户<–> FE | FE上的mysql server端口 |
FE | edit_log_port | 9010 | FE<–>FE | FE上bdbje之间通信用的端口 |
Broker | broker_ipc_port | 8000 | FE–>BROKERBE–>BROKER | Broker上的thrift server用于接收请求 |
端口部署可以更改,表中为官方版本各组件的默认端口
2.1.6 部署常见的注意事项
(1)FE的磁盘空间主要用于存储元数据,包括日志和image。通常从几百MB到几个GB不等。
(2)BE的磁盘空间主要用于存放用户数据,总磁盘空间按用户总数据量* 3(3副本)计算,然后再预留额外40%的空间用作后台compaction以及一些中间数据的存放。
(3)一台机器上可以部署多个BE实例,但是只能部署一个 FE。如果需要 3 副本数据,那么至少需要 3 台机器各部署一个BE实例(而不是1台机器部署3个BE实例)。多个FE所在服务器的时钟必须保持一致(允许最多5秒的时钟偏差)
(4)测试环境也可以仅适用一个BE进行测试。实际生产环境,BE实例数量直接决定了整体查询延迟。
(5)所有部署节点关闭Swap。
(6)FE节点数据至少为1(1个Follower)。当部署1个Follower和1个Observer时,可以实现读高可用。当部署3个Follower时,可以实现读写高可用(HA)。
(7)Follower的数量必须为奇数,Observer 数量随意。
(8)根据以往经验,当集群可用性要求很高时(比如提供在线业务),可以部署3个 Follower和1-3个Observer。如果是离线业务,建议部署1个Follower和1-3个Observer。
(9)Broker是用于访问外部数据源(如HDFS)的进程。通常,在每台机器上部署一个 broker实例即可。
2.2 Doris集群部署
2.2.1 机器规划
机器1: hdt-dmcp-ops01 | 机器2: hdt-dmcp-ops02 | 机器3: hdt-dmcp-ops03 | 机器4: hdt-dmcp-ops04 | 机器5: hdt-dmcp-ops05 |
---|---|---|---|---|
FE(LEADER) | FE(FOLLOWER) | FE(OBSERVER) | FE扩容使用 | FE扩容使用 |
BE | BE | BE | BE扩容使用 | BE扩容使用 |
生产环境建议 FE 和 BE 分开
2.2.2 安装包准备
官方下载地址:https://doris.apache.org/download
注意:查看服务器是否支持 CPU Model :avx2
如果CPU不支持avx2指令集,请选择无avx2版本。您可以通过cat /proc/cpuinfo检查是否支持。avx2指令将提高诸如布隆过滤器之类的数据结构的计算效率
支持avx2 可以下载X86( avx2 ) , 不支持avx2 可以下载X86( no avx2 )
lscpu
2.2.3 下载安装包
# 下载be安装包
[wangting@hdt-dmcp-ops01 software]$ wget https://www.apache.org/dyn/mirrors/mirrors.cgi?action=download&filename=doris/1.1/1.1.5-rc02/apache-doris-be-1.1.5-bin-x86_64.tar.gz
# 下载fe安装包
[wangting@hdt-dmcp-ops01 software]$ wget https://www.apache.org/dyn/mirrors/mirrors.cgi?action=download&filename=doris/1.1/1.1.5-rc02/apache-doris-fe-1.1.5-bin.tar.gz
2.2.4 安装Java和gcc环境
# java版本信息查看
[wangting@hdt-dmcp-ops01 ~]$ java -version
java version "1.8.0_212"
Java(TM) SE Runtime Environment (build 1.8.0_212-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.212-b10, mixed mode)
# gcc版本信息查看
[wangting@hdt-dmcp-ops01 ~]$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
Copyright (C) 2015 Free Software Foundation, Inc.
因java和gcc都为常用环境,如没有需自行安装
2.2.5 设置系统文件句柄数和内核参数优化
- 系统文件句柄
[wangting@hdt-dmcp-ops01 doris]$ sudo vim /etc/security/limits.conf
# End of file
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 65536
在操作系统中,每个进程都有一个打开文件句柄的限制,它限制了进程能够同时打开的文件数。这个限制对于一些需要同时处理大量文件的应用程序来说可能会成为瓶颈。因此,可以通过修改系统最大打开文件句柄数来提高应用程序的性能。
具体来说,增加最大打开文件句柄数可以:
- 提高服务器的并发性能:如果你的服务器需要同时处理大量的网络连接和文件 I/O 操作,那么增加最大打开文件句柄数可以提高服务器的并发性能,从而降低响应时间和延迟。
- 提高数据库性能:一些数据库软件如 MySQL,需要在处理大量的数据时打开大量的文件句柄,增加最大打开文件句柄数可以提高数据库的性能。
- 解决程序打开文件失败的问题:如果你的程序在运行时出现 “too many open files” 的错误,那么增加最大打开文件句柄数可以解决这个问题。
- Linux内核参数vm.max_map_count
[wangting@hdt-dmcp-ops01 ~]$ sudo sysctl -w vm.max_map_count=2000000
vm.max_map_count = 2000000
2.2.6 时间同步
[wangting@hdt-dmcp-ops01 doris]$ xcall date
========== hdt-dmcp-ops01 info ==========
Tue May 9 16:41:50 CST 2023
========== hdt-dmcp-ops02 info ==========
Tue May 9 16:41:50 CST 2023
========== hdt-dmcp-ops03 info ==========
Tue May 9 16:41:50 CST 2023
========== hdt-dmcp-ops04 info ==========
Tue May 9 16:41:50 CST 2023
========== hdt-dmcp-ops05 info ==========
Tue May 9 16:41:50 CST 2023
Doris 的元数据要求时间精度要小于5000ms,所以所有集群所有机器要进行时钟同步,避免因为时钟问题引发的元数据不一致导致服务出现异常
2.2.7 解压安装
[wangting@hdt-dmcp-ops01 software]$ mkdir -p /opt/module/doris
[wangting@hdt-dmcp-ops01 software]$ tar -xf apache-doris-fe-1.1.5-bin.tar.gz -C /opt/module/doris/
[wangting@hdt-dmcp-ops01 software]$ tar -xf apache-doris-be-1.1.5-bin-x86_64.tar.gz -C /opt/module/doris/
[wangting@hdt-dmcp-ops01 doris]$ cd /opt/module/doris/
[wangting@hdt-dmcp-ops01 doris]$ ll
total 8
drwxr-xr-x 9 wangting wangting 4096 Dec 9 15:43 apache-doris-be-1.1.5-bin-x86_64
drwxr-xr-x 12 wangting wangting 4096 Dec 9 15:43 apache-doris-fe-1.1.5-bin
[wangting@hdt-dmcp-ops01 doris]$ mv apache-doris-be-1.1.5-bin-x86_64 be
[wangting@hdt-dmcp-ops01 doris]$ mv apache-doris-fe-1.1.5-bin fe
[wangting@hdt-dmcp-ops01 doris]$ ll
total 8
drwxr-xr-x 9 wangting wangting 4096 Dec 9 15:43 be
drwxr-xr-x 12 wangting wangting 4096 Dec 9 15:43 fe
2.2.8 配置FE
# 创建FE元数据存储目录
[wangting@hdt-dmcp-ops01 doris]$ mkdir -p /opt/module/doris/doris-meta
# 修改FE配置文件
[wangting@hdt-dmcp-ops01 doris]$ ll
total 12
drwxr-xr-x 9 wangting wangting 4096 Dec 9 15:43 be
drwxrwxr-x 2 wangting wangting 4096 May 9 17:04 doris-meta
drwxr-xr-x 12 wangting wangting 4096 Dec 9 15:43 fe
[wangting@hdt-dmcp-ops01 doris]$ cd fe/conf/
[wangting@hdt-dmcp-ops01 conf]$ vim fe.conf
meta_dir = /opt/module/doris/doris-meta
priority_networks = 172.20.8.117/24
http_port = 8130
注意:
http_port 默认为8030端口,可以不改;因为8030端口也是Hadoop的ResourceManager端口,是Hadoop的常用组件资源管理器,所以我这里更换了一个8130端口避免冲突
priority_networks 换成本机ip/24
meta_dir 换成本地存储元数据路径
2.2.9 启动FE
[wangting@hdt-dmcp-ops01 conf]$ /opt/module/doris/fe/bin/start_fe.sh --daemon
# 查看服务是否启动
[wangting@hdt-dmcp-ops01 log]$ netstat -tnlpu|grep 8130
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:8130 0.0.0.0:* LISTEN 26849/java
[wangting@hdt-dmcp-ops01 log]$ jps -l | grep 26849
26849 org.apache.doris.PaloFe
# 如有异常可以查看日志位置
[wangting@hdt-dmcp-ops01 conf]$ cd /opt/module/doris/fe/log/
2.2.10 FE Web 登录页面
访问地址: http://hdt-dmcp-ops01:8130/login
初始用户: root
密码:无
- 登录后界面
2.2.11 配置 BE
# 创建BE数据存放目录
[wangting@hdt-dmcp-ops01 doris]$ mkdir -p /opt/module/doris/data/doris-storage1
[wangting@hdt-dmcp-ops01 doris]$ mkdir -p /opt/module/doris/data/doris-storage2.SSD
# 修改BE配置文件
[wangting@hdt-dmcp-ops01 doris]$ vim /opt/module/doris/be/conf/be.conf
storage_root_path = /opt/module/doris/data/doris-storage1;/opt/module/doris/data/doris-storage2.SSD,10
priority_networks = 172.20.8.117/24
webserver_port = 8043
注意:
- storage_root_path
Doris的storage_root_path参数是指数据存储的根目录,它是在Doris集群的配置文件中进行设置的。该参数指定了Doris存储数据的根目录,包括了Doris的元数据、数据块、日志等。在Doris集群中,不同的节点可以通过配置不同的storage_root_path参数来指定存储数据的不同目录。
需要注意的是,storage_root_path参数只需要在集群初始化时设置一次,一旦集群启动后,不应该再修改该参数。如果需要更改存储路径,应该通过添加新的磁盘来扩展存储空间
storage_root_path可以通过路径区别存储目录的介质,HDD或SSD。可以添加容量限制在每个路径的末尾,通过英文状态逗号,隔开,如:
storage_root_path=/home/disk1/doris.HDD,50;/home/disk2/doris.SSD,10;/home/disk2/doris
说明:
/home/disk1/doris.HDD,50,表示存储限制为50GB,HDD;
/home/disk2/doris.SSD,10,存储限制为10GB,SSD;
/home/disk2/doris,存储限制为磁盘最大容量,默认为HDD
- priority_networks 换成本机ip/24
- webserver_port = 8043
Hadoop的8040端口是ResourceManager Web应用程序的默认端口,为避免冲突,改成了8043
- 这里先不启动 BE
2.2.12 分发BE和BE存储目录并配置
[wangting@hdt-dmcp-ops01 log]$ cd /opt/module/doris/
[wangting@hdt-dmcp-ops01 doris]$ ll
total 16
drwxr-xr-x 9 wangting wangting 4096 Dec 9 15:43 be
drwxrwxr-x 4 wangting wangting 4096 May 9 17:29 data
drwxrwxr-x 4 wangting wangting 4096 May 9 17:16 doris-meta
drwxr-xr-x 14 wangting wangting 4096 May 9 17:16 fe
# 分发BE安装目录
[wangting@hdt-dmcp-ops01 doris]$ scp -r be hdt-dmcp-ops02:$PWD/
[wangting@hdt-dmcp-ops01 doris]$ scp -r be hdt-dmcp-ops03:$PWD/
# 分发BE存储目录
[wangting@hdt-dmcp-ops01 doris]$ scp -r data hdt-dmcp-ops02:$PWD/
[wangting@hdt-dmcp-ops01 doris]$ scp -r data hdt-dmcp-ops03:$PWD/
# 在 hdt-dmcp-ops02 和 hdt-dmcp-ops03 中修改 BE配置的priority_networks参数
[wangting@hdt-dmcp-ops02 ~]$ vim /opt/module/doris/be/conf/be.conf
priority_networks = 172.20.14.164/24
[wangting@hdt-dmcp-ops03 ~]$ vim /opt/module/doris/be/conf/be.conf
priority_networks = 172.20.14.243
2.2.13 添加 BE
BE节点需要先在FE中添加,才可加入集群。可以使用mysql-client连接到FE
注意:
这里需要有MySQL客户端连接MySQL的client,安装忽略,yum安装mysqld或者mariadb均可
- 使用 Mysql 客户端连接到 FE
FE 默认没有密码
[wangting@hdt-dmcp-ops01 ~]$ mysql -h hdt-dmcp-ops01 -uroot -P 9030
# 设置密码
MySQL [(none)]> SET PASSWORD FOR 'root' = PASSWORD('123456');
Query OK, 0 rows affected (0.00 sec)
MySQL [(none)]> exit;
Bye
注意:
这里密码改过以后,那FE的前端访问页面的ROOT密码,就是改后的,注意下次登录时需要输入对应的新密码
- 添加BE
# 登录
[wangting@hdt-dmcp-ops01 ~]$ mysql -h hdt-dmcp-ops01 -uroot -P 9030 -p123456
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.7.37 Doris version 1.1.5-rc02-ef0635dae7
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
# 添加BE 方式
MySQL [(none)]> ALTER SYSTEM ADD BACKEND "hdt-dmcp-ops01:9050";
Query OK, 0 rows affected (0.04 sec)
MySQL [(none)]> ALTER SYSTEM ADD BACKEND "hdt-dmcp-ops02:9050";
Query OK, 0 rows affected (0.01 sec)
MySQL [(none)]> ALTER SYSTEM ADD BACKEND "hdt-dmcp-ops03:9050";
Query OK, 0 rows affected (0.00 sec)
# 查看BE 状态
MySQL [(none)]> SHOW PROC '/backends'\G;
*************************** 1. row ***************************
BackendId: 10002
Cluster: default_cluster
IP: 172.20.8.117
HostName: hdt-dmcp-ops01
HeartbeatPort: 9050
Alive: false
*************************** 2. row ***************************
BackendId: 10003
Cluster: default_cluster
IP: 172.20.14.164
HostName: hdt-dmcp-ops02
HeartbeatPort: 9050
Alive: false
*************************** 3. row ***************************
BackendId: 10004
Cluster: default_cluster
IP: 172.20.14.243
HostName: hdt-dmcp-ops03
HeartbeatPort: 9050
Alive: false
3 rows in set (0.00 sec)
# (内容省略部分)
MySQL [(none)]> exit;
Bye
注意:
这时的BE已经添加,但是状态是异常的(Alive: false),因为BE服务还未启动
2.2.14 启动 BE
# 分别在三台设备启动 BE 进程
[wangting@hdt-dmcp-ops01 ~]$ /opt/module/doris/be/bin/start_be.sh --daemon
[wangting@hdt-dmcp-ops02 ~]$ /opt/module/doris/be/bin/start_be.sh --daemon
[wangting@hdt-dmcp-ops03 ~]$ /opt/module/doris/be/bin/start_be.sh --daemon
- 再次查询 BE 状态
[wangting@hdt-dmcp-ops01 ~]$ mysql -h hdt-dmcp-ops01 -uroot -P 9030 -p123456
# 查看BE 状态
MySQL [(none)]> SHOW PROC '/backends'\G;
此时的 Alive: true ,表示BE已经正常
3. Doris扩容和缩容
3.1 FE 扩容和缩容
可以通过将FE扩容至3个以上节点(必须是奇数)来实现FE的高可用
3.1.1 FE扩容
- 查看 FE 转态
MySQL [(none)]> show proc '/frontends'\G;
*************************** 1. row ***************************
Name: 172.20.8.117_9010_1683623765731
IP: 172.20.8.117
HostName: hdt-dmcp-ops01
EditLogPort: 9010
HttpPort: 8130
QueryPort: 9030
RpcPort: 9020
Role: FOLLOWER
IsMaster: true
ClusterId: 2040453956
Join: true
Alive: true
ReplayedJournalId: 18054
LastHeartbeat: 2023-05-10 09:59:13
IsHelper: true
ErrMsg:
Version: 1.1.5-rc02-ef0635dae7
CurrentConnected: Yes
1 row in set (0.01 sec)
从查询结果看,目前只有一个 FE,Role 为 FOLLOWER
- 增加FE节点
FE分为Leader,Follower和Observer三种角色。 默认一个集群只能有一个Leader,可以有多个Follower和Observer。其中Leader和Follower组成一个Paxos选择组,如果 Leader宕机,则剩下的Follower 会自动选出新的Leader,保证写入高可用。Observer 同步 Leader的数据,但是不参加选举。
如果只部署一个FE,则FE 默认就是Leader。在此基础上,可以添加若干Follower和 Observer。
# 增加FOLLOWER
MySQL [(none)]> ALTER SYSTEM ADD FOLLOWER "hdt-dmcp-ops02:9010";
Query OK, 0 rows affected (0.04 sec)
# 增加OBSERVER
MySQL [(none)]> ALTER SYSTEM ADD OBSERVER "hdt-dmcp-ops03:9010";
Query OK, 0 rows affected (0.01 sec)
# 增加FOLLOWER
MySQL [(none)]> ALTER SYSTEM ADD FOLLOWER "hdt-dmcp-ops04:9010";
Query OK, 0 rows affected (0.03 sec)
此时只是加入角色,各 FE 节点服务还未部署
- 配置Follower和Observer
分发 FE目录
[wangting@hdt-dmcp-ops01 ~]$ cd /opt/module/doris/
[wangting@hdt-dmcp-ops01 doris]$ ll
total 16
drwxr-xr-x 9 wangting wangting 4096 Dec 9 15:43 be
drwxrwxr-x 4 wangting wangting 4096 May 9 17:29 data
drwxrwxr-x 4 wangting wangting 4096 May 9 17:16 doris-meta
drwxr-xr-x 14 wangting wangting 4096 May 9 17:16 fe
[wangting@hdt-dmcp-ops01 doris]$ scp -r fe hdt-dmcp-ops02:$PWD/
[wangting@hdt-dmcp-ops01 doris]$ scp -r fe hdt-dmcp-ops03:$PWD/
[wangting@hdt-dmcp-ops01 doris]$ scp -r fe hdt-dmcp-ops04:$PWD/
新 FE 节点创建元数据目录
[wangting@hdt-dmcp-ops02 doris]$ mkdir -p /opt/module/doris/doris-meta
[wangting@hdt-dmcp-ops03 doris]$ mkdir -p /opt/module/doris/doris-meta
[wangting@hdt-dmcp-ops04 doris]$ mkdir -p /opt/module/doris/doris-meta
修改配置文件(fe.conf)
# priority_networks 参数IP地址需要更改
[wangting@hdt-dmcp-ops02 doris]$ vim /opt/module/doris/fe/conf/fe.conf
priority_networks = 172.20.14.164/24
[wangting@hdt-dmcp-ops03 doris]$ vim /opt/module/doris/fe/conf/fe.conf
priority_networks = 172.20.14.243/24
[wangting@hdt-dmcp-ops04 doris]$ vim /opt/module/doris/fe/conf/fe.conf
priority_networks = 172.20.9.6/24
启动新的 FE 节点
注意:
扩容的节点第一次启动时,启动命令需要添加参 --helper leader的IP:port,第一次需要成功启动加入到集群后,后续就不需要helper参数了
[wangting@hdt-dmcp-ops02 conf]$ /opt/module/doris/fe/bin/start_fe.sh --helper hdt-dmcp-ops01:9010 --daemon
[wangting@hdt-dmcp-ops03 conf]$ /opt/module/doris/fe/bin/start_fe.sh --helper hdt-dmcp-ops01:9010 --daemon
[wangting@hdt-dmcp-ops04 conf]$ /opt/module/doris/fe/bin/start_fe.sh --helper hdt-dmcp-ops01:9010 --daemon
查看 FE 状态
MySQL [(none)]> show proc '/frontends'\G;
*************************** 1. row ***************************
Name: 172.20.9.6_9010_1683692414911
IP: 172.20.9.6
HostName: hdt-dmcp-ops04
EditLogPort: 9010
HttpPort: 8130
QueryPort: 9030
RpcPort: 9020
Role: FOLLOWER
IsMaster: false
ClusterId: 2040453956
Join: true
Alive: true
ReplayedJournalId: 20570
LastHeartbeat: 2023-05-10 12:21:19
IsHelper: true
ErrMsg:
Version: 1.1.5-rc02-ef0635dae7
CurrentConnected: No
*************************** 2. row ***************************
Name: 172.20.8.117_9010_1683623765731
IP: 172.20.8.117
HostName: hdt-dmcp-ops01
EditLogPort: 9010
HttpPort: 8130
QueryPort: 9030
RpcPort: 9020
Role: FOLLOWER
IsMaster: true
ClusterId: 2040453956
Join: true
Alive: true
ReplayedJournalId: 20571
LastHeartbeat: 2023-05-10 12:21:19
IsHelper: true
ErrMsg:
Version: 1.1.5-rc02-ef0635dae7
CurrentConnected: Yes
*************************** 3. row ***************************
Name: 172.20.14.164_9010_1683687283135
IP: 172.20.14.164
HostName: hdt-dmcp-ops02
EditLogPort: 9010
HttpPort: 8130
QueryPort: 9030
RpcPort: 9020
Role: FOLLOWER
IsMaster: false
ClusterId: 2040453956
Join: true
Alive: true
ReplayedJournalId: 20570
LastHeartbeat: 2023-05-10 12:21:19
IsHelper: true
ErrMsg:
Version: 1.1.5-rc02-ef0635dae7
CurrentConnected: No
*************************** 4. row ***************************
Name: 172.20.14.243_9010_1683687284603
IP: 172.20.14.243
HostName: hdt-dmcp-ops03
EditLogPort: 9010
HttpPort: 8130
QueryPort: 9030
RpcPort: 9020
Role: OBSERVER
IsMaster: false
ClusterId: 2040453956
Join: true
Alive: true
ReplayedJournalId: 20570
LastHeartbeat: 2023-05-10 12:21:19
IsHelper: false
ErrMsg:
Version: 1.1.5-rc02-ef0635dae7
CurrentConnected: No
4 rows in set (0.04 sec)
也可以在WEB-UI上查看验证,使用新增加的ops04尝试访问
3.1.1 FE缩容
删除只需执行如下命令即可:
ALTER SYSTEM DROP FOLLOWER[OBSERVER] "fe_host:edit_log_port";
注意:
删除 Follower FE 时,确保最终剩余的 Follower(包括 Leader)节点为奇数的合理状态
3.2 BE扩容和缩容
3.2.1 BE扩容
BE扩容和第一次部署添加 BE 方式一样
在MySQL命令行,通过 ALTER SYSTEM ADD BACKEND
命令增加BE节点
- 命令行增添 BE 节点
MySQL [(none)]> ALTER SYSTEM ADD BACKEND "hdt-dmcp-ops04:9050";
Query OK, 0 rows affected (0.02 sec)
MySQL [(none)]> ALTER SYSTEM ADD BACKEND "hdt-dmcp-ops05:9050";
Query OK, 0 rows affected (0.01 sec)
- 分发 BE
[wangting@hdt-dmcp-ops01 log]$ cd /opt/module/doris/
# 分发BE安装目录
[wangting@hdt-dmcp-ops01 doris]$ scp -r be hdt-dmcp-ops04:$PWD/
[wangting@hdt-dmcp-ops01 doris]$ scp -r be hdt-dmcp-ops05:$PWD/
# 分发BE存储目录
[wangting@hdt-dmcp-ops01 doris]$ scp -r data hdt-dmcp-ops04:$PWD/
[wangting@hdt-dmcp-ops01 doris]$ scp -r data hdt-dmcp-ops05:$PWD/
- 修改BE配置的priority_networks参数
[wangting@hdt-dmcp-ops04 ~]$ vim /opt/module/doris/be/conf/be.conf
priority_networks = 172.20.9.6/24
[wangting@hdt-dmcp-ops05 ~]$ vim /opt/module/doris/be/conf/be.conf
priority_networks = 172.20.12.179/24
- 启动BE
# 在新节点上启动 BE 进程
[wangting@hdt-dmcp-ops04 ~]$ /opt/module/doris/be/bin/start_be.sh --daemon
[wangting@hdt-dmcp-ops05 ~]$ /opt/module/doris/be/bin/start_be.sh --daemon
- 查询 BE 状态
# 查看BE 状态
MySQL [(none)]> SHOW PROC '/backends'\G;
此时已经可以看到新加入集群的 BE 节点信息
也可以在WEB-UI界面查看所有backends情况
3.2.2 BE缩容
使用
DECOMMISSION
方式删除BE节点
语法:ALTER SYSTEM DECOMMISSION BACKEND "be_host:be_heartbeat_service_port";
示例:ALTER SYSTEM DECOMMISSION BACKEND "hdt-dmcp-ops05:9050";
注意:
该命令用于安全删除BE节点。命令下发后,Doris 会尝试将该BE上的数据向其他BE节点迁移,当所有数据都迁移完成后,Doris会自动删除该节点。
该命令是一个异步操作。执行后,可以通过 SHOW PROC ‘/backends’; 看到该 BE 节点的isDecommission状态为true。表示该节点正在进行下线。
该命令不一定执行成功。比如剩余BE存储空间不足以容纳下线BE上的数据,或者剩余机器数量不满足最小副本数时,该命令都无法完成,并且BE会一直处于 isDecommission为true的状态。
DECOMMISSION的进度,可以通过SHOW PROC ‘/backends’; 中的TabletNum查看,如果正在进行,TabletNum将不断减少。
该操作可以通过如下命令取消:
CANCEL DECOMMISSION BACKEND "be_host:be_heartbeat_service_port";
- 如执行取消命令后,该BE上的数据将维持当前剩余的数据量。后续Doris重新进行负载均衡
除了使用
DECOMMISSION
方式,还可以直接使用 DROP 方式删除 BE 节点,但生产环境不建议使用示例:
ALTER SYSTEM DROP BACKEND "be_host:be_heartbeat_service_port";
DROP BACKEND 会直接删除该BE,并且其上的数据将不能再恢复。方式比较暴力,所以不推荐使用 DROP BACKEND 这种方式删除BE节点。当执行这个语句时,也会有对应的防误操作提示信息
4. Doris 基本概念与介绍
4.1 Doris基本概念
4.1.1 Row & Column
一张表包括行(Row)和列(Column):
-
Row , 即用户的一行数据;
-
Column , 用于描述一行数据中不同的字段。
Column 可以分为两大类:Key 和 Value。从业务角度看,Key 和 Value 可以分别对应维度列和指标列
Doris数据库是一个分布式的列式存储引擎,它的数据模型是基于列式存储的。在Doris数据库中,一个Row就是一个数据行,它由多个Column组成。每个Column则代表这个数据行中的一个属性或者字段。因此,我们也可以将一个Row看做是一个数据表中的一行数据,而Column则对应数据表中的列。
在Doris数据库中,由于数据是以列式存储的,因此在查询时可以只读取需要的Column数据,而不用读取整个Row数据,这就大大提高了查询性能。同时,Doris还支持Column的压缩和编码,可以进一步减小存储空间,提高数据的存储和查询效率。
总之,在Doris数据库中,Row和Column是基本的数据结构,Row代表一个数据行,Column代表一个属性或字段,这种设计使得Doris能够高效地存储和查询海量数据。
4.1.2 Tablet & Partition
在Doris的存储引擎中,用户数据首先被划分成若干个分区(Partition),划分的规则通常是按照用户指定的分区列进行范围划分,比如按时间划分。而在每个分区内,数据被进一步的按照Hash的方式分桶,分桶的规则是要找用户指定的分桶列的值进行Hash后分桶。每个分桶就是一个数据分片(Tablet),也是数据划分的最小逻辑单元。
Tablet之间的数据是没有交集的,独立存储的。Tablet也是数据移动、复制等操作的最小物理存储单元。
Partition可以视为是逻辑上最小的管理单元。数据的导入与删除,都可以或仅能针对一个 Partition 进行,例如,可以按照数据的时间戳、地理位置、业务类型等进行分区,以保证数据的高效存储和查询。每个Partition都包含一定数量的数据块(Data Block),一个数据块包含一段连续的数据和对应的元数据信息,用于支持查询和数据的压缩存储等功能。
总之,Doris的Tablet和Partition是实现高性能、高可用的分布式存储和计算的关键组件,通过合理的划分和分配,可以充分利用计算和存储资源,提高数据的利用率和系统的性能
4.2 Doris字段类型
TINYINT | 1字节 | 范围:-2^7 + 1 ~ 2^7 - 1 |
---|---|---|
SMALLINT | 2字节 | 范围:-2^15 + 1 ~ 2^15 - 1 |
INT | 4字节 | 范围:-2^31 + 1 ~ 2^31 - 1 |
BIGINT | 8字节 | 范围:-2^63 + 1 ~ 2^63 - 1 |
LARGEINT | 16字节 | 范围:-2^127 + 1 ~ 2^127 - 1 |
FLOAT | 4字节 | 支持科学计数法 |
DOUBLE | 12字节 | 支持科学计数法 |
DECIMAL[(precision, scale)] | 16字节 | 保证精度的小数类型。默认是 DECIMAL(10, 0)precision: 1 ~ 27scale: 0 ~ 9其中整数部分为 1 ~ 18不支持科学计数法 |
DATE | 3字节 | 范围:0000-01-01 ~ 9999-12-31 |
DATETIME | 8字节 | 范围:0000-01-01 00:00:00 ~ 9999-12-31 23:59:59 |
CHAR[(length)] | 定长字符串。长度范围:1 ~ 255。默认为1 | |
VARCHAR[(length)] | 变长字符串。长度范围:1 ~ 65533 | |
BOOLEAN | 与TINYINT一样,0代表false,1代表true | |
HLL | 1~16385个字节 | hll列类型,不需要指定长度和默认值、长度根据数据的聚合程度系统内控制,并且HLL列只能通过配套的hll_union_agg、Hll_cardinality、hll_hash进行查询或使用 |
BITMAP | bitmap列类型,不需要指定长度和默认值。表示整型的集合,元素最大支持到2^64 - 1 | |
STRING | 变长字符串,0.15版本支持,最大支持2147483643 字节(2GB-4),长度还受be 配置string_type_soft_limit , 实际能存储的最大长度取两者最小值。只能用在value 列,不能用在 key 列和分区、分桶列 |
4.3 Doris数据模型
Doris 的数据模型主要分为3类
-
Aggregate - 实现聚合查询
Doris的Aggregate模型是Doris中的一种数据模型,用于支持快速的聚合查询。该模型将数据按照一定的规则进行分组,并对每个分组内的数据进行聚合计算,得到一个汇总的结果。在Doris中,Aggregate模型是通过一个存储在内存中的数据结构进行计算的,这个数据结构被称为“HyperLogLog”(简称HLL)。HLL可以快速地统计一个数据集的基数(不同元素的个数),并且可以进行基于聚合的计算,例如计算不同的元素的个数、求和、平均值等。在Doris中,用户可以通过定义聚合键、聚合函数等参数来创建Aggregate模型,从而支持更高效的查询操作。
-
Unique - 实现唯一性约束
Doris数据库的Unique模型是指在Doris中使用了一种特殊的索引结构,称为Unique索引,来实现唯一性约束。这种索引结构允许在表的某个列上创建唯一性约束,保证该列的值在表中是唯一的,并且可以快速地检查重复值。
在Doris中,Unique索引使用B+树数据结构来实现,通过将唯一性列的值作为索引的键值,将其它列的值作为索引的数据值,来构建索引。当插入或更新数据时,Doris会自动检查唯一性列的值是否已经存在,如果不存在则插入数据,否则更新数据。这样就可以避免重复数据的插入,保证数据的唯一性。
Unique模型主要用于实现单列唯一性约束,如果需要实现多列唯一性约束,则需要使用Doris的联合索引。
-
Duplicate - 实现自动检测和删除重复数据
Doris数据库的Duplicate模型是用于处理数据冗余问题的模型,它可以自动检测和删除重复数据。在Doris数据库中,数据是以分布式表的形式存储的,分布式表由多个分片组成,每个分片都有自己的数据副本。当用户执行插入操作时,Duplicate模型会首先检测分片中是否已经存在相同的数据,如果存在,则会自动删除重复数据,从而保证数据的唯一性。Duplicate模型还支持对唯一性约束进行自定义设置,用户可以根据自己的业务需求来定义唯一性约束。
建测试库
MySQL [(none)]> create database test_db;
Query OK, 0 rows affected (0.02 sec)
MySQL [(none)]> use test_db;
Database changed
MySQL [test_db]>
4.3.1 Aggregate使用示例
- 建表
CREATE TABLE IF NOT EXISTS test_db.example_site_visit
(
`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 10;
- 插入样例数据
insert into test_db.example_site_visit values\
(10000,'2017-10-01','北京',20,0,'2017-10-01 06:00:00' ,20,10,10),\
(10000,'2017-10-01','北京',20,0,'2017-10-01 07:00:00',15,2,2),\
(10001,'2017-10-01','北京',30,1,'2017-10-01 17:05:45',2,22,22),\
(10002,'2017-10-02','上海',20,1,'2017-10-02 12:59:12' ,200,5,5),\
(10003,'2017-10-02','广州',32,0,'2017-10-02 11:20:00',30,11,11),\
(10004,'2017-10-01','深圳',35,0,'2017-10-01 10:00:15',100,3,3),\
(10004,'2017-10-03','深圳',35,0,'2017-10-03 10:20:22',11,6,6);
- 查看数据验证
可以观察结果针对同一个user_id
进行的聚合结果
根据建表语句中AGGREGATE KEY(
user_id,
date,
city,
age,
sex)
,涉及的字段信息都相同进行聚合,如有不同不触发聚合
10000信息相同进行聚合,而10004灌入日期时间就已经不同,不进行聚合
4.3.2 Unique 使用示例
- 建表
CREATE TABLE IF NOT EXISTS test_db.user
(
`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 10;
- 插入样例数据
insert into test_db.user values\
(10000,'wuyanzu','北京',18,0,12345678910,'北京朝阳区','2017-10-01 07:00:00'),\
(10000,'wuyanzu','北京',19,0,12345678910,'北京朝阳区','2017-10-01 07:00:00'),\
(10000,'zhangsan','北京',20,0,12345678910,'北京海淀区','2017-11-15 06:10:20');
- 查看数据验证
可以观察结果针对同一个user_id
进行的聚合结果
根据建表语句中UNIQUE KEY(user_id, username)
,涉及的字段信息都相同进行去重,如有不同不触发去重
注意:
Unique 模型完全可以用聚合模型中的 REPLACE 方式替代。其内部的实现方式和数据存储方式也完全一样
简单的理解就是 Unique 能实现的功能都可以用 Aggregate 实现
补充示例:
# 建表
CREATE TABLE IF NOT EXISTS test_db.user_2
(
`user_id` LARGEINT NOT NULL COMMENT "用户id",
`username` VARCHAR(50) NOT NULL COMMENT "用户昵称",
`city` VARCHAR(20) REPLACE COMMENT "用户所在城市",
`age` SMALLINT REPLACE COMMENT "用户年龄",
`sex` TINYINT REPLACE COMMENT "用户性别",
`phone` LARGEINT REPLACE COMMENT "用户电话",
`address` VARCHAR(500) REPLACE COMMENT "用户地址",
`register_time` DATETIME REPLACE COMMENT "用户注册时间"
)
AGGREGATE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 10;
# 插入样例数据
insert into test_db.user_2 values\
(10000,'wuyanzu','北京',18,0,12345678910,'北京朝阳区','2017-10-01 07:00:00'),\
(10000,'wuyanzu','北京',19,0,12345678910,'北京朝阳区','2017-10-01 07:00:00'),\
(10000,'zhangsan','北京',20,0,12345678910,'北京海淀区','2017-11-15 06:10:20');
# 查询验证 发现也是只有2条,成功去重
MySQL [test_db]> select user_id,username,city,age from user_2;
+---------+----------+--------+------+
| user_id | username | city | age |
+---------+----------+--------+------+
| 10000 | wuyanzu | 北京 | 19 |
| 10000 | zhangsan | 北京 | 20 |
+---------+----------+--------+------+
4.3.3 Duplicate 使用示例
- 建表
CREATE TABLE IF NOT EXISTS test_db.example_log
(
`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`)
DISTRIBUTED BY HASH(`timestamp`) BUCKETS 10;
- 插入样例数据
insert into test_db.example_log values\
('2017-10-01 08:00:05',1,404,'not found page', 101, '2017-10-01 08:00:05'),\
('2017-10-01 08:00:05',1,404,'not found page', 101, '2017-10-01 08:00:05'),\
('2017-10-01 08:00:05',2,404,'not found page', 101, '2017-10-01 08:00:06'),\
('2017-10-01 08:00:06',2,404,'not found page', 101, '2017-10-01 08:00:07');
- 查看数据验证
MySQL [test_db]> select * from example_log;
+---------------------+------+------------+----------------+-------+---------------------+
| timestamp | type | error_code | error_msg | op_id | op_time |
+---------------------+------+------------+----------------+-------+---------------------+
| 2017-10-01 08:00:05 | 1 | 404 | not found page | 101 | 2017-10-01 08:00:05 |
| 2017-10-01 08:00:05 | 1 | 404 | not found page | 101 | 2017-10-01 08:00:05 |
| 2017-10-01 08:00:05 | 2 | 404 | not found page | 101 | 2017-10-01 08:00:06 |
| 2017-10-01 08:00:06 | 2 | 404 | not found page | 101 | 2017-10-01 08:00:07 |
+---------------------+------+------------+----------------+-------+---------------------+
Duplicate 这种数据模型区别于 Aggregate 和 Unique 模型。数据完全按照导入文件中的数据进行存储,不会有任何聚合。即使两行数据完全相同,也都会保留。 而在建表语句中指定的 DUPLICATE KEY,只是用来指明底层数据按照那些列进行排序。
在 DUPLICATE KEY 的选择上,建议适当的选择前 2-4 列就可以,这种数据模型适用于既没有聚合需求,又没有主键唯一性约束的原始数据的存储。
4.4 Doris web-ui使用
-
首页可以查看Doris应用部署的版本信息
Version
和对应服务器的硬件信息Hardware Info
-
页面
Playground
可以进行SQL查询
-
页面
System
可以查看集群的基本信息,例如用户、节点、状态等等情况 -
页面
Log
可以直接查看部署应用的log日志,十分便捷 -
页面
Session Info
可以实时监控当前Doris数据库实时会话信息,例如使用命令行连接数据库,再使用Navicat工具连一个会话,则可以在页面看到当前2个连接session信息
4.5 Doris丰富的建表示例
- 查看建表帮助
HELP CREATE TABLE;
可以查看建表的各类示例:
Description:
该语句用于创建 table。
语法:
```
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [database.]table_name
(column_definition1[, column_definition2, ...]
[, index_definition1[, index_definition2, ...]])
[ENGINE = [olap|mysql|broker|hive|iceberg]]
[key_desc]
[COMMENT "table comment"];
[partition_desc]
[distribution_desc]
[rollup_index]
[PROPERTIES ("key"="value", ...)]
[BROKER PROPERTIES ("key"="value", ...)]
```
例如帮助中有非常丰富的不同场景的建表示例( 都可以通过HELP CREATE TABLE;
直接查看获取 ):
- 创建一个 olap 表,使用 HASH 分桶,使用列存,相同key的记录进行聚合
- 创建一个 olap 表,使用 Hash 分桶,使用列存,相同key的记录进行覆盖,
- 创建一个 olap 表,使用 Range 分区,使用Hash分桶,默认使用列存,
- 创建一个 olap 表,使用 List 分区,使用Hash分桶,默认使用列存,
- 创建一个 mysql 表
- 创建一个数据文件存储在HDFS上的 broker 外部表, 数据使用 “|” 分割,“\n” 换行
- 创建一张含有HLL列的表
- 创建一张含有BITMAP_UNION聚合类型的表(v1和v2列的原始数据类型必须是TINYINT,SMALLINT,INT)
- 创建两张支持Colocate Join的表t1 和t2
- 创建一个数据文件存储在BOS上的 broker 外部表
- 创建一个带有bitmap 索引的表
- 创建一个动态分区表(需要在FE配置中开启动态分区功能),该表每天提前创建3天的分区,并删除3天前的分区。例如今天为
2020-01-08
,则会创建分区名为p20200108
,p20200109
, - 创建一个带有rollup索引的表
- 创建一个内存表
- 创建一个hive外部表
- 通过 replication_allocation 指定表的副本分布
- 创建一个 Iceberg 外表
更多推荐
所有评论(0)