下载
编译与部署
开始使用
操作手册
- 数据导入
- 表结构变更
- 物化视图
- HTTP API
- FE
- MANAGER
- Bootstrap Action
- Cancel Load Action
- Check Decommission Action
- Check Storage Type Action
- Config Action
- Connection Action
- Get DDL Statement Action
- Get Load Info Action
- Get Load State
- Get FE log file
- Get Small File
- HA Action
- Hardware Info Action
- Health Action
- Log Action
- Logout Action
- Meta Action
- Meta Action
- Meta Replay State Action
- Profile Action
- Query Detail Action
- Query Profile Action
- Row Count Action
- Session Action
- Set Config Action
- Show Data Action
- Show Meta Info Action
- Show Proc Action
- Show Runtime Info Action
- Statement Execution Action
- System Action
- Table Query Plan Action
- Table Row Count Action
- Table Schema Action
- Upload Action
- CANCEL LABEL
- Compaction Action
- CONNECTION
- getlogfile
- GET LABEL STATE
- GET TABLETS ON A PARTICULAR BE
- PROFILE
- QUERY DETAIL
- RESTORE TABLET
- SHOW DATA
- MIGRATE SINGLE TABLET TO A PARTICULAR DISK
- GET TABLETS DISTRIBUTION BETWEEN DIFFERENT DISKS
- FE
- 运维操作
- 配置文件
- 拦截规则
- 备份与恢复
- Broker
- Colocation Join
- Bucket Shuffle Join
- 动态分区
- 数据导出
- 导出查询结果集
- 分区缓存
- 权限管理
- LDAP
- 资源管理
- 查询执行的统计
- Runtime Filter
- Segment V2 升级手册
- 文件管理器
- SQL MODE
- 时区
- 变量
- 更新
- 多租户和资源划分
最佳实践
扩展功能
- 审计日志插件
- Doris On ES
- Doris output plugin
- ODBC External Table Of Doris
- Doris 插件框架
- Spark Doris Connector
- Flink Doris Connector
- DataX doriswriter
- UDF
设计文档
SQL 手册
- SQL 函数
- 日期函数
- convert_tz
- curdate
- current_timestamp
- curtime,current_time
- date_add
- date_format
- date_sub
- datediff
- day
- dayname
- dayofmonth
- dayofweek
- dayofyear
- from_days
- from_unixtime
- hour
- makedate
- minute
- month
- monthname
- now
- second
- strtodate
- time_round
- timediff
- timestampadd
- timestampdiff
- to_days
- unix_timestamp
- utc_timestamp
- week
- weekofyear
- year
- yearweek
- 地理位置函数
- 字符串函数
- 聚合函数
- bitmap 函数
- Hash函数
- Doris 窗口函数使用
- CAST
- DIGITAL_MASKING
- 日期函数
- 语法帮助
- 用户账户管理
- 集群管理
- ADMIN CANCEL REPAIR
- ADMIN CLEAN TRASH
- ADMIN CHECK TABLET
- ADMIN REPAIR
- ADMIN SET CONFIG
- ADMIN SET REPLICA STATUS
- ADMIN SHOW CONFIG
- ADMIN SHOW REPLICA DISTRIBUTION
- ADMIN SHOW REPLICA STATUS
- ADMIN SHOW DATA SKEW
- ALTER CLUSTER
- ALTER SYSTEM
- CANCEL DECOMMISSION
- CREATE CLUSTER
- CREATE FILE
- DROP CLUSTER
- DROP FILE
- ENTER
- INSTALL PLUGIN
- LINK DATABASE
- MIGRATE DATABASE
- SET LDAPADMINPASSWORD
- SHOW BACKENDS
- SHOW BROKER
- SHOW FILE
- SHOW FRONTENDS
- SHOW FULL COLUMNS
- SHOW INDEX
- SHOW MIGRATIONS
- SHOW PLUGINS
- SHOW TABLE STATUS
- SHOW TRASH
- UNINSTALL PLUGIN
- DDL
- ALTER DATABASE
- ALTER TABLE
- ALTER VIEW
- BACKUP
- CANCEL ALTER
- CANCEL BACKUP
- CANCEL RESTORE
- CREATE DATABASE
- CREATE ENCRYPTKEY
- CREATE INDEX
- CREATE MATERIALIZED VIEW
- CREATE REPOSITORY
- CREATE RESOURCE
- CREATE TABLE LIKE
- CREATE TABLE
- CREATE VIEW
- DROP DATABASE
- DROP ENCRYPTKEY
- DROP INDEX
- DROP MATERIALIZED VIEW
- DROP REPOSITORY
- DROP RESOURCE
- DROP TABLE
- DROP VIEW
- HLL
- RECOVER
- RESTORE
- SHOW ENCRYPTKEYS
- SHOW RESOURCES
- TRUNCATE TABLE
- CREATE FUNCTION
- DROP FUNCTION
- SHOW FUNCTIONS
- DML
- BROKER LOAD
- CANCEL LOAD
- DELETE
- EXPORT
- GROUP BY
- LOAD
- MINI LOAD
- MULTI LOAD
- PAUSE ROUTINE LOAD
- RESUME ROUTINE LOAD
- ROUTINE LOAD
- SHOW ALTER
- SHOW BACKUP
- SHOW CREATE FUNCTION
- SHOW CREATE ROUTINE LOAD
- SHOW DATA
- SHOW DATABASES
- SHOW DELETE
- SHOW DYNAMIC PARTITION TABLES
- SHOW EXPORT
- SHOW LOAD
- SHOW PARTITIONS
- SHOW PROPERTY
- SHOW REPOSITORIES
- SHOW RESTORE
- SHOW ROUTINE LOAD TASK
- SHOW ROUTINE LOAD
- SHOW SNAPSHOT
- SHOW TABLES
- SHOW TABLET
- SHOW TRANSACTION
- SPARK LOAD
- STOP ROUTINE LOAD
- STREAM LOAD
- ALTER ROUTINE LOAD
- INSERT
- UPDATE
- 数据类型
- 辅助命令
开发者手册
- 调试工具
- Doris BE存储层Benchmark工具
- 使用 Eclipse 搭建 FE 开发环境
- 使用 IntelliJ IDEA 搭建 FE 开发环境
- Apache Doris Be 开发调试
- Java 代码格式化
- C++ 代码格式化
Apache 社区
多租户和资源划分
Doris 的多租户和资源隔离方案,主要目的是为了多用户在同一 Doris 集群内进行数据操作时,减少相互之间的干扰,能够将集群资源更合理的分配给各用户。
该方案主要分为两部分,一是集群内节点级别的资源组划分,二是针对单个查询的资源限制。
Doris 中的节点
首先先简单介绍一下 Doris 的节点组成。一个 Doris 集群中有两类节点:Frontend(FE) 和 Backend(BE)。
FE 主要负责元数据管理、集群管理、用户请求的接入和查询计划的解析等工作。
BE 主要负责数据存储、查询计划的执行等工作。
FE 不参与用户数据的处理计算等工作,因此是一个资源消耗较低的节点。而 BE 负责所有的数据计算、任务处理,属于资源消耗型的节点。因此,本文所介绍的资源划分及资源限制方案,都是针对 BE 节点的。FE 节点因为资源消耗相对较低,并且还可以横向扩展,因此通常无需做资源上的隔离和限制,FE 节点由所有用户共享即可。
节点资源划分
节点资源划分,是指将一个 Doris 集群内的 BE 节点设置标签(Tag),标签相同的 BE 节点组成一个资源组(Resource Group)。资源组可以看作是数据存储和计算的一个管理单元。下面我们通过一个具体示例,来介绍资源组的使用方式。
为 BE 节点设置标签
假设当前 Doris 集群有 6 个 BE 节点。分别为 host[1-6]。在初始情况下,所有节点都属于一个默认资源组(Default)。
我们可以使用以下命令将这6个节点划分成3个资源组:group_a、group_b、group_c:
alter system modify backend "host1:9050" set ("tag.location": "group_a"); alter system modify backend "host2:9050" set ("tag.location": "group_a"); alter system modify backend "host3:9050" set ("tag.location": "group_b"); alter system modify backend "host4:9050" set ("tag.location": "group_b"); alter system modify backend "host5:9050" set ("tag.location": "group_c"); alter system modify backend "host6:9050" set ("tag.location": "group_c");
这里我们将
host[1-2]
组成资源组group_a
,host[3-4]
组成资源组group_b
,host[5-6]
组成资源组group_c
。注:一个 BE 只支持设置一个 Tag。
按照资源组分配数据分布
资源组划分好后。我们可以将用户数据的不同副本分布在不同资源组内。假设一张用户表 UserTable。我们希望在3个资源组内各存放一个副本,则可以通过如下建表语句实现:
create table UserTable (k1 int, k2 int) distributed by hash(k1) buckets 1 properties( "replica_allocation" = "tag.location.group_a:1, tag.location.group_b:1, tag.location.group_c:1" )
这样一来,表 UserTable 中的数据,将会以3副本的形式,分别存储在资源组 group_a、group_b、group_c所在的节点中。
下图展示了当前的节点划分和数据分布:
┌────────────────────────────────────────────────────┐ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ host1 │ │ host2 │ │ │ │ ┌─────────────┐ │ │ │ │ │ group_a │ │ replica1 │ │ │ │ │ │ │ └─────────────┘ │ │ │ │ │ │ │ │ │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ ├────────────────────────────────────────────────────┤ ├────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ host3 │ │ host4 │ │ │ │ │ │ ┌─────────────┐ │ │ │ group_b │ │ │ │ replica2 │ │ │ │ │ │ │ └─────────────┘ │ │ │ │ │ │ │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ ├────────────────────────────────────────────────────┤ ├────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ host5 │ │ host6 │ │ │ │ │ │ ┌─────────────┐ │ │ │ group_c │ │ │ │ replica3 │ │ │ │ │ │ │ └─────────────┘ │ │ │ │ │ │ │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ └────────────────────────────────────────────────────┘
使用不同资源组进行数据查询
在前两步执行完成后,我们就可以通过设置用户的资源使用权限,来限制某一用户的查询,只能使用指定资源组中的节点来执行。
比如我们可以通过以下语句,限制 user1 只能使用
group_a
资源组中的节点进行数据查询,user2 只能使用group_b
资源组,而 user3 可以同时使用 3 个资源组:set property for 'user1' 'resource_tags.location' : 'group_a'; set property for 'user2' 'resource_tags.location' : 'group_b'; set property for 'user3' 'resource_tags.location' : 'group_a, group_b, group_c';
设置完成后,user1 在发起对 UserTable 表的查询时,只会访问
group_a
资源组内节点上的数据副本,并且查询仅会使用group_a
资源组内的节点计算资源。而 user3 的查询可以使用任意资源组内的副本和计算资源。这样,我们通过对节点的划分,以及对用户的资源使用限制,实现了不同用户查询上的物理资源隔离。更进一步,我们可以给不同的业务部门创建不同的用户,并限制每个用户使用不同的资源组。以避免不同业务部分之间使用资源干扰。比如集群内有一张业务表需要共享给所有9个业务部门使用,但是希望能够尽量避免不同部门之间的资源抢占。则我们可以为这张表创建3个副本,分别存储在3个资源组中。接下来,我们为9个业务部门创建9个用户,每3个用户限制使用一个资源组。这样,资源的竞争程度就由9降低到了3。
另一方面,针对在线和离线任务的隔离。我们可以利用资源组的方式实现。比如我们可以将节点划分为 Online 和 Offline 两个资源组。表数据依然以3副本的方式存储,其中 2 个副本存放在 Online 资源组,1 个副本存放在 Offline 资源组。Online 资源组主要用于高并发低延迟的在线数据服务,而一些大查询或离线ETL操作,则可以使用 Offline 资源组中的节点执行。从而实现在统一集群内同时提供在线和离线服务的能力。
单查询资源限制
前面提到的资源组方法是节点级别的资源隔离和限制。而在资源组内,依然可能发生资源抢占问题。比如前文提到的将3个业务部门安排在同一资源组内。虽然降低了资源竞争程度,但是这3各部门的查询依然有可能相互影响。
因此,除了资源组方案外,Doris 还提供了对单查询的资源限制功能。
目前 Doris 对单查询的资源限制主要分为 CPU 和 内存限制两方面。
内存限制
Doris 可以限制一个查询被允许使用的最大内存开销。以保证集群的内存资源不会被某一个查询全部占用。我们可以通过以下方式设置内存限制:
// 设置会话变量 exec_mem_limit。则之后该会话内(连接内)的所有查询都使用这个内存限制。 set exec_mem_limit=1G; // 设置全局变量 exec_mem_limit。则之后所有新会话(新连接)的所有查询都使用这个内存限制。 set global exec_mem_limit=1G; // 在 SQL 中设置变量 exec_mem_limit。则该变量仅影响这个 SQL。 select /*+ SET_VAR(exec_mem_limit=1G) */ id, name from tbl where xxx;
因为 Doris 的查询引擎是基于全内存的 MPP 查询框架。因此当一个查询的内存使用超过限制后,查询会被终止。因此,当一个查询无法在合理的内存限制下运行时,我们就需要通过一些 SQL 优化手段,或者集群扩容的方式来解决了。
CPU 限制
用户可以通过以下方式限制查询的 CPU 资源:
// 设置会话变量 cpu_resource_limit。则之后该会话内(连接内)的所有查询都使用这个CPU限制。 set cpu_resource_limit = 2 // 设置用户的属性 cpu_resource_limit,则所有该用户的查询情况都使用这个CPU限制。该属性的优先级高于会话变量 cpu_resource_limit set property for 'user1' 'cpu_resource_limit' = '3';
cpu_resource_limit
的取值是一个相对值,取值越大则能够使用的 CPU 资源越多。但一个查询能使用的CPU上限也取决于表的分区分桶数。原则上,一个查询的最大 CPU 使用量和查询涉及到的 tablet 数量正相关。极端情况下,假设一个查询仅涉及到一个 tablet,则即使cpu_resource_limit
设置一个较大值,也仅能使用 1 个 CPU 资源。
通过内存和CPU的资源限制。我们可以在一个资源组内,将用户的查询进行更细粒度的资源划分。比如我们可以让部分时效性要求不高,但是计算量很大的离线任务使用更少的CPU资源和更多的内存资源。而部分延迟敏感的在线任务,使用更多的CPU资源以及合理的内存资源。
最佳实践和向前兼容
Tag 划分和 CPU 限制是 0.15 版本中的新功能。为了保证可以从老版本平滑升级,Doris 做了如下的向前兼容:
- 每个 BE 节点会有一个默认的 Tag:
"tag.location": "default"
。 - 通过
alter system add backend
语句新增的 BE 节点也会默认设置 Tag:"tag.location": "default"
。 - 所有表的副本分布默认修改为:
"tag.location.default:xx
。其中 xx 为原副本数量。 - 用户依然可以通过
"replication_num" = "xx"
在建表语句中指定副本数,这种属性将会自动转换成:"tag.location.default:xx
。从而保证无需修改原建表语句。 - 默认情况下,单查询的内存限制为单节点2GB,CPU资源无限制,和原有行为保持一致。且用户的
resource_tags.location
属性为空,即默认情况下,用户可以访问任意 Tag 的 BE,和原有行为保持一致。
这里我们给出一个从原集群升级到 0.15 版本后,开始使用资源划分功能的步骤示例:
关闭数据修复与均衡逻辑
因为升级后,BE的默认Tag为
"tag.location": "default"
,而表的默认副本分布为:"tag.location.default:xx
。所以如果直接修改 BE 的 Tag,系统会自动检测到副本分布的变化,从而开始数据重分布。这可能会占用部分系统资源。所以我们可以在修改 Tag 前,先关闭数据修复与均衡逻辑,以保证我们在规划资源时,不会有副本重分布的操作。ADMIN SET FRONTEND CONFIG ("disable_balance" = "true"); ADMIN SET FRONTEND CONFIG ("disable_tablet_scheduler" = "true");
设置 Tag 和表副本分布
接下来可以通过
alter system modify backend
语句进行 BE 的 Tag 设置。以及通过alter table
语句修改表的副本分布策略。示例如下:alter system modify backend "host1:9050, 1212:9050" set ("tag.location": "group_a"); alter table my_table modify partition p1 set ("replica_allocation" = "tag.location.group_a:2");
开启数据修复与均衡逻辑
在 Tag 和副本分布都设置完毕后,我们可以开启数据修复与均衡逻辑来触发数据的重分布了。
ADMIN SET FRONTEND CONFIG ("disable_balance" = "false"); ADMIN SET FRONTEND CONFIG ("disable_tablet_scheduler" = "false");
该过程根据涉及到的数据量会持续一段时间。并且会导致部分 colocation table 无法进行 colocation 规划(因为副本在迁移中)。可以通过
show proc "/cluster_balance/
来查看进度。也可以通过show proc "/statistic"
中UnhealthyTabletNum
的数量来判断进度。当UnhealthyTabletNum
降为 0 时,则代表数据重分布完毕。设置用户的资源标签权限。
等数据重分布完毕后。我们就可以开始设置用户的资源标签权限了。因为默认情况下,用户的
resource_tags.location
属性为空,即可以访问任意 Tag 的 BE。所以在前面步骤中,不会影响到已有用户的正常查询。当resource_tags.location
属性非空时,用户将被限制访问指定 Tag 的 BE。
通过以上4步,我们可以较为平滑的在原有集群升级后,使用资源划分功能。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论