Lucene4.3进阶开发之初入仙界(一) Directory



Lucene4.3 Directory (一)



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

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

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

  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.   } 
  1. volatile protected boolean isOpen = true;  

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

散仙来分析Directory的静态常量内部类SlicedIndexInput的作用,Lucene的索引文件是非常松散的,不同类型的数据存储在不同的文件里,我们可以通过文件名,来单独读取指定索引文件的内容,同样道理我们也可以,在写入信息时候,单独写入某部分数据的信息,这样一来,就避免了操作整个目录的可能,按需所用,从一定程度上来说,这样的设计提升了性能,保证了数据的稳定与可靠性,虽然也从某种程度上加大了Directory目录管理的复杂度,但这些都是微不足道的。

SlicedIndexInput这个类的作用保证了Lucene可以单独读取部分索引文件的内容,注意这些内容都不是最原始的数据,而是SlicedIndexInput克隆的一份副本,这样一来在并发读的环境下是非常有利的,每个线程都会从主存中load一份副本出来。在我们的源码中,我们并没有发现它具有深度克隆的功能,但是通过一系列继承的追踪,我们发现,SlicedIndexInput==》BufferedIndexInput==》IndexInput==》DataInput,在最后的这个父类中实现了Cloneable和Closeable接口,从而确保保证了SlicedIndexInput可以正常的工作,以及释放一些占用的IO资源。
 

除了上面几个比较重要的作用外,Directory还提供了,其他的一些文件管理功能,例如获取所有的索引文件信息,删除一个索引文件,获取一个索引文件的大小,索引的备份,等等在这里散仙,就不给出演示了,此篇文章重点分析的Directory的功能和作用,后续的文章,散仙会重点分析它的一些子类的实现和功能。 
Please read full article from Lucene4.3 Directory (一)


No comments:

Post a Comment

Labels

Algorithm (219) Lucene (130) LeetCode (97) Database (36) Data Structure (33) text mining (28) Solr (27) java (27) Mathematical Algorithm (26) Difficult Algorithm (25) Logic Thinking (23) Puzzles (23) Bit Algorithms (22) Math (21) List (20) Dynamic Programming (19) Linux (19) Tree (18) Machine Learning (15) EPI (11) Queue (11) Smart Algorithm (11) Operating System (9) Java Basic (8) Recursive Algorithm (8) Stack (8) Eclipse (7) Scala (7) Tika (7) J2EE (6) Monitoring (6) Trie (6) Concurrency (5) Geometry Algorithm (5) Greedy Algorithm (5) Mahout (5) MySQL (5) xpost (5) C (4) Interview (4) Vi (4) regular expression (4) to-do (4) C++ (3) Chrome (3) Divide and Conquer (3) Graph Algorithm (3) Permutation (3) Powershell (3) Random (3) Segment Tree (3) UIMA (3) Union-Find (3) Video (3) Virtualization (3) Windows (3) XML (3) Advanced Data Structure (2) Android (2) Bash (2) Classic Algorithm (2) Debugging (2) Design Pattern (2) Google (2) Hadoop (2) Java Collections (2) Markov Chains (2) Probabilities (2) Shell (2) Site (2) Web Development (2) Workplace (2) angularjs (2) .Net (1) Amazon Interview (1) Android Studio (1) Array (1) Boilerpipe (1) Book Notes (1) ChromeOS (1) Chromebook (1) Codility (1) Desgin (1) Design (1) Divide and Conqure (1) GAE (1) Google Interview (1) Great Stuff (1) Hash (1) High Tech Companies (1) Improving (1) LifeTips (1) Maven (1) Network (1) Performance (1) Programming (1) Resources (1) Sampling (1) Sed (1) Smart Thinking (1) Sort (1) Spark (1) Stanford NLP (1) System Design (1) Trove (1) VIP (1) tools (1)

Popular Posts