`
mozhenghua
  • 浏览: 319504 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

内存缓存与硬盘缓存访问速度的比较

阅读更多

      这两天在为一个应用做solr搜索方案定制的过程中,需要用到solr的fieldcache,在估算fieldcache需要的内存容量,缓存中key是int,value是两个64bit大小的long类型数组,数据量大约是8100w,64×8100w/1024/1024,大致需要10G的容量,

 然而服务器总共也只有8G内存,实在无法支持这么大容量的缓存数据。

         

    于是开始想是不是可以有其他的替换的方案,可以不需要使用这么大的缓存容量,有能满足缓存的需要。考虑是不是可以将fieldcache中的数据内存存放到硬盘中去,在调用的时候可以通过key值快速计算出文档中的偏移量从而量数据取出,因为直观感觉只要知道一个文件偏移量而取内存应该是很快的。

          

    光有感觉是不行的,还需要实际测试一下,测试硬盘访问速度到底和内存访问速度相差多大。

 

  初始化测试数据       

    分别写一个向内存中和向硬盘中写数据的代码,内容如下:

  1. 向内存中写
    Map<Integer, Long[]> data = new HashMap<Integer, Long[]>();
    
    for (int i = 0; i < 2000000; i++) {
    	data.put(i, new Long[] { (long) (i + 1), (long) (i + 2) });
    }

     

  2. 向硬盘中写
    import java.io.File;
    import java.io.RandomAccessFile;
    
    import org.apache.lucene.analysis.Analyzer;
    import org.apache.lucene.analysis.payloads.PayloadHelper;
    import org.apache.lucene.analysis.standard.StandardAnalyzer;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.document.Field;
    import org.apache.lucene.index.IndexWriter;
    import org.apache.lucene.index.IndexWriterConfig;
    import org.apache.lucene.index.IndexWriterConfig.OpenMode;
    import org.apache.lucene.store.Directory;
    import org.apache.lucene.store.SimpleFSDirectory;
    import org.apache.lucene.util.Version;
    
    public class DocReplication {
    
    	public static Analyzer analyzer;
    	static {
    		analyzer = new StandardAnalyzer(Version.LUCENE_34);
    	}
    
    	public static void main(String[] arg) throws Exception {
    		RandomAccessFile randomFile = new RandomAccessFile(new File(
    				"DocReplication.text"), "rw");
    
    		Directory dir = new SimpleFSDirectory(new File("indexdir"));
    
    		IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_34,
    				analyzer);
    		iwc.setOpenMode(OpenMode.CREATE_OR_APPEND);
    		IndexWriter writer = new IndexWriter(dir, iwc);
    
    		for (int i = 0; i < 2000000; i++) {
                            // 向一个随机访问文件中写
    			randomFile.write(PayloadHelper.encodeInt(i));
    			randomFile.write(long2Array(i + 1));
    			randomFile.write(long2Array(i + 2));
                            // 向lucene中document中写
    			Document doc = new Document();
    			doc.add(new Field("id", String.valueOf(i), Field.Store.YES,
    					Field.Index.NOT_ANALYZED_NO_NORMS));
    			doc.add(new Field("id2", String.valueOf(i), Field.Store.YES,
    					Field.Index.NOT_ANALYZED_NO_NORMS));
    			writer.addDocument(doc);
    			System.out.println("point:" + randomFile.getFilePointer());
    		}
    		writer.commit();
    		writer.close();
    		randomFile.close();
    	}
    
    	static byte[] long2Array(long val) {
    
    		int off = 0;
    		byte[] b = new byte[8];
    		b[off + 7] = (byte) (val >>> 0);
    		b[off + 6] = (byte) (val >>> 8);
    		b[off + 5] = (byte) (val >>> 16);
    		b[off + 4] = (byte) (val >>> 24);
    		b[off + 3] = (byte) (val >>> 32);
    		b[off + 2] = (byte) (val >>> 40);
    		b[off + 1] = (byte) (val >>> 48);
    		b[off + 0] = (byte) (val >>> 56);
    		return b;
    
    	}
    }

     以上向内存中和向硬盘中写都是写200w条数据,在执行向硬盘中写的过程中分别是向lucene的索引文件和向RandomAccessFile随机文件中写,下面介绍一下用RandomAccessFile写的文件结构,文件中一条记录的数据结构,如图:

     一条记录的长度为20字节,只要拿到docid也就是key值就能计算出
    RandomAccessFile的文件偏移量=docid × 20。

     至于为什么要向lucene索引文件中写的原因是,想比较一下通过lucene的 indexread.get(docid) 方法取得到document的fieldvalue 的访问速度,和用RandomAccessFile访问缓存值的速度到底谁更快。

 

编写读数据测试案例

  1. 从自定义随机文件中读取
    public static void main(String[] args) throws Exception {
    
    		RandomAccessFile randomFile = new RandomAccessFile(new File(
    				"DocReplication.text"), "rw");
    
    		long current = System.currentTimeMillis();
    
    		for (int i = 0; i < 100000; i++) {
    
    			int docid = (int) (Math.random() * 2000000);
    			randomFile.seek(docid * 20 + 4);
    
    			randomFile.readLong();
    			randomFile.readLong();
    
    		}
    
    		System.out.println((System.currentTimeMillis() - current) / 1000);
    
    		randomFile.close();
    
    	}

     

  2. 从内存中读取
    public static void main(String[] args) {
    		Map<Integer, Long[]> data = new HashMap<Integer, Long[]>();
    
    		for (int i = 0; i < 2000000; i++) {
    			data.put(i, new Long[] { (long) (i + 1), (long) (i + 2) });
    		}
    		long start = System.currentTimeMillis();
    		Long[] row = null;
    		long tmp = 0;
    		for (int i = 0; i < 100000; i++) {
    			int doc = (int) (Math.random() * 2000000);
    			row = data.get(doc);
    			tmp = row[0];
    			tmp = row[1];
    		}
    		System.out.println((System.currentTimeMillis() - start) );
    	}

     

  3. 从lucene索引文件中随机访问
    public static void main(String[] args) throws Exception {
    	Directory dir = new SimpleFSDirectory(new File("indexdir"));
    	long start = System.currentTimeMillis();
    	IndexReader reader = IndexReader.open(dir);
    	Document doc = null;
    	for (int i = 0; i < 100000; i++) {
    		int docid = (int) (Math.random() * 2000000);
    		doc = reader.document(docid);
    		doc.get("id");
    		doc.get("id2");
    	}
    
    	System.out.println("consume:" + (System.currentTimeMillis() - start)/ 1000);
    }

     三个测试案例,都是从目标存储中从有200w数据量的cache中随机取出一个key,通过key取到value,这样的过程重复10w次,看看需要花费多少时间。

测试结果:

   从自定义随机文件中读取  从内存中读取  从lucene索引文件中随机访问
 总耗时  3717ms  75ms  1673ms

 

    从测试结果看,通过内存读cache是最快的,无疑和预想的结果是一致的,但是本来以为从自定义的随机文件中读取速度要比从lucene的indexreader来取要快些,但从测试结果看恰恰相反,从lucene的indexreader要比自定义随机文件快差不多一倍。

   比较之下,内存和磁盘的访问速度比是75比1673=1比22,速度还是相差挺大的,我很好奇,要是将磁盘改成SSD存储介质的话,磁盘访问速度会有多大提升,无奈现在测试环境中还没有SSD的服务器,改天找一台来测试一下,到时候再将测试结果公布一下。

  • 大小: 14.1 KB
分享到:
评论

相关推荐

    FancyCache 将系统内存或闪存虚拟成硬盘缓存的软件

    它把从硬盘中读取的数据存入系统内存或闪存,使系统在下次访问该数据时可以很快从内存读取,避免再次读取速度较慢的硬盘,从而突破硬盘瓶颈,提升系统性能。 FancyCache还具有检测和利用系统未识别内存的功能,解决...

    PHP中文件缓存转内存缓存的方法

    前言 顾名思义文件缓存转内存缓存就是将存储在文件中的数据转到内存中去,实现磁盘操作转为内存操作,这样可以大大提高数据访问速度,并能实现缓存数据的分布式部署。文件缓存与内存缓存的介绍请参考名词解释部分。 ...

    硬盘缓存增强软件 PrimoCache Desktop Edition 3.0.2 中文多语免费版.zip

    它可以自动将硬盘中读取的数据存入物理内存等速度较快的设备,当系统再次需要该数据时它可以很快从缓存设备中读取,而无需再次访问速度较慢的硬盘,从而有效提升物理硬盘的访问性能。 硬盘缓存增强软件 PrimoCache ...

    geoserver配置图层缓存

    把geoserver图层或图层组缓存到硬盘上,提高访问速度

    PrimoCach服务器版(虚拟硬盘缓存加速工具)v2.2.0官方安装版

    它可以自动将硬盘中读取的数据存入物理内存等速度较快的设备,当系统再次需要该数据时它可以很快从缓存设备中读取,而无需再次访问速度较慢的硬盘,从而有效提升物理硬盘的访问性能。需要的朋友们可以下载试试吧! ...

    PrimoCach普通版(虚拟硬盘缓存加速工具)v2.2.0免费安装版

    它可以自动将硬盘中读取的数据存入物理内存等速度较快的设备,当系统再次需要该数据时它可以很快从缓存设备中读取,而无需再次访问速度较慢的硬盘,从而有效提升物理硬盘的访问性能。需要的朋友们可以下载试试吧! ...

    SMARTDRV.EXE(设置磁盘加速器,它可以提高硬盘访问速度。)

    执行并驻留内存,开辟磁盘加速缓存区,并屏蔽所有驱动器缓存,是较常用的方法(一般用这个参数) 其它参数: smartdrv /c 将缓存内的信息都写入硬盘 smartdrv /e: 数字 设置一次移动的信息量 smartdrv /b: ...

    免费内存虚拟盘VSuite.Ramdisk1.18,超级兔子虚拟磁盘1.6

    它采用独特的软件算法,高效率地将内存虚拟成物理硬盘,使得对硬盘文件的数据读写转化为对内存的数据访问,极大的提高数据访问速度,从而突破硬盘瓶颈,飞速提升计算机性能。另一方面它大大减少了对物理硬盘的访问...

    快速文件系统

    文件高速缓存被设置在内存中,从而解决CPU与硬盘访问速度差异太大的问题。高速缓存即在读文件时预读,从而加速访问。异步传输改变内存访问的指令顺序,从而提高了代码执行效率。 本程序通过对三种文件读写操作的...

    内存数据库与Hybrid DBMS技术简介

    相对于磁盘,内存的数据读写速度要高出几个数量级,将数据保存在内存中相比从磁盘上访问能够极大地提高应用的性能。同时,内存数据库抛弃了磁盘数据管理的传统方式,基于全部数据都在内存中重新设计了体系结构,并且...

    服务器虚拟化部署方案.doc

    磁盘:即使内存很充足,系统还得执行大量的磁盘I/O,从硬盘中读取数据并写入 修改的数据,因此磁盘的访问速度对性能影响也很大。另外,磁盘中的数据非常重要 。为了提高访问数据库的性能,并保护磁盘中的重要数据,...

    PrimoCache2.2

    它可以自动将硬盘中读取的数据存入物理内存等速度较快的设备,当系统再次需要该数据时它可以很快从缓存设备中读取,而无需再次访问速度较慢的硬盘,从而有效提升物理硬盘的访问性能。    PrimoCache 支持将 SSD ...

    PrimoCach v2.4.0 普通版.zip

    它可以自动将硬盘中读取的数据存入物理内存等速度较快的设备,当系统再次需要该数据时它可以很快从缓存设备中读取,而无需再次访问速度较慢的硬盘,从而有效提升物理硬盘的访问性能。如果目前您对这务方面还是不太...

    10分钟彻底搞懂Http的强制缓存和协商缓存(小结)

    浏览器缓存是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就可以直接从本地磁盘加载文档。 所以根据上面的特点,浏览器缓存有下面的优点: 减少冗余的数据传输 减少...

    PrimoCache Server2.2.0服务器版.exe

    它可以自动将硬盘中读取的数据存入物理内存等速度较快的设备,当系统再次需要该数据时它可以很快从缓存设备中读取,而无需再次访问速度较慢的硬盘,从而有效提升物理硬盘的访问性能。 PrimoCache 支持将 SSD 硬盘...

    fancycache0.7.2硬盘保护神(硬盘版)

    它把从硬盘中读取的数据存入系统内存或闪存,使系统在下次访问该数据时可以很快从内存读取,避免再次读取速度较慢的硬盘,从而突破硬盘瓶颈,提升系统性能。 FancyCache还具有检测和利用系统未识别内存的功能,解决...

    Android中使用二级缓存、异步加载批量加载图片完整案例

    Android应用中经常涉及从网络中加载大量图片,为提升加载速度和效率,减少网络流量都会采用二级缓存和异步加载机制,所谓二级缓存就是通过先从内存中获取、再从文件中获取,最后才会访问网络。内存缓存(一级)本质...

    primocache 破解版

    如果电脑系统将再次需要该数据时它可以很快从缓存设备中读取,而无需再次访问速度较慢的硬盘,从而有效提升物理硬盘的访问性能。 PrimoCache破解版2018功能特点:  1、支持物理内存、SSD固态硬盘、闪存盘等作为...

    FancyCache 0.7.2 中文硬盘版

    它把从硬盘中读取的数据存入系统内存或闪存,使系统在下次访问该数据时可以很快从内存读取,避免再次读取速度较慢的硬盘,从而突破硬盘瓶颈,提升系统性能。 FancyCache还具有检测和利用系统未识别内存的功能,解决...

Global site tag (gtag.js) - Google Analytics