限制内存以加载大文件并查找 phone 数字。

limit memory to load large file and look for a phone number.

一个非常大的文件中有十亿个条目,每个条目包含一个名称和his/her phone 编号。

我需要设计系统来输入姓名并快速找到 his/her phone 号码。棘手的部分是,内存无法加载这么大的文件。我正在考虑将数据传输到内存中,并且可能使用一些多线程技术,但是,我不确定如何决定我应该使用多少线程。

尚未在网上找到此类问题,也不确定解决此问题的一般规则是什么。

有人可以给我一些建议吗?

我可以想到几种方法:

Approach 1: Single file reader thread, multiple processing threads

  1. 在单线程中读取(流)文件
  2. 在阅读时将每条记录推入队列
  3. 会有多个线程监视队列中的记录,这将从队列中pop一条记录并检查名称是否匹配
  4. 如果名称匹配,它将把数字放入结果队列并通知文件reader和其他线程停止进一步处理
  5. 如果名称不匹配,它将继续到队列中的下一条记录

这将确保您不会使用太多内存,因为处理线程将从队列中弹出记录。但这里的问题是 I/O 很可能比匹配输入名称慢,因此您可能无法使处理线程饱和(请参阅有关选择多少线程的问题的答案)。

Approach 2: Multiple file reader threads, multiple processing threads

  1. 在多个线程中读取文件,通过划分每个线程查看的文件部分
  2. 其余步骤与方法 1 类似

这里棘手的部分是如何在多个 reader 线程之间划分文件部分。使用随机访问文件可以工作,但会很混乱。 一种更好的方法可能是拥有多个较小的文件,而不是拥有一个大文件,每个文件都可以很容易地被多个线程搜索。您还可以考虑先将文件按名字的第一个字母分成更小的块,然后进一步分成更小的块,每个块有 10000 条记录。

这种方法应该会给你更好的并行性。

How many threads should you use

我的建议是阅读 Java 并发实践 第 11 章,即使您不使用 Java,它也是一个很好的资源这个问题的答案:

Java Concurrency in Practice - Chapter 11