元数据支持存储计算分离
在存储计算架构中,数据可能存储在本地、远端,或同时存储在本地和远端。当数据存储在远端时,本地存储将作为一个全量Cache存在。在这种架构,现有的以下流程需求进行重新设计:
- Backend 的元数据管理
- 建表或创建分区时数据分片的分布管理
- 数据副本的修改,数据分片的修复和均衡
- 数据导入控制
- StorageMedium 分级存储
- Backend 节点的上下线操作
- 和现有元数据的兼容方案
本文档针对以上问题进行说明。
目标
基于新的设计,我们希望 Doris 获得以下新的特性:
- 支持全部数据存储在远端存储
当全部数据都塞远端存储后,本地节点可以非常灵活的添加或删除,而无需进行数据的重分布等操作。
- 支持数据副本的存储位置
通过将数据的副本存储在不同的节点,可以将对同一个表的在线、离线业务进行物理隔离。
- 支持多机房部署
支持将一个 Doris 集群同时在多个机房机型部署。
概念解释
在存储计算分离中,我们将引入几个新的概念。
Resource
资源。可以为 Doris 提供某种服务的实体。比如 Backend 是一种资源,Broker 也是一种资源。资源需要先通过命令加入到 Doris 集群中才能被使用。
Resource Tag
资源标签。一个资源可以被赋予一个或多个标签。标签可以让用户自定义的描述一个资源,如资源的功能、属性等等。
每一个标签都归属一个类型。对标签进行分类,可以某些场景下,通过类型来晒选出合适标签,而无需指定标签的名称。本期 Doris 提供两个内置的类型:
- type:包含表示资源类型的标签。
- function:包含表示资源功能的标签。
- location:包含表示物理的位置的标签,如机房、机架等
- custom:包含用户自定义的标签。
标签的表示方法为:"tag.type" = "tag1.tag2"
。其中 tag
是关键词。如:
"tag.location" = "zone1,rack1",
"tag.type" = "store,computation"
内置资源和标签
Doris 会内置一些资源和他们的标签。
内置标签
type
frontend
:FEbackend
:BEbroker
:Brokerremote_storage
:RemoteStoragefunction
store
:表示拥有数据存储功能computation
:表示拥有计算功能location
default
:默认的位置标签
内置资源
- Frontend
FE 节点。和先用 FE 功能保持一致(请求接入、元数据管理、查询计划生成等)。默认拥有标签:
"tag.type" = "frontend"
- Backend
BE 节点。当前 BE 节点提供存储和计算属性。后续可能会加入仅存储、仅计算、仅导入等属性。默认拥有标签:
"tag.type" = "backend",
"tag.function" = "store, computation",
"tag.location" = "default_cluster"
- Broker
Broker 节点。和现有功能保持一致(为远端存储提供文件系统读写接口)。默认拥有标签:
"tag.type" = "broker"
- RemoteStorage
远端储存。用于在计算存储分离架构下,提供远端存储属性。默认拥有标签:
"tag.type" = "remote_storage",
"tag.function" = "store"
资源管理
资源可以被添加或删除。资源可以添加、删除或修改资源标签。
添加资源
对 Doris 中已有的资源(FE、BE、BROKER),为保证兼容性,我们沿用现有的操作命令。同时,新增增加 Remote Storage 的命令。
ALTER SYSTEM ADD FOLLOWER xxx;
ALTER SYSTEM ADD BACKEND xxx;
ALTER SYSTEM ADD BROKER xxx;
ALTER SYSTEM ADD REMOTE STORAGE xxx;
上述为默认的资源添加语句。在添加语句中,也支持自定义资源标签。举例如下:
ALTER SYSTEM ADD BACKNED "host:ip"
PROPERTIES(
"tag.function" = "store, computation",
"tag.location" = "rack1, asia"
);
ALTER SYSTEM ADD REMOTE STORAGE WITH BROKER broker_name
PROPERTIES(
"path" = "/path/"
"username" = "user",
"password" = "pass",
"tag.function" = "store",
"tag.location" = "rack1, asia"
);
删除资源
资源可以被删除,对于现有资源,删除方式和现在保持一致。
ALTER SYSTEM DROP BACKEND xxx;
ALTER SYSTEM DROP FOLLOWER xxx;
ALTER SYSTEM DROP BROKER xxx;
ALTER SYSTEM DROP REMOTE STORAGE xxx;
修改资源
资源可以被修改,如增加或删除资源属性、修改资源组等。示例如下:
ALTER SYSTEM MODIFY BACKEND "host:ip"
PROPERTIES (
"tag.xxx" = "xxx"
)
对 store
属性的修改可能会导致数据迁移,需要配合副本修复流程一起修改。
资源选择
统一通过标签来选择资源。比如选择 tag 为 asia 和 rack1 Backend,则可以通过以下标签组合来选择:
{
"tag.type" = "backend"
"tag.location" = "asia,rack1"
}
资源使用
资源创建并正常加入集群后,才能被使用。这里主要介绍有改动的一些操作的使用方式。
创建表和分区
创建表和分区时,可以指定资源组。Doris 会在资源组中寻找拥有 Store 属性的资源,进行数据分片副本的分布。同时我们示例如下:
CREATE TABLE tbl1 (k1 int) DISTRIBUTED BY HASH(k1) BUCKETS 4
PROPERTIES (
"backend.tag.location" = "rack1:2",
"backend.tag.location" = "rack2:1",
"remote_storage.tag.location" = "zone1"
);
其中 backend.tag
指定了副本在本地存储中的分布,必选。如上表示在标签为 rack1 的 Backend 中部署2副本,在标签为 rack2 中 Backend 中部署1副本。remote_storage.tag
表示使用的远端存储的标签,可选。
ALTER TABLE tbl2 ADD PARTITION p2 VALUES LESS THAN("200")
(
"backend.tag.location" = "rack1:2",
"backend.tag.location" = "rack2:1",
"remote_storage.tag.location" = "zone1"
LocalMode 和 RemoteMode
必须为一个表或分区指定至少一个 backend.tag
。每个 Backend 存放至少1个副本。
remote_storage.tag
至多一个。如果不指定,则相当于一个LocalMode表。如果指定,则这是一个RemoteMode的表。
通过在建表时设置 backend.tag
和 remote_storage.tag
,确定了一个表是 LocalMode 还是 RemoteMode。这个属性后续不可修改。但是可以修改 backend.tag
和 remote_storage.tag
。比如为不同的分区指定不同的 Tag 等。
为保持兼容,当用户指定 "replication_num" = "3"
时,等同于:
"backend.tag.location" = "default_cluster:3"
如果指定 backend.tag
属性,replication_num
将失效。
修改副本和数据分片管理
ALTER TABLE MODIFY PARTITION p1 SET ("backend.tag.xxx" : "xxx");
对于 LocalMode 或 RemoteMode 的表,都可以通过这个方式更换本地副本的 backend.tag
,以及每个 backend.tag
中副本的数量。副本检查模块会检查并开始迁移副本。RemoteMode 的副本会直接从远端存储下载数据。
remote_storage.tag
暂不支持修改。
对于LocalMode的表。数据分片的管理方式和现在相同,区别在于需要按照 tag 粒度进行数据分片的修复和均衡。
对于RemoteMode的表。数据分片在本地的管理方式和 LocalMode 相同。但 RemoteMode 允许用户删除所有 backend.tag
(类似关闭集群),此时集群将处于冻结状态(TODO:当需要删除所有 backend.tag
时,需要将表先进入一个“冻结“状态,用于同步还没有同步到 remote_storage.tag
的数据)。
导入控制
对于LocalMode的表,导入和之前流程一样。
对于RemoteMode的表。我们会在建表时,指定一个本地副本作为 PrimaryReplica。导入请求会尽量发给 PrimaryReplica,由 PrimaryReplica 完成导入并通知其他副本同步数据。如果 PrimaryReplica 不可用(比如节点宕机,PrimaryReplica多次导入失败等),也可以将导入发给其他节点。
FE 根据一定得策略来判断是否需要更换 PrimaryReplica。当 PrimaryReplica 在一段时间内不可用后,会切换一个新的副本作为 PrimaryReplica。尽量不切换 PrimaryReplica,防止频繁切换导致的冷数据问题。
Storage Medium 分级存储
本期我们先不支持 RemoteMode 表的分级存储功能。在存储计算分离框架下,这个功能可能被其他方案取代(比如新的缓存策略)
查询
用户可以在查询某个表时,通过 hint 的方式,来指定使用满足某些标签的资源进行查询
SELECT * FROM TBALE /*+ tag:tag1,tag2,... */
权限控制
可以通过 SET PROPERTY
语句将一个或多个资源标签赋予某个用户,则该用户可以查询其有权限访问的表的在这些标签所属资源上的副本。当一个用户没有任何标签时,即使有表的 SELECT 权限,也无法执行查询。为保证兼容,默认所有用户拥有 backend
标签的权限。
对于 LocalMode 的表,当修改了表的 backend.tag
后,可能因为新的 Storage 中数据还没有 ready 而无法查询。因此我们建议先增加新的 tag,再删除旧的 tag。RemoteMode 不存在这个问题,查询会直接从远端存储拉取数据,不过第一次查询会较慢。
Cluster
我们希望新的设计能够取代之前的多 cluster 功能。所以要对多 cluster 进行一些兼容性改建。当前多 cluster 主要有以下功能和命令:
- CREATE CLUSTER
创建一个 cluster 对象。不再使用,替换为单独为 BE 添加标签
- DROP CLUSTER
把cluster包含的 backend 设为 free。不再使用,替换为单独删除 BE 的标签。
- ADD FREE BACKNED
增加一个没有标签的 BE。继续保留。
- ADD BACKEND TO CLUSTER
将 Backend 增加到一个 cluster 中。保留,但建议替换为为 BE 增加标签的语句。
- ALTER CLUSTER
cluster 中的节点扩缩容,或者decommission 某个 BE。不再支持,替换为为Backend 增加会删除标签。
- LINK Database
不再支持,当用户想查询某个db时,直接授权db读权限,并授权对应标签即可。
- MIGRATION Database
不再支持。替换为修改表的副本的标签。
- Enter cluster
支持,但该命令不再产生任何实际改动。(原先会设置 context 中的 cluster name)。即使enter 一个错误的 cluster,系统也不会报错。
同时,我们需要对集群内已存在的 cluster 相关的元信息进行变换已兼容新的框架:
- Backend
属于某一 cluster 的 backend,将被添加标签 "tag.location" = "cluster_name"
。对于 FREE 的backend,无标签。
- Database
属于某一 cluster 的 database。会将database下所有表的副本的标签设置为 cluster_name。
- User
属于某一 cluster 的 user。变更为给user这个 cluster name 标签的权限。
使用场景
这里介绍一下在 tag 系统框架下的一下典型使用场景
多机房部署
一个 Doris 集群可以将 BE 部署在不同的机房以保证数据的可靠性。我们可以通过 tag.location
区分不同机房的 BE。用户在建表时,可以指定将副本存储在不同 tag.location
的 BE 上。或者仅说明是否要进行多机房部署,Doris 会自动根据不同的 tag.location
来分配副本。
在多机房部署场景下,查询会自动选择同一个机房内的副本进行查询。如果机房不可用,Doris 可以自动切换到另一个可用机房。
独立资源、共享数据
当数据支持存储在远端存储系统中后,用户可以方便的单独启动一组 BE 资源并分配 tag。然后将希望使用的表或分区的副本扩展到这些 BE 上。这种方式可以用户分离一些业务场景,比如 QA 环境,DEV 环境等,可以共享一套数据,但是使用独立的计算资源。
13条答案
按热度按时间vsaztqbk1#
@morningman
我觉得我们应该还是保留Backend这个实体,而不是将Storage全部替换为Backend。
所以我认为我们这里不应该把我们的Backend变成Storage,而Storage只应该是Backend的一个属性。
06odsfpq2#
@morningman
我觉得我们应该还是保留Backend这个实体,而不是将Storage全部替换为Backend。
所以我认为我们这里不应该把我们的Backend变成Storage,而Storage只应该是Backend的一个属性。
我重新做了修改
nx7onnlm3#
Resource
资源。可以为 Doris 提供某种服务的实体。比如 Backend 是一种资源,Broker 也是一种资源。资源需要先通过命令加入到 Doris 集群中才能被使用。
我们需要把所有的节点都打平么?感觉BE、FE、Broker这些之间似乎也没有什么共性。还有打平的话我觉得叫做资源不太恰当。毕竟通常我们说的都是CPU资源,IO资源,网络资源,存储资源,一般都指的是逻辑的概念。
而现在吧FE、BE、Broker与Remote Storage放在一起我觉得也有不妥。FE、BE、Broker都是Doris自身的模块,是个物理存在的实体。但是Remote Storage更像是一个逻辑的概念,感觉跟其他节点放在一起讨论并不是十分适合。
Resource Attribute
资源属性。一个资源可以被赋予一个多个属性。属性用于表述资源能够提供的功能或服务。比如将 Computation 和 Storage 属性赋予 Backend 这个资源。则这个 Backend 可以提供计算和存储功能。
Default
Default 属性专门赋予一些暂不支持属性,或者属性未定义的资源。如 Frontend,Broker 等。这些资源通常功能比较明确,或者暂时无需通过属性来划分功能。
属性我理解更像是一个set,如果对于FE、Broker这种没有属性的节点,我个人觉得让他们的属性为空会更加好一些。属性是Default太难理解了,而且未来再增加新的属性的时候,会跟这个Default可能会有兼容性的问题。
Resource Group
多个拥有相同资源属性的资源可以组成一个资源组。一些操作可以指定一个资源组,来使用组内的资源共同完成一项功能。比如在建表时,可以指定数据分片的副本分布在指定的一组拥有存储属性的 Backend 资源中;或者在查询时,指定一组拥有计算属性的 Backend 资源进行查询。
资源必须属于至少一个资源组。因为对资源的使用,是以资源组为单位的。一个资源可以属于多个资源组。资源组中只能包含相同类型的资源,但是资源的属性可以不同。
我觉得我们可以没有group的概念,只是提供tag机制。其实这我觉得是可以跟attribute合成一个的。如果说拆出来的话,可能是作为用户自定义属性?因为你定义为Group,可能就需要Group的管理,但其实我们的Group可能是个很松散的Group,是用时才发现的Group。所以我理解这里作为一个attribute扩充就可以了。
但是我们需要考虑的一个问题是,假如我们要支持跨机房部署,那么我们可以把三个副本分配在不同的Group中。但是查询的时候我们可能要某个查询尽量的都在一个Group中。但是这个很难表达,所以我们可能需要支持一些指定的属性,比如,“location”这种属性。
643ylb084#
我们需要把所有的节点都打平么?感觉BE、FE、Broker这些之间似乎也没有什么共性。还有打平的话我觉得叫做资源不太恰当。毕竟通常我们说的都是CPU资源,IO资源,网络资源,存储资源,一般都指的是逻辑的概念。
这个我得意思主要是所有的这些节点都可以用一套 tag 机制来管理。而当前其实我们主要是对 Backend 添加标签,其他的都不动。所以不论从用户理解还是使用,都没有太大的变化。Remote Storage 我理解和 Backend 一样也是一个实体,类似一个只能存储的Backend,所以就放在一起了。
其他的建议和 @yiguolei 的意见差不多,我修改了一版
zf2sa74q5#
资源这个词,可以再讨论~
hgtggwj06#
CREATE TABLE tbl1 (k1 int) DISTRIBUTED BY HASH(k1) BUCKETS 4
PROPERTIES (
"backend_tag" = "rack1:2, rack2:1,", // required
"remote_storage_tag" = "zone1" // optional
);
要求用户在建表时必须指定backend_tag,感觉不是很合理。 我觉得我们可以在整个集群,cluster,DB粒度设置backend_tag属性,建表时backend_tag作为可选项。 让用户在建表时指定backend_tag,会极大增加Doris Admin的运维成本。
remote_storage_tag 至多一个。
感觉我们在设计时不应该做这个假设。 目前我们Druid同时使用了HDFS和S3两个远端存储,HDFS为主,S3备份,用于在HDFS整个机房不可用时提供服务,远端存储不可用的情况是存在的, 所以我们应该允许用户配置多个远端存储。
升级时会检查如果用户使用了除 default_cluster 外的其他cluster,则不支持升级。
What !!! 使用了cluster的用户想哭。。。
3df52oht7#
要求用户在建表时必须指定backend_tag,感觉不是很合理。 我觉得我们可以在整个集群,cluster,DB粒度设置backend_tag属性,建表时backend_tag作为可选项。 让用户在建表时指定backend_tag,会极大增加Doris Admin的运维成本。
backend_tag 不是必选项,用户可以完全按照之前的方式建表,会走默认配置。
remote_storage_tag 至多一个。
这个是第一期的实现,可以扩展
cluster
这个。。那我再想想 TT
5t7ly7z58#
更新
apeeds0o9#
location:zone1.rack1#custom:tag1.tag2`
一般都是逗号、分号来分隔吧?这种方式太少见了,而且也不直观。
ALTER SYSTEM ADD BACKNED "host:ip"
PROPERTIES(
"resource_tag" = "fucntion:computation.store#location:rack1.asia"
);
ALTER SYSTEM ADD REMOTE STORAGE WITH BROKER broker_name
PROPERTIES(
"username" = "user",
"password" = "pass",
"resource_tag" = "function:store#location:zone1.asia"
);
为什么需要把这个打平成一个resource_tag? 而不是"function" = "", "location=xxx"
CREATE TABLE tbl1 (k1 int) DISTRIBUTED BY HASH(k1) BUCKETS 4
PROPERTIES (
"backend_tag" = "location:rack1:2, location:rack2:1,", // required
"remote_storage_tag" = "location:zone1" // optional
);
这种方式太难使用了,让用户建表的成本就更高了。通常建表的使用者与集群搭建的使用者并不是一个人。建表的人大部分并不需要感知这么复杂的配置。把这个当成一个必选项必须 -1
lokaqttq10#
一般都是逗号、分号来分隔吧?这种方式太少见了,而且也不直观。
那就不打平了,每个type 一行
这种方式太难使用了
这个其实不是必选项,用户依然可以按照之前的方式建表,无需感知tag
nafvub8i11#
Hi,关于多机房部署方面,doris是否有新的计划或者进展呢,我们这边对多机房有需求场景。
bnl4lu3b12#
Hi,关于多机房部署方面,doris是否有新的计划或者进展呢,我们这边对多机房有需求场景。
是否可以简单描述下你的多机房部署需求?
amrnrhlw13#
@morningman ,其实我们这边核心的需求是如何应对idc搬迁时doris平滑切换的问题。目前doris看文档是支持最小分区粒度的全量复制,idc搬迁时候主备场景下需要写入层做一个缓冲层,重新导入中间缺失的数据。我们这边把doris作为服务平台使用,切换过程就需要用户配合的比较多。目前希望doris能给出个类似mysql binlog同步增量的方案或者能直接在多idc部署中支持这种需求就更好了。