从源码的角度来分析下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);
- }
- }
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;
//注意,使用的是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;
- }
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的功能和作用
相关推荐
Directory Opus是一款强大的文件管理器,它为用户提供了一种高效且功能丰富的替代Windows资源管理器的方式。这款软件以其高度自定义的界面、强大的文件操作功能和广泛的文件预览支持而闻名。"Directory Opus 12 文档...
安装Active Directory 安装Active Directory 安装Active Directory
Directory Opus Pro是一个功能十分强劲的文件可视化工具,Directory Opus有着和Windows资源管理器相近的页面,支持:拷贝、挪动、删掉、改名、搜索、检索、访问、缩小、压缩包解压、切分、合拼、立即邮件发送、缩小...
小甲鱼在讲解解密系列系统篇中用到的IMAGE_DATA_DIRECTORY DataDirectory元素索引对应的内容
Apache Directory Server 使用指南 Apache Directory Server 是一个基于 Java 语言的开源 LDAP 服务器,由 Apache 软件基金会开发和维护。该服务器提供了一个完整的目录解决方案,包括目录服务器、目录工具和其他...
它简化了树状结构的展现和管理,能够帮助用户高效地浏览层级数据。通过理解和掌握DirectoryTree插件的使用,开发者可以提升网站或应用的用户体验,特别是对于需要展示多层分类或目录的场景。在实际项目中,根据需求...
安装程序由 NSIS 封装,封装了Directory Opus文件管理器安装版和便携版。安装包有个人习惯设置,请自行决定是否要继续安装。 Directory Opus这是一个强大的文件管理软件,支持标签页,多窗口,色彩标记文件夹和文件...
Directory Opus(最好的文件管理器之一) 简繁体中文破解版(32位和64位) 是可与 Total Commander 相媲美的文件管理器。其总体水平与TC持平,称得上双峰对峙、二水分流。但在易用性、现代性、内置功能(相比插件实现...
在当今的IT环境中,管理和配置Active Directory是一项至关重要的技能,特别是在企业级网络架构中。Active Directory作为微软Windows Server操作系统中的核心组件,提供了组织和管理网络资源和用户账户的机制。获得...
Directory Opus插件Everything 最新带安装说明 directory opus是最好的资源管理器 Everything是最好的文件搜索工具 现在可以将Everything集成到Directory Opus中
4. **递归操作**:对于多层目录结构,`Directory`类可能还支持递归遍历,这意味着它能够遍历子目录中的所有文件,这对于处理多层级结构的数据集至关重要。 5. **文件操作**:虽然`Directory`类主要是处理目录,但...
Active Directory 详细教程 Active Directory 是微软的一种目录服务,能够提供身份验证、授权和资源管理等功能。在企业中,Active Directory 广泛应用于域管理、资源共享和身份验证等方面。本文将对 Active ...
### Active Directory Certificate Services (ADCS) 知识点详述 #### 一、ADCS概述 **Active Directory Certificate Services (ADCS)** 是一种基于 **Active Directory** 的服务,用于管理和提供数字证书及相关...
C# Directory类的操作 C# Directory类是System.IO命名空间中的一个类,它提供了在目录和子目录中进行创建、移动和列举操作的静态方法。此外,还可以访问和操作各种各样的目录属性,例如创建或最后一次修改时间以及...
《深入理解Novell.Directory.Ldap.dll在C#中的应用》 Novell.Directory.Ldap.dll是C#编程中用于访问Directory(目录服务)或eDirectory(Novell的企业级目录服务)的重要组件,它提供了一组丰富的类和方法,使得...
Chapter 18, Active Directory Application Mode and Active Directory Lightweight Directory Service Covers the new Active Directory Application Mode (ADAM) functionality that’s available with R2. ...
标题:"Sun Directory" 描述:"OIM Sun Directory Connector" 知识点详细说明: ### 1. Oracle Identity Manager (OIM) Oracle Identity Manager是Oracle公司提供的一款企业级身份管理解决方案,它旨在帮助企业...
### Active Directory系列教程知识点概述 #### 一、为何需要Active Directory(AD)域管理模型? 在探讨Active Directory之前,我们首先要理解为什么要引入这样的管理模型。对于很多初学者来说,理解域的概念及其...
Directory Opus 12是一款功能强大的文件管理器。该软件界面简洁,使用方便。能够帮助用户朋友快速处理电脑文件,强力的搜索功能让每一个文件都无处可逃,并且能够轻松管理,执行各种可行性操作,简单方便实用,为你...
**Active Directory:基础概念与重要性** Active Directory(AD)是微软Windows Server操作系统中的一个核心组件,它是一种目录服务,用于存储和管理网络资源的信息。AD使得管理员能够集中控制网络中的用户账户、...