转载请务必注明,原创地址,谢谢配合!
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
分享到:
相关推荐
Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会...
总的来说,"lucene4.3 按坐标距离排序"是利用Lucene的地理空间功能来优化搜索体验的一个重要特性。通过对地理位置数据的有效处理和排序,开发者能够为用户提供更精确、更具相关性的搜索结果,从而提升应用的整体价值...
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立即体验...
结合笔者的实际开发经验,总结了一些新的开发技巧和开发思路,并对网上流传的一些错误技术点和代码进行验证,同时给出正确的思路,旨在给开发者提供一本清晰、完整、易懂的指导手册。本书既可为零起点的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排序...
在本课程中,我们主要探讨了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搜索引擎开发进阶实战》是一本针对Java开发者深入学习Lucene搜索引擎的高级教程,旨在帮助读者掌握如何利用Lucene构建高效、精准的全文检索系统。Lucene是Apache软件基金会的一个开源项目,它提供了高性能、...
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排序...