FileSwitchDirectory 学习笔记 并在solr上的使用
2012-09-21 23:43
639 查看
FileSwitchDirectory实现原理与应用
FileSwitchDirectory是lucene的另一种Directory实现类,从名字个就可以理解为文件切换的Directory实现,
的确是针对lucene的不同的索引文件使用不同的Directory .借助FileSwitchDirectory整合不同的Directory实现类的优点于一身。
比如MMapDirectory,借助内存映射文件方式提高性能,但又要减少内存切换的可能 ,当索引太大的时候,内存映射也需要不断地切换,这样优点也可能变缺点,而之前的NIOFSDirectory实现java NIO的方式提高高并发性能,但又因高并发也会导致IO过多的影响,所以这次可以借助FileSwitchDirectory发挥他们两的优点。
MMapDirectory与NIOFSDirectory的实现差别。
NIOFSDirectory----只是使用了直接内存读取文件缓存方式
@Override
protected void newBuffer(byte[] newBuffer) {
super.newBuffer(newBuffer);
byteBuf = ByteBuffer.wrap(newBuffer);
}
MMapDirectory------使用MMap技术映射文件,默认会映射1G的内存(64位)或者256m(32位系统))
MMapDiretory就是将文件映射到内存中。。使用的是MMap技术
this.buffers[bufNr] = rafc.map(MapMode.READ_ONLY, bufferStart, bufSize);
首先将索引目录里占比例比较小的文件使用MMapDirectory,这样几乎可以全部映射到内存里了。。而占有大比例的文档存储文件交由于NIOFSDirectory方式读取。
这个结合不错呀。。
FileSwitchDirectory实现代码解析
FileSwitchDirectory的代码很简单,因为可以理解为它就是一个Dao的入口也是个控制器,所以它并没有具体的文件操纵实现。
先了解它的构造是:
首先是文件后缀的集合参数
主要的Directory
次要的Directory
是否关闭的时候调用
所以都是调用对应的Directory获得IndexInput 与IndexOuput
通过文件名字取到对应的Directory
solr使用的DirectoryFactory实现
solrconfig.xml上的配置,使用于新的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文件好大,这个也是需要考虑的。
从上面的代码可以看出,最大也只能是1G大小。。。杯具。。
转载请写明引用:FileSwitchDirectory 学习笔记 并在solr上的使用
FileSwitchDirectory是lucene的另一种Directory实现类,从名字个就可以理解为文件切换的Directory实现,
的确是针对lucene的不同的索引文件使用不同的Directory .借助FileSwitchDirectory整合不同的Directory实现类的优点于一身。
比如MMapDirectory,借助内存映射文件方式提高性能,但又要减少内存切换的可能 ,当索引太大的时候,内存映射也需要不断地切换,这样优点也可能变缺点,而之前的NIOFSDirectory实现java NIO的方式提高高并发性能,但又因高并发也会导致IO过多的影响,所以这次可以借助FileSwitchDirectory发挥他们两的优点。
MMapDirectory与NIOFSDirectory的实现差别。
NIOFSDirectory----只是使用了直接内存读取文件缓存方式
@Override
protected void newBuffer(byte[] newBuffer) {
super.newBuffer(newBuffer);
byteBuf = ByteBuffer.wrap(newBuffer);
}
MMapDirectory------使用MMap技术映射文件,默认会映射1G的内存(64位)或者256m(32位系统))
MMapDiretory就是将文件映射到内存中。。使用的是MMap技术
this.buffers[bufNr] = rafc.map(MapMode.READ_ONLY, bufferStart, bufSize);
首先将索引目录里占比例比较小的文件使用MMapDirectory,这样几乎可以全部映射到内存里了。。而占有大比例的文档存储文件交由于NIOFSDirectory方式读取。
这个结合不错呀。。
FileSwitchDirectory实现代码解析
FileSwitchDirectory的代码很简单,因为可以理解为它就是一个Dao的入口也是个控制器,所以它并没有具体的文件操纵实现。
先了解它的构造是:
public FileSwitchDirectory(Set<String> primaryExtensions, Directory primaryDir, Directory secondaryDir, boolean doClose) { this.primaryExtensions = primaryExtensions; this.primaryDir = primaryDir; this.secondaryDir = secondaryDir; this.doClose = doClose; this.lockFactory = primaryDir.getLockFactory(); }
首先是文件后缀的集合参数
主要的Directory
次要的Directory
是否关闭的时候调用
所以都是调用对应的Directory获得IndexInput 与IndexOuput
@Override public IndexInput openInput(String name) throws IOException { return getDirectory(name).openInput(name); }
@Override public IndexOutput createOutput(String name) throws IOException { return getDirectory(name).createOutput(name); }
通过文件名字取到对应的Directory
private Directory getDirectory(String name) { String ext = getExtension(name); if (primaryExtensions.contains(ext)) { return primaryDir; } else { return secondaryDir; } }
solr使用的DirectoryFactory实现
/** * * * 支持某些后缀文件不作映射优化,比如去掉fdt,fdx * * * * <directoryFactory class="solr.MMapDirectoryFactoryExt"> <str name="unmap">true</str> <lst name="filetypes"> <bool name="fdt">false</bool> <bool name="fdx">false</bool> </lst> </directoryFactory> * */ public class MMapDirectoryFactoryExt extends DirectoryFactory { // filetypes不作映射 private Set<String> nonMappedFiles = new HashSet<String>(); // 是否使用不映射选择 private Boolean useUnmapHack = false; public Directory open(String path) throws IOException { MMapDirectory mmapDir = new MMapDirectory(new File(path)); mmapDir.setUseUnmap(useUnmapHack); return new FileSwitchDirectory(nonMappedFiles, mmapDir, FSDirectory.open(new File(path)), true); } public void init(NamedList args) { Object unmap, namedlist; nonMappedFiles = new HashSet<String>(); if ((unmap = args.get("unmap")) instanceof Boolean) useUnmapHack = (Boolean) unmap; if ((namedlist = args.get("filetypes")) instanceof NamedList) { NamedList filetypes = (NamedList) namedlist; for (String type : IndexFileNames.INDEX_EXTENSIONS) { Object mapped = filetypes.get(type); if (Boolean.FALSE.equals(mapped)) nonMappedFiles.add(type); } } } }
solrconfig.xml上的配置,使用于新的DirectoryFactory
<directoryFactory class="solr.MMapDirectoryFactory"> <str name="unmap">true</str> <lst name="filetypes"> <bool name="fdt">false</bool> <bool name="tii">false</bool> </lst> </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文件好大,这个也是需要考虑的。
public final void setMaxChunkSize(final int maxChunkSize) { if (maxChunkSize <= 0) throw new IllegalArgumentException("Maximum chunk size for mmap must be >0"); //System.out.println("Requested chunk size: "+maxChunkSize); this.chunkSizePower = 31 - Integer.numberOfLeadingZeros(maxChunkSize); assert this.chunkSizePower >= 0 && this.chunkSizePower <= 30; //System.out.println("Got chunk size: "+getMaxChunkSize()); }
从上面的代码可以看出,最大也只能是1G大小。。。杯具。。
转载请写明引用:FileSwitchDirectory 学习笔记 并在solr上的使用
相关文章推荐
- java学习笔记 switch中使用枚举enum
- [学习笔记]Java基础_IO(包含对象流序列化使用和RandomAccessFile 类的使用)
- 学习笔记:zipfile的简单使用解压和压缩文件,以为处理加密的情况
- Solr学习笔记五--solrj的使用(查询文档)
- docker学习笔记4.1-使用Dockerfile文件构建镜像
- Docker学习笔记(3)-- 如何使用Dockerfile构建镜像
- Docker学习笔记(3)-- 如何使用Dockerfile构建镜像
- Docker学习笔记-- 如何使用Dockerfile构建镜像
- docker学习笔记(六)使用Dockerfile构建镜像
- Docker学习笔记(3)-- 如何使用Dockerfile构建镜像
- solr学习笔记 -- day05 solrJ的使用
- Silverlight学习笔记五( 在Silverlight 2.0/3.0/4.0 中使用OpenFileDialog浏览本地图片)
- Docker学习笔记-- 如何使用Dockerfile构建镜像
- Solr学习笔记---部署Solr到Tomcat上,可视化界面的介绍和使用,Solr的基本内容介绍,SolrJ的使用
- solr学习笔记-2012-5-11 --主目录-home-directory --src包
- Objective-C学习笔记(十二)——switch多分支语句的使用
- solr学习笔记 -- day03 使用solrJ客户端
- Solr学习笔记四--solrj的使用(更新文档)
- Docker学习笔记之使用Dockerfile创建镜像
- docker学习笔记3—使用Dockerfile与docker build命令创建一个nginx服务器镜像,并使用浏览器进行访问