From 577a4cf2be5ddb4e9faa9e1ec72356c5fb06034c Mon Sep 17 00:00:00 2001 From: "xin.hu" <350324002@qq.com> Date: Wed, 27 Mar 2024 09:48:01 +0800 Subject: [PATCH 1/2] add doc 002 --- .../assets/image-20240308185340155.png | Bin .../assets/image-20240311152445338.png | Bin huxin/{ => 001}/zstorage_components.md | 264 +++++++++--------- huxin/002/assets/image-20240326145914282.png | Bin 0 -> 22917 bytes huxin/002/assets/image-20240326170105053.png | Bin 0 -> 18872 bytes huxin/002/zstorage_update.md | 63 +++++ 6 files changed, 195 insertions(+), 132 deletions(-) rename huxin/{ => 001}/assets/image-20240308185340155.png (100%) rename huxin/{ => 001}/assets/image-20240311152445338.png (100%) rename huxin/{ => 001}/zstorage_components.md (97%) create mode 100644 huxin/002/assets/image-20240326145914282.png create mode 100644 huxin/002/assets/image-20240326170105053.png create mode 100644 huxin/002/zstorage_update.md diff --git a/huxin/assets/image-20240308185340155.png b/huxin/001/assets/image-20240308185340155.png similarity index 100% rename from huxin/assets/image-20240308185340155.png rename to huxin/001/assets/image-20240308185340155.png diff --git a/huxin/assets/image-20240311152445338.png b/huxin/001/assets/image-20240311152445338.png similarity index 100% rename from huxin/assets/image-20240311152445338.png rename to huxin/001/assets/image-20240311152445338.png diff --git a/huxin/zstorage_components.md b/huxin/001/zstorage_components.md similarity index 97% rename from huxin/zstorage_components.md rename to huxin/001/zstorage_components.md index 3a9a035..571d767 100644 --- a/huxin/zstorage_components.md +++ b/huxin/001/zstorage_components.md @@ -1,132 +1,132 @@ -# zstorage各组件关系以及功能介绍 - -## 1 前言 - -zstorage作为分布式存储,那么就一定会有很多不同的组件分布在不同的存储节点上,并且互相协作,本文主要介绍zstorage集群内部各个组件之间的关系以及各组件承担的功能,并且宏观的介绍一下zstorage内部的一些概念,有助于读者在阅读zstorage其他技术文章的时候可以更好的理解为什么会这么做,这么做又需要其他哪些前置条件以及其他组件的协助等。 - -## 2 整体组件关系图 - -![image-20240311152445338](./assets/image-20240311152445338.png) - -白色部分:zstorage内部组件 - -绿色部分:zstorage集群内第三方组件 - -黄色部分:外部使用部分以及外部管理组件 - -## 3 组件的分布 - -zstorage集群是由众多节点组成(3个及以上),其中又细分为控制节点和存储节点,控制节点和存储节点只是逻辑上的分开,但物理上可以同时是控制节点和存储节点。 - -- 控制节点:固定3个,控制节点负责接收控制命令,维护集群的配置信息,管理集群其他组件,控制节点在安装的时候指定 -- 存储节点:管理硬盘,提供存储服务,对外提供块存储服务,存储节点可以动态扩容增加 - -控制节点组件:monitor,manager,etcd - -存储节点组件:frontend,chunkserver,mds - -zs命令行,nodeagent,keeper,healthmanager为公共基础服务组件,每个节点都有这些组件。 - -## 4 组件功能介绍 - -#### monitor - -monitor为集群“大脑”,监控集群的状态以及为集群其他进程提供一致性视图。 - -monitor为主从关系,集群只有monitor leader提供服务,集群内的monitor通过raft协议选举leader。 - -集群所有视图的配置信息以及视图的持久化,其他进程按需订阅需要的视图,在对应的视图配置有变更的时候,会通知所有订阅的进程。 - -主要有以下视图: - -- node视图:集群各节点的配置以及状态 -- proc视图:集群各进程配置以及状态 -- pool视图:存储池配置以及状态 -- osd视图:osd配置以及状态 -- pg视图:pg副本的分布情况以及状态,pg视图为核心视图,pg为zstorge的基础数据管理单元,存储池的数据会根据一定规则均匀的分配到不同的pg上面去,每个pg会有多个副本。monitor会根据存储池的osd配置,根据crush算法计算出每个pg的不同副本分别应该分布在哪个osd上面 -- config视图:集群的全局配置信息 -- mds视图:mds和vmds的分布情况 - -#### keeper - -守护进程,在子进程异常退出后也可以重新拉起子进程。 - -如果是控制节点,则拉起etcd,monitor,manager,组成控制节点集群。 - -从monitor接收proc视图,根据proc视图配置拉起其他对应的进程(chunkserver,frontend,mds)。 - -#### manager - -manager为主从关系,集群只有manager leader提供服务。 - -提供https api,给zs命令行和其他管理软件提供集群配置入口,允许配置VIP,用户就可以忽略leader切换导致http服务的切换。 - -收到命令后,将配置存储到etcd或者mds。 - -一个命令有可能会有多条kv的写入,manager有事务的保证,多个kv配置要不都成功,要不全部失败。 - -有一些命令还需要通知到所有chunkserver,比如部分快照和部分卷相关的命令,manager也可以保证按顺序异步通知chunkserver。 - -manager提供了高可用方案,kv配置的回滚和异步任务的通知,在故障切主后,可以继续完成。 - -#### etcd - -第三方开源组件,用于存储一些集群重要的元数据。比如pool,osd,proc,node等配置信息。 - -#### mds - -mds提供kv存储服务以及分布式锁服务,kv服务可以订阅,修改后会通知订阅进程。 - -mds kv功能由rocksdb提供服务,rocksdb实现了插件让数据从本地盘存储到chunkserver里面。 - -mds之间直接没有直接联系,互相独立,并且数量不固定,但内部维护了数量固定的vmds,vmds由monitor根据mds进程的数量来统一分配,mds管理由mds视图分配给自己的vmds,每个vmds对应一个rocksdb实例。 - -![](./assets/image-20240308185340155.png) - -#### chunkserver - -管理从monitor收到的osd视图里面的硬盘。 - -从pg视图里的副本分布创建,删除,同步对应的pg副本。 - -以pg为单位提供读写服务,pg各副本间通过raft保证数据的一致性。 - -osd状态和pg副本状态有变化给monitor,让monitor及时进行故障处理以及副本调度。 - -#### frontend - -frontend对外提供块存储服务。 - -计算节点通过iscsi/nvme-of协议发现由frontend创建的设备。 - -frontend支持多路径,配置多路径后,一条链路断了不会影响io的读写。 - -收到用户的读写请求后,根据hash算法,把数据均匀的分配到不同的pg上面去,根据pg视图找到对应的chunkserver节点和osd读写数据。 - -#### zs命令行 - -zs命令行每个zstorage节点都包含,用于zstorage的命令配置。 - -#### nodeagent - -用于收集本节点chunkserver和frontend的一些统计信息,包括: - -- 映射到本节点的卷和本节点的osd的io读写量,iops和时延等信息 -- 本节点的重构速度,重构总量等信息 - -#### healthmanager - -亚健康管理进程,收集本节点的硬件,网络,进程等的健康状态,可以由管理节点用api收集并集成到Prometheus进行监控。 - -#### update - -提供在线和离线升级。 - -在线升级过程中如果有节点失败,支持继续升级或者回滚。 - -提供api在线升级期间查询升级进度。 - -#### install - -提供待安装的节点的大业检查和配置接口,安装接口。 - +# zstorage各组件关系以及功能介绍 + +## 1 前言 + +zstorage作为分布式存储,那么就一定会有很多不同的组件分布在不同的存储节点上,并且互相协作,本文主要介绍zstorage集群内部各个组件之间的关系以及各组件承担的功能,并且宏观的介绍一下zstorage内部的一些概念,有助于读者在阅读zstorage其他技术文章的时候可以更好的理解为什么会这么做,这么做又需要其他哪些前置条件以及其他组件的协助等。 + +## 2 整体组件关系图 + +![image-20240311152445338](./assets/image-20240311152445338.png) + +白色部分:zstorage内部组件 + +绿色部分:zstorage集群内第三方组件 + +黄色部分:外部使用部分以及外部管理组件 + +## 3 组件的分布 + +zstorage集群是由众多节点组成(3个及以上),其中又细分为控制节点和存储节点,控制节点和存储节点只是逻辑上的分开,但物理上可以同时是控制节点和存储节点。 + +- 控制节点:固定3个,控制节点负责接收控制命令,维护集群的配置信息,管理集群其他组件,控制节点在安装的时候指定 +- 存储节点:管理硬盘,提供存储服务,对外提供块存储服务,存储节点可以动态扩容增加 + +控制节点组件:monitor,manager,etcd + +存储节点组件:frontend,chunkserver,mds + +zs命令行,nodeagent,keeper,healthmanager为公共基础服务组件,每个节点都有这些组件。 + +## 4 组件功能介绍 + +#### monitor + +monitor为集群“大脑”,监控集群的状态以及为集群其他进程提供一致性视图。 + +monitor为主从关系,集群只有monitor leader提供服务,集群内的monitor通过raft协议选举leader。 + +集群所有视图的配置信息以及视图的持久化,其他进程按需订阅需要的视图,在对应的视图配置有变更的时候,会通知所有订阅的进程。 + +主要有以下视图: + +- node视图:集群各节点的配置以及状态 +- proc视图:集群各进程配置以及状态 +- pool视图:存储池配置以及状态 +- osd视图:osd配置以及状态 +- pg视图:pg副本的分布情况以及状态,pg视图为核心视图,pg为zstorge的基础数据管理单元,存储池的数据会根据一定规则均匀的分配到不同的pg上面去,每个pg会有多个副本。monitor会根据存储池的osd配置,根据crush算法计算出每个pg的不同副本分别应该分布在哪个osd上面 +- config视图:集群的全局配置信息 +- mds视图:mds和vmds的分布情况 + +#### keeper + +守护进程,在子进程异常退出后也可以重新拉起子进程。 + +如果是控制节点,则拉起etcd,monitor,manager,组成控制节点集群。 + +从monitor接收proc视图,根据proc视图配置拉起其他对应的进程(chunkserver,frontend,mds)。 + +#### manager + +manager为主从关系,集群只有manager leader提供服务。 + +提供https api,给zs命令行和其他管理软件提供集群配置入口,允许配置VIP,用户就可以忽略leader切换导致http服务的切换。 + +收到命令后,将配置存储到etcd或者mds。 + +一个命令有可能会有多条kv的写入,manager有事务的保证,多个kv配置要不都成功,要不全部失败。 + +有一些命令还需要通知到所有chunkserver,比如部分快照和部分卷相关的命令,manager也可以保证按顺序异步通知chunkserver。 + +manager提供了高可用方案,kv配置的回滚和异步任务的通知,在故障切主后,可以继续完成。 + +#### etcd + +第三方开源组件,用于存储一些集群重要的元数据。比如pool,osd,proc,node等配置信息。 + +#### mds + +mds提供kv存储服务以及分布式锁服务,kv服务可以订阅,修改后会通知订阅进程。 + +mds kv功能由rocksdb提供服务,rocksdb实现了插件让数据从本地盘存储到chunkserver里面。 + +mds之间直接没有直接联系,互相独立,并且数量不固定,但内部维护了数量固定的vmds,vmds由monitor根据mds进程的数量来统一分配,mds管理由mds视图分配给自己的vmds,每个vmds对应一个rocksdb实例。 + +![](./assets/image-20240308185340155.png) + +#### chunkserver + +管理从monitor收到的osd视图里面的硬盘。 + +从pg视图里的副本分布创建,删除,同步对应的pg副本。 + +以pg为单位提供读写服务,pg各副本间通过raft保证数据的一致性。 + +osd状态和pg副本状态有变化给monitor,让monitor及时进行故障处理以及副本调度。 + +#### frontend + +frontend对外提供块存储服务。 + +计算节点通过iscsi/nvme-of协议发现由frontend创建的设备。 + +frontend支持多路径,配置多路径后,一条链路断了不会影响io的读写。 + +收到用户的读写请求后,根据hash算法,把数据均匀的分配到不同的pg上面去,根据pg视图找到对应的chunkserver节点和osd读写数据。 + +#### zs命令行 + +zs命令行每个zstorage节点都包含,用于zstorage的命令配置。 + +#### nodeagent + +用于收集本节点chunkserver和frontend的一些统计信息,包括: + +- 映射到本节点的卷和本节点的osd的io读写量,iops和时延等信息 +- 本节点的重构速度,重构总量等信息 + +#### healthmanager + +亚健康管理进程,收集本节点的硬件,网络,进程等的健康状态,可以由管理节点用api收集并集成到Prometheus进行监控。 + +#### update + +提供在线和离线升级。 + +在线升级过程中如果有节点失败,支持继续升级或者回滚。 + +提供api在线升级期间查询升级进度。 + +#### install + +提供待安装的节点的大业检查和配置接口,安装接口。 + diff --git a/huxin/002/assets/image-20240326145914282.png b/huxin/002/assets/image-20240326145914282.png new file mode 100644 index 0000000000000000000000000000000000000000..a8dce5f62003922f131e414684095b545b0dd7dd GIT binary patch literal 22917 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 literal 0 HcmV?d00001 diff --git a/huxin/002/assets/image-20240326170105053.png b/huxin/002/assets/image-20240326170105053.png new file mode 100644 index 0000000000000000000000000000000000000000..87269cd309dfd400f58ef70f86e01804fd3558bc GIT binary patch literal 18872 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
    E&_DY3O9kABqR$B`U!% zrabs6)nmUEH69S`m7)3RU+X)VFy*m1>!$}SZn6+%)L=n$0L52V>`98s^5hgVW1edz z*)1{Rdg{y+2<;8#_8=wE!+=2YLTTTynVB@GbG7vAzhVWX)G;g1dw^{RfG^9>fwxVS zf8q4ep40nzW9SqVUA_k`idbjYDft7wvX8Bu3%(qDMcE0(fIo!J`Oi6kdLsaap&W&Z z{iX7Gk~GVe7N$0D`<9dZR3@PnbYST|R;!;#$4z@;CdRrz3~a?S2r(+v#Oyx@W>Zfk z!N6&-s|uFHUfldvxXejoOgi(=wg2KM$gkDIcagQOA6iiz9mm%_RXs_--5!h`W2~zW zF=la*33}_jpmkLviI|hm9(h!u4&ornWPdk=GmZ6w(kpo2K>Mtx9X$19qVR7o{j4sT zC(`!1)0gcgx>Oq7SPSK79Ya)o&HUe7d<`|DS=`M zqUfe0(~}z@CPRa0JuHj69Evvi;qQKge61M1QeR_}DvF8*V1f{f@s?&De3jO~w01Ki zI1HWh$i51eD{MrFK-4{FU>?#%wHjdLHDZics6b7I>>R)&$4~Hqet0U79-|(oklv|& zS8t3GJ15p}_D({y_BcHf{{8jCnfzB)u=vH-Tm~6hAH1i~&)NQg6fQ{|I@7@!pd7tg zHJc4st}$Uds@;RzrI4MNAP*wWc5CJHc7sNRAZuUFVS8;^q6=s|j1=LLenWQ)fqJY3 z==B~LC167hsk#Wff50im_iX4bDq;NVt!lUa>(G#bZmXQ8siI5}+vCEapyAB^GNPjb zYAM<@m`Kia8=u+s1e{vMR3@2j)ltqtPfa}lF3mDNVyJXj7U8KTNMqV6$-d>b%E#R0 z?9ZrC?vcZcI9=^GpZ^0v5`y!3xwj>Z=UV!E}; zvw@*+fC!N^J*1HE@K9fH)$-A_{7W8yf$PceB?U08WM*bE_xs~8{)gv3<;B-Ovs@@{ zSed+uV^D9$xO`|L(rY~g{dz7>EA@Z-DL>N93>u%c=m literal 0 HcmV?d00001 diff --git a/huxin/002/zstorage_update.md b/huxin/002/zstorage_update.md new file mode 100644 index 0000000..e5131b3 --- /dev/null +++ b/huxin/002/zstorage_update.md @@ -0,0 +1,63 @@ +# zStorage如何在线升级的 + +## 1 前言 + +在软件行业,一个成熟的产品,升级能力是一个很基础但又重要的功能,升级可以解决旧版本的BUG,也可以上线新版本的新特性。升级又分为在线升级和离线升级,离线升级指的是暂停提供服务,在升级完成后才能提供服务,在线升级的话是指的不影响用户使用的情况下进行升级。存储作为很多上层应用的基础软件,一旦停止服务,那么上层应用也会停止服务,造成的影响就会放大,所以存储产品的在线升级能力至关重要。下面将会详细介绍一下zStorage分布式存储的在线升级方案以及如何保证升级期间可以继续提供服务。 + +## 2 在线升级流程 + +![image-20240326145914282](./assets/image-20240326145914282.png) + +update: 升级组件,控制升级流程。 + +manager: zstorage的https api处理组件。 + +monitor: zstorage集群控制进程,提供租约服务,所有zstorage进程都要和monitor保持连接并周期申请租约。 + +#### 整体升级流程 + +1. update通过api向manager发起开始升级,manager通知monitor,然后monitor通知所有进程,全部返回后monitor修改状态,update周期性的查询状态,如果状态是完成或者失败,则做出对应处理。 +2. update进程等待所有进程回复后开始更升级一个节点,升级完一个节点后,需要等待集群完全恢复正常后,再进行下一个节点的升级。 +3. update进程发起更新元数据命令,每个进程根据需要看是否需要更新元数据,更新完成后返回完成。 +4. update进程通知所有进程升级结束。 + +#### 升级期间故障处理 + +分布式环境中,故障时随时可能发生的,比如机器故障,网络故障等,在升级期间如果出现了某个节点故障,在线升级会一直轮询,等待故障处理后继续升级。如果故障的节点已经无法恢复,那么也可以主动停止升级,然后更换故障节点后重新发起升级。 + +## 3 如何保证升级过程中新旧版本的兼容性 + +#### 协议兼容 + +zstorage进程之间通过rpc进行通信,那么升级期间就可能会有新的client连接旧的server,或者旧的client连接新的server的情况出现,然后又细分为新增协议和修改原有的通信协议。所以有以下3种情况需要特殊处理,旧版本已经无法修改,所以只能在新版本上进行兼容处理。 + +![image-20240326170105053](./assets/image-20240326170105053.png) + +zstorage的rpc通信协议格式是tlv格式,tlv的意思就是:type类型, lenght长度,value值。tlv格式的好处就是消息体v长度是可变的,如果v的长度有变化,通过tlv格式的方式解析,就不会照成程序内部的越界导致进程崩溃,从协议层面达到了新旧版本的兼容性。在tlv协议格式的基础上,我们再进行一定的特殊处理,就可以达到功能上的兼容。 + +###### 原有协议修改 + +原有协议修改既指的请求参数增加或者返回结果字段增加,既tlv的t不变,l和v变长,这种情况下,new client和new server需要处理新增字段为空的情况,以达成兼容。 + +这种原有协议修改的场景一般用在某个原有功能新增了一些附加功能,比如使用容量查询,old server只返回了total space,new server除了返回total space,又多返回了used space。 + +###### 新增协议 + +新增协议指的是增加一个通信协议,既tlv的t新增,这种情况只有new client发送到old server才会触发,那么old server只要返回一个无法识别就可以了。 + +这种新增协议一般使用在增加了一个全新的功能场景下使用。 + +#### 元数据兼容 + +zstorage元数据包括配置元数据和磁盘管理元数据。 + +###### 配置元数据 + +配置元数据管理了集群的配置,包括节点信息,存储池信息,卷数据等,这部分信息以json格式存储到etcd或mds里面。 + +json格式是比较好兼容的,如果有新的字段需要增加,一般会是新版本的命令才会产生新的字段,比如卷原来的元数据格式为{“name”:"vol,"id":10},新版本增加了克隆卷的功能,我们只需要新增一个字段{“name”:"vol,"id":10,"clone":1},那么新版本创建的clone卷就包含新的字段,原有的卷就没有这个新字段。 + +###### 磁盘管理元数 + +磁盘管理元数据是zstorage内部为了管理数据在磁盘上按特定格式持久化到磁盘上的数据。这部分元数据就要复杂一些,因为这部分数据格式一旦出错,就会导致数据无法寻址,读不出正确的数据。所以这部分数据需要一直向下兼容,新版本可以以旧版本元数据格式进行工作。 + -- Gitee From 46965d8028d96bcb9a9b986d701b8288cf2e3901 Mon Sep 17 00:00:00 2001 From: "xin.hu" <350324002@qq.com> Date: Wed, 27 Mar 2024 16:40:33 +0800 Subject: [PATCH 2/2] fix --- huxin/002/zstorage_update.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/huxin/002/zstorage_update.md b/huxin/002/zstorage_update.md index e5131b3..d3b1e5f 100644 --- a/huxin/002/zstorage_update.md +++ b/huxin/002/zstorage_update.md @@ -1,10 +1,10 @@ # zStorage如何在线升级的 -## 1 前言 +## 1. 前言 在软件行业,一个成熟的产品,升级能力是一个很基础但又重要的功能,升级可以解决旧版本的BUG,也可以上线新版本的新特性。升级又分为在线升级和离线升级,离线升级指的是暂停提供服务,在升级完成后才能提供服务,在线升级的话是指的不影响用户使用的情况下进行升级。存储作为很多上层应用的基础软件,一旦停止服务,那么上层应用也会停止服务,造成的影响就会放大,所以存储产品的在线升级能力至关重要。下面将会详细介绍一下zStorage分布式存储的在线升级方案以及如何保证升级期间可以继续提供服务。 -## 2 在线升级流程 +## 2. 在线升级流程 ![image-20240326145914282](./assets/image-20240326145914282.png) @@ -14,20 +14,20 @@ manager: zstorage的https api处理组件。 monitor: zstorage集群控制进程,提供租约服务,所有zstorage进程都要和monitor保持连接并周期申请租约。 -#### 整体升级流程 +### 2.1. 整体升级流程 1. update通过api向manager发起开始升级,manager通知monitor,然后monitor通知所有进程,全部返回后monitor修改状态,update周期性的查询状态,如果状态是完成或者失败,则做出对应处理。 2. update进程等待所有进程回复后开始更升级一个节点,升级完一个节点后,需要等待集群完全恢复正常后,再进行下一个节点的升级。 3. update进程发起更新元数据命令,每个进程根据需要看是否需要更新元数据,更新完成后返回完成。 4. update进程通知所有进程升级结束。 -#### 升级期间故障处理 +### 2.2. 升级期间故障处理 分布式环境中,故障时随时可能发生的,比如机器故障,网络故障等,在升级期间如果出现了某个节点故障,在线升级会一直轮询,等待故障处理后继续升级。如果故障的节点已经无法恢复,那么也可以主动停止升级,然后更换故障节点后重新发起升级。 -## 3 如何保证升级过程中新旧版本的兼容性 +## 3. 如何保证升级过程中新旧版本的兼容性 -#### 协议兼容 +### 3.1. 协议兼容 zstorage进程之间通过rpc进行通信,那么升级期间就可能会有新的client连接旧的server,或者旧的client连接新的server的情况出现,然后又细分为新增协议和修改原有的通信协议。所以有以下3种情况需要特殊处理,旧版本已经无法修改,所以只能在新版本上进行兼容处理。 @@ -35,29 +35,29 @@ zstorage进程之间通过rpc进行通信,那么升级期间就可能会有新 zstorage的rpc通信协议格式是tlv格式,tlv的意思就是:type类型, lenght长度,value值。tlv格式的好处就是消息体v长度是可变的,如果v的长度有变化,通过tlv格式的方式解析,就不会照成程序内部的越界导致进程崩溃,从协议层面达到了新旧版本的兼容性。在tlv协议格式的基础上,我们再进行一定的特殊处理,就可以达到功能上的兼容。 -###### 原有协议修改 +#### 3.1.1. 原有协议修改 原有协议修改既指的请求参数增加或者返回结果字段增加,既tlv的t不变,l和v变长,这种情况下,new client和new server需要处理新增字段为空的情况,以达成兼容。 这种原有协议修改的场景一般用在某个原有功能新增了一些附加功能,比如使用容量查询,old server只返回了total space,new server除了返回total space,又多返回了used space。 -###### 新增协议 +#### 3.1.2. 新增协议 新增协议指的是增加一个通信协议,既tlv的t新增,这种情况只有new client发送到old server才会触发,那么old server只要返回一个无法识别就可以了。 这种新增协议一般使用在增加了一个全新的功能场景下使用。 -#### 元数据兼容 +### 3.2. 元数据兼容 zstorage元数据包括配置元数据和磁盘管理元数据。 -###### 配置元数据 +#### 3.2.1. 配置元数据 配置元数据管理了集群的配置,包括节点信息,存储池信息,卷数据等,这部分信息以json格式存储到etcd或mds里面。 json格式是比较好兼容的,如果有新的字段需要增加,一般会是新版本的命令才会产生新的字段,比如卷原来的元数据格式为{“name”:"vol,"id":10},新版本增加了克隆卷的功能,我们只需要新增一个字段{“name”:"vol,"id":10,"clone":1},那么新版本创建的clone卷就包含新的字段,原有的卷就没有这个新字段。 -###### 磁盘管理元数 +#### 3.2.2. 磁盘管理元数 磁盘管理元数据是zstorage内部为了管理数据在磁盘上按特定格式持久化到磁盘上的数据。这部分元数据就要复杂一些,因为这部分数据格式一旦出错,就会导致数据无法寻址,读不出正确的数据。所以这部分数据需要一直向下兼容,新版本可以以旧版本元数据格式进行工作。 -- Gitee