`
weitao1026
  • 浏览: 1062742 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Directory家族的层级分布图

阅读更多

从源码的角度来分析下Lucene的根基Directory的实现,在此之前,我们先来看下Directory家族的层级分布图。



从上图中,我们可以看出Directory共有11个直接或者间接的子类,不同的子类的作用和功能不一样,那么Directory作为此继承图的顶级父类,在Lucene中确实发挥重要的根基作用,就像Hadoop的根基是HDFS一样,Directory肩负着索引存储的重任,如果没有存储,那么检索就无从谈起了,虽然我们经常称全文检索,搜索引擎什么的,其实它们的背后,Directory才是默默无闻的”雷锋“。


下面,散仙就来详细的剖析下Directory的核心实现。
Directory是由lucene中的一些列索引文件组成的目录,一个典型索引文件结构图的截图如下:



而Directory的作用,就是负责管理这些索引文件,包括数据的读取和写入,以及索引文件的添加,删除和合并。从这样的角度来分析,Directory更像一个系统的管理员,下面,散仙再具体的分析下一些核心方法的作用。

我们都知道Lucene的索引体系,支持读共享,写独占的方式来访问索引目录,也就是说,它允许多个线程实例同时并发的读取,而不允许多个线程同时写入,大家可能会有疑问,为什么不支持多线程写入呢?这其实是因为索引目录有自己的某一时刻的内部状态,比如说文件指针,而多线程写入时,会造成指针混乱,从而引起索引结构损坏或某些数据丢失,所以lucene任何时候都禁止有多个线程并发的写入索引,即使是多线程写,每次也只能通过队列的方式,一次只允许一个线程操作索引,按这样的情况分析,多线程写入与单线程写入,在性能上的提升,并不是明显的,那么lucene又是怎么控制一次只能有一个线程写入呢,打开Directory的源码,我们就会发现,它其实是在内部维护了一个锁的实例,通过加锁方式,来禁止后来线程的写入操作,当然锁的作用不仅仅是防止并发写入,它还可以通过锁名字来判断,这两份索引是否为同一份索引,那么如果我们想使用多线程来提升写入速度,一个折中的办法就是,每个线程写一份目录,最后在对这些目录,进行合并,下面散仙给出了一些源码中锁的实现方法

Java代码 复制代码 收藏代码
  1. protected LockFactory lockFactory;//锁实现,只能由子类覆盖  
  2. //设置锁名  
  3.   public Lock makeLock(String name) {  
  4.       return lockFactory.makeLock(name);  
  5.   }  
  6.   //清除锁  
  7.   public void clearLock(String name) throws IOException {  
  8.     if (lockFactory != null) {  
  9.       lockFactory.clearLock(name);  
  10.     }  
  11.   }  
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的作用

Java代码 复制代码 收藏代码
  1. //注意,使用的是volatile关键字修饰  
  2.  volatile protected boolean isOpen = true;  
	//注意,使用的是volatile关键字修饰
  volatile protected boolean isOpen = true;


isOpen是用来判断当前的Directory实例,在内存中的状态,它使用的是volatile 关键字修饰的,被此变量修饰的内容,JVM虚拟机读取的时候会直接在主存中读取该变量的值,而不会在各个线程的本地内存中读,这样一来,当并发读的时候,如果Directory实例关闭了,那么各个读的线程会立即获取最新的状态,如果不做处理的话,将会抛出一个目录实例关闭的异常。isOpen 确保了索引在并发读的时候,各个线程实例获取Directory状态的一致性。

Java代码 复制代码 收藏代码
  1. private static final class SlicedIndexInput extends BufferedIndexInput {  
  2.   IndexInput base;  
  3.   long fileOffset;  
  4.   long length;  
  5.     
  6.   SlicedIndexInput(final String sliceDescription, final IndexInput base, final long fileOffset, final long length) {  
  7.     this(sliceDescription, base, fileOffset, length, BufferedIndexInput.BUFFER_SIZE);  
  8.   }  
  9.     
  10.   SlicedIndexInput(final String sliceDescription, final IndexInput base, final long fileOffset, final long length, int readBufferSize) {  
  11.     super("SlicedIndexInput(" + sliceDescription + " in " + base + " slice=" + fileOffset + ":" + (fileOffset+length) + ")", readBufferSize);  
  12.     this.base = base.clone();  
  13.     this.fileOffset = fileOffset;  
  14.     this.length = length;  
  15.   }  
  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 12 文档预览 office预览 插件

    Directory Opus是一款强大的文件管理器,它为用户提供了一种高效且功能丰富的替代Windows资源管理器的方式。这款软件以其高度自定义的界面、强大的文件操作功能和广泛的文件预览支持而闻名。"Directory Opus 12 文档...

    安装Active Directory 安装Active Directory 安装Active Directory

    安装Active Directory 安装Active Directory 安装Active Directory

    Directory Opus Pro 12.33 学习版

    Directory Opus Pro是一个功能十分强劲的文件可视化工具,Directory Opus有着和Windows资源管理器相近的页面,支持:拷贝、挪动、删掉、改名、搜索、检索、访问、缩小、压缩包解压、切分、合拼、立即邮件发送、缩小...

    IMAGE_DATA_DIRECTORY DataDirectory

    小甲鱼在讲解解密系列系统篇中用到的IMAGE_DATA_DIRECTORY DataDirectory元素索引对应的内容

    Apache Directory Server使用指南

    Apache Directory Server 使用指南 Apache Directory Server 是一个基于 Java 语言的开源 LDAP 服务器,由 Apache 软件基金会开发和维护。该服务器提供了一个完整的目录解决方案,包括目录服务器、目录工具和其他...

    DirectoryTree插件-jquery树形滑动导航

    它简化了树状结构的展现和管理,能够帮助用户高效地浏览层级数据。通过理解和掌握DirectoryTree插件的使用,开发者可以提升网站或应用的用户体验,特别是对于需要展示多层分类或目录的场景。在实际项目中,根据需求...

    Directory Opus 12.6 破解版

    安装程序由 NSIS 封装,封装了Directory Opus文件管理器安装版和便携版。安装包有个人习惯设置,请自行决定是否要继续安装。 Directory Opus这是一个强大的文件管理软件,支持标签页,多窗口,色彩标记文件夹和文件...

    Directory Opus 12.x Patch

    Directory Opus(最好的文件管理器之一) 简繁体中文破解版(32位和64位) 是可与 Total Commander 相媲美的文件管理器。其总体水平与TC持平,称得上双峰对峙、二水分流。但在易用性、现代性、内置功能(相比插件实现...

    管理Active Directory

    在当今的IT环境中,管理和配置Active Directory是一项至关重要的技能,特别是在企业级网络架构中。Active Directory作为微软Windows Server操作系统中的核心组件,提供了组织和管理网络资源和用户账户的机制。获得...

    Directory Opus插件Everything

    Directory Opus插件Everything 最新带安装说明 directory opus是最好的资源管理器 Everything是最好的文件搜索工具 现在可以将Everything集成到Directory Opus中

    opencv contrib Directory

    4. **递归操作**:对于多层目录结构,`Directory`类可能还支持递归遍历,这意味着它能够遍历子目录中的所有文件,这对于处理多层级结构的数据集至关重要。 5. **文件操作**:虽然`Directory`类主要是处理目录,但...

    Active Directory详细教程

    Active Directory 详细教程 Active Directory 是微软的一种目录服务,能够提供身份验证、授权和资源管理等功能。在企业中,Active Directory 广泛应用于域管理、资源共享和身份验证等方面。本文将对 Active ...

    Active Directory Certificate Services

    ### Active Directory Certificate Services (ADCS) 知识点详述 #### 一、ADCS概述 **Active Directory Certificate Services (ADCS)** 是一种基于 **Active Directory** 的服务,用于管理和提供数字证书及相关...

    C# Directory类的操作

    C# Directory类的操作 C# Directory类是System.IO命名空间中的一个类,它提供了在目录和子目录中进行创建、移动和列举操作的静态方法。此外,还可以访问和操作各种各样的目录属性,例如创建或最后一次修改时间以及...

    Novell.Directory.Ldap.dll

    《深入理解Novell.Directory.Ldap.dll在C#中的应用》 Novell.Directory.Ldap.dll是C#编程中用于访问Directory(目录服务)或eDirectory(Novell的企业级目录服务)的重要组件,它提供了一组丰富的类和方法,使得...

    Active Directory Cookbook, 3rd Edition.pdf

    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

    标题:"Sun Directory" 描述:"OIM Sun Directory Connector" 知识点详细说明: ### 1. Oracle Identity Manager (OIM) Oracle Identity Manager是Oracle公司提供的一款企业级身份管理解决方案,它旨在帮助企业...

    Active Directory系列教程

    ### Active Directory系列教程知识点概述 #### 一、为何需要Active Directory(AD)域管理模型? 在探讨Active Directory之前,我们首先要理解为什么要引入这样的管理模型。对于很多初学者来说,理解域的概念及其...

    Directory Opus 12.6 Crack

    Directory Opus 12是一款功能强大的文件管理器。该软件界面简洁,使用方便。能够帮助用户朋友快速处理电脑文件,强力的搜索功能让每一个文件都无处可逃,并且能够轻松管理,执行各种可行性操作,简单方便实用,为你...

    active directory安装包(域控制器补丁)

    **Active Directory:基础概念与重要性** Active Directory(AD)是微软Windows Server操作系统中的一个核心组件,它是一种目录服务,用于存储和管理网络资源的信息。AD使得管理员能够集中控制网络中的用户账户、...

Global site tag (gtag.js) - Google Analytics