首先,Gridfs基于MongoDB,易用易扩展。而文件系统则老练且成熟稳定。
网传XXX公司用Gridfs存储海量图片,本文记录了测试Gridfs与文件系统在存储1.2KB与7.5KB的小图片文件时的读取性能对比。图片的文件名为8位数字,从0开始每2位建1个目录最多3层。比如文件:01234567.jpg 存储路径为 01/23/45/01234567.jpg (测试脚本)。
使用Nginx的gridfs模块直接读取文件系统和Gridfs里的文件。
MongoDB配置:
测试环境:
场景一:
向文件系统和Gridfs各存入100万张约1.2KB的图片,随机访问前3万张图片。测试结果如下图:
1、MongoDB的瓶颈在CPU,而文件系统的瓶颈交替出现在带宽和磁盘IO上
2、由于被查询的数据少,MongoDB完全将其缓存到内存里,完全没有磁盘IO
3、从现象看,文件系统的缓存不间断的被置入和移出内存,导致性能不稳定。命中缓存则带宽瓶颈,否则磁盘IO跑满(缓存命中率是多么重要啊!)
4、此场景下,文件系统性能明显优于MongoDB
场景二:
向文件系统和Gridfs各插入100万张约7.6KB的图片,随机访问这100万张图片。测试结果如下图:
Gridfs:
FileSystem:
结论:
1、由于随机范围大导致内存无法Hold住所有数据,两者瓶颈都定位在磁盘IO
2、使用Gridfs时的iops要高于直接文件系统时,但Gridfs的CPU占用率要低
3、Gridfs读取磁盘的数据量居然达到文件系统的近10倍
4、此场景下Gridfs的读取性能只有文件系统的1半
随后又进行了42KB的图片测试,MongoDB的读取性能仍是比文件系统的一半稍好一点。没有本质变化,正如Gridfs排头第1句据说,它就是为存储大文件所设计的。用它来存大文件或许性能能追求甚至超越原生的文件系统吧……
OK,先到这里。MongoDB的官网有说明“Gridfs适合存储海量大文件,不适合存储少量小文件”,而这里的少量和海量没有确切的定义。通过这两个测试结果来看,如果使用Gridfs存储小文件,若是追求性能且必须采用集群(CPU)和高性能存储介质(IO)。还不如使用大内存的服务器+分布式文件系统来得好。因为一旦内存足够,使用文件系统就非常强大了;而此时Gridfs毕竟还是基于数据库的,需要CPU也足够给力。