带你读《存储漫谈:Ceph原理与实践》——3.2.5 元数据 / 数据同步

简介: 带你读《存储漫谈:Ceph原理与实践》——3.2.5 元数据 / 数据同步

3.2.5  元数据 / 数据同步

Ceph RGW 的多数据中心(Multisite)机制用于实现多个 Ceph 对象存储集群之间的元数据、数据同步。


1. 元数据同步

(1)多数据中心简介

Ceph 的多数据中心有如下几个概念:Realm、Zone Group、Zone,如图 3-31 所示。

image.png

图 3-31 多数据中心示意

每个 Realm 都为一个独立的命名空间,桶名在所在命名空间内是唯一的,即一旦在某个 Realm 下创建了桶 A,则 A 这个名字就被使用了,在该 Realm 下其他人就无法创建出名字为 A 的桶。

一个 Realm 下可以有多个 Zone Group。顾名思义,每个 Zone Group 可以对应多个Zone,即 Zone Group 是一组 Zone 的集合,Zone 之间同步数据和元数据。

通常一个 Zone 为多台服务器组成的一个 Ceph 集群,由一组 RGW 对外提供服务,一个集群上部署多个 RGW 网关,以对请求进行负载均衡。

在一个 Realm 下的多个 Zone Group 中,必须有一个 Master Zone Group,Master Zone Group 中必须有一个 Master Zone,在 Master Zone Group 下的 Master Zone 中执行用户的创建、删除、修改操作会记录一些日志信息(MDlog),这些日志信息被克隆到其他 Zone Group 下的 Zone 中,其他 Zone 中的 RGW 网关依照日志信息从 Master Zone Group 下的 Master Zone 中已配置的 endpoints 拉取元数据信息并执行相应操作。

在 Ceph 的配置中有以下几个参数与多数据中心机制相关,分别为 rgw_realm、rgw_zonegroup、rgw_zone。一旦设置好这 3 个参数并启动 RGW 网关,RGW 就会默认到 .rgw.root 下寻找相应的 Realm、Zone Group、Zone 信息,如果无法找到则启动失败。用户也

可 以 通 过 修 改 参 数 rgw_realm_root_pool、rgw_zonegroup_root_pool、rgw_zone_root_

pool 的配置值,来告诉 RGW 网关到指定的存储池下读取 Realm、Zone Group、Zone 等信息。

默认情况下,一个 Realm 下的不同 Zone Group 之间只会进行元数据同步,元数据包括用户信息、bucket、bucket.instance 信息。RGW 实例在启动时,会启动 RGWMetaSyncProcessorThread 线程进行多数据中心元数据的同步服务。

一个新的 Zone Group 加入已存在的 Realm 时,会执行全量同步,完成全量同步后就会进入增量同步阶段。在此阶段,新加入的 Zone Group 下的 Zone 内的 RGW 网关每隔 20s(通过 INCREMENTAL_INTERVAL 参数配置)到 Master Zone Group 中拉取日志信息 MDlog。

在增量同步阶段,每隔 20s 执行如下动作。

1)查询请求带上 marker 参数发送到 Master Zone Group,查询是否有新增的 MDlog,如果有,则拉取新增的 MDlog 到本地集群;

2)读取保存在本集群的新增的 MDlog 并处理,按照 MDlog 记录信息发送读取元数据请求到 Master Zone Group ;

3)保存从 Master Zone Group 读取到的元数据信息到本地集群;

4)更新 marker 参数。

(2)MDLog 简介

Mdlog 为 Master Zone Group 上的 RGW 网关记录,日志信息记录在 Log 池下的meta.log.PERIOD.SHARD_ID 对象的 OMAP 上,shard_id 默认为 0 ~ 31。

以下命令可查询第 0 个 shard 上的 omapkey,key 为 1_ 开头,后面带记录 Log 的时间戳。

#rados -p zgp2-z1.rgw.log listomapkeys meta.log.315d0473-9ff8-4828-83fd-96fdc
36ed618.01_1598684563.695864_0.1

也可以使用 radosgw-admin 命令查看 MDlog 日志信息的状态,状态信息中有 marker 和last_update 的时间信息,marker 记录上次同步的位置,last_update 记录上次同步的时间。

#radosgw-admin mdlog status
[
  {
    "marker": "1_1598768113.971442_11.1"
    "last_update": "2020-08-30 06:15:13.971442Z"
  }
]

status 信息保存在 Log 池下的 RADOS 对象中,可通过如下命令进行查询。

#rados -p zgp2-z1.rgw.log ls
mdlog.sync-status.shard.0
mdlog.sync-status

当主数据中心没有元数据更新记录到 MDlog 时,以下是从主数据中心拉取 MDlog 请求时没有新 MDlog 返回的请求和响应。

GET /admin/log?type=metadata&id=0&period=315d0473-9ff8-4828-83fd-
96fdc36ed618&max-entries=100&marker= 当前的 marker&rgwx-zonegroup=7085627f-27f8-
4779-9552-ebdd13c265e2 HTTP/1.1
HTTP/1.1 200 OK
Content-Length: 44
{
"marker": ""
"entries": []
"truncated": false
}

当主数据中心有元数据更新记录到 MDlog 时,以下是从主数据中心拉取 MDlog 请求时有新 MDlog 返回的请求和响应。

GET /admin/log?type=metadata&id=0&period=315d0473-9ff8-4828-83fd-
96fdc36ed618&max-entries=100&marker= 当前的 marker&rgwx-zonegroup=7085627f-27f8-
4779-9552-ebdd13c265e2 HTTP/1.1
 HTTP/1.1 200 OK
Content-Length: 598
{
"marker": "1_1598774754.303770_13.1"
"entries": [
  {
   "timestamp": "2020-08-30 08:05:54.234410256Z"
   "section": "user"
   "data": {
    "status": {
     "status": "write"
...
}

如果从主数据中心拉取 MDlog 请求时有新的 MDlog 返回,发起拉取请求的 RGW 则进入 MDlog 的处理流程,即发送新的获取元数据请求到 Master Zone Group 去拉取新的信息覆盖本地旧的元数据信息。如下为在 Master Zone Group 中创建一个用户后,非 Master Zone Group 向 Master Zone Group 的网关发起的拉取用户信息的请求。

GET /admin/metadata/user/user001?key=user001&rgwx-zonegroup=abc HTTP/1.1
HTTP/1.1 200 OK
Content-Length: 713
{
"data": {
...
  "default_storage_class": ""
  "keys": [
   {
    "access_key": ""
    "secret_key": ""
    "user": "user001"
   }
  ]
...
}

拉取到新的用户信息写入本地集群后,更新 marker 参数,这样在下一个 20s 时带上该 Marker 参数,就会只返回本 Zone 没有的 MDlog,对处理过的 MDlog 就不会返回,从而实现了元数据的增量更新。

RGW 进程只有同时满足如下条件,才会进行 MDlog 的记录。

rgw_zonegroup 为 Master Zone Group。

当前的 Zone Group内的 Zone个数多于 1个或者当前 Realm下的 Zone Group多于 1个。

(3)示例:非主数据中心创建桶

用户信息在 Master Zone Group 中创建后通过 MDlog 的方式同步到其他 Zone Group下所有的 Zone 中,例如非 Master Zone Group 下的某个 RGW 网关接收到创建桶的请求,该 RGW 网关会将请求转发到 Master Zone Group 的网关处理。

void RGWCreateBucket::execute()
{
...
if (!store->svc.zone->is_meta_master()) {
  JSONParser jp;
  op_ret = forward_request_to_master(s NULL store in_data &jp);
...
}

如果主数据中心创建失败(例如主数据中心没有该用户,该用户在非 Master Zone Group 中创建),则创建桶失败。因此所有用户必须在 Master Zone Group 中创建,并通过 MDlog 同步到其他数据中心,用户的修改和删除也必须在 Master Zone Group 中执行。如果 Master Zone Group 成功返回转发创建桶的请求,则继续执行剩余的创建桶流程,将 bucket info 保存到本数据中心的 RADOS。Master Zone Group 接收到该创建桶的请求后,其下的 RGW 也会执行 RGWCreateBucket::execute()。由于它是主数据中心,同时也会记录 MDlog,在元数据同步线程中 MDlog 会克隆到其他 Zone Group,所有的 Zone Group 下都会保存该 bucket info 信息,例如 Master Zone Group 为 beijing1,创建桶的请求发到 Zone Group 为 beijing2 的 RGW 网关,这个请求会被 beijing2 的 RGW网关转发到 beijng1 的 RGW 网关,同时 MDlog 信息会被同步到 beijing2、guangzhou1、hunan1 等所有 Zone Group。在创建好桶之后,如果向这个桶上传数据,则需要将上传数据请求发到 Zone Group 为 beijing2 的 RGW 网关。如果上传请求发到 Zone Group 为guangzhou1 的 RGW 网关,guangzhou1 的 RGW 网关会返回 301 状态码,表明请求所访问的桶不在本数据中心。

对于其他桶的元数据操作,大部分的请求会被转发到 Master Zone Group,例如删除桶、设置桶的静态网站、设置桶的多版本控制、设置桶的桶策略、设置桶的 ACL、设置桶的生命周期规则、设置桶的跨域访问配置等。

2. 数据同步

Ceph 的数据同步是指在多数据中心不同 Zone 之间同步用户上传的文件数据。可以将实体数据的同步分为 3 个部分:记录日志、数据更新通知以及数据更新。下面分别介绍。

(1)记录日志

在对数据进行操作时(比如上传、删除等操作),RGW 会记录一些日志信息,为之后的实体数据同步服务。日志主要分两部分。

◆ bucket index log :在更新 bucket index、设置 olh(object logical head,对象逻辑头)时会记录该日志,包含了对象、操作类型等信息;

data log :记录发生变化的 bucket shard 等信息。

在进行同步时,依据 data log,可以知道哪些 bucket shard 发生了数据的变化。而通过 bucket index log,则可以对对应的对象进行操作。比如,index log 中记录的是 add 操作,就会从 Source Zone 获取具体的对象,如果是 remove 操作,就会把相应的对象删除。

(2)数据更新通知

与元数据同步类似,实体数据的同步同样拥有一个线程周期性地进行数据更新通知。

初始化

实体数据的更新通知由 RGWDataNotifier 线程负责。它的初始化以及启动都是在RGWRados 的初始化函数中。

data_notififier = new RGWDataNotififier(this);
data_notififier->start();

运行

在被启动之后,每隔一段时间(由 rgw_md_notify_interval_msec 配置,默认 200ms)会进行数据更新通知,将记录在 data log 中发生变化的 shard 发送到其他 Zone。其他Zone 在接收到更新通知后,会唤醒相应的数据同步线程。

(3)数据更新

为了与不同的 Zone 进行实体数据的同步,RGW 会启动单独的同步线程。

初始化

数据同步线程的初始化,同样在 RGW 的初始化中,数据同步线程可能会有多个。对于需要进行数据同步的 Zone,都会启动一个线程来专门负责从该 Zone 获取同步数据。

运行

同步线程启动之后,会开始调用 RGWDataSyncProcessorThread 的 process 来对数据进行处理,其主要流程如下。

1)从 RADOS 中读取 data sync status,以及各个 Log shard 的 sync marker。如果是第一次同步,RADOS 中还不存在这些信息,会先对 status 进行初始化。

2)

data sync status 共 有 3 种 状 态, 即 StateInit、StateBuildingFullSyncMaps、StateSync。依据状态的不同,会执行不同的操作。

a)

StateInit :该状态下,会执行一些同步的初始化操作,例如,往 Log Pool 中写入sync_status 对象,从远端获取各个 Log shard 的 sync marker 写入 Log Pool,将 sync_status 设置为 StateBuildingFullSyncMaps 等。

b)

StateBuildingFullSyncMaps :该状态下,会从远端获取所有的 bucket 信息。之后,会以 bucket shard 为单位,将所有需要同步的 bucket shard 写入 OMAP 中,并更新 Log shard 的同步 marker,最后将状态置为 StateSync。

c)

StateSync :该状态即为正常的同步状态,在进行同步时,以 Log shard 为单位,对每一个 Log shard 进行数据同步操作。

3)在对某个 Log shard 进行数据同步时,依据 Log shard 的 sync marker 来判断执行全量还是增量同步。同样,在执行过一次全量同步后,之后执行的就是增量同步了。

4)在每一个 Log shard 中,包含了多个条目,每一个条目是一个 bucket shard 信息。对 Log shard 的同步,实际上就是遍历并同步这些 bucket shard。

5)同步 bucket shard 过程中有不同的状态。依据不同的状态,来依次执行初始化、全量同步以及增量同步。同样,初始化与全量同步只会执行一次,之后便是增量同步。为了同步 bucket shard,RGW 会从对端 Zone 的 RGW 获取该 bucket shard 的 bucket index log,并依据这些 Log,最终决定是从远端获取实体对象,还是从本地删除对象,或者进行其他的操作,此时才会涉及真正的实体数据的操作。

(4)删除日志

如果不删除日志,则随着时间的增加,日志会越来越大。因此,RGW 每隔一段时间都会删除已经同步完成的数据日志。间隔时间由 rgw_sync_log_trim_interval 确定,默认是1200s。在进行日志删除时,需要从各个 Zone 获取数据同步状态信息,并根据这些信息,判断出哪些日志已经被同步完成了,并将其从 RADOS 中删除。

(5)总结

从实体数据同步过程中可以看到涉及多种同步状态的判断。之所以有这么多的状态,是因为 RGW 在进行数据同步时,将其在逻辑上分成了多个层级。我们可以将同步的层级分成如下 4 个层次。

1)Zone 级别

该层级表示了与某个 Zone 的同步状态,表征该层级的同步状态由下面的结构给出。

struct rgw_data_sync_info {
  enum SyncState {
  StateInit = 0 
  StateBuildingFullSyncMaps = 1
  StateSync = 2
  };
  uint16_t state;
  uint32_t num_shards;
  r

2)Log shard 级别

记录数据变化时会将日志分成多个 Log,从而在数据量较大时,获得较好的性能。下面是表示 Log shard 层级的同步状态结构。

struct rgw_data_sync_marker {
enum SyncState {
  FullSync = 0
  IncrementalSync = 1
};
uint16_t state;
string marker;
string next_step_marker;
uint64_t total_entries;
uint64_t pos;
real_time timestamp;
rgw_data_sync_marker() : state(FullSync) total_entries(0) pos(0) {}
}

3)bucket shard 级别

默认情况下,bucket shard 大小为 0。但为了让单个容器可以承载更多的对象,不得不以牺牲 list 对象的性能为代价,增大 bucket shard 的值。目前在线上环境中,该值通常都不配置为 0。因此,我们可以认为,每个 bucket 实际上都存在多个 shard,各自承载着部分对象。而在同步过程中,每一个 bucket shard 都归属于某个 Log shard。对于 log shard 的同步,实际上就是对其下的各个 bucket shard 进行同步。

4)对象级别

在每一个 bucket shard 中都保存了很多对象,同步 bucket shard,就是同步其下面的这些对象。该层级涉及对实体数据的操作,并且也是同步过程中的最底层(不考虑RADOS),没有专门的结构来保存同步信息。


3. 小结

因为 Multisite 是一个 Zone 层面的功能处理机制,所以默认情况下是 Zone 级的数据同步,即配置了 Multisite 之后,整个 Zone 中的数据都会被同步处理。

整个 Zone 层面的数据同步,操作粒度过于粗糙,在很多场景下都是非常不适用的。当前,Ceph RGW 还支持通过 bucket sync enable/disable 来启用 / 禁用存储桶级的数据同步,操作粒度更细,灵活度也更高。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
6月前
|
存储 监控 文件存储
存储之外,还有什么?云计算对象存储服务OSS深度洞察
存储之外,还有什么?云计算对象存储服务OSS深度洞察
279 0
|
4月前
|
存储 Java 对象存储
springboot配置阿里云OSS存储实现文件上传下载功能
【1月更文挑战第1天】springboot配置阿里云OSS存储实现文件上传下载功能
612 2
|
1天前
|
存储 SQL 关系型数据库
存储系统、数据库和对象存储 | 青训营
存储系统、数据库和对象存储 | 青训营
|
6天前
|
NoSQL Redis
Redis入门到通关之Redis主从数据同步原理
Redis入门到通关之Redis主从数据同步原理
15 0
|
14天前
|
存储 安全 API
对象存储OSS产品常见问题之附件上传后存储存在被窃取的风险如何解决
对象存储OSS是基于互联网的数据存储服务模式,让用户可以安全、可靠地存储大量非结构化数据,如图片、音频、视频、文档等任意类型文件,并通过简单的基于HTTP/HTTPS协议的RESTful API接口进行访问和管理。本帖梳理了用户在实际使用中可能遇到的各种常见问题,涵盖了基础操作、性能优化、安全设置、费用管理、数据备份与恢复、跨区域同步、API接口调用等多个方面。
19 0
|
2月前
|
存储 安全 数据安全/隐私保护
oss数据加密与存储
阿里云OSS提供多种数据加密(SSE-S3, SSE-KMS, SSE-C, CSE-KMS)与存储安全措施,包括服务器和客户端加密、数据在磁盘上加密存储、多重冗余备份、访问控制列表和HTTPS安全传输。KMS支持密钥管理,确保数据静态和传输时的安全。严格的访问策略和身份验证保护资源免受未授权访问,满足高安全性和合规性需求。
44 3
|
4月前
|
存储 负载均衡 NoSQL
Redis 高可用篇:你管这叫主从架构数据同步原理?
Redis 高可用篇:你管这叫主从架构数据同步原理?
241 5
|
4月前
|
存储 对象存储 Python
Python中使用阿里云OSS存储实现文件上传和下载功能
Python中使用阿里云OSS存储实现文件上传和下载功能
466 2
|
4月前
|
存储 NoSQL 数据库连接
Redis主从模式以及数据同步原理:全量数据同步、增量数据同步
Redis主从模式以及数据同步原理:全量数据同步、增量数据同步
197 0
|
5月前
|
存储 对象存储 数据安全/隐私保护
这个错误提示表明你没有权限列出OSS的存储桶
这个错误提示表明你没有权限列出OSS的存储桶
78 1

热门文章

最新文章