虎牙 裸舞 Doris(一)-简介、架构、编译、装置和数据表的基本使用-CSDN博客
目次虎牙 裸舞
1、Doris简介
2、Doris网址
3、Doris架构
3、编译和装置
3.4.1 FE 扩容和缩容
3.4.2 BE 扩容和缩容
3.4.3 Broker 扩容缩容
3.3.1、创建目次并拷贝编译后的文献
3.3.2、部署 FE 节点
3.3.3、配置 BE 节点
3.3.4、在 FE 中添加统共 BE 节点
3.3.5、启动 BE
3.3.6、部署 FS_Broker(可选)
3.2.1、装置Docker环境
3.2.2、使用Docker 开采镜像编译
3.1、软硬件需求
3.2、编译
3.3、集群部署
3.4、扩容和缩容
4、数据表的基本使用
4.3.1、建表语法
4.3.2、字段类型
4.3.3、Doris建示意例
4.3.4、数据区分
4.3.5 数据模子
4.3.6 动态分区
4.3.7 Rollup
4.3.8 死一火视图
4.3.9 修改表
4.3.10 删除数据(Delete)
4.3.3.1、Range Partition
4.3.3.2、 List Partition
4.3.4.3.1 replication_num
4.3.4.3.2、storage_medium & storage_cooldown_time
4.3.4.2.1、Partition
4.3.4.2.2、Bucket
4.3.4.2.3、使用复合分区的场景
4.3.4.2.4、多列分区
4.3.4.1、列界说
4.3.4.2、分区与分桶
4.3.4.3、PROPERTIES
4.3.4.4、ENGINE
4.3.5.1.2 示例二:保留明细数据
4.3.5.1.3 示例三:导入数据与已独特据团员
4.3.5.1 Aggregate 模子
4.3.5.2 Uniq 模子
4.3.5.3 Duplicate 模子
4.3.5.4 数据模子的遴荐提议
4.3.6.3.1 主要参数
4.3.6.3.2 创建历史分区的参数
4.3.6.3.3 创建历史分区规则
4.3.6.3.4 创建历史分区例如
4.3.6.3.5 属目事项
4.3.6.1 旨趣
4.3.6.2 使用方式
4.3.6.3 动态分区规则参数
4.3.6.4 示例
4.3.7.3.1 前缀索引
4.3.7.3.2 ROLLUP 调整前缀索引
4.3.7.1 基本想法
4.3.7.2 Aggregate 和 Uniq 模子中的 ROLLUP
4.3.7.3 Duplicate 模子中的 ROLLUP
4.3.7.4 ROLLUP 的几点阐扬
4.3.8.5.1 案例一
4.3.8.5.2 案例二:猜想告白的 pv、uv
4.3.8.5.3 案例三
4.3.8.4.1 创建死一火视图
4.3.8.4.2 查询
4.3.8.4.3 查询自动匹配
4.3.8.4.4 最优旅途遴荐
4.3.8.4.5 查询改写
4.3.8.4.6 使用及猖狂
4.3.8.1 适用场景
4.3.8.2 上风
4.3.8.3 死一火视图 VS Rollup
4.3.8.4 死一火视图旨趣
4.3.8.5 案例演示
4.3.9.1 rename
4.3.9.2 partition
4.3.9.3 rollup
4.3.9.4 表结构变更
4.3.10.1 DELETE FROM Statement(条目删除)
4.3.10.2 DROP PARTITION Statement(删除分区)
4.2.1、Row&Column
4.2.2、Partition&Tablet
4.1、创建用户和数据库
4.2、Doris中数据表的基本想法
4.3、建示意例
1、Doris简介
Doris是由百度大数据研发,是一个当代化的MPP(Massively Parallel Processing)大界限并行处理的分析型数据库产物。仅需亚秒级反当令刻即可获取查询终结,灵验地救援及时数据分析。
Apache Doris 的漫步式架构尽头直快,易于运维,何况不错救援 10PB 以上的超大数据集。
Apache Doris 不错缓和多种数据分析需求,例如固定历史报表,及时数据分析,交互式
数据分析和探索式数据分析等。
图片
图片
2、Doris网址
1、官网地址
2、文档稽查地址
3、下载地址
4、github地址
3、Doris架构
图片
Doris 的架构很直快,只设FE(Frontend)、BE(Backend)两种变装、两个进程,不依赖于外部组件,粗拙部署和运维,FE、BE齐可线性膨胀。
Frontend(FE),存储、难得集群元数据;防御采选、理解查询央求,推敲查询筹备,疗养查询奉行,复返查询终结。主要有三个变装:
1)Leader 和Follower:主若是用来达到元数据的高可用,保证单节点宕机的情况下,元数据梗概及时地在线复原,而不影响统共这个词管事。
2)Observer:用来膨胀查询节点,同期起到元数据备份的作用。如果在发现集群压力尽头大的情况下,需要去膨胀统共这个词查询的期间,那么不错加observer 的节点。observer 不参与任何的写入,只参与读取。
Backend(BE),防御物理数据的存储和猜想;依据FE 生成的物理筹备,漫步式地奉行查询。
数据的可靠性由BE 保证,BE 会对统共这个词数据存储多副本或者是三副本。副本数可凭据需求动态调整。
MySQLClient:Doris借助MySQL契约,用户使用淘气MySQL的ODBC/JDBC以及MySQL的客户端,齐不错顺利拜访Doris。
Broker:Broker为一个独处的无景况进程。封装了文献系统接口,提供Doris读取远端存储系统华文献的期间,包括HDFS,S3,BOS等。
3、编译和装置
3.1、软硬件需求
玄虚
Doris 行为一款开源的 MPP 架构 OLAP 数据库,梗概运行在绝大多数主流的商用管事器上。为了梗概充分运用 MPP 架构的并发上风,以及 Doris 的高可用本性,咱们提议 Doris 的部署受命以下需求:
Linux 操作系统版块需求
Linux 系统版块
CentOS
7.1 及以上
Ubuntu
16.04 及以上
软件需求
软件版块
Java
1.8 及以上
GCC
4.8.2 及以上
操作系统装置要求
建树系统最大掀开文献句柄数vi /etc/security/limits.conf * soft nofile 65536 * hard nofile 65536
时钟同步
Doris 的元数据要求时刻精度要小于5000ms,是以统共集群统共机器要进行时钟同步,幸免因为时钟问题激发的元数据不一致导致管事出现极端。
关闭交换分区(swap)
Linux交换分区会给Doris带来很严重的性能问题,需要在装置之前禁用交换分区
Liunx文献系统
这里咱们推选使用ext4文献系统,在装置操作系统的时候,请遴荐ext4文献系统。
开采测试环境
模块CPU内存磁盘汇聚实例数目
Frontend
8核+
8GB+
SSD 或 SATA,10GB+ *
千兆网卡
1
Backend
8核+
16GB+
SSD 或 SATA,50GB+ *
千兆网卡
1-3 *
分娩环境
模块CPU内存磁盘汇聚实例数目(最低要求)
Frontend
16核+
64GB+
SSD 或 RAID 卡,100GB+ *
万兆网卡
1-3 *
Backend
16核+
64GB+
SSD 或 SATA,100G+ *
万兆网卡
3 *
注1:
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 变装分为 Follower 和 Observer,(Leader 为 Follower 组中选举出来的一种变装,以下统称 Follower)。
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 实例即可。
默许端标语:
实例称呼端口称呼默许端口通讯标的阐扬
BE
be_port
9060
FE --> BE
BE 上 thrift server 的端口,用于采选来自 FE 的央求
BE
webserver_port
8040
BE <–> BE
BE 上的 http server 的端口
BE
heartbeat_service_port
9050
FE --> BE
BE 上心跳管事端口(thrift),用于采选来自 FE 的心跳
BE
brpc_port
8060
FE <–> BE, BE <–> BE
BE 上的 brpc 端口,用于 BE 之间通讯
FE
http_port
8030
FE <–> FE,用户 <–> FE
FE 上的 http server 端口
FE
rpc_port
9020
BE --> FE, FE <–> FE
FE 上的 thrift server 端口,每个fe的配置需要保捏一致
FE
query_port
9030
用户 <–> FE
FE 上的 mysql server 端口
FE
edit_log_port
9010
FE <–> FE
FE 上的 bdbje 之间通讯用的端口
Broker
broker_ipc_port
8000
FE --> Broker, BE --> Broker
Broker 上的 thrift server,用于采选央求
当部署多个 FE 实例时,要保证 FE 的 http_port 配置调换。
部署前请确保各个端口在应有方进取的拜访权限。
IP 绑定
因为有多网卡的存在,或因为装置过 docker 等环境导致的臆造网卡的存在,兼并个主机可能存在多个不同的 ip。现时 Doris 并不成自动识别可用 IP。是以当遭受部署主机上有多个 IP 时,必须通过 priority_networks 配置项来强制指定正确的 IP。
priority_networks 是 FE 和 BE 齐有的一个配置,配置项需写在 fe.conf 和 be.conf 中。该配置项用于在 FE 或 BE 启动时,告诉进程应该绑定哪个IP。示例如下:
priority_networks=10.1.3.0/24
这是一种 CIDR 的示意方法。FE 或 BE 会凭据这个配置项来寻找匹配的IP,行为我方的 localIP。
属目:当配置完 priority_networks 并启动 FE 或 BE 后,只是保证了 FE 或 BE 自身的 IP 进行了正确的绑定。而在使用 ADD BACKEND 或 ADD FRONTEND 语句中,也需要指定和 priority_networks 配置匹配的 IP,不然集群无法诞生。例如:
BE 的配置为:priority_networks=10.1.3.0/24
然则在 ADD BACKEND 时使用的是:ALTER SYSTEM ADD BACKEND “192.168.0.1:9050”;
则 FE 和 BE 将无法浅近通讯。
这时,必须 DROP 掉这个添加造作的 BE,再利用用正确的 IP 奉行 ADD BACKEND。
FE 同理。
BROKER 现时莫得,也不需要 priority_networks 这个选项。Broker 的管事默许绑定在 0.0.0.0 上。只需在 ADD BROKER 时,奉行正确可拜访的 BROKER IP 即可。
表名大小写明锐性建树
doris默许为表名大小写明锐,如有表名大小写不解锐的需求需在集群运行化时进行建树。表名大小写明锐性在集群运行化完成后不可再修改。
详备参见 变量 中对于lower_case_table_names变量的先容。
3.2、编译
装置Doris,需要先通过源码编译,主要有两种方式:使用Docker开采镜像编译(推选)、顺利编译。顺利编译的方式,不错参考官网:https://doris.apache.org/zh-CN/installing/compilation.html
3.2.1、装置Docker环境
1)Docker要求CentOS系统的内核版块高于3.10,当先稽查系统内核版块是否缓和
uname -r
2)使用root权限登录系统,确保yum包更新到最新
sudo yum update -y
3)假如装置过旧版块,先卸载旧版块
cable av 国产sudo yum remove docker docker-common docker-selinux docker-engine
4)装置yum-util用具包和devicemapper驱动依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
5)建树yum源(加速yum下载速率)
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
如果相接超时,不错使用alibaba的镜像源:
sudo yum-config-manager --add-repo
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
6)稽查统共仓库中统共docker版块,并遴荐特定版块装置,一般可顺利装置最新版
yum list docker-ce --showduplicates | sort -r
7)装置docker
(1)装置最新自若版块的方式:
sudo yum install docker-ce -y #装置的是最新自若版块,因为repo中默许只开启stable仓库
(2)装置指定版块的方式:
sudo yum install -y
#例如:
sudoyum install docker-ce-20.10.11.ce -y
8)启动并加入开机启动
sudo systemctl start docker #启动
docker sudo systemctl enable docker #加入开机自启动
9)稽查Version,考证是否装置顺利
docker version
若出现Client和Server两部天职容,则讲授装置顺利。
3.2.2、使用Docker 开采镜像编译
1)下载源码并解压
通过wget下载(或者手动上传下载好的压缩包)。
wget
https://dist.apache.org/repos/dist/dev/incubator/doris/0.15/0.15.0-rc04/apache-doris-0.15.0-incubating-src.tar.gz
解压到/opt/software/
tar -zxvf apache-doris-0.15.0-incubating-src.tar.gz -C /opt/software
2)下载 Docker 镜像
docker pull apache/incubator-doris:build-env-for-0.15.0
不错通过以下号令稽查镜像是否下载完成。
docker images
3)挂载腹地目次运行镜像
以挂载腹地 Doris 源码目次的方式运行镜像,这么编译的产出二进制文献会存储在宿主
机中,不会因为镜像退出而隐藏。同期将镜像中 maven 的 .m2 目次挂载到宿主机目次,以
庄重每次启动镜像编译时,重复下载 maven 的依赖库。
docker run -it
-v /opt/software/.m2:/root/.m2
-v /opt/software/apache-doris-0.15.0-incubating-src/:/root/apachedoris-0.15.0-incubating-src/
\ apache/incubator-doris:build-env-for-0.15.0
4)切换到 JDK 8
alternatives --set java java-1.8.0-openjdk.x86_64
alternatives --set javac java-1.8.0-openjdk.x86_64
export JAVA_HOME=/usr/lib/jvm/java-1.8.0
5)准备 Maven 依赖
编译经由会下载好多依赖,不错将咱们准备好的 doris-repo.tar.gz 解压到 Docker 挂载的
对应目次,来幸免下载依赖的经由,加速编译。
tar -zxvf doris-repo.tar.gz -C /opt/software
也不错通过指定阿里云镜像仓库来加速下载:
vim /opt/software/apache-doris-0.15.0-incubating-src/fe/pom.xml在标签下添加: aliyun http://maven.aliyun.com/nexus/content/groups/public/vim /opt/software/apache-doris-0.15.0-incubating-src/be/pom.xml 在标签下添加: aliyun http://maven.aliyun.com/nexus/content/groups/public/
6)编译 Doris
sh build.sh
如果是第一次使用 build-env-for-0.15.0 或之后的版块,第一次编译的时候要使用如下号令:
sh build.sh --clean --be --fe --ui
因为 build-env-for-0.15.0 版块镜像升级了 thrift(0.9 -> 0.13),需要通过–clean 号令强制
使用新版块的 thrift 生成代码文献,不然会出现不兼容的代码。
3.3、集群部署
主机 1主机 2主机 3
FE(LEADER)
FE(FOLLOWER)
FE(OBSERVER)
BE
BE
BE
BROKER
BROKER
BROKER
分娩环境提议 FE 和 BE 分开。
3.3.1、创建目次并拷贝编译后的文献
1)创建目次并拷贝编译后的文献
mkdir /opt/module/apache-doris-0.15.0 cp -r
/opt/software/apache-doris-0.15.0-incubating-src/output
/opt/module/apache-doris-0.15.0
2)修改可掀开文献数(每个节点)
sudo vim /etc/security/limits.conf
soft nofile 65535
hard nofile 65535
soft nproc 65535
hard nproc 65535
重启遥远收效,也不错用 ulimit -n 65535 临时收效。
3.3.2、部署 FE 节点
1)创建 fe 元数据存储的目次
mkdir /opt/module/apache-doris-0.15.0/doris-meta
2)修改 fe 的配置文献
vim /opt/module/apache-doris-0.15.0/fe/conf/fe.conf
#配置文献中指定元数据旅途: meta_dir = /opt/module/apache-doris-0.15.0/doris-meta
#修改绑定 ip(每台机器修改成我方的 ip) priority_networks = 192.168.8.101/24
属目:
⚫ 分娩环境热烈提议单独指定目次不要放在 Doris 装置目次下,最佳是单独的磁盘(如果有 SSD 最佳)。
⚫ 如果机器有多个 ip, 比如内网外网, 臆造机 docker 等, 需要进行 ip 绑定,才能正确识
别。
⚫ JAVA_OPTS 默许 java 最大堆内存为 4GB,提议分娩环境调整至 8G 以上。
3)启动 hadoop1 的 FE
/opt/module/apache-doris-0.15.0/fe/bin/start_fe.sh --daemon
3.3.3、配置 BE 节点
1)分发 BE
scp -r /opt/module/apache-doris-0.15.0/be hadoop2:/opt/module scp -r
/opt/module/apache-doris-0.15.0/be hadoop3:/opt/module
2)创建 BE 数据存放目次(每个节点)
mkdir /opt/module/apache-doris-0.15.0/doris-storage1 mkdir
/opt/module/apache-doris-0.15.0/doris-storage2
3)修改 BE 的配置文献(每个节点)
vim /opt/module/apache-doris-0.15.0/be/conf/be.conf
#配置文献中指定数据存放旅途: storage_root_path = /opt/module/apache-doris-0.15.0/dorisstorage1;/opt/module/apache-doris-0.15.0/doris-storage2
#修改绑定 ip(每台机器修改成我方的 ip) priority_networks = 192.168.8.101/24
属目:
⚫ storage_root_path 默许在 be/storage 下,需要手动创建该目次。多个旅途之间使用英文状
态的分号;分隔(临了一个目次后不要加)。
⚫ 不错通过旅途区别存储目次的介质,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
⚫ 如果机器有多个 IP, 比如内网外网, 臆造机 docker 等, 需要进行 IP 绑定,才能正确识别。
3.3.4、在 FE 中添加统共 BE 节点
BE 节点需要先在 FE 中添加,才可加入集群。不错使用 mysql-client 相接到 FE。
1)装置 MySQL Client
(1)创建目次
mkdir /opt/software/mysql-client/
(2)上传磋议以下三个 rpm 包到/opt/software/mysql-client/
➢ mysql-community-client-5.7.28-1.el7.x86_64.rpm
➢ mysql-community-common-5.7.28-1.el7.x86_64.rpm
➢ mysql-community-libs-5.7.28-1.el7.x86_64.rpm
(3)查验现时系统是否装置过 MySQL
sudo rpm -qa|grep mariadb
#如果存在,先卸载
sudo rpm -e --nodeps mariadb mariadb-libs mariadb-server
(4)装置
rpm -ivh /opt/software/mysql-client/*
2)使用 MySQL Client 相接 FE
mysql -h hadoop1 -P 9030 -uroot
默许 root 无密码,通过以下号令修改 root 密码。
SET PASSWORD FOR 'root’ = PASSWORD('000000’);
3)添加 BE
ALTER SYSTEM ADD BACKEND “hadoop1:9050”;
ALTER SYSTEM ADD BACKEND “hadoop2:9050”;
ALTER SYSTEM ADD BACKEND “hadoop3:9050”;
4)稽查 BE 景况
SHOW PROC '/backends’;
3.3.5、启动 BE
1)启动 BE(每个节点)
/opt/module/apache-doris-0.15.0/be/bin/start_be.sh --daemon
2)稽查 BE 景况
mysql -h hadoop1 -P 9030 -uroot -p
SHOW PROC '/backends’;
Alive 为 true 示意该 BE 节点存活。
3.3.6、部署 FS_Broker(可选)
Broker 以插件的神色,独处于 Doris 部署。如果需要从第三方存储系统导入数据,需要部署相应的 Broker,默许提供了读取 HDFS、百度云 BOS 及 Amazon S3 的 fs_broker。fs_broker 是无景况的,提议每一个 FE 和 BE 节点齐部署一个 Broker。
1)编译 FS_BROKER 并拷贝文献
(1)插足源码目次下的 fs_brokers 目次,使用 sh build.sh 进行编译
(2)拷贝源码 fs_broker 的 output 目次下的相应 Broker 目次到需要部署的统共节点上虎牙 裸舞,更名为: apache_hdfs_broker。提议和 BE 或者 FE 目次保捏同级。
方法同 2.2。
2)启动 Broker
/opt/module/apache-doris-0.15.0/apache_hdfs_broker/bin/start_broker.sh
–daemon
3)添加 Broker
要让 Doris 的 FE 和 BE 知说念 Broker 在哪些节点上,通过 sql 号令添加 Broker 节
点列表。
(1)使用 mysql-client 相接启动的 FE,奉行以下号令:
mysql -h hadoop1 -P 9030 -uroot -p
ALTER SYSTEM ADD BROKER broker_name “hadoop1:8000”,“hadoop2:8000”,“hadoop3:8000”;
其中 broker_host 为 Broker 场地节点 ip;broker_ipc_port 在 Broker 配置文献中的
conf/apache_hdfs_broker.conf。
4)稽查 Broker 景况
使用 mysql-client 相接任一已启动的 FE,奉行以下号令稽查 Broker 景况:
SHOW PROC “/brokers”;
注:在分娩环境中,统共实例齐应使用守护进程启动,以保证进程退出后,会被自动拉
起,如 Supervisor(opens new window)。如需使用守护进程启动,在 0.9.0 及之前版块中,
需要修改各个 start_xx.sh 剧本,去掉临了的 & 标志。从 0.10.0 版块动手,顺利调用 sh
start_xx.sh 启动即可。
3.4、扩容和缩容
Doris 不错很粗拙的扩容和缩容 FE、BE、Broker 实例。
3.4.1 FE 扩容和缩容
不错通过将 FE 扩容至 3 个以上节点来已矣 FE 的高可用。
1)使用 MySQL 登录客户端后,不错使用 sql 号令稽查 FE 景况,目下就一台 FE
mysql -h hadoop1 -P 9030 -uroot -p
SHOW PROC '/frontends’;
也不错通过页面拜访进行监控,拜访 8030,账户为 root,密码默许为空无谓填写。
2)增多 FE 节点
FE 分为 Leader,Follower 和 Observer 三种变装。 默许一个集群,只可有一个 Leader,不错有多个 Follower 和 Observer。其中 Leader 和 Follower 构成一个 Paxos 遴荐组,如果Leader 宕机,则剩下的 Follower 会自动选出新的 Leader,保证写入高可用。Observer 同步Leader 的数据,然则不参加选举。
如果只部署一个 FE,则 FE 默许等于 Leader。在此基础上,不错添加若干 Follower 和Observer。
ALTER SYSTEM ADD FOLLOWER “hadoop2:9010”;
ALTER SYSTEM ADD OBSERVER “hadoop3:9010”;
3)配置及启动 Follower 和 Observer
第一次启动时,启动号令需要添加参–helper leader 主机: edit_log_port:
(1)分发 FE,修改 FE 的配置(同 2.4.2)
scp -r /opt/module/apache-doris-0.15.0/fe hadoop2:/opt/module/
apache-doris-0.15.0
scp -r /opt/module/apache-doris-0.15.0/fe hadoop3:/opt/module/
apache-doris-0.15.0
(2)在 hadoop2 启动 Follower
/opt/module/apache-doris-0.15.0/fe/bin/start_fe.sh --helper
hadoop1:9010 --daemon
(3)在 hadoop3 启动 Observer
/opt/module/apache-doris-0.15.0/fe/bin/start_fe.sh --helper
hadoop1:9010 --daemon
4)稽查运功绩态
使用 mysql-client 相接到任一已启动的 FE。
SHOW PROC '/frontends’;
5)删除 FE 节点号令
ALTER SYSTEM DROP FOLLOWER[OBSERVER] “fe_host:edit_log_port”;
属目:删除 Follower FE 时,确保最终剩余的 Follower(包括 Leader)节点为奇数。
3.4.2 BE 扩容和缩容
1)增多 BE 节点
在 MySQL 客户端,通过 ALTER SYSTEM ADD BACKEND 号令增多 BE 节点。
2)DROP 方式删除 BE 节点(不推选)
ALTER SYSTEM DROP BACKEND “be_host:be_heartbeat_service_port”;
属目:DROP BACKEND 会顺利删除该 BE,何况其上的数据将不成再复原!!!是以咱们热烈不推选使用 DROP BACKEND 这种方式删除 BE 节点。当你使用这个语句时,会有对应的防误操作辅导。
3)DECOMMISSION 方式删除 BE 节点(推选)
ALTER SYSTEM DECOMMISSION BACKEND
“be_host:be_heartbeat_service_port”;
⚫ 该号令用于安全删除 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 再行进行负载平衡。
3.4.3 Broker 扩容缩容
Broker 实例的数目莫得硬性要求。世俗每台物理机部署一个即可。Broker 的添加和删除不错通过以下号令完成:
ALTER SYSTEM ADD BROKER broker_name “broker_host:broker_ipc_port”;
ALTER SYSTEM DROP BROKER broker_name “broker_host:broker_ipc_port”;
ALTER SYSTEM DROP ALL BROKER broker_name;
Broker 是无景况的进程,不错精真金不怕火启停。天然,住手后,正在其上运行的功课会失败,重试即可。
4、数据表的基本使用
4.1、创建用户和数据库
1)创建test用户
mysql -h hadoop1 -P 9030 -uroot -p
create user 'test’ identified by 'test’;
2)创建数据库
create database test_db;
3)用户授权
grant all on test_db to test;
4.2、Doris中数据表的基本想法
在Doris中,数据齐以关连表(Table)的神色进行逻辑上的形容。
4.2.1、Row&Column
一张表包含行(Row)和列(Column)。Row 即用户的一瞥数据。Column 用于形容一瞥数据中不同的字段。
在默许的数据模子中,Column 只分为排序列和非排序列。存储引擎会按照排序列对数据进行排序存储,并诞生零散索引,以便在排序数据上进行快速查找。
而在团员模子中,Column 不错分为两大类:Key 和 Value。从业务角度看,Key 和Value 不错分别对应维度列和筹备列。从团员模子的角度来说,Key 列调换的行,会团员成一瞥。其中 Value 列的团员方式由用户在建表时指定。
4.2.2、Partition&Tablet
在 Doris 的存储引擎中,用户数据当先被区分红若干个分区(Partition),区分的规则世俗是按照用户指定的分区列进行范围区分,比如按期间区分。而在每个分区内,数据被进一
步的按照 Hash 的方式分桶,分桶的规则是要找用户指定的分桶列的值进行 Hash 后分桶。每个分桶等于一个数据分片(Tablet),亦然数据区分的最小逻辑单元。
Tablet 之间的数据是莫得杂乱的,独处存储的。Tablet 亦然数据出动、复制等操作的最小物理存储单元。
Partition 不错视为是逻辑上最小的经管单元。数据的导入与删除,齐不错或仅能针对一个 Partition 进行。
4.3、建示意例
4.3.1、建表语法
使用 CREATE TABLE 号令诞生一个表(Table)。更多详备参数不错稽查:
help create table;
建表语法:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [database.]table_name
(column_definition1[, column_definition2, …]
[, index_definition1[, index_definition12,]])
[ENGINE = [olap|mysql|broker|hive]]
[key_desc]
[COMMENT “table comment”];
[partition_desc]
[distribution_desc]
[rollup_index]
[PROPERTIES (“key”=“value”, …)]
[BROKER PROPERTIES (“key”=“value”, …)];
Doris建表是一个同步号令,号令复返顺利,即示意建表顺利。
Doris 救支援援单分区和复合分区两种建表方式。
1)复合分区:既有分区也有分桶
第一级称为 Partition,即分区。用户不错指定某一维度列行为分区列(现时只救援整型和时刻类型的列),并指定每个分区的取值范围。
第二级称为 Distribution,即分桶。用户不错指定一个或多个维度列以及桶数对数据进行 HASH 漫步。
2)单分区:只作念 HASH 漫步,即只分桶。
4.3.2、字段类型
字段类型名类型字节单元长度
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 列和分区、分桶列
属目:团员模子在界说字段类型后,不错指定字段的 agg_type 团员类型,如果不指定,则该列为 key 列。不然,该列为value 列, 类型包括:SUM、MAX、MIN、REPLACE。
4.3.3、Doris建示意例
4.3.3.1、Range PartitionCREATE TABLE IF NOT EXISTS example_db.expamle_range_tbl ( `user_id` LARGEINT NOT NULL COMMENT "用户 id", `date` DATE NOT NULL COMMENT "数据灌入日历时刻", `timestamp` DATETIME 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 "用户最小停留时刻" ) ENGINE=OLAP AGGREGATE KEY(`user_id`,`date`,`timestamp`,`city`,`age`,`sex`) partition by range(`date`) ( PARTITION `p201701` VALUES LESS THAN ("2017-02-01"), PARTITION `p201702` VALUES LESS THAN ("2017-03-01"), PARTITION `p201703` VALUES LESS THAN ("2017-04-01") ) DISTRIBUTED BY HASH(`user_id`) BUCKETS 16 PROPERTIES ( "replication_num" = "3", "storage_medium" = "SSD", "storage_cooldown_time" = "2018-01-01 12:00:00" )
4.3.3.2、 List PartitionCREATE TABLE IF NOT EXISTS example_db.expamle_list_tbl ( `user_id` LARGEINT NOT NULL COMMENT "用户 id", `date` DATE NOT NULL COMMENT "数据灌入日历时刻", `timestamp` DATETIME 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 "用户最小停留时 间" ) ENGINE=olap AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`) PARTITION BY LIST(`city`) ( PARTITION `p_cn` VALUES IN ("Beijing", "Shanghai", "Hong Kong"), PARTITION `p_usa` VALUES IN ("New York", "San Francisco"), PARTITION `p_jp` VALUES IN ("Tokyo") ) DISTRIBUTED BY HASH(`user_id`) BUCKETS 16 PROPERTIES ( "replication_num" = "3", "storage_medium" = "SSD", "storage_cooldown_time" = "2018-01-01 12:00:00" );
4.3.4、数据区分
4.3.4.1、列界说
以 AGGREGATE KEY 数据模子为例进行阐扬。更多数据模子参阅 Doris 数据模子。
列的基本类型,不错通过在 mysql-client 中奉行 HELP CREATE TABLE; 稽查。
AGGREGATE KEY 数据模子中,统共莫得指定团员方式(SUM、REPLACE、MAX、
MIN)的列视为 Key 列。而其余则为 Value 列。
界说列时,可参照如下提议:
➢ Key 列必须在统共 Value 列之前。
➢ 尽量遴荐整型类型。因为整型类型的猜想和查找相比效力远高于字符串。
➢ 对于不同长度的整型类型的遴荐原则,受命够用即可。
➢ 对于 VARCHAR 和 STRING 类型的长度,受命 够用即可。
➢ 统共列的总字节长度(包括 Key 和 Value)不成进步 100KB。
4.3.4.2、分区与分桶
Doris 救援两层的数据区分。第一层是 Partition,救援 Range 和 List 的区分方式。第二层是 Bucket(Tablet),仅救援 Hash 的区分方式。
也不错仅使用一层分区。使用一层分区时,只救援 Bucket 区分。
4.3.4.2.1、Partition
➢ Partition 列不错指定一列或多列。分区类必须为 KEY 列。多列分区的使用方式在后头先容。
➢ 无论分区列是什么类型,在写分区值时,齐需要加双引号。
➢ 分区数目表面上莫得上限。
➢ 当不使用 Partition 建表时,系统会自动生成一个和表名同名的,全值范围的
Partition。该 Partition 对用户不可见,何况不可改变。
1) Range 分区
分区列世俗为时刻列,以粗拙的经管新旧数据。不可添加范围相通的分区。
Partition 指定范围的方式
⚫ VALUES LESS THAN (…) 仅指定上界,系统会将前一个分区的上界行为该分区的下界,生成一个左闭右开的区间。分区的删除不会改变已存在分区的范围。删除分区可能出现虚浮。
⚫ VALUES […) 指定同期指定高下界,生成一个左闭右开的区间。
通过 VALUES […) 同期指定高下界相比容易清醒。这里例如阐扬,当使用 VALUES
LESS THAN (…) 语句进行分区的增删操作时,分区范围的变化情况:
(1)如上 expamle_range_tbl 示例,当建表完成后,会自动生成如下 3 个分区:
p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201703: [2017-03-01, 2017-04-01)
(2)增多一个分区 p201705 VALUES LESS THAN (“2017-06-01”),分区终结如下:
p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201703: [2017-03-01, 2017-04-01)
p201705: [2017-04-01, 2017-06-01)
(3)此时删除分区 p201703,则分区终结如下:
p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201705: [2017-04-01, 2017-06-01)
属目到 p201702 和 p201705 的分区范围并莫得发生变化,而这两个分区之间,出现了一个虚浮:[2017-03-01, 2017-04-01)。即如果导入的数据范围在这个虚浮范围内,是无法导入的。
(4)延续删除分区 p201702,分区终结如下:
p201701: [MIN_VALUE, 2017-02-01)
p201705: [2017-04-01, 2017-06-01)
虚浮范围变为:[2017-02-01, 2017-04-01)
(5)当今增多一个分区 p201702new VALUES LESS THAN (“2017-03-01”),分区终结如下:
p201701: [MIN_VALUE, 2017-02-01)
p201702new: [2017-02-01, 2017-03-01)
p201705: [2017-04-01, 2017-06-01)
不错看到虚浮范围减轻为:[2017-03-01, 2017-04-01)
(6)当今删除分区 p201701,并添加分区 p201612 VALUES LESS THAN (“2017-01-01”),
分区终结如下:
p201612: [MIN_VALUE, 2017-01-01)
p201702new: [2017-02-01, 2017-03-01)
p201705: [2017-04-01, 2017-06-01)
即出现了一个新的虚浮:[2017-01-01, 2017-02-01)
2)List 分区
分 区 列支 捏 BOOLEAN, TINYINT, SMALLINT, INT, BIGINT, LARGEINT, DATE,
DATETIME, CHAR, VARCHAR 数据类型,分区值为陈设值。只消当数据为办法分区陈设值其中之一时,才不错射均分区。不可添加范围相通的分区。
Partition 救援通过 VALUES IN (…) 来指定每个分区包含的陈设值。底下通过示例阐扬,
进行分区的增删操作时,分区的变化。
(1)如上 example_list_tbl 示例,当建表完成后,会自动生成如下 3 个分区:
p_cn: (“Beijing”, “Shanghai”, “Hong Kong”)
p_usa: (“New York”, “San
Francisco”) p_jp: (“Tokyo”)
(2)增多一个分区 p_uk VALUES IN (“London”),分区终结如下:
p_cn: (“Beijing”, “Shanghai”, “Hong Kong”)
p_usa: (“New York”, “San
Francisco”) p_jp: (“Tokyo”)
p_uk: (“London”)
(3)删除分区 p_jp,分区终结如下:
p_cn: (“Beijing”, “Shanghai”, “Hong Kong”)
p_usa: (“New York”, “San
Francisco”) p_uk: (“London”)
4.3.4.2.2、Bucket
(1)如果使用了 Partition,则 DISTRIBUTED … 语句形容的是数据在各个分区内的区分规则。如果不使用 Partition,则形容的是对统共这个词表的数据的区分规则。
(2)分桶列不错是多列,但必须为 Key 列。分桶列不错和 Partition 列调换或不同。
(3)分桶列的遴荐,是在 查询隐隐 和 查询并发 之间的一种衡量:
① 如果遴荐多个分桶列,则数据漫步更均匀。
如果一个查询条目不包含统共分桶列的等值条目,那么该查询会触发统共分桶同期扫描,这么查询的隐隐会增多,单个查询的延长随之缩小。这个方式符合大隐隐低并发的查询场景。
② 如果仅遴荐一个或少数分桶列,则对应的点查询不错仅触发一个分桶扫描。
此时,当多个点查询并发时,这些查询有较大的概率分别触发不同的分桶扫描,各个查询之间的 IO 影响较小(尤其当不同桶漫步在不同磁盘上时),是以这种方式符合高并发的点查询场景。
(4)分桶的数目表面上莫得上限。
4.3.4.2.3、使用复合分区的场景
以下场景推选使用复合分区
(1)偶然刻维度或近似带有有序值的维度,不错以这类维度列行为分区列。分区粒度不错凭据导入频次、分区数据量等进行评估。
(2)历史数据删除需求:如有删除历史数据的需求(比如仅保留最近 N 天的数据)。
使用复合分区,不错通过删除历史分区来达到目的。也不错通过在指定分区内发送 DELETE 语句进行数据删除。
(3)经管数据歪斜问题:每个分区不错单独指定分桶数目。如按天分区,当每天的数据量各别很大时,不错通过指定分区的分桶数,合理区分不同分区的数据,分桶列提议遴荐区分度大的列。
4.3.4.2.4、多列分区
4.3.4.3、PROPERTIES
在建表语句的临了 PROPERTIES 中,不错指定以下两个参数:
4.3.4.3.1 replication_num
每个 Tablet 的副本数目。默许为 3,提议保捏默许即可。在建表语句中,统共 Partition 中的 Tablet 副本数目融合指定。而在增多新分区时,不错单独指定新分区中 Tablet 的副本数目。
副本数目不错在运行时修改。热烈提议保捏奇数。
最大副本数目取决于集群中独处 IP 的数目(属目不是 BE 数目)。Doris 中副本漫步的原则是,不允许兼并个 Tablet 的副本漫步在兼并台物理机上,而识别物理机即通过 IP。是以,即使在兼并台物理机上部署了 3 个或更多 BE 实例,如果这些 BE 的 IP 调换,则依然只可建树副本数为 1。
对于一些小,何况更新不频繁的维度表,不错探讨建树更多的副本数。这么在 Join 查询时,不错有更大的概率进行腹地数据 Join。
4.3.4.3.2、storage_medium & storage_cooldown_time
BE 的数据存储目次不错显式的指定为 SSD 或者 HDD(通过 .SSD 或者 .HDD 后缀区分)。建表时,不错融合指定统共 Partition 运行存储的介质。属目,后缀作用是显式指定磁盘介质,而不会查验是否与履行介质类型相符。
默许运行存储介质可通过 fe 的配置文献 fe.conf 中指定 default_storage_medium=xxx,如果莫得指定,则默许为 HDD。如果指定为 SSD,则数据运行存放在 SSD 上。
如果莫得指定 storage_cooldown_time,则默许 30 天后,数据会从 SSD 自动移动到 HDD 上。如果指定了 storage_cooldown_time,则在到达storage_cooldown_time 时刻后,数据才会移动。
属目,当指定 storage_medium 时,如果 FE 参数enable_strict_storage_medium_check 为False 该参数只是一个“极力而为”的建树。即使集群内莫得建树 SSD 存储介质,也不会报错,而是自动存储在可用的数据目次中。 相似,如果 SSD 介质不可拜访、空间不及,齐可能导致数据运行顺利存储在其他可用介质上。而数据到期移动到 HDD 时,如果 HDD 介质不 可 访 问 、 空 间 不 足 , 也 可 能 迁 移 失 败 ( 但 是 会 不 断 尝 试 ) 。 如 果 FE 参 数enable_strict_storage_medium_check 为 True 则当集群内莫得建树 SSD 存储介质时,会报错Failed to find enough host in all backends with storage medium is SSD。
4.3.4.4、ENGINE
本示例中,ENGINE 的类型是 olap,即默许的 ENGINE 类型。在 Doris 中,只消这个ENGINE 类型是由 Doris 防御数据经管和存储的。其他 ENGINE 类型,如 mysql、broker、es 等等,本色上只是对外部其他数据库或系统中的表的映射,以保证 Doris 不错读取这些数据。而 Doris 本人并不创建、经管和存储任何非 olap ENGINE 类型的表和数据。
4.3.5 数据模子
Doris 的数据模子主要分为 3 类:Aggregate、Uniq、Duplicate
4.3.5.1 Aggregate 模子
表中的列按照是否建树了 AggregationType,分为 Key(维度列)和 Value(筹备列)。莫得建树 AggregationType 的称为 Key,建树了 AggregationType 的称为 Value。
当咱们导入数据时,对于 Key 列调换的行会团员成一瞥,而 Value 列会按照建树的AggregationType 进行团员。AggregationType 目下有以下四种团员方式:
➢ SUM:乞降,多行的 Value 进行累加。
➢ REPLACE:替代,下一批数据中的 Value 会替换之前导入过的行中的 Value。
REPLACE_IF_NOT_NULL :当遭受 null 值则不更新。
➢ MAX:保留最大值。
➢ MIN:保留最小值。
数据的团员,在 Doris 中有如下三个阶段发生:
(1)每一批次数据导入的 ETL 阶段。该阶段会在每一批次导入的数据里面进行团员。
(2)底层 BE 进行数据 Compaction 的阶段。该阶段,BE 会对已导入的不同批次的数据进行进一步的团员。
(3)数据查询阶段。在数据查询时,对于查询触及到的数据,会进行对应的团员。数据在不同期间,可能团员的程度不一致。比如一批数据刚导入时,可能还未与之前已存在的数据进行团员。然则对于用户而言,用户只可查询到团员后的数据。即不同的团员程度对于用户查询而言是透明的。用户需恒久觉得数据以最终的完成的团员程度存在,而不应假定某些团员还未发生。(可参阅团员模子的局限性一节获取更多笃定。)
3.5.1.1 示例一:导入数据团员
1)建表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 "用户临了一次拜访时刻", `last_visit_date_not_null` DATETIME REPLACE_IF_NOT_NULL 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;
2)插入数据insert into test_db.example_site_visit values(10000,'2017-10-01','北京',20,0,'2017-10-01 06:00:00','2017-10-01 06:00:00',20,10,10),(10000,'2017-10-01','北京',20,0,'2017-10-01 07:00:00','2017-10-01 07:00:00',15,2,2),(10001,'2017-10-01','北京',30,1,'2017-10-01 17:05:45','2017-10-01 07:00:00',2,22,22),(10002,'2017-10-02',' 上 海 ',20,1,'2017-10-02 12:59:12',null,200,5,5),(10003,'2017-10-02','广州',32,0,'2017-10-02 11:20:00','2017-10-02 11:20:00',30,11,11),(10004,'2017-10-01','深圳',35,0,'2017-10-01 10:00:15','2017-10-01 10:00:15',100,3,3),(10004,'2017-10-03','深圳',35,0,'2017-10-03 10:20:22','2017-10-0310:20:22',11,6,6);
属目:Insert into 单条数据这种操作在 Doris 里只可演示不成在分娩使用,会激发写梗阻.
3)稽查表select * from test_db.example_site_visit;
不错看到,用户 10000 只剩下了一瞥团员后的数据。而其余用户的数据和原始数据保捏一致。经过团员,Doris 中最终只会存储团员后的数据。换句话说,即明细数据会丢失,用户不梗概再查询到团员前的明细数据了。
4.3.5.1.2 示例二:保留明细数据
1)建表CREATE TABLE IF NOT EXISTS test_db.example_site_visit2 ( `user_id` LARGEINT NOT NULL COMMENT "用户 id", `date` DATE NOT NULL COMMENT "数据灌入日历时刻", `timestamp` DATETIME 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`, `timestamp`, `city`, `age`, `sex`) DISTRIBUTED BY HASH(`user_id`) BUCKETS 10;
2)插入数据insert into test_db.example_site_visit2 values(10000,'2017-10- 01','2017-10-01 08:00:05',' 北 京 ',20,0,'2017-10-01 06:00:00',20,10,10),(10000,'2017-10-01','2017-10-01 09:00:05','北京',20,0,'2017-10-01 07:00:00',15,2,2),(10001,'2017-10-01','2017-10-01 18:12:10','北京',30,1,'2017-10-01 17:05:45',2,22,22),(10002,'2017-10-02','2017-10-02 13:10:00','上海',20,1,'2017-10-02 12:59:12',200,5,5),(10003,'2017-10-02','2017-10-02 13:15:00','广州',32,0,'2017-10-02 11:20:00',30,11,11),(10004,'2017-10-01','2017-10-01 12:12:48','深圳',35,0,'2017-10-01 10:00:15',100,3,3),(10004,'2017-10-03','2017-10-03 12:38:20','深圳',35,0,'2017-10-03 10:20:22',11,6,6);
3)稽查表
select * from test_db.example_site_visit2;
存储的数据,和导入数据彻底一样,莫得发生任何团员。这是因为,这批数据中,因为加入了 timestamp 列,统共行的 Key 齐不彻底调换。也等于说,只消保证导入的数据中,每一瞥的 Key 齐不彻底调换,那么即使在团员模子下,Doris 也不错保存完竣的明细数据。
4.3.5.1.3 示例三:导入数据与已独特据团员
1)往实例一中延续插入数据insert into test_db.example_site_visit values(10004,'2017-10-03',' 深圳',35,0,'2017-10-03 11:22:00',null,44,19,19),(10005,'2017-10-03','长沙',29,1,'2017-10-03 18:11:02','2017-10-03 18:11:02',3,1,1);
2)稽查表
select * from test_db.example_site_visit;
不错看到,用户 10004 的已独特据和新导入的数据发生了团员。同期新增了 10005 用户的数据。
4.3.5.2 Uniq 模子
在某些多维分析场景下,用户更关注的是若何保证 Key 的惟一性,即若何获取 Primary Key 惟一性阻抑。因此,咱们引入了 Uniq 的数据模子。该模子本色上是团员模子的一个特例,亦然一种简化的表结构示意方式。
1)建表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;
2)插入数据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');
3)查询表
select * from test_db.user;
Uniq 模子彻底不错用团员模子中的 REPLACE 方式替代。其里面的已矣方式和数据存储方式也彻底一样.
4.3.5.3 Duplicate 模子
在某些多维分析场景下,数据既莫得主键,也莫得团员需求。Duplicate 数据模子不错缓和这类需求。数据彻底按照导入文献中的数据进行存储,不会有任何团员。即使两行数据彻底调换,也齐会保留。 而在建表语句中指定的 DUPLICATE KEY,只是用来指明底层数据按照那些列进行排序。
1)建表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;
2)插入数据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');
3)稽查表
select * from test_db.example_log;
4.3.5.4 数据模子的遴荐提议
因为数据模子在建表时就如故确定,且无法修改。是以,遴荐一个合适的数据模子尽头迫切。
(1)Aggregate 模子不错通过预团员,极地面缩小团员查询时所需扫描的数据量和查询的猜想量,尽头符合有固定模式的报表类查询场景。然则该模子对 count(*) 查询很不友好。同期因为固定了 Value 列上的团员方式,在进行其他类型的团员查询时,需要探讨语意正确性。
(2)Uniq 模子针对需要惟一主键阻抑的场景,不错保证主键惟一性阻抑。然则无法利用 ROLLUP 等预团员带来的查询上风(因为本色是 REPLACE,莫得 SUM 这种团员方式)。
(3)Duplicate 符合淘气维度的 Ad-hoc 查询。天然相似无法利用预团员的本性,然则不受团员模子的阻抑,不错发达列存模子的上风(只读取磋议列,而不需要读取统共 Key 列)
3.5.5 团员模子的局限性
这里咱们针对 Aggregate 模子(包括 Uniq 模子),来先容下团员模子的局限性。
在团员模子中,模子对外展现的,是最终团员后的数据。也等于说,任何还未团员的数据(比如说两个不同导入批次的数据),必须通过某种方式,以保证对外展示的一致性。咱们例如阐扬。
假定表结构如下:
ColumnNameTypeAggregationTypeComment
user_id
LARGEINT
用户 id
date
DATE
数据灌入日历
cost
BIGINT
SUM
用户总消费
假定存储引擎中有如下两个如故导入完成的批次的数据:
batch 1
user_iddatecost
10001
2017-11-20
50
10002
2017-11-21
39
batch 2
user_iddatecost
10001
2017-11-20
1
10001
2017-11-21
5
10003
2017-11-22
22
不错看到,用户 10001 分属在两个导入批次中的数据还莫得团员。然则为了保证用户只可查询到如下最终团员后的数据:
user_iddatecost
10001
2017-11-20
51
10001
2017-11-21
5
10002
2017-11-21
39
10003
2017-11-22
22
在查询引擎中加入了团员算子,来保证数据对外的一致性。
另外,在团员列(Value)上,奉行与团员类型不一致的团员类查询时,要属目语意。比如咱们在如上示例中奉行如下查询:
SELECT MIN(cost) FROM table;
得到的终结是 5,而不是 1。
同期,这种一致性保证,在某些查询中,会极大的缩小查询效力。
咱们以最基本的 count(*) 查询为例:
SELECT COUNT(*) FROM table;
在其他数据库中,这类查询齐会很快的复返终结。因为在已矣上,咱们不错通过如“导入时对行进行计数,保存 count 的统计信息”,或者在查询时“仅扫描某一列数据,获取 count值”的方式,只需很小的支拨,即可获取查询终结。然则在 Doris 的团员模子中,这种查询支拨尽头大。
上头的例子,select count(*) from table; 的正确终结应该为 4。但如果咱们只扫描 user_id 这一列,如果加上查询时团员,最终得到的终结是 3(10001, 10002, 10003)。而如果不加查询时团员,则得到的终结是 5(两批次一共 5 行数据)。可见这两个终结齐是分歧的。
为高出到正确的终结,咱们必须同期读取 user_id 和 date 这两列的数据,再加上查询时团员,才能复返 4 这个正确的终结。也等于说,在 count() 查询中,Doris 必须扫描统共的AGGREGATE KEY 列(这里等于 user_id 和 date),何况团员后,才能得到语意正确的终结。当团员列绝酌定时,count()查询需要扫描大量的数据。
因此,当业务上有频繁的 count() 查询时,咱们提议用户通过增多一个值恒为 1 的,团员类型为 SUM 的列来模拟 count()。如刚才的例子中的表结构,咱们修改如下:
ColumnNameTypeAggregateTypeComment
user_id
BIGINT
用户 id
date
DATE
数据灌入日历
cost
BIGINT
SUM
用户总消费
count
BIGINT
SUM
用于猜想 count
增多一个 count 列,何况导入数据中,该列值恒为 1。则 select count() from table; 的终结等价于 select sum(count) from table;。此后者的查询效力将远高于前者。不外这种方式也有使用猖狂,等于用户需要自行保证,不会重复导入 AGGREGATE KEY 列齐调换的行。不然,select sum(count) from table; 只可表述原始导入的行数,而不是 select count() from table; 的语义。
另一种方式,等于 将如上的 count 列的团员类型改为 REPLACE,且依然值恒为 1。那么 select sum(count) from table; 和 select count(*) from table; 的终结将是一致的。何况这种方式,莫得导入重复行的猖狂。
4.3.6 动态分区
动态分区是在 Doris 0.12 版块中引入的新功能。旨在对表级别的分区完终身命周期经管(TTL),减少用户的使用包袱。
目下已矣了动态添加分区及动态删除分区的功能。动态分区只救援 Range 分区。
4.3.6.1 旨趣
在某些使用场景下,用户会将表按照天进行分区画分,每天定时奉行例行任务,这时需要使用方手动经管分区,不然可能由于使用方莫得创建分区导致数据导入失败,这给使用方带来了额外的难得资本。
通过动态分区功能,用户不错在建表时设定动态分区的规则。FE 会启动一个后台线程,凭据用户指定的规则创建或删除分区。用户也不错在运行时对现存规则进行变更。
4.3.6.2 使用方式
动态分区的规则不错在建表时指定,或者在运行时进行修改。现时仅救援对单分区列的分区表设定动态分区规则。
建表时指定:CREATE TABLE tbl1 (...) PROPERTIES ( "dynamic_partition.prop1" = "value1", "dynamic_partition.prop2" = "value2", ... )
运行时修改ALTER TABLE tbl1 SET ( "dynamic_partition.prop1" = "value1", "dynamic_partition.prop2" = "value2", ... )
4.3.6.3 动态分区规则参数
4.3.6.3.1 主要参数
动态分区的规则参数齐以 dynamic_partition. 为前缀:
dynamic_partition.enable是否开启动态分区本性,可指定 true 或 false,默许为 true
dynamic_partition.time_unit
动态分区疗养的单元,可指定 HOUR、DAY、WEEK、MONTH。HOUR,后缀形貌为 yyyyMMddHH,分区列数据类型不成为DATE。DAY,后缀形貌为 yyyyMMdd。WEEK,后缀形貌为 yyyy_ww。即现时日历属于这一年的第几周。MONTH,后缀形貌为 yyyyMM。
dynamic_partition.time_zone
动态分区的时区,如果不填写,则默许为现时机器的系统的时区
dynamic_partition.start
动态分区的肇始偏移,为负数。凭据 time_unit 属性的不同,以今日(星期/月)为基准,分区范围在此偏移之前的分区将会被删除。如果不填写默许值为 Interger.Min_VALUE 即-2147483648,即不删除历史分区
dynamic_partition.end
动态分区的终结偏移,为正数。凭据 time_unit 属性的不同,以今日(星期/月)为基准,提前创建对应范围的分区
dynamic_partition.prefix
动态创建的分区名前缀
dynamic_partition.buckets
动态创建的分区所对应分桶数目
dynamic_partition.replication_num
动态创建的分区所对应的副本数目,如果不填写,则默许为该表创建时指定的副本数目。
dynamic_partition.start_day_of_week
当 time_unit 为 WEEK 时,该参数用于指定每周的肇始点。取值为 1 到 7。其中 1 示意周一,7 示意周日。默许为 1,即示意每周以周一为肇始点
dynamic_partition.start_day_of_month
当 time_unit 为 MONTH 时,该参数用于指定每月的肇始日历。取值为 1 到 28。其中 1 示意每月 1 号,28 示意每月 28 号。默许为 1,即示意每月以 1 号位肇始点。暂不救援以 29、30、31 号为肇始日,以幸免因闰年或闰月带来的歧义
4.3.6.3.2 创建历史分区的参数
⚫ dynamic_partition.create_history_partition
默许为 false。当置为 true 时,Doris 会自动创建统共分区,当欲望创建的分区个数大于 max_dynamic_partition_num 值时,操作将被谢却。当不指定 start 属性时,该参数不收效。
⚫ dynamic_partition.history_partition_num
当 create_history_partition 为 true 时,该参数用于指定创建历史分区数目。默许值为 -1, 即未建树。
⚫ dynamic_partition.hot_partition_num
指定最新的几许个分区为热分区。对于热分区,系统会自动建树其 storage_medium 参数为 SSD,何况建树 storage_cooldown_time。
hot_partition_num 是往前 n 天和改日统共分区
咱们例如阐扬。假定今天是 2021-05-20,按天分区,动态分区的属性建树为:
hot_partition_num=2, end=3, start=-3。则系统会自动创建以下分区,何况建树 storage_medium 和 storage_cooldown_time 参数:p20210517 : ["2021-05-17", "2021-05-18") storage_medium=HDD storage_cooldown_time=9999-12-31 23:59:59 p20210518 : ["2021-05-18", "2021-05-19") storage_medium=HDD storage_cooldown_time=9999-12-31 23:59:59 p20210519 : ["2021-05-19", "2021-05-20") storage_medium=SSD storage_cooldown_time=2021-05-21 00:00:00 p20210520 : ["2021-05-20", "2021-05-21") storage_medium=SSD storage_cooldown_time=2021-05-22 00:00:00 p20210521 : ["2021-05-21", "2021-05-22") storage_medium=SSD storage_cooldown_time=2021-05-23 00:00:00 p20210522 : ["2021-05-22", "2021-05-23") storage_medium=SSD storage_cooldown_time=2021-05-24 00:00:00 p20210523 : ["2021-05-23", "2021-05-24") storage_medium=SSD storage_cooldown_time=2021-05-25 00:00:00
⚫ dynamic_partition.reserved_history_periods
需要保留的历史分区的时刻范围。当 dynamic_partition.time_unit 建树为
“DAY/WEEK/MONTH” 时,需要以 [yyyy-MM-dd,yyyy-MM-dd],[…,…] 形貌进行建树。当dynamic_partition.time_unit 建树为 “HOUR” 时,需要以 [yyyy-MM-dd HH:mm:ss,yyyyMM-dd HH:mm:ss],[…,…] 的形貌来进行建树。如果不建树,默许为 “NULL”。
咱们例如阐扬。假定今天是 2021-09-06,按天分类,动态分区的属性建树为:
time_unit=“DAY/WEEK/MONTH”, \ end=3, \ start=-3,
reserved_history_periods=“[2020-06-01,2020-06-20],[2020-10-
31,2020-11-15]”。
则系统会自动保留:
[“2020-06-01”,“2020-06-20”], [“2020-10-31”,“2020-11-15”]
或者
time_unit=“HOUR”, \ end=3, \ start=-3,
reserved_history_periods=“[2020-06-01 00:00:00,2020-06-01 03:00:00]”.
则系统会自动保留:
[“2020-06-01 00:00:00”,“2020-06-01 03:00:00”]
这两个时刻段的分区。其中,reserved_history_periods 的每一个 […,…] 是一双建树项,两者需要同期被建树,且第一个时刻不成大于第二个时刻``。
4.3.6.3.3 创建历史分区规则
假定需要创建的历史分区数目为 expect_create_partition_num,凭据不同的建树具体数目如下:
(1)create_history_partition = true
① dynamic_partition.history_partition_num 未建树,即 -1.
则 expect_create_partition_num = end - start;
② dynamic_partition.history_partition_num 已建树
则 expect_create_partition_num = end - max(start, -histoty_partition_num);
(2)create_history_partition = false
不会创建历史分区,expect_create_partition_num = end - 0;
(3)当 expect_create_partition_num > max_dynamic_partition_num(默许 500)时,谢却创建过多分区。
4.3.6.3.4 创建历史分区例如
假定今天是 2021-05-20,按天分区,动态分区的属性建树为:create_history_partition=true, end=3, start=-3, history_partition_num=1,则系统会自动创建以下分区:
p20210519
p20210520
p20210521
p20210522
p20210523
history_partition_num=5,其余属性与 1 中保捏一直,则系统会自动创建以下分区:
p20210517
p20210518
p20210519
p20210520
p20210521
p20210522
p20210523
history_partition_num=-1 即不建树历史分区数目,其余属性与 1 中保捏一直,则系统
会自动创建以下分区:
p20210517
p20210518
p20210519
p20210520
p20210521
p20210522
p20210523
4.3.6.3.5 属目事项
动 态 分 区 使 用 过 程 中 , 如 果 因 为 一 些 意 外 情 况 导 致 dynamic_partition.start 和
dynamic_partition.end 之间的某些分区丢失,那么现时时刻与 dynamic_partition.end 之间的
丢失分区会被再行创建,dynamic_partition.start 与现时时刻之间的丢失分区不会再行创建。
4.3.6.4 示例
1)创建动态分区表
分区列 time 类型为 DATE,创建一个动态分区规则。按天分区,只保留最近 7 天的分
区,何况事先创建改日 3 天的分区。create table student_dynamic_partition1 (id int, time date, name varchar(50), age int ) duplicate key(id,time) PARTITION BY RANGE(time)() DISTRIBUTED BY HASH(id) buckets 10 PROPERTIES( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "DAY", "dynamic_partition.start" = "-7", "dynamic_partition.end" = "3", "dynamic_partition.prefix" = "p", "dynamic_partition.buckets" = "10", "replication_num" = "1" );
2)稽查动态分区表疗养情况
SHOW DYNAMIC PARTITION TABLES;
⚫ LastUpdateTime: 临了一次修改动态分区属性的时刻
⚫ LastSchedulerTime: 临了一次奉行为态分区疗养的时刻
⚫ State: 临了一次奉行为态分区疗养的景况
⚫ LastCreatePartitionMsg: 临了一次奉行为态添加分区疗养的造作信息
⚫ LastDropPartitionMsg: 临了一次奉行为态删除分区疗养的造作信息
3)稽查表的分区
SHOW PARTITIONS FROM student_dynamic_partition1;
4)插入测试数据,不错沿途顺利(修改成对当令刻)insert into student_dynamic_partition1 values(1,'2022-03-3111:00:00','name1',18); insert into student_dynamic_partition1 values(1,'2022-04-01 11:00:00','name1',18); insert into student_dynamic_partition1 values(1,'2022-04-02 11:00:00','name1',18);
5)建树创建历史分区ALTER TABLE student_dynamic_partition1 SET ("dynamic_partition.create_history_partition" = "true");
稽查分区情况SHOW PARTITIONS FROM student_dynamic_partition1;
6)动态分区表与手动分区表相互移动
对于一个表来说,动态分区和手动分区不错摆脱移动,但二者不成同期存在,有且只消一种景况。
(1)手动分区移动为动态分区
如果一个表在创建时未指定动态分区,不错通过 ALTER TABLE 在运行时修改动态分区磋议属性来滚动为动态分区,具体示例不错通过 HELP ALTER TABLE 稽查。
属目:如果已设定 dynamic_partition.start,分区范围在动态分区肇始偏移之前的历史分区将会被删除。
(2)动态分区移动为手动分区ALTER TABLE tbl_name SET ("dynamic_partition.enable" = "false")
关闭动态分区功能后,Doris 将不再自动经管分区,需要用户手动通过 ALTER TABLE 的方式创建或删除分区。
4.3.7 Rollup
ROLLUP 在多维分析中是“上卷”的兴味,行将数据按某种指定的粒度进行进一步团员。
4.3.7.1 基本想法
在 Doris 中,咱们将用户通过建表语句创建出来的表称为 Base 表(Base Table)。Base 表中保存着按用户建表语句指定的方式存储的基础数据。
在 Base 表之上,咱们不错创建淘气多个 ROLLUP 表。这些 ROLLUP 的数据是基于 Base 表产生的,何况在物理上是独处存储的。
ROLLUP 表的基本作用,在于在 Base 表的基础上,获取更粗粒度的团员数据。
4.3.7.2 Aggregate 和 Uniq 模子中的 ROLLUP
因为 Uniq 只是 Aggregate 模子的一个特例,是以这里咱们不加以区别。
1)以 4.3.5.1.2 中创建的 example_site_visit2 表为例。
(1)稽查表的结构信息desc example_site_visit2 all;
(2)比如需要稽查某个用户的总消费,那么不错诞生一个只消 user_id 和 cost 的 rollupalter table example_site_visit2 add rollup rollup_cost_userid(user_id,cost);
(3)稽查表的结构信息desc example_site_visit2 all;
(4)然后不错通过 explain 稽查奉行筹备,是否使用到了 rollupexplain SELECT user_id, sum(cost) FROM example_site_visit2 GROUP BY user_id;
Doris 会自动射中这个 ROLLUP 表,从而只需扫描极少的数据量,即可完成此次团员查询。
(5)通过号令稽查完成景况SHOW ALTER TABLE ROLLUP;
2)示例 2:获取不同城市,不同庚岁段用户的总消费、最长和最短页面驻留时刻
(1)创建 ROLLUPalter table example_site_visit2 add rollup rollup_city_age_cost_maxd_mind(city,age,cost,max_dwell_time,min_d well_time);
(2)稽查 rollup 使用explain SELECT city, age, sum(cost), max(max_dwell_time), min(min_dwell_time) FROM example_site_visit2 GROUP BY city, age; explain SELECT city, sum(cost), max(max_dwell_time), min(min_dwell_time) FROM example_site_visit2 GROUP BY city; explain SELECT city, age, sum(cost), min(min_dwell_time) FROM example_site_visit2 GROUP BY city, age;
(3)通过号令稽查完成景况SHOW ALTER TABLE ROLLUP;
4.3.7.3 Duplicate 模子中的 ROLLUP
因为 Duplicate 模子莫得团员的语意。是以该模子中的 ROLLUP,如故失去了“上卷”
这一层含义。而只是是行为调整列礼貌,以射中前缀索引的作用。底下详备先容前缀索引,
以及若何使用 ROLLUP 改变前缀索引,以获取更好的查询效力。
4.3.7.3.1 前缀索引
不同于传统的数据库想象,Doris 不救援在职意列上创建索引。Doris 这类 MPP 架构的 OLAP 数据库,世俗齐是通过提高并发,来处理大量数据的。
本色上,Doris 的数据存储在近似 SSTable(Sorted String Table)的数据结构中。该结构是一种有序的数据结构,不错按照指定的列进行排序存储。在这种数据结构上,以排序列行为条目进行查找,会尽头的高效。
在 Aggregate、Uniq 和 Duplicate 三种数据模子中。底层的数据存储,是按照各自建表语句中,AGGREGATE KEY、UNIQ KEY 和 DUPLICATE KEY 中指定的列进行排序存储的。而前缀索引,即在排序的基础上,已矣的一种凭据给定前缀列,快速查询数据的索引方式。
咱们将一瞥数据的前 36 个字节 行为这行数据的前缀索引。当遭受 VARCHAR 类型时,前缀索引会顺利截断。例如阐扬:
1)以下表结构的前缀索引为 user_id(8 Bytes) + age(4 Bytes) + message(prefix 20 Bytes)。
ColumnNameType
user_id
BIGINT
age
INT
message
VARCHAR(100)
max_dwell_time
DATETIME
min_dwell_time
DATETIME
2)以下表结构的前缀索引为 user_name(20 Bytes)。即使莫得达到 36 个字节,因为遭受VARCHAR,是以顺利截断,不再往后延续。
ColumnNameType
user_name
VARCHAR(20)
age
INT
message
VARCHAR(100)
max_dwell_time
DATETIME
min_dwell_time
DATETIME
3)当咱们的查询条目,是前缀索引的前缀时,不错极大的加速查询速率。比如在第一个例子中,咱们奉行如下查询:SELECT * FROM table WHERE user_id=1829239 and age=20;
该查询的效力会远高于如下查询:SELECT * FROM table WHERE age=20;
是以在建表时,正确的遴荐列礼貌,梗概极地面提高查询效力。
4.3.7.3.2 ROLLUP 调整前缀索引
因为建表时如故指定了列礼貌,是以一个表只消一种前缀索引。这对于使用其他不成射中前缀索引的列行为条目进行的查询来说,效力上可能无法缓和需求。因此,咱们不错通过创建 ROLLUP 来东说念主为的调整列礼貌。例如阐扬。
Base 表结构如下:
ColumnNameType
user_id
BIGINT
age
INT
message
VARCHAR(100)
max_dwell_time
DATETIME
min_dwell_time
DATETIME
咱们不错在此基础上创建一个 ROLLUP 表:
ColumnNameType
age
INT
user_id
BIGINT
message
VARCHAR(100)
max_dwell_time
DATETIME
min_dwell_time
DATETIME
不错看到,ROLLUP 和 Base 表的列彻底一样,只是将 user_id 和 age 的礼貌调换了。那么当咱们进行如下查询时:SELECT * FROM table where age=20 and message LIKE "%error%";
会优先遴荐 ROLLUP 表,因为 ROLLUP 的前缀索引匹配度更高。
4.3.7.4 ROLLUP 的几点阐扬
⚫ ROLLUP 最压根的作用是提高某些查询的查询效力(无论是通过团员来减少数据量,如故修改列礼貌以匹配前缀索引)。因此 ROLLUP 的含义如故超出了“上卷”的范围。这亦然为什么在源代码中,将其定名为 Materialized Index(死一火索引)的原因。
⚫ ROLLUP 是从属于 Base 表的,不错看作念是 Base 表的一种赞成数据结构。用户不错在 Base 表的基础上,创建或删除 ROLLUP,然则不成在查询中显式的指定查询某ROLLUP。是否射中 ROLLUP 彻底由 Doris 系统自动决定。
⚫ ROLLUP 的数据是独处物理存储的。因此,创建的 ROLLUP 越多,占用的磁盘空间也就越大。同期对导入速率也会有影响(导入的 ETL 阶段会自动产生统共
ROLLUP 的数据),然则不会缩小查询效力(只会更好)。
⚫ ROLLUP 的数据更新与 Base 表是彻底同步的。用户无需饶恕这个问题。
⚫ ROLLUP 中列的团员方式,与 Base 表彻底调换。在创建 ROLLUP 无需指定,也不成修改。
⚫ 查询能否射中 ROLLUP 的一个必要条目(非充分条目)是,查询所触及的统共列(包括 select list 和 where 中的查询条目列等)齐存在于该 ROLLUP 的列中。不然,查询只可射中 Base 表。
⚫ 某些类型的查询(如 count(*))在职何条目下,齐无法射中 ROLLUP。具体参见接下来的团员模子的局限性一节。
⚫ 不错通过 EXPLAIN your_sql; 号令获取查询奉行筹备,在奉行筹备中,稽查是否射中 ROLLUP。
⚫ 不错通过 DESC tbl_name ALL; 语句裸露 Base 表和统共已创建完成的 ROLLUP。
4.3.8 死一火视图
死一火视图等于包含了查询终结的数据库对象,可能是对而已数据的腹地 copy,也可能是一个表或多表 join 后终结的行或列的子集,也可能是团员后的终结。说白了,等于事先存储查询终结的一种数据库对象。
在 Doris 中的死一火视图,等于查询终结事先存储起来的特殊的表。
死一火视图的出现主若是为了缓和用户,既能对原始明细数据的淘气维度分析,也能快速的对固定维度进行分析查询。
4.3.8.1 适用场景
⚫ 分析需求隐蔽明细数据查询以及固定维度查询两方面。
⚫ 查询仅触及表中的很小一部分列或行。
⚫ 查询包含一些耗时处理操作,比如:时刻很久的团员操作等。
⚫ 查询需要匹配不同前缀索引。
4.3.8.2 上风
⚫ 对于那些经常重复的使用调换的子查询终结的查询性能大幅晋升。
⚫ Doris 自动难得死一火视图的数据,无论是新的导入,如故删除操作齐能保证 base 表和死一火视图表的数据一致性。无需任何额外的东说念主工难得资本。
⚫ 查询时,会自动匹配到最优死一火视图,并顺利从死一火视图中读取数据。
自动难得死一火视图的数据会变成一些难得支拨,会在后头的死一火视图的局限性中伸开阐扬。
4.3.8.3 死一火视图 VS Rollup
在莫得死一火视图功能之前,用户一般齐是使用 Rollup 功能通过预团员方式晋升查询效力的。然则 Rollup 具有一定的局限性,他不成基于明细模子作念预团员。
死一火视图则在隐蔽了 Rollup 的功能的同期,还能救援更丰富的团员函数。是以死一火视图其实是 Rollup 的一个超集。
也等于说,之前 ALTER TABLE ADD ROLLUP 语法救援的功能当今均不错通过
CREATE MATERIALIZED VIEW 已矣。
4.3.8.4 死一火视图旨趣
Doris 系统提供了一整套对死一火视图的 DDL 语法,包括创建,稽查,删除。DDL 的语法和 PostgreSQL, Oracle 齐是一致的。然则 Doris 目下创建死一火视图只可在单表操作,不救援 join.
4.3.8.4.1 创建死一火视图
当先要凭据查询语句的特质来决定创建一个什么样的死一火视图。并不是说死一火视图界说和某个查询语句一模一样就最佳。这里有两个原则:
(1)从查询语句中抽象出,多个查询共有的分组和团员方式行为死一火视图的界说。
(2)不需要给统共维度组合齐创建死一火视图。
当先第一个点,一个死一火视图如果抽象出来,何况多个查询齐不错匹配到这张死一火视图。
这种死一火视图终结最佳。因为死一火视图的难得本人也需要消耗资源。
如果死一火视图只和某个特殊的查询很贴合,而其他查询均用不到这个死一火视图。则会导致这张死一火视图的性价比不高,既占用了集群的存储资源,还不成为更多的查询管事。
是以用户需要连合我方的查询语句,以及数据维度信息去抽象出一些死一火视图的界说。
第二点等于,在履行的分析查询中,并不会隐蔽到统共的维度分析。是以给常用的维度组合创建死一火视图即可,从而到达一个空间和时刻上的平衡。
通过底下号令就不错创建死一火视图了。创建死一火视图是一个异步的操作,也等于说用户顺利提交创建任务后,Doris 会在后台对存量的数据进行猜想,直到创建顺利。
具体的语法不错通过底下号令稽查:HELP CREATE MATERIALIZED VIEW
这里以一个销售纪录表为例:
图片
比如咱们有一张销售纪录明细表,存储了每个往复的时刻,销售员,销售门店,和金额。
提交完创建死一火视图的任务后,Doris 就会异步在后台生成死一火视图的数据,构建死一火视图。
在构建期间,用户依然不错浅近的查询和导入新的数据。创建任务会自动处理现时的存量数据和统共新到达的增量数据,从而保捏和 base 表的数据一致性。用户不需饶恕一致性问题.
4.3.8.4.2 查询
图片
死一火视图创建完成后,用户的查询会凭据规则自动匹配到最优的死一火视图。
比如咱们有一张销售纪录明细表,何况在这个明细表上创建了三张死一火视图。一个存储了不同期间不同销售员的售卖量,一个存储了不同期间不同门店的销售量,以及每个销售员的总销售量。
当查询 7 月 19 日,各个销售员齐买了几许钱的话。就不错匹配 mv_1 死一火视图。顺利对 mv_1 的数据进行查询。
4.3.8.4.3 查询自动匹配
图片
死一火视图的自动匹配分为底下两个才能:
(1)凭据查询条目删选出一个最优的死一火视图:这一步的输入是统共候选死一火视图表的元数据,凭据查询的条目从候选集结输出最优的一个死一火视图
(2)凭据选出的死一火视图对查询进行改写:这一步是连合上一步遴荐出的最优死一火视图,进行查询的改写,最终达到顺利查询死一火视图的目的。
图片
其中 bitmap 和 hll 的团员函数在查询匹配到死一火视图后,查询的团员算子会凭据死一火视图的表结构进行一个改写。详备见实例 2
4.3.8.4.4 最优旅途遴荐
图片
这里分为两个才能:
(1)对候选集会进行一个过滤。只若是查询的终结能从死一火视图数据猜想(取部分行,部分列,或部分行列的团员)出齐不错留在候选集结,过滤完成后候选集会大小>=1.
(2)从候选集会中凭据团员程度,索引等条目选出一个最优的也等于查询挥霍最少死一火视图。
这里再举一个相对复杂的例子,来体现这个经由:
图片
候选集过滤目下分为 4 层,每一层过滤后去除不缓和条目的死一火视图。
比如查询 7 月 19 日,各个销售员齐买了几许钱,候选集结包括统共的死一火视图以及 base表共 4 个:
第一层过滤先判断查询 where 中的谓词触及到的数据是否能从死一火视图中得到。也等于销售时刻列是否在表中存在。由于第三个死一火视图中压根不存在销售时刻列。是以在这一层过滤中,mv_3 就被淘汰了。
第二层是过滤查询的分组列是否为候选集的分组列的子集。也等于销售员 id 是否为表均分组列的子集。由于第二个死一火视图中的分组列并不触及销售员 id。是以在这一层过滤中,mv_2 也被淘汰了。
第三层过滤是看查询的团员列是否为候选集结团员列的子集。也等于对销售额乞降是否能从候选集的表中团员得出。这里 base 表和死一火视图表均缓和顺序。
临了一层是过滤看查询需要的列是否存在于候选集会的列中。由于候选集会中的表均缓和顺序,是以最终候选集会中的表为 销售明细表,以及 mv_1,这两张。
图片
候选集过滤完后输出一个集会,这个集会中的统共表齐能缓和查询的需求。但每张表的查询效力齐不同。这时候就需要再这个集会凭据前缀索引是否能匹配到,以及团员程度的高低来选出一个最优的死一火视图。
从表结构中不错看出,base 表的销售日历列是一个非排序列,而死一火视图表的日历是一个排序列,同期团员程度上 mv_1 赏赐着比 base 表高。是以临了遴荐出 mv_1行为该查询的最优匹配。
图片
临了再凭据遴荐出的最优解,改写查询。
刚才的查询选中 mv_1 后,将查询改写为从 mv_1 中读取数据,过滤出日记为 7 月 19 日的 mv_1 中的数据然后复返即可。
4.3.8.4.5 查询改写
图片
有些情况下的查询改写还会触及到查询中的团员函数的改写。
比如业务方经常会用到 count distinct 对 PV UV 进行猜想。
例如;
告白点击明细纪录表中存放哪个用户点击了什么告白,从什么渠说念点击的,以及点击的时刻。何况在这个 base 表基础上构建了一个死一火视图表,存储了不同告白不同渠说念的用户bitmap 值。
由于 bitmap union 这种团员方式本人会对调换的用户 user id 进行一个去重团员。当用户查询告白在 web 端的 uv 的时候,就不错匹配到这个死一火视图。匹配到这个死一火视图表后就需要对查询进行改写,将之前的对用户 id 求 count(distinct) 改为对死一火视图中 bitmap union列求 count。
是以临了查询取死一火视图的第一和第三行求 bitmap 团员中有几个值。
4.3.8.4.6 使用及猖狂
图片
(1)目下救援的团员函数包括,常用的 sum,min,max count,以及猜想 pv ,uv, 留存率,等常用的去重算法 hll_union,和用于精准去重猜想 count(distinct)的算法bitmap_union。
(2)死一火视图的团员函数的参数不救援抒发式仅救援单列,比如: sum(a+b)不救援。
(3)使用死一火视图功能后,由于死一火视图履行上是失掉了部分维度数据的。是以对表的 DML 类型操作会有一些猖狂:
如果表的死一火视图 key 中不包含删除语句中的条目列,则删除语句不成奉行。
比如思要删除渠说念为 app 端的数据,由于存在一个死一火视图并不包含渠说念这个字段,则这个删除不成奉行,因为删除在死一火视图中无法被奉行。这时候你只可把死一火视图先删除,然后删除完数据后,再行构建一个新的死一火视图。
(4)单表上过多的死一火视图会影响导入的效力:导入数据时,死一火视图和 base 表数据是同步更新的,如果一张表的死一火视图表进步 10 张,则有可能导致导入速率很慢。这就像单次导入需要同期导入 10 张表数据是一样的。
(5)调换列,不同团员函数,不成同期出当今一张死一火视图中,比如:select sum(a), min(a) from table 不救援。
(6)死一火视图针对 Unique Key 数据模子,只可改变列礼貌,不成起到团员的作用,是以在 Unique Key 模子上不成通过创建死一火视图的方式对数据进行粗粒度团员操作.
4.3.8.5 案例演示
4.3.8.5.1 案例一
1)创建一个 Base 表create table sales_records( record_id int, seller_id int, store_id int, sale_date date, sale_amt bigint ) distributed by hash(record_id) properties("replication_num" = "1");
插入数据insert into sales_records values(1,2,3,'2020-02-02',10);
2)基于这个 Base 表的数据提交一个创建死一火视图的任务create materialized view store_amt as select store_id, sum(sale_amt) from sales_records group by store_id;
3)查验死一火视图是否构建完成
由于创建死一火视图是一个异步的操作,用户在提交完创建死一火视图任务后,需要异步的
通过号令查验死一火视图是否构建完成。
SHOW ALTER TABLE MATERIALIZED VIEW FROM test_db; (Version 0.13)
稽查 Base 表的统共死一火视图desc sales_records all;
4)磨练现时查询是否匹配到了合适的死一火视图EXPLAIN SELECT store_id, sum(sale_amt) FROM sales_records GROUP BY store_id;
5)删除死一火视图语法DROP MATERIALIZED VIEW 死一火视图名 on Base 表名;
4.3.8.5.2 案例二:猜想告白的 pv、uv
假定用户的原始告白点击数据存储在 Doris,那么针对告白 PV, UV 查询就不错通过创建 bitmap_union 的死一火视图来晋升查询速率。
1)创建 base 表create table advertiser_view_record( time date, advertiser varchar(10), channel varchar(10), user_id int ) distributed by hash(time) properties("replication_num" = "1");
插入数据insert into advertiser_view_record values('2020-02- 02','a','app',123);
2)创建死一火视图create materialized view advertiser_uv as select advertiser, channel, bitmap_union(to_bitmap(user_id)) from advertiser_view_record group by advertiser, channel;
在 Doris 中,count(distinct) 团员的终结和 bitmap_union_count 团员的终结是彻底一致的。而 bitmap_union_count 等于 bitmap_union 的终结求 count,是以如果查询中触及到count(distinct) 则通过创建带 bitmap_union 团员的死一火视图方可加速查询。
因为本人 user_id 是一个 INT 类型,是以在 Doris 中需要先将字段通过函数 to_bitmap 移动为 bitmap 类型然后才不错进行 bitmap_union 团员。
3)查询自动匹配SELECT advertiser, channel, count(distinct user_id) FROM advertiser_view_record GROUP BY advertiser, channel;
会自动移动成。SELECT advertiser, channel, bitmap_union_count(to_bitmap(user_id)) FROM advertiser_uv GROUP BY advertiser, channel;
4)磨练是否匹配到死一火视图explain SELECT advertiser, channel, count(distinct user_id) FROM advertiser_view_record GROUP BY advertiser, channel;
在 EXPLAIN 的终结中,当先不错看到 OlapScanNode 的 rollup 属性值为 advertiser_uv。
也等于说,查询会顺利扫描死一火视图的数据。阐扬匹配顺利。其次对于 user_id 字段求 count(distinct)被改写为求bitmap_union_count(to_bitmap)。也等于通过 bitmap 的方式来达到精准去重的终结。
4.3.8.5.3 案例三
用户的原始表有(k1, k2, k3)三列。其中 k1, k2 为前缀索引列。这时候如果用户查询条目中包含 where k1=1 and k2=2 就能通过索引加速查询。
然则有些情况下,用户的过滤条目无法匹配到前缀索引,比如 where k3=3。则无法通过索引晋升查询速率。
创建以 k3 行为第一列的死一火视图就不错经管这个问题。
1)查询
explain select record_id,seller_id,store_id from sales_records
where store_id=3;
2)创建死一火视图create materialized view mv_1 as select store_id, record_id, seller_id, sale_date, sale_amt from sales_records;
通过上头语法创建完成后,死一火视图中既保留了完竣的明细数据,且死一火视图的前缀索引为 store_id 列。
3)稽查表结构desc sales_records all;
4)查询匹配explain select record_id,seller_id,store_id from sales_records where store_id=3;
这时候查询就会顺利从刚才创建的 mv_1 死一火视图中读取数据。死一火视图对 store_id是存在前缀索引的,查询效力也会晋升。
4.3.9 修改表
使用 ALTER TABLE 号令不错对表进行修改,包括 partition 、rollup、schema change、
rename 和 index 五种。语法:ALTER TABLE [database.]table alter_clause1[, alter_clause2, ...];
alter_clause 分为 partition 、rollup、schema change、rename 和 index 五种。
4.3.9.1 rename
1)将名为 table1 的表修改为 table2ALTER TABLE table1 RENAME table2;
2)将表 example_table 中名为 rollup1 的 rollup index 修改为 rollup2ALTER TABLE example_table RENAME ROLLUP rollup1 rollup2;
3)将表 example_table 中名为 p1 的 partition 修改为 p2ALTER TABLE example_table RENAME PARTITION p1 p2;
4.3.9.2 partition
1)增多分区, 使用默许分桶方式
现存分区 [MIN, 2013-01-01),增多分区 [2013-01-01, 2014-01-01),ALTER TABLE example_db.my_table ADD PARTITION p1 VALUES LESS THAN ("2014-01-01");
2)增多分区,使用新的分桶数ALTER TABLE example_db.my_table ADD PARTITION p1 VALUES LESS THAN ("2015-01-01") DISTRIBUTED BY HASH(k1) BUCKETS 20;
3)增多分区,使用新的副本数ALTER TABLE example_db.my_table ADD PARTITION p1 VALUES LESS THAN ("2015-01-01") ("replication_num"="1");
4)修改分区副本数ALTER TABLE example_db.my_table MODIFY PARTITION p1 SET("replication_num"="1");
5)批量修改指定分区ALTER TABLE example_db.my_table MODIFY PARTITION (p1, p2, p4) SET("in_memory"="true");
6)批量修改统共分区ALTER TABLE example_db.my_table MODIFY PARTITION (*) SET("storage_medium"="HDD");
7)删除分区ALTER TABLE example_db.my_table DROP PARTITION p1;
8)增多一个指定高下界的分区ALTER TABLE example_db.my_table ADD PARTITION p1 VALUES [("2014-01-01"), ("2014-02-01"));
4.3.9.3 rollup
1)创建 index: example_rollup_index,基于 base index(k1,k2,k3,v1,v2)。列式存储。ALTER TABLE example_db.my_table ADD ROLLUP example_rollup_index(k1, k3, v1, v2);
2)创建 index: example_rollup_index2,基于 example_rollup_index(k1,k3,v1,v2)ALTER TABLE example_db.my_table ADD ROLLUP example_rollup_index2 (k1, v1) FROM example_rollup_index;
3)创建 index: example_rollup_index3, 基于 base index (k1,k2,k3,v1), 自界说 rollup 超往往刻一小时。ALTER TABLE example_db.my_table ADD ROLLUP example_rollup_index(k1, k3, v1) PROPERTIES("timeout" = "3600");
4)删除 index: example_rollup_index2ALTER TABLE example_db.my_table DROP ROLLUP example_rollup_index2;
4.3.9.4 表结构变更
使用 ALTER TABLE 号令不错修改表的 Schema,包括如下修改:
⚫ 增多列
⚫ 删除列
⚫ 修改列类型
⚫ 改变列礼貌
以增多列为例:
1)咱们新增一列 uv,类型为 BIGINT,团员类型为 SUM,默许值为 0:ALTER TABLE table1 ADD COLUMN uv BIGINT SUM DEFAULT '0' after pv;
2)提交顺利后,不错通过以下号令稽查功课程度:SHOW ALTER TABLE COLUMN;
当功课景况为 FINISHED,则示意功课完成。新的 Schema 已收效。
3)稽查新的 SchemaDESC table1;
4)不错使用以下号令取消现时正在奉行的功课:CANCEL ALTER TABLE ROLLUP FROM table1;
5)更多不错参阅: HELP ALTER TABLE
https://doris.apache.org/zh-CN/sql-reference/sql-statements/Data Definition/ALTER TABLE.html
4.3.10 删除数据(Delete)
Doris 目下不错通过两种方式删除数据:DELETE FROM 语句和 ALTER TABLE DROP
PARTITION 语句。
4.3.10.1 DELETE FROM Statement(条目删除)
delete from 语句近似顺序 delete 语法,具体使用不错稽查 help delete; 匡助。
语法:DELETE FROM table_name [PARTITION partition_name] WHERE column_name1 op { value | value_list } [ AND column_name2 op { value | value_list } ...];
如:
delete from student_kafka where id=1;
属目事项。
(1)该语句只可针对 Partition 级别进行删除。如果一个表有多个 partition 含有需要删除的数据,则需要奉行屡次针对不同 Partition 的 delete 语句。而如果是莫得使用Partition 的表,partition 的称呼即表名。
(2)where 后头的条目谓词只可针对 Key 列,何况谓词之间,只可通过 AND 相接。
如果思已矣 OR 的语义,需要奉行多条 delete。
(3)delete 是一个同步号令,号令复返即示意奉行顺利。
(4)从代码已矣角度,delete 是一种特殊的导入操作。该号令所导入的内容,亦然一
个新的数据版块,只是该版块中只包含号令中指定的删除条目。在履行奉行查询时,会凭据
这些条目进行查询时过滤。是以,不提议大量频繁使用 delete 号令,因为这可能导致查询
效力缩小。
(5)数据的信得过删除是在 BE 进行数据 Compaction 时进行的。是以奉行完 delete 命
令后,并不会立即开释磁盘空间。
(6)delete 号令一个较强的猖狂条目是,在奉行该号令时,对应的表,不成有正在进行的导入任务(包括 PENDING、ETL、LOADING)。而如果有 QUORUM_FINISHED 景况的导入任务,则可能不错奉行。
(7)delete 也有一个隐含的近似 QUORUM_FINISHED 的景况。即如果 delete 只在多数副本上完成了,也会复返用户顺利。然则会在后台生成一个异步的 delete job(Async Delete Job),来延续完成对剩余副本的删除操作。如果此时通过 show delete 号令,不错看到这种任务在 state 一栏会裸露 QUORUM_FINISHED。
4.3.10.2 DROP PARTITION Statement(删除分区)
该号令不错顺利删除指定的分区。因为 Partition 是逻辑上最小的数据经管单元,是以使用 DROP PARTITION 号令不错很轻量的完成数据删除责任。何况该号令不受 load 以及任何其他操作的猖狂,同期不会影响查询效力。是相比推选的一种数据删除方式。
该号令是同步号令虎牙 裸舞,奉行顺利即收效。此后台数据信得过删除的时刻可能会延长 10 分钟操纵。
本站仅提供存储管事,统共内容均由用户发布,如发现存害或侵权内容,请点击举报。