docs(docs-zh): change rst to markdown and update docs

Signed-off-by: pengtianyue <pengtianyue@oppo.com>
This commit is contained in:
pengtianyue 2023-02-27 19:16:09 +08:00 committed by leonrayang
parent 4a1225916f
commit 04baa5c848
64 changed files with 727 additions and 390 deletions

View File

@ -0,0 +1,23 @@
# 文章合集
## 入门系列
- [K8S容器化存储](https://mp.weixin.qq.com/s/RgpunU_j2ggE679B5y0sbQ)2023-02-07, 胡炜财@贝壳
- [集群安装部署](https://mp.weixin.qq.com/s/B98CJ_gh-ViPlDKXkmptTA)2022-07-26存储团队@OPPO
- [云原生分布式存储CubeFS](https://mp.weixin.qq.com/s/mhxODmVEkSLhH8EqgJzcuQ)2022-06-28存储团队@OPPO
## 最佳实践
- [纠删码模式选型](https://mp.weixin.qq.com/s/v-fFJZtDY2_9loHWAnPXqA)2022-12-15存储团队@OPPO
- [常见运营问题处理](https://mp.weixin.qq.com/s/cH9xw5sK80RIkkZWpyd4qA)2022-11-29存储团队@OPPO
- [大数据冷热分离技术实践](https://mp.weixin.qq.com/s/F9_Ix1lkAfn0b05hoWlVwg)2022-09-01存储团队@OPPO
- [机器学习平台技术实践](https://mp.weixin.qq.com/s/RB1iYn850vfnwE37-UDhdA)2022-08-09存储团队@OPPO
## 技术揭秘
- [元数据管理设计](https://mp.weixin.qq.com/s/_PwSANyJZZuFst1SOolNGQ)2023-01-04存储团队@OPPO
- [Posix文件客户端热升级原理设计](https://mp.weixin.qq.com/s/AUcOjcXOIs4ba1vvnu0-3Q)2022-12-22存储团队@OPPO
- [均衡、巡检与故障自愈设计](https://mp.weixin.qq.com/s/CUfaEKUqvQ6UekcTDqkMqQ)2022-11-04存储团队@OPPO
- [纠删码单机存储引擎设计](https://mp.weixin.qq.com/s/jCdvwueQrjeIbwAADzb_7Q)2022-10-13存储团队@OPPO
- [混合云加速设计](https://mp.weixin.qq.com/s/kkUvZUMhg-qmy6Bw_RM2xw)2022-09-16存储团队@OPPO
- [纠删码引起系统设计](https://mp.weixin.qq.com/s/Bx2QM3p7Tz-2y6IGlXAdKA)2022-07-21存储团队@OPPO

View File

@ -1,4 +0,0 @@
文章合集
========================
TODO

View File

@ -1,4 +0,0 @@
贡献者
========================
TODO

View File

@ -0,0 +1,16 @@
# 加入社区
## 开发指南
你可以通过多种方式参与到CubeFS的开源建设当中
- **报告问题**:请合理的使用关键字搜索 [查找问题](https://github.com/cubeFS/cubefs/search?q=&type=Issues&utf8=%E2%9C%93),以确保问题没有提交。然后通过 [打开问题](https://github.com/cubeFS/cubefs/issues) 提交问题描述和复现方法。
- **新增补丁**[规范说明](https://github.com/cubefs/cubefs/blob/master/CONTRIBUTING.md)。
## 开发者
[主要维护者及其职责列表](https://github.com/cubefs/cubefs/blob/master/MAINTAINERS.md)
## 用户
[使用用户](https://github.com/cubefs/cubefs/blob/master/ADOPTERS.md)

View File

@ -1,4 +0,0 @@
使用者
========================
TODO

View File

@ -39,7 +39,7 @@ release = u''
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autodoc','recommonmark','sphinx_markdown_tables',
]
# Add any paths that contain templates here, relative to this directory.
@ -49,7 +49,7 @@ templates_path = ['_templates']
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
source_suffix = ['.rst', '.md']
# The master toctree document.
master_doc = 'index'
@ -75,7 +75,7 @@ pygments_style = None
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
html_theme = 'piccolo_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the

View File

@ -0,0 +1,81 @@
# 鉴权
众所周知Internet国际互联网和intranet企业内部网都是不安全的地方黑客通常可以使用工具在网络上嗅探到很多敏感信息。更糟糕的是由于无法确认对端是否诚实的表达了自己的身份客户端与服务端之间没有办法建立可信的连接。因此如果没有鉴权机制CubeFS一旦部署在了网络中便会存在一些常见的安全问题。
## 安全问题
- 未认证的节点可能会访问敏感信息,如`restful API``volume`信息等
- 通信信道可能受到 `Man-in-the-middle (MITM)` 攻击
## 系统架构
`Authnode` 是为 CubeFS 提供通用认证和授权框架的安全节点。此外, `Authnode` 还充当对称密钥和非对称密钥的集中密钥存储。`Authnode` 采用并定制了基于票证的 `Kerberos` 认证思想。具体来说,当客户端节点( `Master 、 Meta 、 Data 或 client `节点)访问服务时,首先需要在 `Authnode` 中展示用于身份验证的共享密钥。如果认证成功, Authnode 将专门为该服务颁发一个限时票证。出于授权的目的,功能嵌入到票证中,以指示 谁可以在什么资源上做什么 。
![Architecture](pic/authflow.png){.align-center}
在`Authnode` 的上下文中,我们将负责初始化一个服务请求的节点定义为 `Client` ,而响应该请求的节点定义为 `Server` 。这样,任何 CubeFS 节点都可以充当 `Client` 或者 `Server`
`Client``Server` 之间通过 `HTTPS` 或者 `TCP` 进行通信。 `Authnode` 的工作流程如上图所示,简要描述如下:
### 凭据请求 (F1)
在任何服务请求之前,需要持有密钥 *Ckey* 的客户端为服务( `target
service`)从 `Authnode` 获取服务的认证信息。
- C-\>A:
客户端发送一个认证请求请求中包含一个代表客户端的客户端ID`id`和一个代表目标服务的服务ID`sid`)。
- C\<-A: 服务端从自己的 [key store]{.title-ref}
中查找客户端秘钥(`CKey`)和服务端秘钥(`SKey`)。如果认证成功,服务端会向客户端回应一条`CKey`加密的消息。消息中会包含会话秘钥(`sess_key`)和目标服务的凭据。
在获取凭据并使用`Ckey`处理一些安全检查后,客户端拥有`sess_key`和Skey{*ticket*}以备将来的服务请求。
### HTTPS中的服务请求 (F2)
如果服务请求是通过HTTPS协议发送的那么它将按如下步骤进行
- C-\>S: 客户端发送一个包含SKey {*ticket*}的请求。
- C\<-S:
服务端进行以下操作
- 1执行消息解密并获取凭据
- 2验证功能
- 3使用从凭据中获取的`sess_key`,加密`data`返回给客户端。
客户端使用`sess_key`解密从服务器返回的消息并验证其有效性。
### TCP中的服务请求 (F3)
如果服务请求是通过TCP协议发送的那么它将按如下步骤进行
- C-\>S: 客户端发送一个包含SKey {*ticket*}的请求。
- C\<-S: 服务端
- 1解密凭据并验证其功能
- 2提取`sess_key`
- 3生成一个随机数`s_n`
- 4用`sess_key`加密的这个数后响应给客户端。
- C-\>S:
客户端解密回复的消息,并向服务端发送另一条消息,其中包括随机生成的数字`s_c`和`s_n+1`,这两个数字都用`sess_key`加密。
- C\<-S:
服务器将验证`s_n`是否增加了1。如果验证成功,服务端将发送一条包含`s_c+1`的消息,该消息由`sess_key`加密。
- C\<-\>S:
客户机在消息解密后验证`s_c`是否增加了一个。如果成功,则已在客户端和服务器之间建立经过身份验证的通信通道。基于此通道,客户端和服务器可以执行进一步的通信。
## 未来工作
`Authnode`支持CubeFS急需的一般的身份验证和授权。未来`CubeFS`的安全增强有两个方向:
### 特性丰富
当前的 `Authnode`实现不支持某些高级功能:
- 密钥轮换:共享密钥在客户端和服务器中硬编码,不会更改。它增加了安全风险,攻击会破坏加密并找到密钥。定期轮换秘钥有助于降低此类风险。
- 凭据撤销:出于性能考虑,凭据将有效一段时间(如几个小时)。如果客户端不幸地泄漏了它的票证,恶意方可以在有效期内将票证用于服务请求。凭据撤销机制可以通过在发生泄漏时撤销凭据来预防此类问题。
- HSM支持:`Authnode`是CubeFS中的安全瓶颈。破坏`Authnode`意味着破坏整个系统因为它管理密钥存储。硬件安全模块HSM为密钥管理提供物理保护。让HSM例如`SGX`)保护`Authnode`,可以降低 `Authnode`被破坏的风险。
### 端到端数据加密
当前的 `Authnode`实现并不系统地支持对传输中和静止数据的加密,即使我们可以在通信期间使用会话密钥加密数据。保护数据的一种更安全的方法是使用`端到端数据加密`。特别是,加密密钥由 `Authnode`管理和分发,数据在客户端节点加密,通过网络发送并存储在服务端中。与基于现有工具(`fscrypt` 、 `ecryptfs` 和`dm-crypt`)的服务端加密相比, `端到端数据加密` 至少具有以下优点:
- 由于数据解码密钥存储在 `Authnode` 中,一旦数据服务器(例如
`data Node`)被攻击者入侵,它就可以减少数据泄漏。
- 它提供对加密密钥的集中管理(轮换、撤销和生成)。

View File

@ -1,79 +0,0 @@
鉴权节点
=========
众所周知Internet国际互联网和intranet企业内部网都是不安全的地方黑客通常可以使用工具在网络上嗅探到很多敏感信息。更糟糕的是由于无法确认对端是否诚实的表达了自己的身份客户端与服务端之间没有办法建立可信的连接。因此如果没有鉴权机制CubeFS一旦部署在了网络中便会存在一些常见的安全问题。
安全问题
------------------
- 未认证的节点可能会访问敏感信息如restful APIvolume信息等
- 通信信道可能受到 `Man-in-the-middle` (`MITM`) 攻击
系统架构
-----------------------
`Authnode` 是为 `CubeFS` 提供通用认证和授权框架的安全节点。此外, `Authnode` 还充当对称密钥和非对称密钥的集中密钥存储。 `Authnode` 采用并定制了基于票证的 `Kerberos` 认证思想。具体来说,当客户端节点( `Master``Meta``Data``client` 节点)访问服务时,首先需要在 `Authnode` 中展示用于身份验证的共享密钥。如果认证成功, `Authnode` 将专门为该服务颁发一个限时票证。出于授权的目的,功能嵌入到票证中,以指示 `谁可以在什么资源上做什么`
.. image:: pic/authflow.png
:align: center
:scale: 50 %
:alt: Architecture
`Authnode` 的上下文中,我们将负责初始化一个服务请求的节点定义为 `Client` ,而响应该请求的节点定义为 `Server` 。这样,任何 `CubeFS` 节点都可以充当 `Client` 或者 `Server`
`Client``Server` 之间通过 `HTTPS` 或者 `TCP` 进行通信。 `Authnode` 的工作流程如上图所示,简要描述如下:
凭据请求 (F1)
+++++++++++++++++++
在任何服务请求之前,需要持有密钥 *Ckey* 的客户端为服务( `target service` )从 `Authnode` 获取服务的认证信息。
- C->A: 客户端发送一个认证请求请求中包含一个代表客户端的客户端ID*id*和一个代表目标服务的服务ID*sid*)。
- C<-A: 服务端从自己的 `key store` 中查找客户端秘钥(*CKey*)和服务端秘钥(*SKey*)。如果认证成功,服务端会向客户端回应一条*CKey*加密的消息。消息中会包含会话秘钥(*sess_key*)和目标服务的凭据。
在获取凭据并使用*Ckey*处理一些安全检查后,客户端拥有*sess_key*和Skey{*ticket*}以备将来的服务请求。
HTTPS中的服务请求 (F2)
+++++++++++++++++++++++++++++
如果服务请求是通过HTTPS协议发送的那么它将按如下步骤进行
- C->S: 客户端发送一个包含SKey {*ticket*}的请求。
- C<-S: 服务端进行以下操作1执行消息解密并获取凭据2验证功能3使用从凭据中获取的*sess_key*,加密*data*返回给客户端。
客户端使用*sess_key*解密从服务器返回的消息并验证其有效性。
TCP中的服务请求 (F3)
+++++++++++++++++++++++++++
如果服务请求是通过TCP协议发送的那么它将按如下步骤进行
- C->S: 客户端发送一个包含SKey {*ticket*}的请求。
- C<-S: 服务端1解密凭据并验证其功能2提取*sess_key*3生成一个随机数*s_n*4*sess_key*加密的这个数后响应给客户端。
- C->S: 客户端解密回复的消息,并向服务端发送另一条消息,其中包括随机生成的数字*s_c**s_n*+1这两个数字都用*sess_key*加密。
- C<-S: 服务器将验证*s_n*是否增加了1。如果验证成功,服务端将发送一条包含*s_c*+1的消息该消息由*sess_key*加密。
- C<->S: 客户机在消息解密后验证*s_c*是否增加了一个。如果成功,则已在客户端和服务器之间建立经过身份验证的通信通道。基于此通道,客户端和服务器可以执行进一步的通信。
未来工作
-----------
`Authnode` 支持CubeFS急需的一般的身份验证和授权。未来 `CubeFS` 的安全增强有两个方向:
特性丰富
++++++++++++++++++
当前的 `Authnode` 实现不支持某些高级功能:
- 密钥轮换:共享密钥在客户端和服务器中硬编码,不会更改。它增加了安全风险,攻击会破坏加密并找到密钥。定期轮换秘钥有助于降低此类风险。
- 凭据撤销:出于性能考虑,凭据将有效一段时间(如几个小时)。如果客户端不幸地泄漏了它的票证,恶意方可以在有效期内将票证用于服务请求。凭据撤销机制可以通过在发生泄漏时撤销凭据来预防此类问题。
- HSM支持: `Authnode` 是CubeFS中的安全瓶颈。破坏 `Authnode` 意味着破坏整个系统因为它管理密钥存储。硬件安全模块HSM为密钥管理提供物理保护。让HSM例如*SGX*)保护 `Authnode` ,可以降低 `Authnode` 被破坏的风险。
端到端数据加密
++++++++++++++++++++++++++
当前的 `Authnode` 实现并不系统地支持对传输中和静止数据的加密,即使我们可以在通信期间使用会话密钥加密数据。保护数据的一种更安全的方法是使用 `端到端` `数据` `加密` 。特别是,加密密钥由 `Authnode` 管理和分发,数据在客户端节点加密,通过网络发送并存储在服务端中。与基于现有工具( `fscrypt``ecryptfs``dm-crypt` )的服务端加密相比, `端到端` `数据` `加密` 至少具有以下优点:
-由于数据解码密钥存储在 `Authnode` 中,一旦数据服务器(例如 `data Node` )被攻击者入侵,它就可以减少数据泄漏。
-它提供对加密密钥的集中管理(轮换、撤销和生成)。

View File

@ -0,0 +1,269 @@
# 纠删码子系统
CubeFS 3.0.0以前版本只提供多副本存储,随着数据规模持续增长,业务面临着更大的成本挑战,用户对更低成本的纠删码(ErasureCode, 下文简称EC)的需求愈加强烈CubeFS近期重磅发布3.0.0版本其关键特性之一是增加了对EC的支持(下图中ErasureCode Subsystem部分)EC将大幅降低数据冗余度优化存储成本有力支撑更大规模存储需求。
![arc](../pic/cfs-arch-ec.png)
本文将为大家分享CubeFS中纠删码存储子系统的设计思考。
## 系统特性
CubeFS的纠删码存储子系统(BlobStore)是一个高可靠、高可用、低成本、支持EB规模的独立键值存储系统。主要特点
1. 采用 Reed-Solomon编码简洁的在线EC架构
2. 动态可配的EC模式支持如“6+3”、“12+3”、“10+4”、...等多种规格 ;
3. 灵活的多AZ部署支持1、2、3不同AZ数目的部署
4. 采用Raft协议保证元数据的强一致性和高可用
5. 高性能的存储引擎:小文件专项优化、高效的垃圾回收机制;
## 整体架构
![arc](./pic/ec-arc.png)
**模块简介**
* Access请求接入网关提供数据读、写、删等基本操作接口
* BlobNode单机存储引擎管理整机的磁盘数据负责数据的持久化存储, 执行卷修补、迁移和回收任务;
* ClusterManager元数据管理模块, 负责集群资源(如磁盘、节点、存储空间单元)的管理;
* ProxyClusterManager与异步消息代理模块提供数据写入空间的分配、删除与修补消息转发等
* Scheduler异步任务调度中心负责磁盘修复、磁盘下线、数据均衡、数据巡检、数据修补以及数据删除等任务的生成和调度。
## 名词解析
**Volume**
一个逻辑的存储空间单元,有固定容量上限 (如32G写满32G变ImmutableVolume 由 Volume ID 标识Volume的创建、销毁、分配在 ClusterManager 统一管理。**不同的 Volume支持不同的EC模式**。
集群的可分配空间由一个个Volume组成。Access写数据前需先申请一个可用的Volume读数据则先查询到数据对应的Volume。
![arc](./pic/ec-volume.png)
**Chunk**
**Chunk**是Volume的基本组成单元是存储数据的容器由 Chunk ID 唯一标识对应磁盘的一段实际的物理存储空间Chunk的创建、销毁由BlobNode管理多个 Chunk按照纠删码编码模式组成一个VolumeChunk和Volume的绑定关系持久化在ClusterManager中。
以纠删码模式为“4+4”(即数据块数目为n=4校验块数目m=4)的Volume举例该Volume由 8 个 Chunk组成。 这 8 个 Chunk分散在不同机器的磁盘上。
![arc](./pic/ec-chunk.png)
**Blob**
**Blob** 是用户数据的一次EC计算的数据大小。由 Access 负责切分Blob用 BlobID 唯一标识BlobID 则由ClusterManager统一管理分配**保证****全局唯一**。
假设系统预设的Blob大小为8 M。当前有用户数据 200 M则会被切分成有序的 25 个 Blob优先写入某个 Volume 中,当前 Volume 空间不足时余下Blob 可写入其他 Volume。
![arc](./pic/ec-blob.png)
**Shard**
**Shard 是****EC****条带****数据****的组成单元。**上面提到 Volume 由多个 Chunk 组成Blob 写入Volume 时对应切成多个块分别写到各个Chunk。**每个小块数据叫做 Shard ,一个 Shard 对应写一个 Chunk**。
假设一份用户Blob 数据大小为8M Volume纠删码模式为“ 4+4 ”Access会把blob切成4份大小为2M的原始数据块再计算出4个大小为2M的冗余校验块。该8个2M块都被称为 Shard ,这些 Shard会被分别写到Volume绑定的各个Chunk中至此完成EC编码及存储流程。
![arc](./pic/ec-shard.png)
## 数据读写流程
**写流程**
1. Access 申请一个或多个足够空间且可用的 volume
2. Access 顺序接收用户数据切分成Blob按照EC编码模式切成N个数据块再计算出M个校验块每一个数据块和校验块表示一个shard
3. 把这些 shard 并发写入卷映射的 chunk中
4. Blob写采用quorum模型大多数的 (>n个)shard写成功即可写失败的shard投递修补消息到Proxy中作异步修补最终达到数据完整。如下图2+1 的纠删码模式用户数据生成3个shard(两个数据块,一个校验块)。并发写入到 BlobNode。正常情况3 份都会成功,假设出现异常情况,写入超过两份也算成功。
![arc](./pic/ec-put.png)
5. Access 把对应的数据位置信息Location返回给用户用户需要保存该位置信息用来作读取数据。
**读流程**
在没有数据损坏的情况下,根据数据位置信息读取指定长度(Range)的数据直接返回。
![arc](./pic/ec-read.png)
当需要读取的数据块有损坏或者数据所在节点故障,需要读取其他节点上的数据来修复数据。
这里可能导致一定程度的读放大,因为它必须读到足够的数据块才能计算出所需数据。
成本考量我们总是希望读取本地数据即可返回给用户。则多AZ模式下优先选择修复读通过本AZ存储的部分数据块和部分校验块计算出完整数据减少IO时间及AZ间的网络带宽以计算时间换取带宽成本。
尾延时通过backup request来优化要得到完整的blob正常读n个shard数据即可实际可发n+x1< x <= m个Shard的读请求任意前n个请求响应后即可得到原始blob优雅应对网络超时节点负载重磁盘IO慢或故障导致的尾延时
![arc](./pic/ec-get.png)
## 元数据中心
元数据中心(ClusterManager)负责 Volume 的创建和分配,并管理集群存储节点的状态信息,也为无状态组件提供服务注册功能。
ClusterManager多节点部署采用Raft协议保障一致性以RocksDB作为底层存储得益于RocksDB其批量聚合特性ClusterManager可提供很高的吞吐能力。
![arc](./pic/ec-raft.png)
## Access 模块
Access是接入层模块负责数据收发、切片、EC编解码及流控等。
### Blob分片
用户数据按照一定大小被切分成多个连续的 Blob打散分布在集群的多个物理节点。在并发场景下读写请求能充分利用全部集群资源数据。
### 并发优化
写数据流程中对应的每个 Blob 被切分成多个ShardShard 之间并发写入。读取流程中的多 Shard 数据构建和用户端数据发送是 Pipeline 并行的节省了网络IO时间。
### Quorum 机制
EC 模式要写入的数据分块数比副本模式要多,往往一份数据需要写多个位置。比如 3 副本只需写 3 次3+2 的 EC 模式则需要写 5 次。在单次写入失败率一定的情况下EC 模式整体失败率更高。 为了提高可用性Access 采用 Quorum 机制,允许一定份数的写入失败,只需要满足 EC 的可恢复条件即可。Quorum 写成功返回后,通过异步流程对失败数据块进行修补,达到最终数据完整性。
### EC 编解码
我们采用 RSReed-Solomon 编解码存储冗余度低但数据耐久性高。在多AZ部署时可配置使用LRC编码在每个AZ内添加1份局部校验块可大幅降低数据修复时需跨AZ读的概率从而降低跨机房带宽传输加速数据修复。
### 小文件优化
小文件做在线EC会有较严重的IO放大。比如 128K 大小的文件切分后的shard存储在 4+4 个位置修复读至少需要4次网络请求才能构建出完整数据。我们提出的优化方案为对于越小文件数据尽可能写入到越少的数据块中以减少读取时的网络请求写入性能并没有明显降低但读取性能大大提高。
举个例子,假设 Blob 阈值为 4 M纠删码模式为"4+4"单个Shard阈值为1M。当前有 128K 的用户数据。如果按照常规的切分方式128K 切成 4 份,每一份 32K
![arc](./pic/ec-tiny.png)
这种切片方式当用户读 128K 数据的时候,需要至少发送 4 次网络请求进行多次 IO异常发生的概率更高。
我们的方案采用空间换时间的方式,只需要 1 次网络请求就可能得到完整的数据。把128K用户数据全部写入第一个数据块后三个数据块以空白数据代替下载时只要能正确得到有用数据块或任一校验快即可修复全部用户数据。
![arc](./pic/ec-opt.png)
## 存储引擎
BlobNode作为单机存储引擎管理本机所有磁盘存储空间负责用户数据在磁盘和内存上的组织对外提供数据读、写、删、修复等接口。
### Key/Value 分离存储
Key 和 Value 分离存储,适合大中型的 Value 存储。kay / value 分离的思想自 2016 年《WiscKey: Separating Keys from Values in SSD-Conscious Storage》[https://www.usenix.org/system/files/conference/fast16/fast16-papers-lu.pdf](https://www.usenix.org/system/files/conference/fast16/fast16-papers-lu.pdf),论文提出以后,有了很多实践的项目,在 BlobStore 系统的存储引擎中也借鉴了该思想。
每个磁盘分为元数据和数据两部分,如下:
![arc](./pic/ec-disk.png)
Shard的元数据存储 LSM Tree 里,实际数据部分存储在一个顺序大文件( Chunk File中。由于 LSM Tree 里面的数据量少compact 带来的影响就很小,实际运行几乎不会出现 compact 。也可以把元数据集中放在高性能的 SSD 介质上SATA 盘来承接用户数据。
Chunk 形式上是一个个大文件大小有上限Chunk只支持Append写对HDD友好。
### 高可靠设计
### 数据保护设计
磁盘硬件故障是常态(如坏道、静默错误),数据损坏后系统要能校验出来,保证返回给上层业务的一定是正常数据。
**Key 元数据**
LSM Tree 有自己的 crc 校验保护。sst 文件由 block 组成:
![arc](./pic/ec-blobnode-data.png)
每个 block 都有 crc 保护:
![arc](./pic/ec-crc.png)
当磁盘出现静默错误的时候,能及时校验出来,避免读到错误的数据。上层感知到这个节点的错误,只需通过其他节点重构出数据即可获得正确的数据。
**Value 数据格式**
用户数据存在于 Chunk File 这是一个大的聚合文件。它有自己的保护设计。Chunk 由 header 头部和 Shard 组成:
![arc](./pic/ec-b-shard.png)
每个 shard 都单独保护起来,它有自己的 magic 定界符,并且内部按照 block 分块保护(而不是一个 shard 只有一个 crc ,这样能做到更细粒度的保护):
![arc](./pic/ec-shard-d.png)
**兜底设计**
考虑到 LSM 里存放的元数据是集中存放,如果出现丢失可能影响很大。所以 Chunk File 在写入 Shard 数据的时候,在 header footer 里会备份一份元数据。在极端情况LSM 的元数据就算全部丢失,能够通过解析 Chunk 文件重构出元数据,从而恢复索引数据,而在读写删的时候,也能通过双重校验来保护数据。
### 高效的垃圾回收
传统的垃圾回收一般采用先标记删除后异步做compact的方式 compact过程则涉及到大量磁盘读写有明显缺点
1. 磁盘IO开销大compact过程是读旧的文件写新的文件然后删旧的文件易导致长时间的随机 IO速度慢效率低也会影响业务的正常IO
2. 空间利用率低因compact过程磁盘IO开销大为减少 compact 次数一般会等垃圾数据累积到一定阈值再做compact易导致空间回收不及时磁盘存储利用率降低。
BlobNode的垃圾回收流程如下
1. 先删数据在LSM中的索引条目
2. 再对Chunk File用系统调用fallocate在指定位置打一个相应大小的"洞"
BlobNode垃圾回收机制充分利用文件系统的“打洞”(punch hole)功能:删除数据打洞时,系统会把文件洞中空间释放,剩余部分的文件偏移不变,而文件大小相应减小,无需整理文件即可快速释放垃圾空间。
![arc](./pic/ec-recycle.png)
BlobNode高效的垃圾回收方法可解决传统垃圾回收compact过程带来的大量IO开销提高存储空间利用率对删除量大的业务场景非常适用。
### Append写
覆盖更新是数据损坏最常见的场景之一Chunk File 的设计是:数据的写入永远都是 Append 写入,不存在覆盖更新的情况。写过的位置只能读,尽量发挥机械磁盘顺序访问性能。
![arc](./pic/ec-append.png)
## 最佳实践
### 多 AZ 部署
BlobStore 支持多 AZ 的部署方式1AZ2AZ3AZ 都是完美支持,只需要配置对应的 EC 编码模式即可。假设3AZ使用"15+9"编码模式任意一个AZ故障导致其中数据完全损毁8份), 利用剩余两个AZ数据(16份)即可将故障AZ的全部数据修复从而实现AZ级故障容灾。
![arc](./pic/ec-az.png)
### 服务器选型
不同的组件对组件有不同的偏重,下面就 Access 接入模块BlobNode 单机引擎ClusterManager 元数据管理做个简单的介绍。
**Access 机器**计算和内存需求多因EC编解码属计算密集型任务需要 CPU 消耗,并且 Access 需要在内存中编解码,也需要消耗内存。当然这个内存消耗和请求并发数有关,可以配置。
**BlobNode 机器**BlobNode 是管理磁盘的单机存储引擎,是集群成本的主要组成部分,所以它的部署机型一般是高密磁盘的机型。比如 4U60 盘的就比较好,这种机型也将会是系统最多的类型。
**ClusterManager 的机器**:元数据中心,它的吞吐能力要求很高,这个必须要部署在高性能的 SSD 盘上CPU 内存都要好点。
## 设计总结
1、 **数据冗余策略**
我们知道,保障数据耐久性的关键手段就是数据冗余,冗余策略又分为**多副本**Replica和**纠删码**Erasure Code简称 EC )两种:
- **多副本策略** Replica ):把数据复制多份,按照策略放到分布式不同的存储位置,当某份数据损坏时,可从其他副本读取或修复;
- **纠删码策略** Erasure Code简称 EC 将原始数据编码得到冗余数据并将原始和冗余数据一并存储以达到容错目的。其基本思想是将n块原始的数据元素通过一定的计算得到m块冗余元素校验块对于这n+m块的元素当其中任意的m块元素出错包括原始数据和冗余数据均可以通过对应的重构算法恢复出原来的n块数据
多副本与纠删码两者在系统复杂度、数据耐久性、存储成本、读写放大比等方面表现不同:
多副本实现简单,数据耐久性一般,资源利用率较低、存储成本较高;纠删码实现较复杂,数据耐久性更高,资源利用率更高,存储成本低。
数据冗余策略如何选型需从业务的数据规模、访问模型、耐久性及成本需求等多维度综合评估以OPPO手机云相册业务为例支撑数亿用户访问数据体量大成本诉求强烈目前已全面使用低成本的纠删码引擎。
2、**离线/在线EC策略**
**离线EC**
多副本策略实现简单,而纠删码数据耐久性高且存储成本低。为兼顾性能和成本,有些产品会同时提供两套系统,数据先写入作为缓存的多副本,再异步迁移到最终的纠删码,即所谓的离线 EC 。这种方式优点在于可提供较低的写入时延无在线EC的计算开销又能利用低数据冗余度的纠删码降低成本
离线EC缺点也较明显
* 架构复杂:包含多副本和纠错码两套存储子系统,系统间涉及数据搬迁,两者相互依赖
* 运维不友好:需管理两套存储集群,模块也更多,运维难度及风险较大
* IO开销高数据先写多副本再转存EC1个业务IO对应后台多份IO磁盘读写放大多IOPS及带宽额外开销大
**在线EC**
得益于CPU算力提升和指令集加速EC编解码计算不再是性能瓶颈在线 EC 逐步流行。
所谓**在线EC**是指系统在收到业务原始数据块时实时同步计算出冗余块与数据块一并下发存储无需再做数据的搬迁相比离线EC在线EC在架构简洁性、运维成本方面更具优势两者对比示意如下
![arc](./pic/ec-online.png)
在线EC也存在一些技术挑战
* 相比离线EC数据写入需实时计算得到冗余块有一定的时间开销
* 相比多副本,业务一次读写涉及更多存储节点,扇出大,易出现尾时延
* 适合于大文件,小文件有一定读写放大
CubeFS对这些问题做了大量针对性优化使得在线EC在实际生产可落地。
**3、块EC/条带EC策略**
计算 EC时数据需切片如果是 N+M 模式,那么用户数据切成 N 块,再生成 M 块校验块就是一个完整的 EC 条带数据。按照凑一个条带的数据方式我们可以分为“条带EC”"和“块EC”两种方式。
**块 EC**
* 定长条带,要凑满一个条带的数据才能去按照 N+M 切块做 EC ,每个条带长度固定,每个条带块长度固定;
* 凑条带的场景有点复杂会导致一个完整的用户数据可能跨条带元数据结构复杂一般使用于离线EC场景
![arc](./pic/ec-block.png)
**条带 EC**
* 直接把用户数据按照 N+M 切块做 EC
* 不需要再凑条带数据,一个用户数据就是完整条带,元数据结构简单;
![arc](./pic/ec-stripe.png)
CubeFS 使用的是更简单、更通用的条带 EC 的方式。
## 未来方向
1. 架构精简,降低对非必要组件的依赖
2. 小文件读写性能优化
3. 三副本卷的支持

View File

@ -1,19 +0,0 @@
纠删码存储计数揭秘
=======================
TODO
纠删码引擎系统设计
--------------------------
TODO
纠删码单机存储引擎
---------------------
TODO
均衡、巡检与故障自愈
---------------------
TODO

View File

@ -1,10 +1,8 @@
客户端
=========
# 客户端
客户端以用户态可执行程序的形式可以运行在容器中并且通过FUSE将挂载的卷及文件系统接口提供给其它用户态应用。
客户端缓存
-----------------------
## 客户端缓存
客户端进程在以下几种情况下会使用客户端缓存。
@ -12,29 +10,31 @@
客户端为了减少与元数据节点的通信会缓存inodedentry以及extent元数据信息。通常意义上读请求应该能够读到之前所有的写入但是客户端元数据缓存可能会导致多客户端写同一个文件时的一致性问题。所以CubeFS的设计中不同客户端或者说挂载点可以同时读一个文件但是不能够同时写一个文件注意不同进程可以从同一个挂载点并发写一个文件。打开文件时客户端会强制从元数据节点更新文件元数据信息。
由于故障恢复时raft复制组的主节点有可能发生变化导致客户端缓存的主节点地址无效。因此客户端在发送请求收到not leader回复时会轮询重试该复制组的所有节点。重试成功后识别出新的主节点客户端会缓存新的主节点地址。
由于故障恢复时raft复制组的主节点有可能发生变化导致客户端缓存的主节点地址无效。因此客户端在发送请求收到not
leader回复时会轮询重试该复制组的所有节点。重试成功后识别出新的主节点客户端会缓存新的主节点地址。
对接FUSE接口
-----------------------
## 对接FUSE接口
CubeFS客户端通过对接FUSE为提供用户态文件系统接口。之前性能较低被认为是用户态文件系统最大的缺点。但是经过多年的发展FUSE已经在性能上有了很大提高。后续CubeFS会着手开发内核态文件系统客户端。
目前来看FUSE的writeback cache特性并未达到预期的性能提升。FUSE默认的写流程走的是directIO接口使得每次写入长度较小时会有性能问题因为每次的写请求都会被推送至后端存储。FUSE的解决方案是writeback cache即小写入写到缓存页即返回由内核根据回刷策略推送至后端存储。这样顺序的小请求会被聚合。但是在实际生产中我们发现writeback cache特性作用非常有限原因是走writecache的写操作触发了内核balance dirty page的流程使得本应该是响应时间非常短的写操作仍然会等较长时间才返回。这个问题在小的写入时尤其明显。
目前来看FUSE的writeback
cache特性并未达到预期的性能提升。FUSE默认的写流程走的是directIO接口使得每次写入长度较小时会有性能问题因为每次的写请求都会被推送至后端存储。FUSE的解决方案是writeback
cache即小写入写到缓存页即返回由内核根据回刷策略推送至后端存储。这样顺序的小请求会被聚合。但是在实际生产中我们发现writeback
cache特性作用非常有限原因是走writecache的写操作触发了内核balance dirty
page的流程使得本应该是响应时间非常短的写操作仍然会等较长时间才返回。这个问题在小的写入时尤其明显。
## 客户端预热
客户端预热
-----------------------
客户端为了提高纠删卷的读取效率可以通过预热功能将纠删码子系统的数据缓存到副本子系统中。副本子系统中的缓存内容会在预热TTL过期后自动删除。
一级缓存(数据缓存)
-----------------------
## 一级缓存(数据缓存)
L1Cache是独立于客户端的本地数据缓存服务对外提供Put/Get/Delete接口基于数据块Block进行缓存读写、淘汰操作整体结构如下图所示。
.. image:: pic/block-cache.png
:align: center
:alt: block cache
![block cache](pic/block-cache.png){.align-center}
L1Cache缓存服务为本机所有打开一级缓存配置的客户端提供缓存服务。本地缓存数据块与远端存储数据块一一对应并按块进行索引BlockKey访问数据块索引BlockKey生成方式为VolumeName_Inode_hex(FileOffset)。数据块索引经过两次取模计算将内存数据块结构映射到本地缓存文件LocalPath
/ hash(BlockKey)%512 / hash(BlockKey)%256 /
BlockKey。L1CacheStoreService统一维护全局的BlockKeys定期按照LRU进行淘汰。
L1Cache缓存服务为本机所有打开一级缓存配置的客户端提供缓存服务。本地缓存数据块与远端存储数据块一一对应并按块进行索引BlockKey访问数据块索引BlockKey生成方式为VolumeName_Inode_hex(FileOffset)。数据块索引经过两次取模计算将内存数据块结构映射到本地缓存文件LocalPath / hash(BlockKey)%512 / hash(BlockKey)%256 / BlockKey。L1CacheStoreService统一维护全局的BlockKeys定期按照LRU进行淘汰。
L1Cache服务重启时自动扫描磁盘上的缓存数据并重建缓存索引信息。缓存目录的增加和退出不涉及数据迁移丢失的缓存数据重新缓存残留的缓存数据最终会被LRU淘汰。
L1Cache服务重启时自动扫描磁盘上的缓存数据并重建缓存索引信息。缓存目录的增加和退出不涉及数据迁移丢失的缓存数据重新缓存残留的缓存数据最终会被LRU淘汰。

View File

@ -0,0 +1,45 @@
# 副本子系统
副本子系统的设计是为了满足大、小文件支持顺序随机访问的多租户需求。采用两种不同的复制协议以确保副本之间的强一致性并在性能和代码可用性上进行一些权衡。也可以用作Cache节点搭建纠删码卷的二级cache
![Data Subsystem Architecture](../pic/data-subsystem.png){.align-center}
## 系统特性
- 大文件存储
对于大文件,内容存储为一个或多个扩展数据块的序列,这些扩展数据块可以分布在不同数据节点上的不同数据分区中。将新文件写入扩展数据块存储区始终会导致数据以新扩展数据块的零偏移量写入,这样就不需要在扩展数据块内进行偏移。文件的最后一个范围不需要通过填充来补齐大小限制(即该范围没有空洞),并且不会存储来自其他文件的数据。
- 小文件存储
将多个小文件的内容聚合存储在一个文件内,并将每个文件内容的物理偏移量记录在相应的元数据中。删除文件内容(释放此文件占用的磁盘空间)是通过底层文件系统提供的文件穿洞接口(`fallocate()`)实现的。这种设计的优点是不需要实现垃圾回收机制,因此在一定程度上避免使用从逻辑偏移到物理偏移的映射。
- 复制
成员间的文件复制根据文件写入模式CubeFS采用不同的复制策略。
当文件按顺序写入CubeFS时使用主备份复制协议来确保与优化的IO吞吐量的强一致性。
![image](../pic/workflow-sequential-write.png){.align-center}
在随机写入时覆盖现有的文件内容时我们采用了一种基于Multi-Raft的复制协议该协议类似于元数据子系统中使用的协议以确保强一致性。
![image](../pic/workflow-overwriting.png){.align-center}
- 故障恢复
由于存在两种不同的复制协议当发现复制副本上的故障时我们首先通过检查每个数据块的长度并使所有数据块对齐启动基于主备份的复制协议的恢复。一旦这个处理完成我们就开始在我们的基于Multi-Raft的恢复。
- 缓存数据
通过使用缓存类型的分区,实现缓存热数据,为纠删码卷提供缓存加速能力,在达到阈值的时候,动态的淘汰缓存中的冷数据。
## HTTP接口
| API | 方法 | 参数 | 描述 |
|-------------|------|--------------------------------|------------------------------------------|
| /disks | GET | N/A | 获取磁盘的列表和信息。 |
| /partitions | GET | N/A | 获取所有数据组的信息。 |
| /partition | GET | partitionId[int] | 获取特定数据组的详细信息。 |
| /extent | GET | partitionId[int]&extentId[int] | 获取特定数据组里面特定extent文件的信息。 |
| /stats | GET | N/A | 获取DATA节点的信息。 |

View File

@ -1,57 +0,0 @@
副本子系统
===================
副本子系统的设计是为了满足大、小文件支持顺序随机访问的多租户需求。采用两种不同的复制协议以确保副本之间的强一致性并在性能和代码可用性上进行一些权衡。也可以用作Cache节点搭建纠删码卷的二级cache
.. image:: ../pic/data-subsystem.png
:align: center
:alt: Data Subsystem Architecture
系统特性
----------
- 大文件存储
对于大文件,内容存储为一个或多个扩展数据块的序列,这些扩展数据块可以分布在不同数据节点上的不同数据分区中。将新文件写入扩展数据块存储区始终会导致数据以新扩展数据块的零偏移量写入,这样就不需要在扩展数据块内进行偏移。文件的最后一个范围不需要通过填充来补齐其大小限制(即该范围没有空洞),并且不会存储来自其他文件的数据。
- 小文件存储
将多个小文件的内容聚合存储在一个文件内并将每个文件内容的物理偏移量记录在相应的元数据中。删除文件内容释放此文件占用的磁盘空间是通过底层文件系统提供的文件穿洞接口fallocate实现的。这种设计的优点是不需要实现垃圾回收机制因此在一定程度上避免使用从逻辑偏移到物理偏移的映射。
- 复制
成员间的文件复制根据文件写入模式CubeFS采用不同的复制策略。
当文件按顺序写入CubeFS时使用主备份复制协议来确保与优化的IO吞吐量的强一致性。
.. image:: ../pic/workflow-sequential-write.png
:align: center
在随机写入时覆盖现有的文件内容时我们采用了一种基于Multi-Raft的复制协议该协议类似于元数据子系统中使用的协议以确保强一致性。
.. image:: ../pic/workflow-overwriting.png
:align: center
- 故障恢复
由于存在两种不同的复制协议当发现复制副本上的故障时我们首先通过检查每个数据块的长度并使所有数据块对齐启动基于主备份的复制协议的恢复。一旦这个处理完成我们就开始在我们的基于Multi-Raft的恢复。
- 缓存数据
通过使用缓存类型的分区,实现缓存热数据,为纠删码卷提供缓存加速能力,在达到阈值的时候,动态的淘汰缓存中的冷数据。
HTTP接口
-----------
.. csv-table::
:header: "API", "方法", "参数", "描述"
"/disks", "GET", "N/A", "获取磁盘的列表和信息。"
"/partitions", "GET", "N/A", "获取所有数据组的信息。 "
"/partition", "GET", "partitionId[int]", "获取特定数据组的详细信息。"
"/extent", "GET", "partitionId[int]&extentId[int]", "获取特定数据组里面特定extent文件的信息。"
"/stats", "GET", "N/A", "获取DATA节点的信息。"

View File

@ -1,11 +1,9 @@
资源管理子系统
==================
# 资源管理子系统
Master负责异步的处理不同类型的任务, 比如 创建/删除/更新/比对副本是否一致等数据分片和元数据分片的操作,管理数据节点和元数据节点的存活状态,创建和维护卷信息。
Master有多个节点它们之间通过raft算法保证元数据一致性并且把元数据持久化到RocksDB。
基于利用率的分布策略
------------------------
## 基于利用率的分布策略
基于利用率的分布策略放置文件元数据和内容是Master最主要的特征此分布策略能够更高效的利用集群资源。
数据分片和元数据分片的分布策略工作流程:
@ -16,14 +14,12 @@ Master有多个节点它们之间通过raft算法保证元数据一致性
1. 当新节点加入时,不需要重新做数据均衡,避免了因为数据迁移带来的开销。
2. 因为使用统一的分布策略, 显著降低了产生热点数据的可能性。
## 副本放置
副本放置
-----------
Master确保一个分片的多个副本都在不同的机器上。
Master确保一个分片的多个副本都在不同的机器上.
## 拆分元数据分片
拆分元数据分片
-----------------
满足下面任意一个条件,元数据分片将会被拆分
1. 元数据节点内存使用率达到设置的阈值比如总内存是64GB阈值是0.75如果元数据节点使用的内存达到48GB该节点上的所有元数据分片都将会被拆分.
2. 元数据分片占用的内存达到16GB
@ -31,9 +27,6 @@ Master确保一个分片的多个副本都在不同的机器上.
只有数据分片ID是卷所有数据分片中ID最大的才会真正被拆分。假设数据分片A符合拆分条件其inode范围是[0,正无穷)
则拆分后A的范围为[0,A.MaxInodeID+step),新生成的B分片的范围是[A.MaxInodeID+step+1正无穷)其中step是步长默认是2的24方.MaxInodeID是由元数据节点汇报。
异常处理
-----------
如果数据/元数据分片某个副本不可用 (硬盘失败、硬件错误等), 该副本上的数据最终会被迁移到新的副本上.
## 异常处理
如果数据/元数据分片某个副本不可用 (硬盘失败、硬件错误等), 该副本上的数据最终会被迁移到新的副本上。

View File

@ -0,0 +1,15 @@
# 元数据子系统
元数据子系统是一个以内存为中心的分布式数据结构是由一个或多个元数据分片组成。元数据子系统数据使用multiraft来充分使用服务器资源和保障数据高可用及强一致性可以很方便的迁移资源并通过分裂实现横向扩展。
## 元数据内部设计
每个元数据可以包含成百上千的元数据分片每个分片由InodeTreeBTree和DentryTreeBTree组成。每个Inode代表文件系统中的一个文件或目录 每个dentry代表一个目录项dentry由parentId和name组成。在DentryTree中以PartentId和name组成索引进行存储和检索在InodeTree中则以inode id进行索引。使用multiRaft协议保障高可用性和数据一致性复制,且每个节点集合会包含大量的分片组每个分片组对应一个raft group每个分片组隶属于某个volume每个分片组都是某个volume的一段元数据范围inode id范[100-20000) );元数据子系统通过分裂来完成动态扩容;当性一分片组的性能(包含如下指标:内存)紧接临近值时,资源管理器服务会预估一个结束点,并通知此组节点设备,只服务到此点之前的数据,同时也会新选出一组节点,并动态加入到当前业务系统中,新节点组其实点刚好是上个节点组的结束点位置。
## 复制
元数据更新的复制是以元数据分片为单位的。复制强一致性是通过Raft改良版本MultiRaft来实现的。MultiRaft减少了心跳通信的负担。
## 故障恢复
内存元数据分片通过快照的方式持久化到磁盘以作备份和恢复使用。日志压缩技术被用来减小日志文件大小和恢复时间。 值得一提的是元数据操作有可能会导致孤儿inode即只有inode但是没有对应的dentry。为了减少这种情况的发生首先元数据节点通过Raft保证高可用单点故障后可以迅速恢复其次客户端保证在一定时间内进行重试。

View File

@ -1,4 +0,0 @@
元数据管理设计
=================
TODO

View File

@ -0,0 +1,130 @@
# 对象存储子系统
对象存储系统提供兼容S3的对象存储接口。它使得CubeFS成为一个可以将两种通用类型接口进行融合的存储POSIX和S3兼容接口。可以使用户使用原生的Amazon
S3 SDK操作CubeFS中的文件。
## 框架
![image](../pic/cfs-object-subsystem-structure.png){.align-center}
ObjectNode是一个功能性的子系统节点。它根据需要从资源管理器Master获取卷视图卷拓扑
每个ObjectNode直接与元数据子系统MetaNode和副本子系统DataNode通信。
ObjectNode是一种无状态设计具有很高的可扩展性能够直接操作CubeFS集群中存储的所有文件而无需任何卷装入操作。
*暂不支持纠删码卷*
## 特性
- 支持原生的Amazon S3 SDKs的对象存储接口
- 支持两种通用接口的融合存储POSIX和S3兼容接口
- 无状态和高可靠性
## 语义转换
基于原有POSIX兼容性的设计。每个来自对象存储接口的文件操作请求都需要对POSIX进行语义转换。
| POSIX | Object Storage |
|----------|----------------|
| `Volume` | `Bucket` |
| `Path` | `Key` |
**示例:**
![image](../pic/cfs-object-subsystem-semantic.png){.align-center}
> Put object \'*example/a/b.txt*\' will be create and write data to file
> \'*/a/b.txt*\' in volume \'*example*\'.
## 用户
在使用对象存储功能前,需要先通过资源管理器创建用户。创建用户的同时,会为每个用户生成
*AccessKey* 和 *SecretKey* ,其中 *AccessKey*
是整个CubeFS集群中唯一的16个字符的字符串。
CubeFS以卷的 **Owner** 字段作为用户ID。创建用户的方式有两种
1. 通过资源管理器的API创建卷时如果集群中没有与该卷的Owner同名的用户时会自动创建一个用户ID为Owner的用户
2. 调用资源管理器的用户管理API创建用户链接
`/admin-api/master/user`{.interpreted-text role="doc"}
## 授权与鉴权
对象存储接口中的签名验证算法与Amazon
S3服务完全兼容。用户可以通过管理API获取用户信息请参见 **Get User
Information** ,链接: `/admin-api/master/user`{.interpreted-text
role="doc"} 。从中获取 *AccessKey* 和 *SecretKey*
后,即可利用算法生成签名来访问对象存储功能。
用户对于自己名下的卷,拥有所有的访问权限。用户可以授予其他用户指定权限来访问自己名下的卷。权限分为以下三类:
- 只读或读写权限;
- 单个操作的权限比如GetObject、PutObject等
- 自定义权限。
当用户使用对象存储功能进行某种操作时CubeFS会鉴别该用户是否拥有当前操作的权限。
## 临时隐藏数据
以原子方式在对象存储接口中进行写操作。每个写操作都将创建数据并将其写入一个不可见的临时对象。ObjectNode中的volume运算符将文件数据放入临时文件临时文件的元数据中只有\'
**inode**\'而没有\'**dentry**\'。当所有文件数据都成功存储时volume操作符在元数据中创建或更新\'**dentry**\'使其对用户可见。
## 对象名称冲突(重要)
POSIX和对象存储是两种不同类型的存储产品对象存储是一种键-值对存储服务。所以在对象存储中,名称为\'*a/b/c*\'和名称为\'*a/b*
\'的对象是两个完全没有冲突的对象。
不过CubeFS是基于POSIX设计的。根据语义转换规则对象名\'*a/b/c*\'中的\'*b*\'部分转换为文件夹\'*a*\'下的文件夹\'*b*\',对象名\'
*a/b*\'中的\'*b*\'部分转换为文件夹\'*a*\'下的文件\'*b*\'。
类似于上面这样的对象名称在CubeFS中是冲突的。
## 支持的S3兼容接口
### 桶接口
| API | Reference |
|---------------------|------------------------------------------------------------------------------|
| `HeadBucket` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html> |
| `GetBucketLocation` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLocation.html> |
### 对象接口
| API | Reference |
|-----------------|--------------------------------------------------------------------------|
| `HeadObject` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html> |
| `PutObject` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html> |
| `GetObject` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html> |
| `ListObjects` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html> |
| `ListObjectsV2` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html> |
| `DeleteObject` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html> |
| `DeleteObjects` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html> |
| `CopyObject` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html> |
### 并发上传接口
| API | Reference |
|---------------------------|------------------------------------------------------------------------------------|
| `CreateMultipartUpload` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html> |
| `ListMultipartUploads` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html> |
| `AbortMultipartUpload` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html> |
| `CompleteMultipartUpload` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html> |
| `ListParts` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html> |
| `UploadPart` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html> |
| `UploadPartCopy` | <https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html> |
## 支持的SDK
Object Node提供兼容S3的对象存储接口所以可以直接使用原生的Amazon S3
SDKs来操作文件。
| Name | Language | Link |
|-----------------------------------|--------------|-------------------------------------------|
| AWS SDK for Java | `Java` | <https://aws.amazon.com/sdk-for-java/> |
| AWS SDK for JavaScript | `JavaScript` | <https://aws.amazon.com/sdk-for-browser/> |
| AWS SDK for JavaScript in Node.js | `JavaScript` | <https://aws.amazon.com/sdk-for-node-js/> |
| AWS SDK for Go | `Go` | <https://docs.aws.amazon.com/sdk-for-go/> |
| AWS SDK for PHP | `PHP` | <https://aws.amazon.com/sdk-for-php/> |
| AWS SDK for Ruby | `Ruby` | <https://aws.amazon.com/sdk-for-ruby/> |
| AWS SDK for .NET | `.NET` | <https://aws.amazon.com/sdk-for-net/> |
| AWS SDK for C++ | `C++` | <https://aws.amazon.com/sdk-for-cpp/> |
| Boto3 | `Python` | <http://boto.cloudhackers.com> |

View File

@ -1,133 +0,0 @@
对象存储 (ObjectNode)
=============================
对象存储系统提供兼容S3的对象存储接口。它使得CubeFS成为一个可以将两种通用类型接口进行融合的存储POSIX和S3兼容接口。可以使用户使用原生的Amazon S3 SDK操作CubeFS中的文件。
框架
---------
.. image:: ../pic/cfs-object-subsystem-structure.png
:align: center
ObjectNode是一个功能性的子系统节点。它根据需要从资源管理器Master获取卷视图卷拓扑
每个ObjectNode直接与元数据子系统MetaNode和副本子系统DataNode通信。
ObjectNode是一种无状态设计具有很高的可扩展性能够直接操作CubeFS集群中存储的所有文件而无需任何卷装入操作。 *暂不支持纠删码卷*
特性
--------
- 支持原生的Amazon S3 SDKs的对象存储接口
- 支持两种通用接口的融合存储POSIX和S3兼容接口
- 无状态和高可靠性
语义转换
-------------------
基于原有POSIX兼容性的设计。每个来自对象存储接口的文件操作请求都需要对POSIX进行语义转换。
.. csv-table::
:header: "POSIX", "Object Storage"
"``Volume``", "``Bucket``"
"``Path``", "``Key``"
**示例:**
.. image:: ../pic/cfs-object-subsystem-semantic.png
:align: center
Put object '*example/a/b.txt*' will be create and write data to file '*/a/b.txt*' in volume '*example*'.
用户
--------------
在使用对象存储功能前,需要先通过资源管理器创建用户。创建用户的同时,会为每个用户生成 *AccessKey**SecretKey* ,其中 *AccessKey* 是整个CubeFS集群中唯一的16个字符的字符串。
CubeFS以卷的 **Owner** 字段作为用户ID。创建用户的方式有两种
1. 通过资源管理器的API创建卷时如果集群中没有与该卷的Owner同名的用户时会自动创建一个用户ID为Owner的用户
2. 调用资源管理器的用户管理API创建用户链接 :doc:`/admin-api/master/user`
授权与鉴权
--------------
对象存储接口中的签名验证算法与Amazon S3服务完全兼容。用户可以通过管理API获取用户信息请参见 **Get User Information** ,链接: :doc:`/admin-api/master/user` 。从中获取 *AccessKey**SecretKey* 后,即可利用算法生成签名来访问对象存储功能。
用户对于自己名下的卷,拥有所有的访问权限。用户可以授予其他用户指定权限来访问自己名下的卷。权限分为以下三类:
- 只读或读写权限;
- 单个操作的权限比如GetObject、PutObject等
- 自定义权限。
当用户使用对象存储功能进行某种操作时CubeFS会鉴别该用户是否拥有当前操作的权限。
临时隐藏数据
-------------------------
以原子方式在对象存储接口中进行写操作。每个写操作都将创建数据并将其写入一个不可见的临时对象。ObjectNode中的volume运算符将文件数据放入临时文件临时文件的元数据中只有'**inode**'而没有'**dentry**'。当所有文件数据都成功存储时volume操作符在元数据中创建或更新'**dentry**'使其对用户可见。
对象名称冲突(重要)
--------------------------------
POSIX和对象存储是两种不同类型的存储产品对象存储是一种键-值对存储服务。所以在对象存储中,名称为'*a/b/c*'和名称为'*a/b*'的对象是两个完全没有冲突的对象。
不过CubeFS是基于POSIX设计的。根据语义转换规则对象名'*a/b/c*'中的'*b*'部分转换为文件夹'*a*'下的文件夹'*b*',对象名'*a/b*'中的'*b*'部分转换为文件夹'*a*'下的文件'*b*'。
类似于上面这样的对象名称在CubeFS中是冲突的。
支持的S3兼容接口
----------------------------
桶接口
^^^^^^^^^^^
.. csv-table::
:header: "API", "Reference"
"``HeadBucket``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html"
"``GetBucketLocation``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLocation.html"
对象接口
^^^^^^^^^^^
.. csv-table::
:header: "API", "Reference"
"``HeadObject``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html"
"``PutObject``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html"
"``GetObject``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html"
"``ListObjects``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html"
"``ListObjectsV2``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html"
"``DeleteObject``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html"
"``DeleteObjects``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html"
"``CopyObject``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html"
并发上传接口
^^^^^^^^^^^^^^^^^^^^^
.. csv-table::
:header: "API", "Reference"
"``CreateMultipartUpload``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html"
"``ListMultipartUploads``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html"
"``AbortMultipartUpload``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html"
"``CompleteMultipartUpload``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html"
"``ListParts``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html"
"``UploadPart``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html"
"``UploadPartCopy``", "https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html"
支持的SDK
--------------
Object Node提供兼容S3的对象存储接口所以可以直接使用原生的Amazon S3 SDKs来操作文件。
.. csv-table::
:header: "Name", "Language", "Link"
"AWS SDK for Java", "``Java``", "https://aws.amazon.com/sdk-for-java/"
"AWS SDK for JavaScript", "``JavaScript``", "https://aws.amazon.com/sdk-for-browser/"
"AWS SDK for JavaScript in Node.js", "``JavaScript``", "https://aws.amazon.com/sdk-for-node-js/"
"AWS SDK for Go", "``Go``", "https://docs.aws.amazon.com/sdk-for-go/"
"AWS SDK for PHP", "``PHP``", "https://aws.amazon.com/sdk-for-php/"
"AWS SDK for Ruby", "``Ruby``", "https://aws.amazon.com/sdk-for-ruby/"
"AWS SDK for .NET", "``.NET``", "https://aws.amazon.com/sdk-for-net/"
"AWS SDK for C++", "``C++``", "https://aws.amazon.com/sdk-for-cpp/"
"Boto3", "``Python``", "http://boto.cloudhackers.com"

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

View File

@ -0,0 +1 @@
# 编译问题

View File

@ -0,0 +1 @@
# Fuse客户端问题

View File

@ -5,7 +5,8 @@
:maxdepth: 2
:caption: 概览
overview
overview/introduction
overview/architecture
.. toctree::
:maxdepth: 2
@ -23,7 +24,7 @@
user-guide/hotvol
user-guide/coldvol
user-guide/datanode
user-guide/cache
user-guide/file
user-guide/objectnode
user-guide/hadoop
@ -49,7 +50,7 @@
.. toctree::
:maxdepth: 0
:caption: 测试评估
evaluation/env
evaluation/tiny
evaluation/io
@ -59,26 +60,24 @@
:maxdepth: 2
:caption: 设计文档
design/master
design/metanode
design/blobstore.rst
.. toctree::
:maxdepth: 2
:caption: 开发指南
dev/guide
dev/code
design/datanode
design/blobstore
design/objectnode
design/client
design/authnode
.. toctree::
:maxdepth: 0
:caption: 社区
community/contributing
community/user
community/overview
community/article
.. toctree::
:maxdepth: 2
:caption: 常见问题
:caption: FAQ
faq
faq/build
faq/fuse

View File

@ -0,0 +1,23 @@
# 技术架构
![arc](../pic/cfs-arch-ec.png)
CubeFS由 **元数据子系统Metadata Subsystem** **数据子系统Data Subsystem** 和 **Master节点Master** 以及 **对象子系统Object Subsystem** 组成可以通过POSIX/HDFS/S3接口访问存储数据。
- **资源管理节点**由多个Master节点组成负责异步处理不同类型的任务如管理数据分片与元数据分片包括创建、删除、更新以及一致性检查等检查数据节点或者元数据节点的健康状态维护管理卷信息等
> Master节点可以有多个节点之前通过Raft算法保证元数据的一致性并且持久化到RocksDB中。
- **元数据子系统**由多个Meta Node节点组成多个元数据分片Meta Partition和Raft实例基于Multi-Raft的示例组成每个元数据分片表示一个Inode范围元数据其中包含两个内存B-Tree数inode BTree与dentry BTree。
> 元数据实例最少需要3个支持水平扩容
- **数据子系统**:分为副本子系统和纠删码子系统,两种子系统可同时存在,也都可单独存在:
- 副本子系统由Data Node组成每个节点管理一组 **数据分片**,多个节点的**数据分片**构成一个副本组;
- 纠删码子系统由多个BlobNode节点组成每个节点管理一组**数据块**,多个节点的**数据块**构成一个纠删码条带。
> 数据节点支持水平扩容
- **对象子系统**由对象节点组成提供了兼容标准S3语义的访问协议可以通过Amazon S3 SDK或者是s3cmd等工具访问存储资源。
- **卷**逻辑上的概念由多个元数据和数据分片组成从客户端的角度看卷可以被看作是可被容器访问的文件系统实例。从对象存储的角度来看一个卷对应着一个bucket。一个卷可以在多个容器中挂载使得文件可以被不同客户端同时访问。

View File

@ -0,0 +1,73 @@
# 什么是CubeFS
## 简介
CubeFS是新一代云原生存储产品目前是云原生计算基金会CNCF托管的孵化阶段开源项目
兼容S3、POSIX、HDFS等数据访问协议支持多副本与纠删码两种存储引擎为用户提供多租户、
多AZ部署以及跨区域复制等多种特性广泛应用于大数据、AI、容器平台、数据库、中间件存算分离、数据共享以及数据保护等场景。
<video width="100%" height="300" controls>
<source src="https://ocs-cn-north1.heytapcs.com/cubefs/community/video1657061611.mp4" type="video/mp4">
</video>
## 系统特性
### 多协议
CubeFS支持多种数据访问协议以满足不同的应用场景协议之间可以无缝转换不再需要元数据或数据的迁移让一份数据可以多协议访问。
- **POSIX兼容**兼容POSIX接口让上层应用的开发变得及其简单就跟使用本地文件系统一样便捷。此外CubeFS在实现时放松了对POSIX语义的一致性要求来兼顾文件和元文件操作的性能。
- **对象存储兼容**兼容AWS的S3对象存储协议用户可以使用原生的Amazon S3 SDK管理CubeFS中的资源。
- **Hadoop协议兼容**兼容Hadoop FileSystem接口协议用户可以使用CubeFS来替换Hadoop 文件系统( HDFS ),做到上层业务无感。
### 双引擎
CubeFS支持两种不同的存储引擎用户可以自由的选择是采用多副本模式或者是纠删码模式又或者是两种协议并存比如选择多副本作为数据缓存层以提升数据的访问性能选择纠删码引擎作为冷数据的底座以降低存储成本。
- **多副本存储引擎**:副本之间的数据为镜像关系,通过强一致的复制协议来保证副本之间的数据一致性,用户可以根据应用场景灵活的配置不同副本数。
- **纠删码存储引擎**:纠删码引擎具备高可靠、高可用、低成本、支持超大规模(EB)的特性不同AZ以及不同纠删码模式可以灵活搭配。
### 可扩展
CubeFS可以帮助你轻松组建PB或者EB级规模的分布式存储系统不管是元数据模块还是数据模块都支持无限水平扩展。
### 高性能
- **元数据管理**元数据集群为内存元数据存储在设计上使用两个B-TreeinodeBTree与dentryBTree来管理索引进而提升元数据访问性能
- **强一致副本协议**CubeFS根据文件写入方式的不同采用不同的复制协议来保证副本间的数据一致性。如果文件按照顺序写入则会使用主备复制协议来优化IO吞吐量如果是随机写入覆盖现有文件内容时则是采用一种基于Multi-Raft的复制协议来确保数据的强一致性
- **多级缓存**:纠删码卷支持多级缓存加速能力,针对热点数据,提供更高数据访问性能:
- 本地缓存可以在Client机器上同机部署BlockCache组件管理本地磁盘作为本地缓存. 可以不经过网络读取本地Cache当中的数据, 容量受本地磁盘限制;
- 全局缓存使用副本组件DataNode搭建的分布式全局Cache, 比如可以通过部署客户端同机房的SSD磁盘的DataNode作为全局cache, 相对于本地cache, 需要经过网络, 但是容量更大, 可动态扩缩容, 副本数可调。
![cache](../pic/cfs-cache.png)
### 多租户
CubeFS具有租户的概念可以创建不同的租户租户之间的数据隔离同时也支持租户与租户之间的数据共享以提升整个系统的资源利用率
## 应用场景
CubeFS作为一个云原生的分布式存储平台提供了多种访问协议因此其应用场景也非常广泛下面简单介绍几种比较典型的应用场景
### 大数据分析
兼容HDFS协议为Hadoop生态如Spark、Hive提供统一存储底座为计算引擎提供无限的存储空间以及大带宽的数据存储能力。
### 深度训练/机器学习
作为分布式并行文件系统支撑AI训练、模型存储及分发、IO加速等需求。
### 容器共享存储
容器集群可以将容器镜像的配置文件或初始化加载数据存储在CubeFS上在容器批量加载时实时读取。多POD间通过CubeFS共享持久化数据在POD故障时可以进行快速故障切换。
### 数据库&中间件
为数据库应用如MySQL、ElasticSearch、ClickHouse提供高并发、低时延云盘服务实现彻底的存算分离。
### 在线服务
为在线业务(如广告、点击流、搜索)或终端用户的图、文、音视频等内容提供高可靠、低成本的对象存储服务。
### 传统NAS上云
替换线下传统本地存储及NAS助力IT业务上云。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -1,4 +0,0 @@
如何使用对象存储
----------------
TODO

View File

@ -0,0 +1 @@
# 开启多级缓存

View File

@ -0,0 +1 @@
# 创建纠删码卷

View File

@ -1,4 +0,0 @@
如何创建就删吗卷
----------------
TODO

View File

@ -1,4 +0,0 @@
如何设置副本系统为缓存
----------------
TODO

View File

@ -0,0 +1 @@
# 对接容器

View File

@ -1,4 +0,0 @@
如何对接容器
----------------
TODO

View File

@ -0,0 +1 @@
# 使用文件存储

View File

@ -1,4 +0,0 @@
如何使用文件存储
----------------
TODO

View File

@ -0,0 +1 @@
# 对接Hadoop

View File

@ -1,4 +0,0 @@
如何使用对接Hadoop
----------------
TODO

View File

@ -0,0 +1 @@
# 创建副本卷

View File

@ -1,4 +0,0 @@
如何创建副本卷
----------------
TODO

View File

@ -0,0 +1 @@
# 对接Kubernetes

View File

@ -1,4 +0,0 @@
如何对接Kubenetes
----------------
TODO

View File

@ -0,0 +1 @@
# 使用对象存储

View File

@ -1,4 +0,0 @@
如何使用对象存储
----------------
TODO