热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Lucene的索引链结构_IndexChain

Lucene将索引文档的过程设计成两个阶段,写入内存阶段和写入硬盘阶段。在写入内存阶段,Lucene通过IndexChain把document分解并把相关信息存储到内存中,等到满足


         Lucene将索引文档的过程设计成两个阶段,写入内存阶段和写入硬盘阶段。在写入内存阶段,Lucene通过IndexChaindocument分解并把相关信息存储到内存中,等到满足flush条件(内存容量或者文档个数积累到临界值),就通过IndexChain把内存中的数据写入硬盘。IndexChainLucene索引文档很重要的一部分,那么IndexChain是什么呢?

       LuceneIndexChain

         Lucene形成索引的过程其实就是对document进行分解的过程。通过对document的分解,得到词典、倒排表等信息。IndexChain就是分解document的对象集合,或者说架构。索引链的结构如下图所示:

,

上图中IndexChain的起点是DocFieldProcessor,它会分别调用DocInverter(倒排信息处理)TowStoredFieldsConsumer(正向信息处理) 反向信息有四种:

信息种类

作用

处理组件

norm信息

用来消除长文本和短文本之间的差距

NormsConsumer

Freq信息

文档排序时的重要因子

FreqProxTermsWriter

Pos信息

位置信息,在PhraseQuery时会有用

FreqProxTermsWriter

TermVector

高亮处理需要记录的信息

TermVectorsConsumer

正向信息有两种:

信息种类

作用

处理组件

Fields

形成完整的一个doc

StoredFieldsProcessor

docValues

排序因子

DocValuesProcessor

对照两个表格,再回头看IndexChain,各个类的作用就很清晰了。

索引链被调用的过程如下图所示:

,

这种设计导致IndexChain只是一个骨架,实际上起分解Document作用的组件如下图所示:

,

         跟上面的IndexChain相比,大多都是在类名后面加了后缀PerField,整个结构都是一样的。由于TwoStoredFieldsConsumers是存储Field的内容,并不对其进行分解,所以就不需要PerField.

LuceneIndexWriter是线程安全的,即它支持多线程索引。默认会生成8DocumentsWriterPerThread,每个DocumentsWriterPerThread都拥有一个IndexChain,每个IndexChain都有一个独立的索引内存空间。这使得IndexChain的这种模式在多线程索引时,各个IndexChain是互不干扰的,因而效率会很高。但是这并不意味着每一个用户线程都会对应一个IndexChain,生成一个独立的索引段。比如:

         public class LuceneDemo{

  

   static class IndexThread implements Runnable{

      IndexWriter iw ;

      String[] vals ;

      int start ;

      public IndexThread(IndexWriter iw,String[] vals,int start){

         this.iw = iw;

         this.vals = vals;

         this.start = start;

      }

      @Override

      public void run() {

            for(int i=start;i<vals.length;i+=2){

                Document doc =new Document();

                doc.add(new TextField("title",vals[i],Store.YES));

                try {

                   iw.addDocument(doc);

                }catch (Exception e) {}

            }

        

      }

   }

   public static voidmain(String[] args) throws IOException, InterruptedException{

      File file = new File("d:/tmp/index");

      Directory dir = FSDirectory.open(file);

      IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_42,new WhitespaceAnalyzer(Version.LUCENE_42));

      IndexWriter iw = new IndexWriter(dir, conf);

      final String[] vals = {"common","term","new","term","term",

                   "term","common","term","common"};

      Thread it1 = new Thread(new IndexThread(iw, vals, 0));

      Thread it2 = new Thread(new IndexThread(iw, vals, 1));

     

      it1.start();it2.start();

      it1.join();it2.join();

     

      iw.commit();

      iw.close();

   }

}     

上面这段代码有两个用户索引线程。这段代码执行,最后生成了索引结构是不确定的.有时会有两个索引段,如下:

,

但有时也会只有一个索引段,如下:

,

这是因为每个索引线程(dwpt)其实是从DocumentsWriterPerThreadPool里面获得空闲的DocumentsWriterPerThread对象。如果一个DocumentsWriterPerThread对象已经足够应付两个索引线程的差遣,就无需新的DocumentsWriterPerThread对象了。就像餐厅里客人用餐一样。如果一个服务员能够应付下来,为什么再去招募多的服务员增加成本呢?

Lucene在多线程索引时会充分利用DocumentsWriterPerThreadPool里面的DocumentsWriterPerThread对象.只要该对象对应的线程锁被释放,就会被其它的线程竞争.我们可以从ThreadAffinityDocumentsWriterThreadPool.getAndLock()方法了解其实现机制.由于多线程竞争的不确定性,导致了索引段个数的不确定性。这种设计方式也降低了多线程程序的复杂性,很值得深入学习。

         IndexChain属于Lucene索引过程的脉络和骨架,其核心点在于多线程的处理方式。但是由于索引中多线程并不常用,而且也不好调试,所以理解起来比较困难。另加上整个索引链组件众多,而且各个类的成员变量都以consumer命名,如果不画图而只是跟踪debug,很容易被consumer弄得晕头转向。

         了解了IndexChain,实际上只是了解了Lucene索引的框架。并没有了解到索引的细节,比如内存管理,数据存储方式。

本文出自 “每天进步一点点” 博客,请务必保留此出处http://sbp810050504.blog.51cto.com/2799422/1440510

Lucene的索引链结构_IndexChain


推荐阅读
  • 在Conda环境中高效配置并安装PyTorch和TensorFlow GPU版的方法如下:首先,创建一个新的Conda环境以避免与基础环境发生冲突,例如使用 `conda create -n pytorch_gpu python=3.7` 命令。接着,激活该环境,确保所有依赖项都正确安装。此外,建议在安装过程中指定CUDA版本,以确保与GPU兼容性。通过这些步骤,可以确保PyTorch和TensorFlow GPU版的顺利安装和运行。 ... [详细]
  • 题目 E. DeadLee:思维导图与拓扑结构的深度解析问题描述:给定 n 种食物,每种食物的数量由 wi 表示。同时,有 m 位朋友,每位朋友喜欢两种特定的食物 x 和 y。目标是通过合理分配食物,使尽可能多的朋友感到满意。本文将通过思维导图和拓扑排序的方法,对这一问题进行深入分析和求解。 ... [详细]
  • 在 Axublog 1.1.0 版本的 `c_login.php` 文件中发现了一个严重的 SQL 注入漏洞。该漏洞允许攻击者通过操纵登录请求中的参数,注入恶意 SQL 代码,从而可能获取敏感信息或对数据库进行未授权操作。建议用户尽快更新到最新版本并采取相应的安全措施以防止潜在的风险。 ... [详细]
  • 本文详细解析了逻辑运算符“与”(&&)和“或”(||)在编程中的应用。通过具体示例,如 `[dehua@teacher~]$[$(id -u) -eq 0] && echo "You are root" || echo "You must be root"`,展示了如何利用这些运算符进行条件判断和命令执行。此外,文章还探讨了这些运算符在不同编程语言中的实现和最佳实践,帮助读者更好地理解和运用逻辑运算符。 ... [详细]
  • 二分查找算法详解与应用分析:本文深入探讨了二分查找算法的实现细节及其在实际问题中的应用。通过定义 `binary_search` 函数,详细介绍了算法的逻辑流程,包括初始化上下界、循环条件以及中间值的计算方法。此外,还讨论了该算法的时间复杂度和空间复杂度,并提供了多个应用场景示例,帮助读者更好地理解和掌握这一高效查找技术。 ... [详细]
  • 在 Android 开发中,`android:exported` 属性用于控制组件(如 Activity、Service、BroadcastReceiver 和 ContentProvider)是否可以被其他应用组件访问或与其交互。若将此属性设为 `true`,则允许外部应用调用或与之交互;反之,若设为 `false`,则仅限于同一应用内的组件进行访问。这一属性对于确保应用的安全性和隐私保护至关重要。 ... [详细]
  • 蚂蚁课堂:性能测试工具深度解析——JMeter应用与实践
    蚂蚁课堂:性能测试工具深度解析——JMeter应用与实践 ... [详细]
  • 在最近的项目中,我们广泛使用了Qt框架的网络库,过程中遇到了一些挑战和问题。本文旨在记录这些经验和解决方案,以便日后参考。鉴于我们的客户端GUI完全基于Qt开发,我们期望利用其强大的网络功能进行Fiddler网络数据包的捕获与分析,以提升开发效率和应用性能。 ... [详细]
  • 在 iOS 开发中,经常会遇到 `@(YES)`、`@[firstViewController]` 以及 `@{@a:@b}` 这样的语法糖。这些简化的写法分别用于初始化布尔值、数组和字典对象,能够显著提高代码的可读性和编写效率。例如,`@(YES)` 可以快速创建一个布尔值对象,`@[firstViewController]` 则用于创建包含单个元素的数组,而 `@{@a:@b}` 则用于创建键值对字典。理解这些语法糖的使用方法,有助于开发者更加高效地进行编码。 ... [详细]
  • Unity3D 中 AsyncOperation 实现异步场景加载及进度显示优化技巧
    在Unity3D中,通过使用`AsyncOperation`可以实现高效的异步场景加载,并结合进度条显示来提升用户体验。本文详细介绍了如何利用`AsyncOperation`进行异步加载,并提供了优化技巧,包括进度条的动态更新和加载过程中的性能优化方法。此外,还探讨了如何处理加载过程中可能出现的异常情况,确保加载过程的稳定性和可靠性。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 深入解析Linux内核中的进程上下文切换机制
    在现代操作系统中,进程作为核心概念之一,负责管理和分配系统资源,如CPU和内存。深入了解Linux内核中的进程上下文切换机制,需要首先明确进程与程序的区别。进程是一个动态的执行流,而程序则是静态的数据和指令集合。进程上下文切换涉及保存当前进程的状态信息,并加载下一个进程的状态,以实现多任务处理。这一过程不仅影响系统的性能,还关系到资源的有效利用。通过分析Linux内核中的具体实现,可以更好地理解其背后的原理和技术细节。 ... [详细]
  • 如何在PDF文档中添加新的文本内容?
    在处理PDF文件时,有时需要向其中添加新的文本内容。这是否可以直接实现呢?有哪些简便且免费的方法可供选择?使用极速PDF阅读器打开文档后,可以通过点击左上角的“注释”按钮切换到注释模式,并选择相应的工具进行编辑。此外,还可以利用其他功能丰富的PDF编辑软件,如Adobe Acrobat DC或Foxit PhantomPDF,它们提供了更多高级的编辑选项,能够满足更复杂的需求。 ... [详细]
  • 题目要求解决一个有趣的编程挑战,即计算由四个自然数 \( p, q, r, s \) 组成的分数序列的和。具体来说,需要编写一个 C# 程序来处理这些自然数,并通过特定的数学运算得出最终结果。该任务不仅考验编程技能,还涉及对数学公式的理解和应用。 ... [详细]
  • Nginx 反向代理配置与应用指南
    本文详细介绍了 Nginx 反向代理的配置与应用方法。首先,用户可以从官方下载页面(http://nginx.org/en/download.html)获取最新稳定版 Nginx,推荐使用 1.14.2 版本。下载并解压后,通过双击 `nginx.exe` 文件启动 Nginx 服务。文章进一步探讨了反向代理的基本原理及其在实际应用场景中的配置技巧,包括负载均衡、缓存管理和安全设置等,为用户提供了一套全面的实践指南。 ... [详细]
author-avatar
书友53034809
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有