装饰工程网站模板下载,网站登录系统,wordpress插件 书籍分享,广东企业黄页网站背景MapDB官网#xff1a;http://www.mapdb.org官方翻译之后的话#xff1a;MapDB基于堆外存储、磁盘存储提供了Java的Maps、Sets、Lists、Queues等功能。它混合了Java集合框架和数据库引擎。它是基于Apache许可的免费的、开源的。个人觉得#xff1a;MapDB是一个轻量级的本…背景MapDB官网http://www.mapdb.org官方翻译之后的话MapDB基于堆外存储、磁盘存储提供了Java的Maps、Sets、Lists、Queues等功能。它混合了Java集合框架和数据库引擎。它是基于Apache许可的免费的、开源的。个人觉得MapDB是一个轻量级的本地缓存的框架它既可以使用对外存储也可以使用磁盘存储(重启时数据不丢失)。它还提供事务的功能。开发文档https://jankotek.gitbooks.io/mapdb/content/quick-start/开发机器配置i5-9400 6c6t32g内存固态硬盘MapDB入门实战1、引入jar包org.mapdbmapdb3.0.72、基于堆外存储的Hello,Simple/*** 堆外内存map*/public static voidoffHeapMapTest1() {DB dbDBMaker.memoryDB().make();ConcurrentMap map db.hashMap(map).createOrOpen();String key Hello;String val simple;map.put(key, val);System.out.println(第1次取值 map.get(key));}执行结果--Hello,simple----第1次取值simple2.1、插曲刚开始执行的时候总是报下面的异常Exception in thread main java.lang.NoClassDefFoundError: org/eclipse/collections/impl/list/mutable/primitive/LongArrayListat org.mapdb.StoreDirectAbstract.(StoreDirectAbstract.kt:41)at org.mapdb.StoreDirect.(StoreDirect.kt:30)at org.mapdb.StoreDirect$Companion.make(StoreDirect.kt:57)at org.mapdb.StoreDirect$Companion.make$default(StoreDirect.kt:56)at org.mapdb.DBMaker$Maker.make(DBMaker.kt:450)at me.lovegao.mapdb.hello.HelloWorldDemo.offHeapMapTest1(HelloWorldDemo.java:18)at me.lovegao.mapdb.hello.HelloWorldDemo.main(HelloWorldDemo.java:11)Caused by: java.lang.ClassNotFoundException: org.eclipse.collections.impl.list.mutable.primitive.LongArrayListat java.net.URLClassLoader.findClass(URLClassLoader.java:381)at java.lang.ClassLoader.loadClass(ClassLoader.java:424)at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)at java.lang.ClassLoader.loadClass(ClassLoader.java:357)... 7 more我以为是jar包没加全又加了Eclipse相关的jar包发现还是这样。对着项目又是清理又是重新编译又是重新导包发现都不行。仔细看了maven的依赖都是存在的看MapDB的文档也说上面那个配置包含全部的。最后索性把本地相关的jar包都删了让maven重新下最终正常了。3、基于磁盘的Hello,Simple基于磁盘存储的为了保证数据的完整性需要在关闭虚拟机前关闭DB。public static voidfileMapTest1() {DB db DBMaker.fileDB(file.db).make();ConcurrentMap map db.hashMap(map).createOrOpen();String key something;String val here;map.put(key, val);System.out.println(第1次取值 map.get(key));db.close();System.out.println(----------重新打开----------);db DBMaker.fileDB(file.db).make();map db.hashMap(map).createOrOpen();System.out.println(第2次取值 map.get(key));db.close();}执行结果--Hello,simple----第1次取值simple----------重新打开----------第2次取值simple结果符合预期。3.1、基于磁盘的内存映射的使用/*** 在64位操作系统中开启内存映射* 个性化序列化*/public static voidfileMapMemoryMapTest() {DB dbDBMaker.fileDB(file.db).fileMmapEnable().make();ConcurrentMap map db.hashMap(mapsl, Serializer.STRING, Serializer.LONG).createOrOpen();long val 51;map.put(DEMO_KEY, val);System.out.println(第1次取值期望值 val 取到的值 map.get(DEMO_KEY));db.close();dbDBMaker.fileDB(file.db).fileMmapEnable().make();map db.hashMap(mapsl, Serializer.STRING, Serializer.LONG).createOrOpen();System.out.println(第2次取值期望值 val 取到的值 map.get(DEMO_KEY));db.close();}执行结果--Hello,simple----第1次取值期望值51取到的值51第2次取值期望值51取到的值514、性能对比1)测试代码packageme.lovegao.mapdb.hello;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.Iterator;importjava.util.List;importjava.util.Map;importjava.util.Map.Entry;importjava.util.concurrent.ConcurrentMap;importorg.eclipse.collections.impl.map.mutable.ConcurrentHashMap;importorg.mapdb.DB;importorg.mapdb.DBMaker;importorg.mapdb.Serializer;public classMapDBSpeedTest {private final static String DEMO_KEY Hello;private final static String DEMO_VAL simple;public static voidmain(String[] args) {System.out.println(--Hello,simple----);//fileMapMemoryMapTest();mapTest();}public static voidmapTest() {int dataNum 10000;List dbList newArrayList();Map testMap newHashMap();Map dataMap generateTestData(dataNum);//java原生-堆内mapConcurrentMap inHeapDbMap newConcurrentHashMap();testMap.put(原生map, inHeapDbMap);//堆外mapDB offHeapDb DBMaker.memoryDB().make();dbList.add(offHeapDb);ConcurrentMap offHeapDbMap offHeapDb.hashMap(map).createOrOpen();testMap.put(堆外map, offHeapDbMap);//基于磁盘mapDB fileDb DBMaker.fileDB(file1.db).make();dbList.add(fileDb);ConcurrentMap fileDbMap fileDb.hashMap(map1, Serializer.STRING, Serializer.LONG).createOrOpen();testMap.put(基于磁盘map, fileDbMap);//基于磁盘-内存映射mapDB fileMmapDb DBMaker.fileDB(file2.db).fileChannelEnable()//By default MapDB uses RandomAccessFile to access disk storage. Outside fast mmap files there is third option based on FileChannel. It should be faster than RandomAccessFile.fileMmapEnable() //Always enable mmap//.fileMmapEnableIfSupported()//Only enable mmap on supported platforms对性能影响较大.fileMmapPreclearDisable() //Make mmap file faster//.allocateStartSize( 10 * 1024*1024*1024)//10GB初始容量//.allocateIncrement(512 * 1024*1024)//512MB每次增加容量.make();//optionally preload file content into disk cachefileMmapDb.getStore().fileLoad();dbList.add(fileMmapDb);ConcurrentMap fileMmapMap fileMmapDb.hashMap(map2, Serializer.STRING, Serializer.LONG).createOrOpen();testMap.put(基于磁盘-内存映射map, fileMmapMap);System.out.println(-----------put---数据量dataNum------);for(String mapType : testMap.keySet()) {putGetMapTest(mapType, testMap.get(mapType), dataMap,true);}System.out.println(-----------------------------------------\n);System.out.println(-----------get---数据量dataNum------);for(String mapType : testMap.keySet()) {putGetMapTest(mapType, testMap.get(mapType), dataMap,false);}for(DB db : dbList) {db.close();}}/*** putGet测试*parammap*paramdataMap*paramput*return*/public static TwoTuple putGetMapTest(String mapType, Map map, Map dataMap, booleanput) {long useTime 0L;long errorNum 0L;Iterator entryIt dataMap.entrySet().iterator();while(entryIt.hasNext()) {Entry entry entryIt.next();if(put) {long t1 System.nanoTime();map.put(entry.getKey(), entry.getValue());useTime System.nanoTime() -t1;}else{long t1 System.nanoTime();long val map.get(entry.getKey());useTime System.nanoTime() -t1;if(val !entry.getValue()) {errorNum;}}}double avgUseTime (double)useTime /dataMap.size();String fmtStr map类型%s总耗时%dns平均耗时%ens异常数量%d;System.out.println(String.format(fmtStr, mapType, useTime, avgUseTime, errorNum));return new TwoTuple(useTime, errorNum);}/*** 生成测试数据*paramsize*return*/public static Map generateTestData(intsize) {Map map newHashMap();int arrLength 26;char[] words new char[arrLength];for(int i0; iwords[i] (char) (a i);}System.out.println(words);String demoWord newString(words);for(int i0; iString key demoWord.substring(i%arrLength, i%arrLength) i;long val i;map.put(key, val);}returnmap;}/*** 对外内存map*/public static voidoffHeapMapTest1() {DB dbDBMaker.memoryDB().make();ConcurrentMap map db.hashMap(map).createOrOpen();map.put(DEMO_KEY, DEMO_VAL);System.out.println(第1次取值 map.get(DEMO_KEY));}/*** 基于磁盘的存储*/public static voidfileMapTest1() {DB db DBMaker.fileDB(file.db).make();ConcurrentMap map db.hashMap(map).createOrOpen();map.put(DEMO_KEY, DEMO_VAL);System.out.println(第1次取值 map.get(DEMO_KEY));db.close();System.out.println(----------重新打开----------);db DBMaker.fileDB(file.db).make();map db.hashMap(map).createOrOpen();System.out.println(第2次取值 map.get(DEMO_KEY));db.close();}/*** 在64位操作系统中开启内存映射* 个性化序列化*/public static voidfileMapMemoryMapTest() {DB dbDBMaker.fileDB(file.db).fileMmapEnable().make();ConcurrentMap map db.hashMap(mapsl, Serializer.STRING, Serializer.LONG).createOrOpen();long val 51;map.put(DEMO_KEY, val);System.out.println(第1次取值期望值 val 取到的值 map.get(DEMO_KEY));db.close();dbDBMaker.fileDB(file.db).fileMmapEnable().make();map db.hashMap(mapsl, Serializer.STRING, Serializer.LONG).createOrOpen();System.out.println(第2次取值期望值 val 取到的值 map.get(DEMO_KEY));db.close();}}2)测试结果map类型测试数据量测试类型总耗时(ns)平均耗时(ns)原生map10000put1001.000000e-02堆外map同上put48004.800000e-01基于磁盘map同上put3450003.450000e01基于磁盘-内存映射map同上put60006.000000e-01原生map同上get1001.000000e-02堆外map同上get20002.000000e-01基于磁盘map同上get754007.540000e00基于磁盘-内存映射map同上get11001.100000e-013)结论①原生的基于堆的map速度始终是最快的②堆外map和基于磁盘且开启了内存映射的map相比优势较小。至于原因有待深入理解。③对于“基于磁盘-内存映射map”使用“fileMmapEnableIfSupported”配置对性能影响较大建议直接开启。配置“fileMmapPreclearDisable”对于put的性能提升较大(约一倍提升)。MapDB事务MapDB是支持事务的具体使用如下packageme.lovegao.mapdb.hello;importjava.util.concurrent.ConcurrentMap;importorg.mapdb.DB;importorg.mapdb.DBMaker;importorg.mapdb.Serializer;public classMapDBTransaction {public static voidmain(String[] args) {DB dbDBMaker.fileDB(file3.db).fileMmapEnable().transactionEnable().closeOnJvmShutdown() //JVM关闭时关闭db.make();ConcurrentMap map db.hashMap(mapsl3, Serializer.STRING, Serializer.LONG).createOrOpen();map.put(a, 1L);map.put(b, 2L);db.commit();System.out.println(map.get(a));System.out.println(map.get(b));map.put(c, 3L);System.out.println(rollback之前c: map.get(c));db.rollback();System.out.println(rollback之后a: map.get(a));System.out.println(rollback之后c: map.get(c));}}运行结果12rollback之前c:3rollback之后a:1rollback之后c:null因为配置了closeOnJvmShutdown所以再次运行时能够正常运行。如果去掉了transactionEnable和closeOnJvmShutdown再次运行时将出现以下异常Exception in thread main org.mapdb.DBException$DataCorruption: Header checksum broken. Store was not closed correctly and might be corrupted. Use DBMaker.checksumHeaderBypass() to recover your data. Use clean shutdown or enable transactions to protect the store in the future.at org.mapdb.StoreDirectAbstract.fileHeaderCheck(StoreDirectAbstract.kt:113)at org.mapdb.StoreDirect.(StoreDirect.kt:114)at org.mapdb.StoreDirect$Companion.make(StoreDirect.kt:57)at org.mapdb.StoreDirect$Companion.make$default(StoreDirect.kt:56)at org.mapdb.DBMaker$Maker.make(DBMaker.kt:450)at me.lovegao.mapdb.hello.MapDBTransaction.main(MapDBTransaction.java:17)最后说以下fileDB(file3.db)这里的路径可以指定其他目录默认是在项目的根目录下。路径是自己创建的文件是MapDB自动创建的切记不要多此一举把文件也创建了那样会报错的。