使用太多目录提高性能

时间:2018-01-15 10:15:22

标签: java linux file window filesystems

在我的项目中,用户可以在服务器上上传一些文件(大约10个文件)。

我决定创建一个名为每个用户的目录,并将其文件上传到相应的目录中。

用户可以直接在url => {url}/users/userId/file1.jpg

中访问其文件夹

因为用户数量会增加(1M),所以会有很多文件夹。我该怎么做才能提高绩效?

2 个答案:

答案 0 :(得分:1)

一些数学:1M用户* 10个文件* 1M + - = 10To

如果我是你,我会创建一个映射在{url} / users

上的servlet / REST端点

然后在我的代码中我会有一张地图

Map<String, String> firstLetterToDisk将userId的第一个字母映射到路径

例如:

"a" -> "/disk1/users
"b" -> "/disk1/users
....
"y" -> "/diskN/users
"z" -> "/diskN/users

在我的代码中,我将构建文件的真实路径并将文件内容作为响应流式传输

通过这种设置,您可以平衡数据和多个磁盘上的负载

编辑:

将第一个字母映射到磁盘不是主要的一点。

重点是使用规则从文件系统中解析url。

答案 1 :(得分:1)

我肯定会对有代表性的用户数进行一些测试。如果你开始有100万用户,那么你应该对100万个帐户进行性能测试,看看它是如何保持的。

您没有指定您正在使用的操作系统和/或文件系统。假设它是Linux,你应该不会遇到性能问题:ext3,ext4和其他现代文件系统都有索引目录,这使得访问目录中的各个子目录/文件变得非常快。

您仍然可以通过管理目录的大小来提升性能,但它不会达到数量级。

但是还有其他限制:在ext3上,目录中最多可以包含32000个子目录,而在ext4中,最多只能包含64000个。因此,/users下不能拥有100万个帐户即使这不会导致任何性能问题。

您可以使用帐户名称的前一个或两个字母来创建子目录:

String directory = "/users/" + username.charAt(0)+ "/" + username.charAt(1) + "/" + username;
// assuming that usernames need to be at least 2 letters, otherwise extra guards are needed

但是这会让你更频繁地集中在更频繁出现的字母的目录中,例如“e”。在整个用户名上使用散列函数可以更好地分发。

您还可以在数据库中记录用户的主目录,从而为您提供更多自由决定权。如果每个目录不需要超过1000个文件,则可以创建1000个编号的子目录,并将每个新创建的帐户循环分配给其中一个存储桶。

注意:虽然Mumrah的关注点可能与较旧的操作系统相关,但在使用逻辑卷管理器的Linux上,您无需担心物理磁盘大小,因为您可以根据需要轻松地跨文件系统扩展文件系统。