[轉]FileSwitchDirectory實現原理與應用

 轉至http://blog.csdn.net/duck_genuine/article/details/8006134html

FileSwitchDirectory實現原理與應用 java

FileSwitchDirectory是lucene的另外一種Directory實現類,從名字個就能夠理解爲文件切換的Directory實現,web

的確是針對lucene的不一樣的索引文件使用不一樣的Directory .藉助FileSwitchDirectory整合不一樣的Directory實現類的優勢於一身。緩存

好比MMapDirectory,藉助內存映射文件方式提升性能,但又要減小內存切換的可能 ,當索引太大的時候,內存映射也須要不斷地切換,這樣優勢也可能變缺點,而以前的NIOFSDirectory實現java NIO的方式提升高併發性能,但又因高併發也會致使IO過多的影響,因此此次能夠藉助FileSwitchDirectory發揮他們兩的優勢。併發

 

 

MMapDirectory與NIOFSDirectory的實現差異。app

NIOFSDirectory----只是使用了直接內存讀取文件緩存方式 ide

 

@Override
    protected void newBuffer(byte[] newBuffer) {
      super.newBuffer(newBuffer);
      byteBuf = ByteBuffer.wrap(newBuffer);
    }高併發

MMapDirectory------使用MMap技術映射文件,默認會映射1G的內存(64位)或者256m(32位系統))oop

 

MMapDiretory就是將文件映射到內存中。。使用的是MMap技術
 this.buffers[bufNr] = rafc.map(MapMode.READ_ONLY, bufferStart, bufSize);性能

 

 

首先將索引目錄裏佔比例比較小的文件使用MMapDirectory,這樣幾乎能夠所有映射到內存裏了。。而佔有大比例的文檔存儲文件交因爲NIOFSDirectory方式讀取。

這個結合不錯呀。。

 

FileSwitchDirectory實現代碼解析

 

FileSwitchDirectory的代碼很簡單,由於能夠理解爲它就是一個Dao的入口也是個控制器,因此它並無具體的文件操縱實現。

先了解它的構造是:

 

[java]   view plain copy
  1. public FileSwitchDirectory(Set<String> primaryExtensions, Directory primaryDir, Directory secondaryDir, boolean doClose) {  
  2.   this.primaryExtensions = primaryExtensions;  
  3.   this.primaryDir = primaryDir;  
  4.   this.secondaryDir = secondaryDir;  
  5.   this.doClose = doClose;  
  6.   this.lockFactory = primaryDir.getLockFactory();  
  7. }  


首先是文件後綴的集合參數

 

主要的Directory

次要的Directory

是否關閉的時候調用

 

因此都是調用對應的Directory得到IndexInput 與IndexOuput

 

[java]   view plain copy
  1. @Override  
  2.   public IndexInput openInput(String name) throws IOException {  
  3.     return getDirectory(name).openInput(name);  
  4.   }  

 

[java]   view plain copy
  1. @Override  
  2.  public IndexOutput createOutput(String name) throws IOException {  
  3.    return getDirectory(name).createOutput(name);  
  4.  }  

 

 

經過文件名字取到對應的Directory

[java]   view plain copy
  1. private Directory getDirectory(String name) {  
  2.   String ext = getExtension(name);  
  3.   if (primaryExtensions.contains(ext)) {  
  4.     return primaryDir;  
  5.   } else {  
  6.     return secondaryDir;  
  7.   }  
  8. }  



solr使用的DirectoryFactory實現

 

 

 

[java]   view plain copy
  1. /** 
  2.  *  
  3.  *  
  4.  * 支持某些後綴文件不做映射優化,好比去掉fdt,fdx 
  5.  *  
  6.  *  
  7.  *  
  8.  *    
  9.  <directoryFactory class="solr.MMapDirectoryFactoryExt"> 
  10.     <str name="unmap">true</str> 
  11.     <lst name="filetypes"> 
  12.        <bool name="fdt">false</bool> 
  13.        <bool name="fdx">false</bool> 
  14.    </lst> 
  15.  </directoryFactory> 
  16.  * 
  17.  */  
  18. public class MMapDirectoryFactoryExt extends DirectoryFactory {  
  19.     // filetypes不做映射  
  20.     private Set<String> nonMappedFiles = new HashSet<String>();  
  21.     // 是否使用不映射選擇  
  22.     private Boolean useUnmapHack = false;  
  23.   
  24.     public Directory open(String path) throws IOException {  
  25.         MMapDirectory mmapDir = new MMapDirectory(new File(path));  
  26.         mmapDir.setUseUnmap(useUnmapHack);  
  27.         return new FileSwitchDirectory(nonMappedFiles, mmapDir, FSDirectory.open(new File(path)), true);  
  28.     }  
  29.   
  30.     public void init(NamedList args) {  
  31.         Object unmap, namedlist;  
  32.         nonMappedFiles = new HashSet<String>();  
  33.         if ((unmap = args.get("unmap")) instanceof Boolean)  
  34.             useUnmapHack = (Boolean) unmap;  
  35.         if ((namedlist = args.get("filetypes")) instanceof NamedList) {  
  36.             NamedList filetypes = (NamedList) namedlist;  
  37.             for (String type : IndexFileNames.INDEX_EXTENSIONS) {  
  38.                 Object mapped = filetypes.get(type);  
  39.                 if (Boolean.FALSE.equals(mapped))  
  40.                     nonMappedFiles.add(type);  
  41.             }  
  42.         }  
  43.     }  
  44. }  



 

solrconfig.xml上的配置,使用於新的DirectoryFactory

 

 

[html]   view plain copy
  1. <directoryFactory class="solr.MMapDirectoryFactory">  
  2. <str name="unmap">true</str>  
  3. <lst name="filetypes">  
  4. <bool name="fdt">false</bool>  
  5. <bool name="tii">false</bool>  
  6. </lst>  
  7. </directoryFactory>  

 

 

線上的索引文件大小:

7.3G    ./_y8b.fdt

201M    ./_y8b.fdx

4.0K    ./_y8b.fnm

1.8G    ./_y8b.frq

76M     ./_y8b.nrm

537M    ./_y8b.prx

7.1M    ./_y8b.tii

571M    ./_y8b.tis

4.0K    ./segments.gen

4.0K    ./segments_1p

 

 

因爲tii文件會加載到內存,因此這個不需要映射,fdt文件太大,主要是正向存儲的數據,可使用NiOFSDirectory方式

還有一個文件frq文件好大,這個也是須要考慮的。

 

 

[java]   view plain copy
  1. public final void setMaxChunkSize(final int maxChunkSize) {  
  2.   if (maxChunkSize <= 0)  
  3.     throw new IllegalArgumentException("Maximum chunk size for mmap must be >0");  
  4.   //System.out.println("Requested chunk size: "+maxChunkSize);  
  5.   this.chunkSizePower = 31 - Integer.numberOfLeadingZeros(maxChunkSize);  
  6.   assert this.chunkSizePower >= 0 && this.chunkSizePower <= 30;  
  7.   //System.out.println("Got chunk size: "+getMaxChunkSize());  
  8. }  

從上面的代碼能夠看出,最大也只能是1G大小。。。杯具。。

相關文章
相關標籤/搜索