我有1500万个简单的键/值记录。密钥大小都是单个单词,它们包含的值的大小范围从几个字节到10MB不等。
随机密钥需要频繁访问。
我认为将这些文件存储在目录中而不是数据库中会更有效。因此,我需要的不是一个包含所有这些条目的大表,而是一个目录,文件名作为键,文件中的值。
这意味着如果我想要键azpdk
的值,我只需要在PHP中file_get_contents('/my/directory/azpdk')
,而不是用这样的请求麻烦MySQL。
在我的头脑中,这是有意义的,我希望使用文件系统而不是数据库来实现这一点更有效。我的假设正确吗?当一个目录中有1500万个文件时,这仍然是快速和高效的吗?
文件系统是xfs
对于这类事情,您可能希望查看数据库(不一定是MySQL)而不是文件系统,原因如下:
一个目录下的文件多会减慢速度
虽然XFS被认为在分配资源方面非常聪明,但是大多数文件系统在单个目录中拥有的文件越多,性能就会下降。在命令行上处理它们也变得令人头痛。看一下这个(http://oss.sgi.com/projects/xfs/datasheet.pdf),上面有一个关于查找的图表,每个目录最多只有50k,而且它正在下降。
头顶每个文件都有一定数量的文件系统开销。如果您有许多小文件,您可能会发现最终的存储会因此而膨胀。
键清洗
你的所有单词都可以安全地放在文件名中吗?你确定吗?一两个斜杠真的会毁了你的一天。
NoSQL可能是一个不错的选择
像MongoDB/Redis这样的东西可能是一个很好的选择。MongoDB可以存储最大16mb的单个文档,使用起来并不比将文件放在文件系统上困难多少。如果您要存储15mb的文档,那么您可能会觉得这个限制有点太接近了,但是还有其他选择。这样做的好处是,查找性能可能会非常好,如果您稍后发现它不是,您可以通过创建集群等方式扩展性能。任何这样的系统都可以很好地智能管理磁盘上的文件,从而获得良好的性能。
如果您要使用磁盘
考虑使用你想要存储的单词的MD5哈希值,并以此作为文件名的基础。例如azpdk
的MD5为:
1c58fb66d5a4d6a1ebe5ec9e217fbbf9
你可以用这个来创建一个文件名,例如:
my_directory/1c5/8fb/66d5a4d6a1ebe5ec9e217fbbf9
这有几个很好的特性:
- 哈希处理可怕的字符
- 目录分散数据,所以没有目录有超过4096个条目
- 这意味着查找性能应该相对不错
希望对你有帮助。
我在一家基因组学研究中心工作,那里的生物信息学专家并不是特别有经验的程序员。
与其使用数据库,它们中的一些会生成数百万个小文件,直到文件系统停止运行。