【问题标题】:What are the drawbacks of using a Lucene directory as a primary file store?使用 Lucene 目录作为主文件存储有哪些缺点?
【发布时间】:2017-12-25 14:51:16
【问题描述】:

我想使用 Lucene MMapDirectory 作为主要文件存储。每个文件将作为StoredField 中的字节数组 存储在单独的文档中。所有应该可搜索的文件属性,如文件名、大小等,都将存储在同一文档的可索引字段中。

我的问题是:

  1. 使用 Lucene 目录存储文件有哪些缺点,尤其是在索引和搜索性能以及内存 (RAM) 消耗方面?
  2. 如果这不是“不行”,有没有比字节数组更好/更快的方式在目录中存储文件?

【问题讨论】:

    标签: elasticsearch lucene memory-mapped-files memory-mapping file-storage


    【解决方案1】:

    简答

    我真的很喜欢 Luсene,并认为它是最好的开源库,但我担心将它用作主要文件源并不是一个好的决定,因为:

    • 高 CPU/内存开销
    • 索引/查询性能缓慢
    • HDD 利用率高,索引大小翻倍
    • 恢复能力较弱

    长答案

    在底层,lucene 使用以下文件将所有存储的字段保存在一个段中:

    • 字段索引文件 (.fdx),
    • 字段数据文件 (.fdt)。

    您可以在Lucene50StoredFieldsFormat’s docs 中了解更多关于它的工作原理。

    1. 这意味着如果出现任何 I/O 问题,几乎不可能恢复任何文件。
    2. 为了返回一个文件 - lucene 必须以逐块方式从磁盘读取和解压缩二进制数据。这意味着高 CPU 开销来解压缩和高内存占用以将整个文件保留在 Java 堆空间中。与文件和网络存储相比,也没有流媒体可用。
    3. 最大文档大小受编解码器实现的限制 - 每个文档 2 GB
    4. Lucene 具有独特的一次写入分段架构:最近索引的文档以仅追加、一次写入的方式写入一个新的自包含分段:一旦写入,这些分段文件将永远不会再更改。当使用过多的 RAM 来保存最近索引的文档时,或者当您要求 Lucene 刷新您的搜索器以便您可以搜索所有最近索引的文档时,就会发生这种情况。随着时间的推移,较小的段被合并成更大的段,并且索引在任何时候都具有活动段文件的对数“阶梯”结构。这种架构成为文件存储的一个大问题:
      • 您不能删除文件 - 只能标记为不可用
      • 合并操作需要 2 倍的磁盘空间并消耗大量资源和磁盘吞吐量 - 它创建新的 .fdt 文件并通过 java 代码和 java 堆内存复制其他 .fdt 文件的内容

    【讨论】:

    • 感谢您提供详细而详尽的答案。由于我是 Lucene 的新手,所以我非常热衷于尝试仅使用 Lucene 来解决与搜索和存储数据相关的任何事情。我很高兴像你这样的人花时间告诉像我这样的“新手”,它也有一些“弱点”,并不是每个问题的最佳/最佳解决方案:)
    【解决方案2】:

    因此,您不会使用 MMapDirectory,而是使用实际的 lucene 索引。

    我在使用 lucene 作为一些项目的主要数据存储方面取得了很好的经验。

    请确保还包含生成的/自然的唯一 ID,因为文档 ID 不是恒定的或可靠的。

    还要确保您使用适合您的用例的目录实现。我已经切换到低负载情况下的普通 RandomAccess 实现,因为它使用更少的内存并且几乎一样快。

    【讨论】:

    • 感谢您的建议。请问您在使用 Lucene 索引作为数据存储时是否遇到过持久性问题?根据我读过的文章,在调用IndexWriter.commit() 之后,索引以及所有存储的数据都应该是持久的。在实践中,您是否曾经遇到过数据不可恢复或索引完全损坏的问题?显然,如果我知道单个写入错误或系统崩溃可能会破坏整个存储,我不会使用 Lucene 来存储大量文件。
    猜你喜欢
    • 2014-05-27
    • 1970-01-01
    • 2016-07-15
    • 2021-11-11
    • 2016-05-15
    • 1970-01-01
    • 2011-02-26
    • 2011-12-11
    • 1970-01-01
    相关资源
    最近更新 更多