cubefs/docs-zh/source/design/client.md
hooklee2000 163b2dd780 Use 1320 document
Signed-off-by: hooklee2000 <hooklee2000@gmail.com>
2023-08-24 20:23:22 +08:00

4.5 KiB
Raw Blame History

客户端

客户端以用户态可执行程序的形式可以运行在容器中并且通过FUSE将挂载的卷及文件系统接口提供给其它用户态应用。

客户端缓存

客户端进程在以下几种情况下会使用客户端缓存。

  • 客户端为了减少与资源管理节点的通信负担,会在挂载启动时获取该挂载卷中所有元数据和数据节点的地址,并且进行缓存,后续会定期从资源管理节点进行更新。

  • 客户端为了减少与元数据节点的通信会缓存inodedentry以及extent元数据信息。通常意义上读请求应该能够读到之前所有的写入但是客户端元数据缓存可能会导致多客户端写同一个文件时的一致性问题。所以CubeFS的设计中不同客户端或者说挂载点可以同时读一个文件但是不能够同时写一个文件。打开文件时客户端会强制从元数据节点更新文件元数据信息。

::: warning 注意 不同进程可以从同一个挂载点并发写一个文件,但是需要解决数据并发写导致的错乱问题 :::

由于故障恢复时raft复制组的主节点有可能发生变化导致客户端缓存的主节点地址无效。因此客户端在发送请求收到not leader回复时会轮询重试该复制组的所有节点。重试成功后识别出新的主节点客户端会缓存新的主节点地址。

对接FUSE接口

CubeFS客户端通过对接FUSE为提供用户态文件系统接口。

::: tip 提示 之前性能较低被认为是用户态文件系统最大的缺点。但是经过多年的发展FUSE已经在性能上有了很大提高。后续CubeFS会着手开发内核态文件系统客户端。 :::

目前来看FUSE的writeback cache特性并未达到预期的性能提升。

FUSE默认的写流程走的是directIO接口使得每次写入长度较小时会有性能问题因为每次的写请求都会被推送至后端存储。

FUSE的解决方案是writeback cache即小写入写到缓存页即返回由内核根据回刷策略推送至后端存储。这样顺序的小请求会被聚合。

但是在实际生产中我们发现writeback cache特性作用非常有限原因是走writecache的写操作触发了内核balance dirty page的流程使得本应该是响应时间非常短的写操作仍然会等较长时间才返回这个问题在小的写入时尤其明显。

在线升级或热重启

支持不停止旧客户端进程进行在线升级。新客户端会先恢复旧客户端FUSE读写请求接替并继续服务旧客户端的数据读写请求。

程序执行如下操作:

  1. 旧客户端停止从/dev/fuse读取请求

  2. 旧客户端保存上下文信息到本地

    上下文信息包括还在fuse客户端和内核之间的、使用中已经打开open或者没有被驱逐evicted的inodes/files

  3. 旧客户端传输/dev/fuse的文件描述符

    使用Unix域套接字Unix Domain Socket向新客户端传输文件描述符

  4. 旧客户端退出,新客户端启动

  5. 新客户端恢复上下文

    新客户端尝试恢复旧客户端的上下文而不是真实挂载fuse。

  6. 恢复/dev/fuse文件描述符

    新客户端读取的旧客户端未处理的请求,继续服务。

LiveUpgrade

客户端预热

客户端为了提高纠删卷的读取效率可以通过预热功能将纠删码子系统的数据缓存到副本子系统中。副本子系统中的缓存内容会在预热TTL过期后自动删除。

一级缓存(数据缓存)

L1Cache是独立于客户端的本地数据缓存服务对外提供Put/Get/Delete接口基于数据块Block进行缓存读写、淘汰操作整体结构如下图所示。

block cache

L1Cache缓存服务为本机所有打开一级缓存配置的客户端提供缓存服务。

本地缓存数据块与远端存储数据块一一对应并按块进行索引BlockKey访问数据块索引BlockKey生成方式为VolumeName_Inode_hex(FileOffset)

::: tip 提示 数据块索引经过两次取模计算将内存数据块结构映射到本地缓存文件,LocalPath / hash(BlockKey)%512 / hash(BlockKey)%256 / BlockKey。 :::

L1CacheStoreService统一维护全局的BlockKeys定期按照LRU进行淘汰。

L1Cache服务重启时自动扫描磁盘上的缓存数据并重建缓存索引信息。缓存目录的增加和退出不涉及数据迁移丢失的缓存数据重新缓存残留的缓存数据最终会被LRU淘汰。