转载请务必注明,原创地址,谢谢配合!
http://qindongliang1922.iteye.com/blog/1980262
Lucene在最近的几个月里已经频繁更新了好几个版本了,越是更新的频繁,就越证明一件事,这个东西越来越流行,越来越火,就在散仙写此篇文章时候,Lucene官方已经更新到4.6的版本了,在此,散仙,不得不力赞一下开源界的力量。
好了,言归正传,散仙今天就从源码的角度来分析下Lucene的根基Directory的实现,在此之前,我们先来看下Directory家族的层级分布图。
从上图中,我们可以看出Directory共有11个直接或者间接的子类,不同的子类的作用和功能不一样,那么Directory作为此继承图的顶级父类,在Lucene中确实发挥重要的根基作用,就像Hadoop的根基是HDFS一样,Directory肩负着索引存储的重任,如果没有存储,那么检索就无从谈起了,虽然我们经常称全文检索,搜索引擎什么的,其实它们的背后,Directory才是默默无闻的”雷锋“。
下面,散仙就来详细的剖析下Directory的核心实现。
Directory是由lucene中的一些列索引文件组成的目录,一个典型索引文件结构图的截图如下:
而Directory的作用,就是负责管理这些索引文件,包括数据的读取和写入,以及索引文件的添加,删除和合并。从这样的角度来分析,Directory更像一个系统的管理员,下面,散仙再具体的分析下一些核心方法的作用。
我们都知道Lucene的索引体系,支持读共享,写独占的方式来访问索引目录,也就是说,它允许多个线程实例同时并发的读取,而不允许多个线程同时写入,大家可能会有疑问,为什么不支持多线程写入呢?这其实是因为索引目录有自己的某一时刻的内部状态,比如说文件指针,而多线程写入时,会造成指针混乱,从而引起索引结构损坏或某些数据丢失,所以lucene任何时候都禁止有多个线程并发的写入索引,即使是多线程写,每次也只能通过队列的方式,一次只允许一个线程操作索引,按这样的情况分析,多线程写入与单线程写入,在性能上的提升,并不是明显的,那么lucene又是怎么控制一次只能有一个线程写入呢,打开Directory的源码,我们就会发现,它其实是在内部维护了一个锁的实例,通过加锁方式,来禁止后来线程的写入操作,当然锁的作用不仅仅是防止并发写入,它还可以通过锁名字来判断,这两份索引是否为同一份索引,那么如果我们想使用多线程来提升写入速度,一个折中的办法就是,每个线程写一份目录,最后在对这些目录,进行合并,下面散仙给出了一些源码中锁的实现方法
protected LockFactory lockFactory;//锁实现,只能由子类覆盖
//设置锁名
public Lock makeLock(String name) {
return lockFactory.makeLock(name);
}
//清除锁
public void clearLock(String name) throws IOException {
if (lockFactory != null) {
lockFactory.clearLock(name);
}
}
下面我们来分析下Directory源码中另外一个变量isOpen的作用
//注意,使用的是volatile关键字修饰
volatile protected boolean isOpen = true;
isOpen是用来判断当前的Directory实例,在内存中的状态,它使用的是volatile 关键字修饰的,被此变量修饰的内容,JVM虚拟机读取的时候会直接在主存中读取该变量的值,而不会在各个线程的本地内存中读,这样一来,当并发读的时候,如果Directory实例关闭了,那么各个读的线程会立即获取最新的状态,如果不做处理的话,将会抛出一个目录实例关闭的异常。isOpen 确保了索引在并发读的时候,各个线程实例获取Directory状态的一致性。
private static final class SlicedIndexInput extends BufferedIndexInput {
IndexInput base;
long fileOffset;
long length;
SlicedIndexInput(final String sliceDescription, final IndexInput base, final long fileOffset, final long length) {
this(sliceDescription, base, fileOffset, length, BufferedIndexInput.BUFFER_SIZE);
}
SlicedIndexInput(final String sliceDescription, final IndexInput base, final long fileOffset, final long length, int readBufferSize) {
super("SlicedIndexInput(" + sliceDescription + " in " + base + " slice=" + fileOffset + ":" + (fileOffset+length) + ")", readBufferSize);
this.base = base.clone();
this.fileOffset = fileOffset;
this.length = length;
}
接下来,散仙来分析Directory的静态常量内部类SlicedIndexInput的作用,Lucene的索引文件是非常松散的,不同类型的数据存储在不同的文件里,我们可以通过文件名,来单独读取指定索引文件的内容,同样道理我们也可以,在写入信息时候,单独写入某部分数据的信息,这样一来,就避免了操作整个目录的可能,按需所用,从一定程度上来说,这样的设计提升了性能,保证了数据的稳定与可靠性,虽然也从某种程度上加大了Directory目录管理的复杂度,但这些都是微不足道的。
SlicedIndexInput这个类的作用保证了Lucene可以单独读取部分索引文件的内容,注意这些内容都不是最原始的数据,而是SlicedIndexInput克隆的一份副本,这样一来在并发读的环境下是非常有利的,每个线程都会从主存中load一份副本出来。在我们的源码中,我们并没有发现它具有深度克隆的功能,但是通过一系列继承的追踪,我们发现,SlicedIndexInput==》BufferedIndexInput==》IndexInput==》DataInput,在最后的这个父类中实现了Cloneable和Closeable接口,从而确保保证了SlicedIndexInput可以正常的工作,以及释放一些占用的IO资源。
除了上面几个比较重要的作用外,Directory还提供了,其他的一些文件管理功能,例如获取所有的索引文件信息,删除一个索引文件,获取一个索引文件的大小,索引的备份,等等在这里散仙,就不给出演示了,此篇文章重点分析的Directory的功能和作用,后续的文章,散仙会重点分析它的一些子类的实现和功能。
文章内容如果有什么不足之处,欢迎大家指正!
转载请务必注明,原创地址,谢谢配合!
http://qindongliang1922.iteye.com/blog/1980262

- 大小: 149.9 KB

- 大小: 43.3 KB
分享到:
相关推荐
总的来说,"lucene4.3 按坐标距离排序"是利用Lucene的地理空间功能来优化搜索体验的一个重要特性。通过对地理位置数据的有效处理和排序,开发者能够为用户提供更精确、更具相关性的搜索结果,从而提升应用的整体价值...
Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会...
lucene4.3增删改查的的一个工具类,对新手来说是一份不可多得的入门资料。
全文检索lucene 4.3 所用到的3个jar包,包含lucene-queryparser-4.3.0.jar、 lucene-core-4.3.0.jar、lucene-analyzers-common-4.3.0.jar。
《Lucene高级搜索进阶项目_04》 在深入探讨Lucene的高级搜索进阶项目时,我们首先需要理解Lucene的核心概念及其在信息检索中的应用。Lucene是一个高性能、全文本搜索库,它提供了丰富的搜索功能,包括布尔运算、...
lucene4.3源代码 censed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information ...
Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发并维护。在Java编程环境中,它为开发者提供了强大的文本检索功能,使得在海量数据中快速查找相关信息变得简单易行。本篇文章将详细探讨Lucene 4.3.1版本的...
本课程由浅入深的介绍了Lucene4的发展历史,开发环境搭建,分析lucene4的中文分词原理,深入讲了lucenne4的系统架构,分析lucene4索引实现原理及性能优化,了解关于lucene4的搜索算法优化及利用java结合lucene4实现...
1.XunTa是在lucene4.3上创建的通过“知识点”来找人的搜人引擎。 输入一个关键词(或组合),XunTa返回一个排名列表,排在前面的人是与该关键词(组合)最相关的“达人”。 可访问 http://www.xunta.so立即体验...
共13页07.Lucene搜索实战1 共4页08.Lucene搜索实战2 共5页09.Lucene搜索深入实战1 共5页10.Lucene搜索深入实战2 共11页11....Lucene高级进阶1 共23页16.Lucene高级进阶2 共4页17.Lucene高级进阶3 共4页18.Lucene排序...
在本课程中,我们主要探讨了Lucene 4.x版本的高级进阶应用,特别是针对大规模文档搜索引擎的构建。Lucene作为一个开源全文搜索引擎库,它提供了高效、灵活的索引和搜索功能,是构建高性能搜索系统的基石。在这个部分...
在高级进阶部分,我们将重点探讨Lucene在索引、搜索、排序、过滤以及分词器等方面的高级用法,旨在帮助开发者掌握Lucene的精髓,打造高效、精确的搜索体验。 1. **Document与索引更新**: 在Lucene中,`Document`...
在本项目"Lucene高级搜索进阶项目_03"中,我们将深入探讨Apache Lucene这一强大的全文搜索引擎库。Lucene是Java开发的开源库,它提供了文本分析、索引和搜索功能,使得开发者能够轻松地在应用程序中实现复杂的搜索...
【Lucene4.X实战类baidu搜索的大型文档海量搜索系统】课程主要涵盖了Lucene搜索引擎的各个方面,包括基础和高级进阶。以下是课程的主要知识点: 1. **Lucene入门与系统架构**:介绍Lucene的基本概念,以及其系统...
《Lucene搜索-引擎开发权威经典》是一本深入解析Apache Lucene搜索引擎库的专业书籍,它为读者提供了构建高效全文搜索引擎的全面指南。Lucene是Java领域最著名的全文检索库,被广泛应用于各种信息检索系统中,包括...
Lucene是一个强大的全文检索库,广泛应用于搜索引擎和信息检索系统中。在中文处理方面,IKAnalyzer是一个优秀的开源中文分词器,专为Lucene设计,旨在提高中文分词的准确性和效率。本文将深入探讨IKAnalyzer的特性和...
共13页07.Lucene搜索实战1 共4页08.Lucene搜索实战2 共5页09.Lucene搜索深入实战1 共5页10.Lucene搜索深入实战2 共11页11....Lucene高级进阶1 共23页16.Lucene高级进阶2 共4页17.Lucene高级进阶3 共4页18.Lucene排序...
共13页07.Lucene搜索实战1 共4页08.Lucene搜索实战2 共5页09.Lucene搜索深入实战1 共5页10.Lucene搜索深入实战2 共11页11....Lucene高级进阶1 共23页16.Lucene高级进阶2 共4页17.Lucene高级进阶3 共4页18.Lucene排序...
共13页07.Lucene搜索实战1 共4页08.Lucene搜索实战2 共5页09.Lucene搜索深入实战1 共5页10.Lucene搜索深入实战2 共11页11....Lucene高级进阶1 共23页16.Lucene高级进阶2 共4页17.Lucene高级进阶3 共4页18.Lucene排序...
共13页07.Lucene搜索实战1 共4页08.Lucene搜索实战2 共5页09.Lucene搜索深入实战1 共5页10.Lucene搜索深入实战2 共11页11....Lucene高级进阶1 共23页16.Lucene高级进阶2 共4页17.Lucene高级进阶3 共4页18.Lucene排序...