使用 lucene 改进多线程索引

2024-03-04

我正在尝试使用多个线程在 Lucene 中构建索引。因此,我开始编码并编写了以下代码。首先,我找到文件,并为每个文件创建一个线程来索引它。之后,我加入线程并优化索引。它有效,但我不确定......我可以大规模信任它吗?有什么办法可以改善吗?

import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Document;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.StopAnalyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.apache.lucene.index.TermFreqVector;

public class mIndexer extends Thread {

    private File ifile;
    private static IndexWriter writer;

    public mIndexer(File f) {
    ifile = f.getAbsoluteFile();
    }

    public static void main(String args[]) throws Exception {
    System.out.println("here...");

    String indexDir;
        String dataDir;
    if (args.length != 2) {
        dataDir = new String("/home/omid/Ranking/docs/");
        indexDir = new String("/home/omid/Ranking/indexes/");
    }
    else {
        dataDir = args[0];
        indexDir = args[1];
    }

    long start = System.currentTimeMillis();

    Directory dir = FSDirectory.open(new File(indexDir));
    writer = new IndexWriter(dir,
    new StopAnalyzer(Version.LUCENE_34, new File("/home/omid/Desktop/stopwords.txt")),
    true,
    IndexWriter.MaxFieldLength.UNLIMITED);
    int numIndexed = 0;
    try {
        numIndexed = index(dataDir, new TextFilesFilter());
    } finally {
        long end = System.currentTimeMillis();
        System.out.println("Indexing " + numIndexed + " files took " + (end - start) + " milliseconds");
        writer.optimize();
        System.out.println("Optimization took place in " + (System.currentTimeMillis() - end) + " milliseconds");
        writer.close();
    }
    System.out.println("Enjoy your day/night");
    }

    public static int index(String dataDir, FileFilter filter) throws Exception {
    File[] dires = new File(dataDir).listFiles();
    for (File d: dires) {
        if (d.isDirectory()) {
        File[] files = new File(d.getAbsolutePath()).listFiles();
        for (File f: files) {
            if (!f.isDirectory() &&
            !f.isHidden() &&
            f.exists() &&
            f.canRead() &&
            (filter == null || filter.accept(f))) {
                Thread t = new mIndexer(f);
                t.start();
                t.join();
            }
        }
        }
    }
    return writer.numDocs();
    }

    private static class TextFilesFilter implements FileFilter {
    public boolean accept(File path) {
        return path.getName().toLowerCase().endsWith(".txt");
    }
    }

    protected Document getDocument() throws Exception {
    Document doc = new Document();
    if (ifile.exists()) {
        doc.add(new Field("contents", new FileReader(ifile), Field.TermVector.YES));
        doc.add(new Field("path", ifile.getAbsolutePath(), Field.Store.YES, Field.Index.NOT_ANALYZED));
        String cat = "WIR";
        cat = ifile.getAbsolutePath().substring(0, ifile.getAbsolutePath().length()-ifile.getName().length()-1);
        cat = cat.substring(cat.lastIndexOf('/')+1, cat.length());
        //doc.add(new Field("category", cat.subSequence(0, cat.length()), Field.Store.YES));
        //System.out.println(cat.subSequence(0, cat.length()));
    }
    return doc;
    }

    public void run() {
    try {
        System.out.println("Indexing " + ifile.getAbsolutePath());
        Document doc = getDocument();
        writer.addDocument(doc);
    } catch (Exception e) {
        System.out.println(e.toString());
    }

    }
}

任何hep都被视为。


如果你想并行化索引,你可以做两件事:

  • 并行调用 addDocument,
  • 增加合并调度程序的最大线程数。

您走在并行调用 addDocuments 的正确道路上,但为每个文档生成一个线程不会随着需要索引的文档数量的增长而扩展。你应该使用固定大小线程池执行器 http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html。由于此任务主要是 CPU 密集型任务(取决于您的分析器和检索数据的方式),因此将计算机的 CPU 数量设置为最大线程数可能是一个好的开始。

关于合并调度程序,您可以增加可使用的最大线程数ConcurrentMergeScheduler 的 setMaxThreadCount 方法 http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/api/core/org/apache/lucene/index/ConcurrentMergeScheduler.html#setMaxThreadCount%28int%29。请注意,磁盘在顺序读/写方面比随机读/写要好得多,因此,为合并调度程序设置过高的最大线程数更有可能减慢索引而不是加快索引速度。

但在尝试并行化索引过程之前,您可能应该尝试找出瓶颈所在。如果您的磁盘太慢,瓶颈可能是刷新和合并步骤,因此并行调用 addDocument (主要是分析文档并将分析结果缓冲在内存中)不会提高索引速度根本不。

一些旁注:

  • Lucene 的开发版本中正在进行一些工作,以提高索引并行性(特别是刷新部分,这博客条目 http://www.searchworkings.org/blog/-/blogs/lucene-indexing-gains-concurrency解释了它是如何工作的)。

  • Lucene 有一个不错的 wiki 页面如何提高索引速度 http://wiki.apache.org/lucene-java/ImproveIndexingSpeed您可以在其中找到提高索引速度的其他方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 lucene 改进多线程索引 的相关文章

  • 当表有聚集索引时,数据是如何存储的

    我发现了无数的帖子 开头都是这样的很多时候我遇到人们说 聚集索引根据聚集索引键对表内的数据进行物理排序 这不是真的 然后这些帖子继续描述它是如何通过链表或其他方式实际存储的 例如 这个post http sqlwithmanoj wordp
  • 为 Nimbus 外观设计简单的单元渲染器

    我有一个简单的单元格渲染器 它由一些组成JLabels 渲染器本身扩展JPanel 并且我正在尝试让它在 Nimbus 的外观和感觉中合理地渲染 基本上发生的事情是在lighter行 正如 Nimbus 所具有的交替行着色 我的特定单元格渲
  • 通过蓝牙将字符串从作为客户端的 PC 发送到作为服务器的移动设备

    我需要通过蓝牙将字符串从 PC 传输到 Android 移动设备的帮助 Android 移动设备应充当服务器并在设备屏幕上显示字符串消息 作为客户端的 PC 应该将字符串发送到移动设备 我希望服务器对提取的字符串 通过蓝牙传输 做出反应 这
  • Gradle中的build-by-convention深度解释是什么?

    The 摇篮用户指南 http www gradle org docs current userguide userguide html经常提到 Gradle 是陈述性的和用途按惯例构建 这是什么意思 据我了解 这意味着 例如 在java插
  • Jersey 客户端异步 POST 请求不等待响应

    我创建了一个简单的 Jersey 客户端 它能够成功地使用有效负载执行 POST 请求 但现在它正在等待来自 http 端点的响应 public void callEndpoint String endpoint String payloa
  • 在 foreach 循环中启动一个新线程

    我有一个对象列表 我想循环该列表并启动一个新线程 传入当前对象 我写了一个我认为应该这样做的例子 但它不起作用 具体来说 线程似乎在每次迭代中都被覆盖 但这对我来说并没有什么意义 因为我每次都会创建一个新的 Thread 对象 这是我写的测
  • 我在 Android Studio 中使用哪个版本的 JDK 有关系吗?

    I know I can choose the SDK location in Android Studio s Project Structure 我有两个问题 当我们已经使用Android SDK时 为什么还需要JDK 毕竟我们不是为
  • 创建UML图时应该编写构造函数吗?

    我有一项作业要求我为实际的 Java 程序创建 UML 图 但程序中有几个构造函数方法 我很困惑 我是否应该将这些构造函数方法添加到图中 根据 UML 规范 2 5 版第 11 4 4 节 构造函数是一个具有所属类类型的单个返回结果参数的操
  • 如何将多个值存储到一个键(java)

    我搜索一个可以存储多个键值对的数据结构 数据基本上是这样的 1 value 1 2 value 2 于是我想到了使用HashMap 遗憾的是 这对我不起作用 因为一个键可能会出现多个值 在上面的例子中 1 value 2 可能是另一个条目
  • Java SSO 与 Wildfly 8、Java 1.8.0_45 和 Active Directory

    我对这个主题进行了很多搜索 但找不到解决方案 要求的简短描述 Wildfly 8 2 下 Web 应用程序上的 SSO 在 Active Directory 中验证 Windows 用户的身份 当 SSO 失败时回退到登录表单 在 Wild
  • 在同一个容器但不同的耳朵中使用本地EJB

    我正在尝试在同一个 Glassfish 但不同的耳朵中使用本地 EJB 但是Glassfish找不到本地EJB或者无法消费 我读到了这个 根据 JavaEE 教程 Local bean 的客户端 必须在与其访问的企业 bean 相同的 JV
  • Spring Hibernate中的@Transient方法调用

    我有一个 Pojo 类 在其中创建一个未与数据库表映射的字段 所以我必须声明字段Declaration和setter和getter方法 Transient 否则会显示错误 Transient private String docHistor
  • 无法使用 Jsoup HTML 解析器 Java 实现某些功能

    我无法使用 Jsoup Java 库解析以下场景的一些文本 1 This is b My Text b some other b b text as well b b b non empty tag1 b other text 预期输出 s
  • 从 Apache Kafka 中的主题删除消息

    所以我是 Apache Kafka 的新手 我正在尝试创建一个简单的应用程序 以便我可以更好地理解 API 我知道这个问题在这里被问了很多 但是如何清除存储在主题上的消息 记录 我看到的大多数答案都说要更改消息保留时间或删除并重新创建主题
  • SQL 执行计划是基于架构还是数据,或者两者兼而有之?

    我希望这个问题不太明显 我已经找到了很多关于解释执行计划的好信息 但有一个问题我还没有找到答案 该计划 更具体地说是相对 CPU 成本 仅基于架构 还是数据库中当前的实际数据 我尝试对我的产品数据库中需要索引的位置进行一些分析 但正在使用我
  • Android 调整图片大小

    我的图像存储在 SD 卡上 每个大小约为 4MB 我想调整每个的大小 而不是将其设置为 ImageView 但我不能使用BitmapFactory decodeFile path 因为异常 java lang OutOfMemoryErro
  • 如何从项目文件夹中的 jlabel 上设置图像?

    我正在尝试制作一个 Java 桌面应用程序 我想设置一个图像JLabel 我正在使用 NetBeans 从我的项目文件夹中 我的目录结构是 F gt MARKET src lib src defaultpackage demo java i
  • 将菜单添加到空活动

    我在 Android Studio 中制作了一个 Android 应用程序 并想在其上创建一个选项菜单 我将其创建为一个空活动 现在意识到我最好创建一个空白活动来获取选项菜单 无论如何 是否可以在空活动中创建选项菜单 如果有人能给我指出一个
  • 应用程序中 GC 长时间暂停

    我当前运行的应用程序需要最大堆大小为 16GB 目前我使用以下标志来处理垃圾收集 XX UseParNewGC XX UseConcMarkSweepGC XX CMSInitiatingOccupancyFraction 50 XX Di
  • JVM锯齿状空闲进程

    我目前正在进行一项涉及 JVM 及其内存使用工作原理的研究 我不明白的是 JVM在空闲时用什么填充它的内存 只是为了在堆几乎达到时释放它 为什么使用的内存不只有一条平线 顺便说一句 这个 java 应用程序托管在 glassfish 上 但

随机推荐

  • Uploadify 插件不调用 Java Servlet

    我刚刚开始使用 Uploadify flash 插件而不是标准 HTML UI 并遇到了下一个问题 当我单击 上传文件 链接时 会显示进度并出现 已完成 状态 但实际上 它没有发生任何事情 Java Servlet 不是从后端调用的 有上传
  • 将 UIButton 的背景颜色从白色动画变为红色

    我正在尝试制作一种颜色脉冲效果来动画背景颜色UIButton使其连续从一种颜色 白色 变为另一种颜色 红色 我正在尝试使用CABasicAnimation用于更改不透明度 但我也无法使其与颜色一起使用 CABasicAnimation th
  • 安全发送 PHP 从 iOS 获取信息

    情况是这样的 我有一个 iOS 应用程序 其中有一部分用户将信息输入到特定标签中 然后我根据用户给定的信息创建一个 URL 请求 并将其发送到我的 PHP 后端 URL 遵循以下结构 http www somewebsite com sen
  • Bazel 和 Gradle 有什么区别?

    谷歌刚刚开源的 https github com bazelbuild bazel它的构建工具Bazel https bazel build 这个工具和之前有什么区别Gradle https gradle org 它能做什么 Gradle
  • Open Shift Angular 8 应用程序内存不足问题

    我正在为 openshift Angular 8 应用程序使用 Modern Web App 映像 但应用程序因 npm build 内存不足问题而失败 错误日志 usr libexec s2i assemble 第 62 行 296 被杀
  • Subversion 分支重新整合

    当分支重新集成到主干时 该分支实际上已经死亡了吗 您可以在重新集成后对分支进行修改并稍后将其合并回主干吗 你可以从技术上做到这一点 你的分支没有死亡也没有禁用 但不建议在重新集成后从分支合并到主干 您可以在这里找到有关其原因的完整讨论 Su
  • 选择不同的列并按列的子集进行分组

    我正在使用 SQL Server 2008 我陷入了这个恶性循环DISTINCT and GROUP BY 我有以下虚拟表myTable ID Street City PostalCode ProjectID Date NameId 1 B
  • OpenCV C++ 中跟踪物体的背景扣除和光流

    我正在开发一个项目 使用背景扣除来检测感兴趣的对象 并使用 OpenCV C 中的光流来跟踪它们 我能够使用背景扣除来检测感兴趣的物体 我能够在单独的程序上实现 OpenCV Lucas Kanade 光流 但是 我陷入了如何将这两个程序合
  • iOS YTPlayerView 强制视频质量

    我目前正在使用iOS youtube player helper我们的应用程序中的库 有一个视图控制器 带有YTPlayerView它的宽高比为 16 9 这意味着它只占据屏幕的一部分 视频以中等格式加载 无论如何 我都无法使其以 720P
  • MongoDB 脚本基础知识 - 如何

    MongoDB 脚本的基础知识是什么 我认为剧本将以 js 我们使用它来运行它mongo try js 但如果我把 print db foo find in try js并使用mongo try js 它会说 MongoDB shell v
  • C++ Linux (Ubuntu) 正确写入串行(对于 Arduino)

    我想知道是否有一种标准方法可以与高效的串行设备进行通信 我应该使用标准库吗 如果有 是哪一个 现在我正在摆弄让 LED 根据输入的数字以给定的量亮起 Arduino 代码如下 只是练习一些东西 看我过于简单且低效的测试 include
  • 如何处理R中的浮点错误

    考虑以下 R 函数 is sqrt lt function x y if x 2 y TRUE else FALSE 它回答 x 是否是 y 的平方根 如果 y 是完全平方数 则函数的行为符合预期 is sqrt 2 4 返回 TRUE i
  • 比较和替换 SQL Server 中字符串中的字符

    我有一个字符串说 Hel 1 oO Input string Hel 1 oO 我想创建一个函数来解析字符串 Hel 1 oO 并将字母数字以外的所有字符替换为 基本上我想使用正则表达式作为 A Za z0 9 这样除了这些字符之外的所有字
  • 从 iOS 照片库中删除图像[重复]

    这个问题在这里已经有答案了 我创建了一个应用程序 它从手机的照片库中获取图像并将其显示在集合视图上 现在 我希望每当用户选择图像并单击删除按钮时 该特定图像就会从集合视图和图像库中删除 我正在使用 ALAssetLibrary 来获取图像
  • 为什么启动流式查询会导致“ExitCodeException exitCode=-1073741515”?

    一直在尝试适应新的结构化流媒体 但一旦我开始 它就会一直给我以下错误 writeStream query 知道是什么原因造成的吗 如果您在本地和 HDFS 之间拆分检查点和元数据文件夹 我能找到的最接近的是一个正在进行的 Spark 错误
  • 调用方法时出现参数数量错误

    我有课AClass和一个方法someMethod得到一个Object数组作为参数 public class AClass public void someMethod Object parameters 主要是 当我尝试在我创建的对象上调用
  • Pubnub 推送通知不适用于跨平台移动应用程序

    我们正在开发一个基于 cordova 的 Android 应用程序 它具有聊天功能 我们正在从服务器发送测试聊天消息 当应用程序位于前台时 我们收到的消息很好 我们希望当应用程序在后台时收到有关聊天消息的通知 但是我们没有收到任何有关聊天消
  • 找不到模块:无法解析“/vercel/path0/node_modules/cross-fetch/node_modules/node-fetch/lib”中的“编码”

    有没有人遇到过 npm 包带来的不间断警告问题 supabase supabase js The warning message warn node modules cross fetch node modules node fetch l
  • 使用 Timer 在 C# 中更新 UI

    我正在努力使我的应用程序从串行端口读取数据并更新 UI 上的仪表更加高效 我想就处理 UI 更改的代码寻求一些建议 我设置了一个计时器来检查发送到 COM 端口的数据 另一个计时器则使用从 COM 端口接收到的变量更新 UI 基本上发生的事
  • 使用 lucene 改进多线程索引

    我正在尝试使用多个线程在 Lucene 中构建索引 因此 我开始编码并编写了以下代码 首先 我找到文件 并为每个文件创建一个线程来索引它 之后 我加入线程并优化索引 它有效 但我不确定 我可以大规模信任它吗 有什么办法可以改善吗 impor