概述
本文主要基于Turbo文件系统的特性,介绍在使用时重点需要关注的使用方法和姿势,以便用户能更合适的使用。
场景一:目录结构规划实践
背景说明
该实践主要应用在使用 Turbo 文件系统下,如何更好的进行目录结构和文件数的分配,以实现更高的性能和更低的延时。
使用建议
当您的业务不涉及频繁删除/修改/新增的情况下,例如以读为主,建议单目录下子目录和文件数控制在10个 - 100万个。
当您的业务涉及频繁删除/修改/新增的情况下,建议单目录下子目录和文件数控制在10个 - 1万个。
建议单个文件系统实例的目录总数控制在1500万以内,避免创建过多的目录。
具体方案
1. 可根据哈希或时间,对文件进行分层、分类存放,避免在一个子目录下存放过多文件。
哈希码串区段分类:一个64个字符的哈希码串,头2个字符形成一级子目录,次2个字符形成二级子目录,二级子目录下放文件。哈希函数统计特性良好时,文件可以比较均匀地分布到65536个目录。文件系统文件规模为6亿时,每一个目录平均1万个文件;文件系统文件规模为12亿时,每一个目录平均2万个文件。
时间分类:年月日构成第一级子目录,小时构成第二级子目录,分钟构成第三级子目录。
2. 通过文件名的前缀来区分,避免嵌套很多层目录之后,仅存放一个文件,造成目录数远大于文件数的情况。例如:
原存储方式:/cfs/1/2/3/4/5/6/file1
建议存储方式:/cfs/1_2_3_4_5_6_file1
底层原理
客户端访问文件系统时,都会基于 VFS layer 进行操作,VFS 层在处理多进程同时读写相同文件时,会串行的进行锁的授予和召回。那么当某个客户端的 IO 在某一层超大目录下时,因 VFS 串行的锁操作行为,会导致 IO 延时变大。
CFS Turbo 为强一致的文件系统,其后端通过一套分布式锁的服务,来实现任意时刻数据均为一致状态。因此客户端在执行 IO 操作,会涉及到后端分布式锁的授予或召回。当大量文件集中在同一层目录下时,尤其是涉及到频繁写操作时(写锁为互斥锁),当此目录下发生读请求后,会额外涉及到对写锁的召回和授予,进而对读取速度产生负面影响。
CFS Turbo 底层的元数据是分布式的架构,每一个目录下的文件的元数据都是打散在内部多个对象上。因此,创建目录的资源开销会大于文件的开销,建议用户把目录数量控制在合理的范围内(单实例1500万目录以内),避免达到系统规格上限,影响使用。
场景二:文件系统根目录(或浅层目录)操作实践
背景说明
该实践主要应用在使用 Turbo 文件系统下,如何对根目录(或浅层目录)的操作进行规划。
使用建议
尽量避免对根目录或浅层目录进行大量的写操作。
需要避免业务侧的探活程序直接对 CFS 的根目录做写探测。
具体方案
1. 业务侧的程序写入分目录执行,不要在根目录或浅层目录执行高负载的写入。
2. 关闭对 CFS Turbo 的写探测,新建一个单独的子目录做写探测,或者使用腾讯云提供的探活指标进行告警监控,通过对 告警指标 中的客户端检测健康成功率来判断该实例是否正常运行。
底层原理
Turbo 文件系统为强一致文件系统,对根目录或浅层目录的写操作,会对根目录或浅层目录加上独占的写锁。读请求访问发生的时候,会依次查询路径上的目录项,需要拿到每一层级目录的读锁。当有大量对根目录的写探测,同时再叠加上高压力的读取请求,会产生高频且不必要的锁授予和召回的操作,会拖慢整个系统的访问速度,进而影响业务访问效率。
场景三:客户端销毁/关机实践
背景说明
该实践主要应用在需要对访问 Turbo 的客户端进行销毁或者停止时,如何进行合适的操作,避免因强制关机等问题,导致业务访问异常。
使用建议
当需要销毁客户端机器时,不要对客户端节点进行强制关机,应使用软关机的方式进行。
当需要卸载 Turbo 文件系统时,使用 umount 方式进行卸载,不要使用
umount -f
强制卸载。具体方案
步骤1:实例关机
方式1:调用 API 接口关机
调用 StopInstances 接口进行关机,StopType 选择 SOFT_FIRST。此方案会优先进行正常关机,当5分钟内未正常关机后,再执行强制关机。此方案能在保证 Turbo 正常使用的情况下,兼顾关机的时效性。
方式2:通过控制台操作关机
1. 登录 云服务器控制台,选中需要关机的云服务器,单击关机。
2. 选择关机方式为关机。
说明:
调用 API 关机时,请勿将 StopType 选择 hard 模式,此模式为强制关机。
在控制台上关机时,请勿选择强制关机,选择关机即可,此选项默认为 SOFT_FIRST。
正常的关机启动,会有序终止进程,并执行 sync 操作,可有效降低拉闸式关机对 Turbo 分布式锁的影响。
步骤2:销毁实例
底层原理
CFS Turbo 为强一致文件系统,通过分布式锁的机制,保证客户端数据的一致性。如果客户端未通过正常途径就断开和服务端的连接,会导致此客户端持有的锁无法正常释放,进而影响其他客户端访问对应的文件。
说明:
若异常断开后,客户端的锁会在一个超时时间范围后释放(默认为2分钟),多其他客户端最多会造成2分钟的 io hang。为了避免不必要的 io hang,建议通过上文提到的 SOFT_FIRST 方式进行关机。
场景四:客户端挂载文件系统实践
背景说明
该实践主要适用于以下场景:
客户端需要同时挂载多个不同的 Turbo 文件系统。
客户端需要对同一个 Turbo 文件系统挂载至不同的路径。
基于此实践,可以避免因客户端设备数超限,导致扩容受阻、挂载新文件系统失败、客户端响应变慢等问题发生。
说明:
在一个客户端上,10个及以内的 Turbo 文件系统挂载,可正常使用。更高的数量的挂载,建议参考此实践进行操作。
使用建议
当您需要在同一客户端挂载多个 Turbo 文件系统时,建议每个文件系统只保留一个原始挂载点,避免不必要的重复挂载。
当您需要在同一个客户端不同路径挂载访问同一个 Turbo 文件系统时,建议采用
bind mount
方式派生访问点,详情请参考下方具体方案。具体方案
1. 查看设备使用情况,当设备数接近8192,建议您按照后续步骤进行处理。
lctl get_param -n devices | wc -l
2. 检查是否存在重复挂载的集群。
mount | grep turbo | awk '{print $1}' | sort | uniq -c | grep -v "1 "# 示例# 3 30.x.x.x@tcp:/01234567/cfs/ # 表示该文件系统被重复挂载3次
3. 清理不必要的挂载点,保留主挂载点,利用 bind mount 派生挂载点。
# 原始挂载方案(消耗设备数)# sudo mount.lustre 30.x.x.x@tcp:/01234567/cfs/ /mnt/turbo_primary1# sudo mount.lustre 30.x.x.x@tcp:/01234567/cfs/ /another/path/to/mount/mount -t lustreumount /another/path/to/mount/# 使用 bind mount 派生挂载点(不消耗设备数)mount --bind /turbo/primary1 /another/path/to/mount/
4. 验证设备使用是否达到预期。
5. 如需在设备重启后保持 bind mount,可参考 自动挂载文件系统,使用 fstab 或 systemd 手动实现重启后自动挂载。
底层原理
MDT(Metadata Target) 和 OST(Object Storage Target) 为服务端提供的元数据节点和数据节点,MDC(Metadata Client) 和 OSC(Object Storage Client)为客户端对应通信的代理组件。每个 MDT/MDC 或 OST/OSC 被抽象为单个“设备”,每个设备会与客户端建立对应的连接。Turbo 软件栈为避免过多的连接影响已有挂载点的稳定性和性能,限制了设备数不超过8192。
bind mount
作为 Linux 内核提供的功能,允许您将一个已挂载的文件系统或目录重新挂载到另一个位置,只在内核层面创建新的挂载点,复用现有的超级块,而不会创建新的设备或超级块,从而更高效地利用资源,也能有效避免设备数超过8192的限制。