首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >小文件海量存储策略

小文件海量存储策略
EN

Stack Overflow用户
提问于 2013-04-29 12:52:08
回答 2查看 749关注 0票数 5

对于数百万个小文件(平均大小约为50 KB )的大容量存储,并自动修剪超过20分钟的文件,什么是好的策略?我需要从web服务器写入和访问它们。

我目前正在使用ext4,在删除期间(计划在cron中),硬盘使用率会达到100%,同时flush-8:0显示为创建负载的进程。此负载会干扰服务器上的其他应用程序。当没有删除时,最大HDD利用率为0-5%。嵌套和非嵌套目录结构的情况相同。最糟糕的是,峰值负载期间的批量删除似乎比插入速度慢,因此需要删除的文件量越来越大。

我尝试过改变调度程序(deadline,cfq,noop),但没有帮助。我也尝试过将didn设置为删除脚本,但也无济于事。

我在MongoDB 2.4.3上试用过GridFS,它运行得很好,但在批量删除旧文件时就很糟糕了。我试过在关闭日志(nojournal)和没有对delete和insert进行写确认(w=0)的情况下运行MongoDB,但没有帮助。只有在没有删除操作的情况下,它才能快速而流畅地工作。

我也尝试过在MySQL 5.5中存储数据,在BLOB列中,在InnoDB表中,将InnoDB引擎设置为使用innodb_buffer_pool=2GB,innodb_log_file_size=1GB,innodb_flush_log_on_trx_commit=2,但性能更差,硬盘负载始终在80%-100% (预期,但我必须尝试)。表仅使用BLOB列、DATETIME列和CHAR(32) latin1_bin UUID,并对UUID和DATETIME列使用索引,因此没有优化的空间,并且所有查询都使用索引。

我查看了pdflush设置(在批量删除期间创建负载的Linux刷新进程),但更改这些值没有任何帮助,因此我恢复为默认值。

我运行自动修剪脚本的频率并不重要,每1秒,每1分钟,每5分钟,每30分钟,无论哪种方式,它都会严重中断服务器。

我曾尝试存储inode值,并在删除时,通过首先按inode编号对旧文件进行排序来按顺序删除旧文件,但没有帮助。

使用固态硬盘6。硬盘为CentOS RAID 1。

对于我的任务,什么是好的、合理的解决方案,可以解决自动修剪性能问题?

EN

回答 2

Stack Overflow用户

发布于 2013-04-29 15:35:37

删除是一种性能麻烦,因为数据和元数据都需要在磁盘上销毁。

它们真的需要是单独的文件吗?旧文件真的需要删除吗,或者如果它们被覆盖了就可以了吗?

如果第二个问题的答案是“不”,试试这个:

  • 保留了一个大致按时间排序的文件列表。
  • 当你想写一个新文件时,找一个比你要替换的文件更大的旧文件。不是删除旧文件,而是将其truncate()到适当的长度,然后覆盖其内容。确保你更新了你的旧文件列表。
  • 清理那些没有被明确替换的真正的旧文件。
  • 在这些文件中建立一个索引可能是有好处的。尝试使用到实际文件系统的充满符号链接的tmpfs

通过将文件分块到可管理大小的子目录中,您可能会也可能不会在此方案中获得性能优势。

如果你对同一文件中有多个东西没问题:

  • 通过将每个文件作为偏移量存储到大小相似的文件数组中,从而将大小相似的文件放在一起。如果每个文件都是32k或64k,则保留一个包含32k区块的完整文件和一个包含64k区块的文件。如果文件是任意大小,向上舍入到2的下一个幂。
  • 您可以在这里通过跟踪每个文件的陈旧程度来执行延迟删除。如果您正在尝试编写内容,并且某些内容已过时,请覆盖它,而不是附加到文件的末尾。

另一种想法是:通过将所有文件按inode顺序truncate()到长度0,然后对它们执行unlink()操作,是否可以获得性能优势?无知让我不知道这是否真的有帮助,但它似乎会让数据归零和元数据写入类似的在一起。

还有另一种想法:与使用data=ordered的ext4相比,XFS的写排序模型更弱。它在XFS上是否足够快?

票数 2
EN

Stack Overflow用户

发布于 2013-04-29 20:22:55

如果批量删除数百万个文件会导致性能问题,您可以通过一次删除所有文件来解决此问题。您可以创建一个新的(空的)文件系统来代替旧的文件系统,而不是使用任何文件系统操作(如“删除”或“截断”)。

为了实现这个想法,你需要将你的硬盘分割成两个(或更多)分区。在一个分区已满后(或20分钟后),您开始写入第二个分区,同时使用第一个分区进行只读。再过20分钟,卸载第一个分区,在其上创建空文件系统,再次挂载它,然后开始写入第一个分区,同时将第二个分区用于只读。

最简单的解决方案是只使用两个分区。但是这种方式并不能有效地利用磁盘空间:您可以在同一驱动器上存储的文件减少两倍。使用更多的分区,您可以提高空间效率。

如果出于某种原因,您需要将所有文件放在一个位置,请使用tmpfs将指向每个分区上的文件的链接存储起来。这需要从tmpfs批量删除数百万个链接,但这减轻了性能问题,因为只应删除链接,而不是文件内容;此外,这些链接只能从内存中删除,而不能从固态硬盘中删除。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16271386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档