对象存储 客户端最佳实践

这篇说说OFS SDK高吞吐读取实践与内存使用控制:通过块大小、预读块及全局缓存配置,在顺序读与随机读场景下调优吞吐,并规避OOM风险。 顺序读:客户端游标检测顺序读后启用预读逻辑,按预读块个数缓存内存,可调块大小与线程数。 随机读:不触发预读,建议调整块大小以减少读放大。 内存控制:单文件控制内存与磁盘cache上限,全局按文件系统粒度限制上传下载内存。

相关产品
对象存储 产品页,含版本规格、价格与购买入口。

一、前提条件

已参见 挂载元数据加速桶 完成 ofs 客户端配置。

二、高吞吐实践

客户端每次从桶中读取数据的大小,通过配置项 fs.ofs.block.memory.trunk.byte 进行控制。

配置项 配置项内容 说明
fs.ofs.block.memory.trunk.byte 1048576 对象块大小,单位为字节,默认值1048576,即1MB

注意:说明:

注意:若你使用 COSN SDK,需要在以上配置项名称前添加 fs.cosn.trsf ,例如 fs.cosn.trsf.fs.ofs.prev.read.block.count。

在高吞吐场景中,客户端引入了预读块逻辑,将一个文件拆分为多个预读块,缓存至内存中,降低读取时延,提升吞吐。你可以通过指定预读块的参数,满足不同场景的吞吐需求。

三、顺序读场景

客户端内部会通过游标检测当前的场景是否为顺序读,若为顺序读场景,则会启用预读逻辑,否则不会使用。预读逻辑中,客户端会固定每次缓存的预读块个数,相关配置项如下,你可以根据机型配置进行相关的参数调优。

配置项 配置项内容 说明
fs.ofs.prev.read.block.count 16 预读块的个数,默认值为16
fs.ofs.prev.read.block.release.enable true 是否从内存中释放已读完的块,默认值为 true
fs.ofs.block.max.read.memory.cache.mb 16 单个文件可用内存量,默认值为16,单位为MB说明:为避免 OOM,你可以参考下文内存使用实践,控制全局 cache 模型。
fs.ofs.data.transfer.thread.count 32 从桶中拉取预读块的 IO 线程池核心线程数
fs.ofs.data.transfer.max.thread.count Integer.MAX_VALUE IO 线程池最大线程数

四、随机读场景

如上文所说,客户端会检测当前场景,若为随机读,则不会触发预读逻辑。另外,此场景下,建议你根据实际业务场景,调整配置项 fs.ofs.block.memory.trunk.byte,修改每次读取 COS 桶的数据大小,避免随机读场景中的读放大。

五、客户端内存使用实践

为提升性能,OFS SDK 在上传和下载数据过程中,会对数据进行 cache。这里的 cache 包括内存 cache 和磁盘 cache,并在上传和下载中有不同的应用:

·上传:使用内存 cache + 磁盘 cache

·下载:只会使用内存 cache

其中,内存 cache 块是按需申请的, 优先申请内存 cache 块, 当内存 cache 块不足后,会申请磁盘 cache 块。磁盘 cache 在写入数据过程中会使用堆外内存,以减少堆内内存与内核态的内存之间的 copy,从而提升写入数据的性能。

为避免多个文件互相影响(例如某个文件未关闭,资源未释放时,导致新的读写无法打开),SDK 总体默认原则是控制单个文件使用的 cache 数量。同时,为避免 OOM 问题,客户端提供全局(文件系统粒度)的缓存配置项,你可以根据客户端环境调整配置,以实现最优性能。

六、单文件 cache 控制模型

OFS SDK 使用以下两个配置项分别控制单个文件的 cache 使用量:

配置项 配置项内容 说明
fs.ofs.block.max.memory.cache.mb 16 内存 cache 使用量,默认值为16,单位为MB
fs.ofs.block.max.file.cache.mb 256 磁盘 cache 使用量,默认值为256,单位为MB

注意:说明:

注意:若你使用 COSN SDK,需要在以上配置项名称前添加 fs.cosn.trsf ,例如 fs.cosn.trsf.fs.ofs.block.max.memory.cache.mb。

七、全局(文件系统粒度)cache 控制模型

SDK 提供对于读、写两种请求的全局(文件系统粒度)cache 控制,以规避 OOM 问题。具体说明如下:

上传下载

OFS SDK 共提供三个配置项用于控制全局上传内存:

配置项 配置项内容 说明
fs.ofs.block.total.memory.cache.mb 0 上传最大内存使用量,默认值为0(不控制),单位MB
fs.ofs.block.total.memory.cache.percent 100 上传最大内存使用比例,默认值为100,单位为百分比
fs.ofs.block.total.memory.jvm.heap.percent 0 最大 JVM 内存使用比例,默认值为0(不控制),单位为百分比

SDK 共提供两种全局控制:

·规则1:通过 fs.ofs.block.total.memory.cache.mb 与 fs.ofs.block.total.memory.cache.percent 控制上传最大内存使用量。配置后,最大使用的内存大小为:fs.ofs.block.total.memory.cache.mb * fs.ofs.block.total.memory.cache.percent / 100。当配置后,SDK 会根据算出的全局内存 cache 大小 / 单个文件最大大小 fs.ofs.block.max.memory.cache.mb,计算出能同时写入的文件量,以此来分配信号。新打开文件时候,会申请1个信号量,当申请失败后,会强制使用磁盘 cache。 当文件关闭时候,会归还信号量。

·规则2:通过 fs.ofs.block.total.memory.jvm.heap.percent 控制最大 JVM 内存。配置后,SDK 会获取 JVM 最大内存(ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getMax()) * fs.ofs.block.total.memory.jvm.heap.percent / 100 来确定。

默认情况下,fs.ofs.block.total.memory.cache.mb 与 fs.ofs.block.total.memory.jvm.heap.percent 值为0,即不会对内存进行任何控制。若两个配置项均为非0,则规则1(最大内存使用量)优先级高于规则2(最大 JVM 内存使用量)。

OFS SDK 共提供两个配置项用于控制全局下载内存:

配置项 配置项内容 说明
fs.ofs.block.total.read.memory.cache.mb 0 下载最大内存使用量,默认值为0(不控制),单位MB
fs.ofs.block.total.read.memory.cache.percent 100 下载最大内存使用比例,默认值为100,单位为百分比

SDK 通过 fs.ofs.block.total.read.memory.cache.mb 与 fs.ofs.block.total.read.memory.cache.percent 控制下载最大内存使用量。配置后,最大使用的内存大小为:fs.ofs.block.total.read.memory.cache.mb * fs.ofs.block.total.read.memory.cache.percent / 100。当配置后,SDK 会根据算出的全局内存 cache 大小 / 单个文件最大大小 fs.ofs.block.max.memory.cache.mb,计算出能同时写入的文件量,以此来分配信号。新打开文件时候,会申请1个信号量,当申请失败后,会强制使用磁盘 cache。 当文件关闭时候,会归还信号量。申请通过队列实现阻塞机制的,当信号量不足时候,会等待其他文件关闭释放信号量。

赞 (0)
上一篇 5天前
下一篇 5天前