使用Java中的并发性在光盘上创建键值存储

del*_*met 4 java concurrency file-io file file-mapping

我需要读取一组文件并将其分解为键值对,并将这些文件保存为光盘上该键的(键,值列表),就像map-reduce范例一样.但是一切都在一台电脑上.例如,我可以在不同文件上写入不同的列表,并使用密钥命名文件.这似乎是一种非常糟糕的做事方式.首先,如果你有十亿个密钥,你将得到十亿个文件.显然这不会起作用,我需要某种内存映射.我还必须有不同的线程来做map工作,所以如果他们要写入这个相同的缓冲区,它们之间必须有某种同步.如果我有一个键值缓冲区映射,并通过缓冲区同步,那么线程不应该踩到彼此的脚趾,所以我认为该部分应该工作.问题是如何将值映射到光盘.如何编写与同一文件中不同键对应的缓冲区?如果有人能指出我正确的方向,我将不胜感激.我对这方面的了解非常可怜.再次感谢.

eri*_*son 5

从实用的角度来看,正如Lirik建议的那样,用BerkeleyDB很容易做到这一点.

如果你对理论比对实践更感兴趣,我建议你把它作为一种"外部排序"操作.也就是说,尽可能多地读入内存中的输入,然后按键排序.将排序的块作为单个文件写出.然后可以将排序的文件轻松合并到单个文件中.

在其他应用程序中,这是Lucene用于构建用于搜索文本的"反向索引"的方法."键"是文档中的单词,"值"是单词出现的文档列表.Lucene读取文档,并为每个单词在内存中创建一个术语到文档的条目.当内存已满时,它会将索引段写入磁盘.当磁盘上有很多索引段时,它们会合并为一个段.事实上,你也可以让Lucene的索引编写器适应你的任务.

工作可以划分为多个线程.但是,您必须对磁盘争用敏感.跳过同时读取和写入许多文件将大大减慢传统驱动器的速度.可能有机会同时安排一些活动.在将先前排序的块写入磁盘时,您可能会从一个文件中读取新数据,尤其是在计算机有两个磁盘驱动器的情况下.当然,使用SSD临时存储某些已排序的段会有很大帮助.