本地数据存储 | wsztrush
最近在考虑如何做算法的优化计算,有两个地方比较头疼:
- 耗时
- 内存
现在的做法是一股脑把所有的东西丢到内存,做起来简单,但是一个任务开跑400MB+的内存就没了,有点慌。并且,读取这400MB+的数据耗时也相当可观,如果能将数据放在本地,在执行任务的时候就地取材,应该也能省不少。
Chronicle
同时支持堆外和持久化。
用法&特点
在创建的时候如果是create则用堆外内存,如果是createPersistedTo(file)则能持久化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class TestMain { public void test() throws Exception { ChronicleMap<Integer, String> chronicleMap = ChronicleMap .of(Integer.class, String.class) .name("test-map") .averageValue("123123") .entries(10000) .create(); for (int i = 0; i < 10000; i++) { chronicleMap.put(i, "123"); } } } |
原理
TODO
RocksDB
在LevelDB的基础开发,牺牲部分写性能,提升大量读性能。
用法&特点
基本的Kev/Value操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | public class TestMain { static { RocksDB.loadLibrary(); } public void test() throws Exception { // INIT Options options = new Options(); options.setCreateIfMissing(true); RocksDB rocksDB = RocksDB.open(options, "/Users/tianchi.gzt/workspace/rocksdb/"); byte[] key = "key".getBytes(), value = "value".getBytes(); // PUT rocksDB.put(key, value); // GET str(rocksDB.get(key)); // MULTI GET Map<byte[], byte[]> ret = rocksDB.multiGet(Lists.newArrayList(key)); for (Map.Entry<byte[], byte[]> entry : ret.entrySet()) { str(entry.getKey(), entry.getValue()); } // ITER RocksIterator iterator = rocksDB.newIterator(); for (iterator.seekToFirst(); iterator.isValid(); iterator.next()) { str(iterator.key(), iterator.value()); } // DELETE rocksDB.delete(key); } private void str(byte[]... bytes) { List<String> content = Lists.newArrayList(); for (byte[] b : bytes) { content.add(new String(b)); } System.out.println(Joiner.on(' ').join(content)); } } |
此外增加了ColumnFamily用法,用来做隔离(可以分别配置),默认使用default:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | public class TestMain { static { RocksDB.loadLibrary(); } public void test() throws Exception { // INIT Options options = new Options(); options.setCreateIfMissing(true); String dbPath = "/Users/tianchi.gzt/workspace/rocksdb/"; // 设置DB中有哪些ColumnFamily List<ColumnFamilyDescriptor> columnFamilyDescriptors = new ArrayList<>(); List<byte[]> columnFamilies = RocksDB.listColumnFamilies(options, dbPath); if (columnFamilies.size() > 0) { columnFamilies.forEach(cf -> columnFamilyDescriptors.add(new ColumnFamilyDescriptor(cf, new ColumnFamilyOptions()))); } else { columnFamilyDescriptors.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, new ColumnFamilyOptions())); } // 链接DB List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>(); DBOptions dbOptions = new DBOptions(); dbOptions.setCreateIfMissing(true); RocksDB rocksDB = RocksDB.open(dbOptions, dbPath, columnFamilyDescriptors, columnFamilyHandles); byte[] table = "table".getBytes(), key = "key".getBytes(), value = "value".getBytes(); // 如果已经有同名的,将其删除 for(int i = 0; i < columnFamilyDescriptors.size(); i++) { if(new String(columnFamilyDescriptors.get(i).columnFamilyName()).equals(table)) { rocksDB.dropColumnFamily(columnFamilyHandles.get(i)); } } // 创建ColumnFamily。 ColumnFamilyHandle columnFamilyHandle = rocksDB.createColumnFamily(new ColumnFamilyDescriptor(table, new ColumnFamilyOptions())); // 插入 rocksDB.put(columnFamilyHandle, key, value); // 读取 str(rocksDB.get(columnFamilyHandle, key)); } private void str(byte[]... bytes) { List<String> content = Lists.newArrayList(); for (byte[] b : bytes) { content.add(new String(b)); } System.out.println(Joiner.on(' ').join(content)); } } |
原理
TODO
SQLite
轻量级数据库(ACID),设计目标为嵌入式,占用资源非常低,支持语言非常广!
用法&特点
很“标准”的数据库方法方式,能通过SQL来快速实现一些功能,但是性能貌似并没有很好:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public class TestMain { public void test() throws Exception { Connection connection = null; Statement stmt = null; try { Class.forName("org.sqlite.JDBC"); connection = DriverManager.getConnection("jdbc:sqlite:test.db"); stmt = connection.createStatement(); String sql = "CREATE TABLE COMPANY " + "(ID INT PRIMARY KEY NOT NULL," + " NAME TEXT NOT NULL, " + " AGE INT NOT NULL, " + " ADDRESS CHAR(50), " + " SALARY REAL)"; stmt.executeUpdate(sql); stmt.close(); connection.close(); } catch (Exception e) { e.printStackTrace(); } } } |
原理
TODO