对于数百万个小文件(平均约50 KB)的大容量存储有什么好的策略,自动修剪超过20分钟的文件?我需要从Web服务器编写和访问它们。
我目前正在使用ext4,并且在删除期间(在cron中安排),当[flush-8:0]显示为创建负载的进程时,HDD使用率高达100%。此负载会干扰服务器上的其他应用程序。如果没有删除,则最大HDD利用率为0-5%。嵌套和非嵌套目录结构的情况相同。最糟糕的是,峰值负载期间的质量去除似乎比插入速率慢,因此需要删除的文件数量越来越大。
我尝试过更改调度程序(截止日期,cfq,noop),但没有帮助。我也试过设置ionice来删除脚本,但它也没有帮助。
我已经尝试过使用MongoDB 2.4.3的GridFS,它表现很好,但在大量删除旧文件时很糟糕。我已经尝试运行MongoDB关闭日志(nojournal)并且没有写入确认删除和插入(w = 0)并且它没有帮助。只有在没有删除的情况下,它才能快速顺畅地工作。
我还尝试在InnoDB表中的BLOB列中的MySQL 5.5中存储数据,InnoDB引擎设置为使用innodb_buffer_pool = 2GB,innodb_log_file_size = 1GB,innodb_flush_log_on_trx_commit = 2,但性能更差,HDD负载总是在80%-100%(预计,但我不得不尝试)。表仅使用BLOB列,DATETIME列和CHAR(32)latin1_bin UUID,UUID和DATETIME列上的索引,因此没有优化空间,并且所有查询都使用索引。
我已经研究了pdflush设置(在大规模删除过程中创建负载的Linux刷新过程),但更改值对任何事情没有帮助,所以我恢复了默认值。
我运行自动修剪脚本的频率并不重要,每1秒,每1分钟,每5分钟,每30分钟一次,无论哪种方式都会中断服务器。
我试图存储inode值,并且在删除时,先删除旧文件,然后先用它们的inode编号对它们进行排序,但它没有帮助。
使用CentOS 6. HDD是SSD RAID 1.
对于解决自动修剪性能问题的任务,什么是好的和合理的解决方案?
答案 0 :(得分:2)
删除是一种性能上的麻烦,因为数据和元数据都需要在磁盘上销毁。
他们真的需要成为单独的文件吗?是否真的需要删除旧文件,或者如果它们被覆盖就可以了吗?
如果第二个问题的答案是“否”,请尝试以下方法:
truncate()
吹走到适当的长度,然后覆盖其内容。确保更新旧文件列表。tmpfs
完整的符号链接到真实文件系统。通过将文件分块到可管理大小的子目录,您可能会或可能不会在此方案中获得性能优势。
如果你可以在同一个文件中存放多个内容:
另一个想法是:通过truncate()
以inode顺序将所有文件设置为长度为0然后unlink()
来获得性能优势?无知阻止我知道这是否真的有用,但似乎它会将数据归零并且元数据类似地写在一起。
另一个想法是:XFS的写入排序模型比具有data=ordered
的ext4弱。它在XFS上足够快吗?
答案 1 :(得分:2)
如果批量删除数百万个文件会导致性能问题,您可以通过一次“删除”所有文件来解决此问题。您可以只创建一个新的(空)文件系统来代替旧文件系统,而不是使用任何文件系统操作(如“删除”或“截断”)。
要实现此想法,您需要将驱动器拆分为两个(或更多)分区。一个分区已满(或20分钟后),您开始写入第二个分区,而第一个分区仅用于读取。再过20分钟后,卸载第一个分区,在其上创建空文件系统,再次安装,然后开始写入第一个分区,同时使用第二个分区进行只读。
最简单的解决方案是仅使用两个分区。但是这样您就不会非常有效地使用磁盘空间:您可以在同一个驱动器上存储两次较少的文件。使用更多分区可以提高空间效率。
如果由于某种原因您需要在一个位置放置所有文件,请使用tmpfs
存储每个分区上文件的链接。这需要从tmpfs
批量删除数百万个链接,但这可以缓解性能问题,因为只应删除链接,而不是文件内容;这些链接也只能从RAM中删除,而不能从SSD中删除。