繁体   English   中英

如何加快对大量文本文件 (1TB) 的搜索

[英]How to speed up a search on large collection of text files (1TB)

我有一组包含匿名医疗数据(年龄、国家、症状、诊断等)的文本文件。 这些数据至少可以追溯到 30 年,所以你可以想象我有一个相当大的数据集。 我总共有大约 20,000 个文本文件,总计约。 1TB。

我需要定期搜索这些文件以查找特定字符串(不是正则表达式)的出现。 搜索这些数据的最快方法是什么?

我尝试使用 grep 并递归搜索目录,如下所示:

LC_ALL=C fgrep -r -i "searchTerm" /Folder/Containing/Files

这样做的唯一问题是搜索这些数据需要几个小时(有时是半天)。

有没有更快的方法来搜索这些数据? 目前我对不同的方法持开放态度,例如数据库、elasticsearch 等。如果我沿着数据库路线执行 go,我将有大约。 10 亿条记录。

我唯一的要求是:

1) 搜索将在我的本地计算机上进行(双核 CPU 和 8GB RAM)

2)我将搜索字符串(不是正则表达式)。

3) 我需要查看所有出现的搜索字符串及其所在的文件。

已经有很多答案了,我只想加两分钱:

  1. 仅使用 8 GB 的 memory 就拥有如此庞大的数据(1 TB)对于任何方法来说都不够好,无论是使用 Lucene 还是 Elasticsearch(内部使用 Lucene)或某些 Z4A037FBAC753C858478ZECF 命令,如果您想要更快的搜索6,64792C616很简单,所有这些系统都将数据保存在最快的 memory 中,以便能够更快地提供服务并且超过 8 GB(您应该为操作系统保留 25%,至少为其他应用程序保留另外 25-50%),您只剩下很少的 GB内存。
  2. 升级 SSD,增加系统上的 RAM 会有所帮助,但这会非常麻烦,而且如果遇到性能问题,将很难对系统进行垂直扩展。

建议

  1. 我知道您已经提到您想在您的系统上执行此操作,但正如我所说,它不会带来任何真正的好处,而且您最终可能会浪费很多时间(基础和代码方面(各种答案中提到的很多方法) )),因此建议您按照我的另一个答案中提到的自上而下的方法来确定正确的容量 它将帮助您快速确定您选择的任何方法的正确容量。
  2. 关于实施方面,我建议使用 Elasticsearch(ES),因为它很容易设置和扩展,您甚至可以使用AWS Elasticsearch ,它也可以在免费层中使用,稍后可以快速扩展,尽管我我不是 AWS ES 的忠实拥护者,它节省了大量的设置时间,如果您对 ES 非常熟悉,您可以快速上手。

  3. 为了使搜索更快,您可以将文件拆分为多个字段(标题、正文、标签、作者等)并仅索引重要字段,这将减少倒排索引的大小,如果您只寻找精确的字符串匹配(没有部分或全文搜索),那么您可以简单地使用keyword字段,索引和搜索速度更快。

  4. 我可以 go 关于为什么 Elasticsearch 很好以及如何优化它,但这不是关键,底线是任何搜索都需要大量的 ZCD69B4957F06CD818D7ZBF3D61980E291和其他应用程序,因此建议您真正考虑在外部系统上执行此操作,并且 Elasticsearch 确实是分布式系统和当今最流行的开源搜索系统的代表。

为了加快搜索速度,您需要一个倒排索引 为了能够添加新文档而无需重新索引所有现有文件,索引应该是增量的。

Apache Lucense 是最早引入增量索引的开源项目之一。 它仍然是使用最广泛的索引和搜索引擎,尽管扩展其功能的其他工具现在更受欢迎。 Elasiticsearch 和 Solr 都基于 Lucense。 但只要您不需要 web 前端,支持分析查询、过滤、分组、支持索引非文本文件或在多个主机上设置集群的基础设施,Lucene 仍然是最佳选择。

Apache Lucense是一个 Java 库,但它附带了一个全功能、基于命令行的演示应用程序 这个基本演示应该已经提供了您需要的所有功能。

借助一些 Java 知识,也可以轻松地使应用程序适应您的需求。 您会惊讶于演示应用程序的源代码是多么简单。 如果 Java 不应该是您选择的语言,那么它的 Pyhton 包装器PyLucene也可能是一种替代方案。 演示应用程序的索引已几乎减少到最低限度。 默认情况下,不使用高级功能,例如复杂查询的词干提取或优化 - 功能,您的用例很可能不需要,但会增加索引的大小和索引时间。

正如几乎每个答案都建议的那样,您显然需要一个索引。 你可以完全改进你的硬件,但既然你说它是固定的,我不会详细说明。

我有一些相关的建议给你:

  1. 仅索引您要在其中查找搜索词的字段,而不是索引整个数据集;
  2. 创建多级索引(即索引上的索引),以便您的索引搜索更快。 如果您的索引增长到超过 8 GB,这将特别重要;
  3. 我想建议将您的搜索缓存作为替代方案,但这将导致新的搜索再次需要半天时间。 因此,预处理数据以构建索引显然比在查询到来时处理数据要好。

小更新:

这里的很多答案都建议您将数据放在云中。 即使是匿名的医疗数据,我也强烈建议您向来源确认(除非您从网络上抓取数据),这样做是可以的。

我为您看到了 3 个选项。

  1. 你真的应该考虑升级你的硬件, hdd -> ssd upgrade 可以使搜索速度成倍增加。

  2. 提高现场搜索的速度。 您可以参考此问题以获取各种建议。 此方法的主要思想是优化 CPU 负载,但您会受到 HDD 速度的限制。 最大速度乘数是您的核心数量。

  3. 您可以索引您的数据集。 因为您正在处理文本,所以您需要一些全文搜索数据库。 Elasticsearch 和 Postgres 是不错的选择。 此方法需要更多磁盘空间(但通常小于 x2 空间,具体取决于数据结构和要索引的字段列表)。 这种方法将无限快(秒)。 如果您决定使用此方法,select 分析器配置会仔细匹配您任务的单个单词( 这里是 Elasticsearch 的示例

值得从两个层面讨论该主题:方法和要使用的特定软件。

方法:根据您描述数据的方式,看起来预索引将提供重要帮助。 预索引将对数据执行一次扫描,并将构建一个紧凑的索引,以便执行快速搜索并确定特定术语在存储库中的显示位置。

根据查询,索引将减少或完全消除搜索实际文档的必要性,即使对于复杂的查询,例如“查找 AAA 和 BBB 一起出现的所有文档”。

特定工具

您描述的硬件是相对基础的。 运行复杂的搜索将受益于大内存/多核硬件。 那里有很好的解决方案——弹性搜索、solr 和类似的工具可以发挥神奇的作用,只要有强大的硬件支持它们。

我相信您想研究两个选项,具体取决于您的技能,以及 OP 的数据(这将有助于共享数据样本)。 * 使用轻量级数据库(sqlite、postgresql)构建您自己的索引,或者 * 使用轻量级搜索引擎。

对于第二种方法,使用描述硬件,我建议查看“一瞥”(以及支持的 agrep 实用程序)。 Glimple 提供了一种对数据进行预索引的方法,这使得搜索速度非常快。 我已经在大数据存储库(几 GB,但从来没有 TB)上使用过它。

见: https://github.com/gvelez17/glimpse

显然,它不像 Elastic Search 那样现代且功能丰富,但更容易设置。 它是无服务器的。 OP 描述的用例的主要好处是能够扫描现有文件,而无需将文档加载到额外的搜索引擎存储库中。

如果 elasticsearch 具有一致的数据结构格式,您能否考虑将所有这些数据摄取到?

If yes, below are the quick steps:
1. Install filebeat on your local computer
2. Install elasticsearch and kibana as well.
3. Export the data by making filebeat send all the data to elasticsearch. 
4. Start searching it easily from Kibana.

Fs Crawler可能会帮助您将数据索引到 elasticsearch 中。之后,正常的 elasticsearch 查询可以成为搜索引擎。

我认为如果您缓存最近搜索的医疗数据,它可能有助于提高性能,而不是遍历整个 1TB,您可以使用 redis/memcached

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM