关于源码分析:H2存储内核分析一

5次阅读

共计 4129 个字符,预计需要花费 11 分钟才能阅读完成。

开篇阐明

  1. 当初做数据库个别都才有 C/C++ 获取其它编译型的语言,为什么会抉择 h2 这种基于 java 的语言?会不会影响效率?其实答复这个问题很简略,无论是用什么语言来实现数据库,其实都是在调用操作系统 IO 的函数。因而仅仅是作为存储的话差异其实是不大的。
  2. 当初大多数,波及到存储内核的文章或者讲义,要么是一堆原理,要么就是玩具版本例子,根本无法利用到理论的工程下面去,就像马保国的闪电五连鞭一样。咱们抉择 h2 的一个重要起因就是,学习完后,能够间接利用到工程上。行不行间接在擂台上比一下就晓得了。

MVStore 的根底办法

1、创立一个 MVStore 的对象时,如果 fileName 设置为空示意纯内存模式。也就是说 MVStore 能够作为 redis 应用,当然性能会比 redis 还弱小。

1.1、纯内存模式

// 创立一个纯内存的 store
MVStore store = MVStore.open(null);

1.2、磁盘模式

// 文件存储地位
String fileName = "/Users/chenfei/temp/my_store.db";
// 创立一个 store
MVStore store = new MVStore.Builder().fileName(fileName).pageSplitSize(1000).open();

1.3、应用 MVStore.Builder() 生成 MVStore

MVStore.Builder() 罕用办法

  1. 生成纯内存 store
        MVStore.Builder builder = new MVStore.Builder();
        MVStore store = builder.open();
  1. fileName(String fileName):设置存储 MVStore 数据的文件名
        String fileName = "/Users/chenfei/temp/my_store.db";
        MVStore.Builder builder = new MVStore.Builder();
        builder.fileName(fileName);
        MVStore store = builder.open();
  1. encryptionKey(char[] key):设置加密密钥,用于对 MVStore 的数据进行加密。如果不设置,则不进行加密。
        String fileName = "/Users/chenfei/temp/my_store.db";
        MVStore.Builder builder = new MVStore.Builder();
        builder.encryptionKey("my_h2".toCharArray());
        builder.fileName(fileName);
        MVStore store = builder.open();
  1. compress():开启压缩选项,用于将 MVStore 的数据进行压缩,以减小存储空间。默认不开启。
        String fileName = "/Users/chenfei/temp/my_store.db";
        MVStore.Builder builder = new MVStore.Builder();
        builder.encryptionKey("my_h2".toCharArray());
        /**
         * 应用 LZF 算法在写入之前压缩数据。这将节俭
         * 大概 50% 的磁盘空间,但会减慢读写速度操作轻微
         * */
        builder.compress();
        builder.fileName(fileName);
        MVStore store = builder.open();
  1. 禁用主动提交事务,须要手动提交。默认开启主动提交事务。
        String fileName = "/Users/chenfei/temp/my_store.db";
        MVStore.Builder builder = new MVStore.Builder();
        builder.encryptionKey("my_h2".toCharArray());
        /**
         * 应用 LZF 算法在写入之前压缩数据。这将节俭
         * 大概 50% 的磁盘空间,但会减慢读写速度操作轻微
         * */
        builder.compress();
        // 禁用主动提交事务,须要手动提交。builder.autoCommitDisabled();
        builder.fileName(fileName);
        MVStore store = builder.open();
  1. 设置 MVStore 为只读模式,不能进行写操作。
        String fileName = "/Users/chenfei/temp/my_store.db";
        MVStore.Builder builder = new MVStore.Builder();
        builder.encryptionKey("my_h2".toCharArray());
        /**
         * 应用 LZF 算法在写入之前压缩数据。这将节俭
         * 大概 50% 的磁盘空间,但会减慢读写速度操作轻微
         * */
        builder.compress();
        // 禁用主动提交事务,须要手动提交。builder.autoCommitDisabled();
        // 设置 MVStore 为只读模式,不能进行写操作。builder.readOnly();
        builder.fileName(fileName);
        MVStore store = builder.open();
  1. 设置 MVStore 的缓存大小,单位为 MB,默认为 16MB。
        String fileName = "/Users/chenfei/temp/my_store.db";
        MVStore.Builder builder = new MVStore.Builder();
        builder.encryptionKey("my_h2".toCharArray());
        /**
         * 应用 LZF 算法在写入之前压缩数据。这将节俭
         * 大概 50% 的磁盘空间,但会减慢读写速度操作轻微
         * */
        builder.compress();
        // 禁用主动提交事务,须要手动提交。builder.autoCommitDisabled();
        // 设置 MVStore 为只读模式,不能进行写操作。// builder.readOnly();
        // 设置 MVStore 的缓存为 8MB,默认为 16MB
        builder.cacheSize(8);
        builder.fileName(fileName);
        MVStore store = builder.open();
  1. pageSplitSize(int pageSplitSize):数据页的大小是通过 pageSplitSize 办法进行设置的,默认值为 4KB。
    **MVStore 应用了数据页的概念来治理存储的数据,将较大的数据文件拆分成多个小的数据页,以进步性能。每个数据页的大小是通过 pageSplitSize 办法进行设置的,默认值为 4KB。当 MVStore 在写入数据时,首先会将数据写入内存缓存中,当缓存中的数据达到肯定大小后,会将数据刷新到磁盘上,并拆分成多个数据页。如果数据大小超过了 pageSplitSize 的设置值,则会拆分成多个数据页。因而,pageSplitSize 的设置值会影响数据拆分的粒度,进而影响 MVStore 的性能。
    通常状况下,pageSplitSize 的默认值能够满足大部分利用的须要。如果须要调整 MVStore 的性能,能够依据理论状况适当调整 pageSplitSize 的值。须要留神的是,pageSplitSize 的值必须是 2 的幂次方。**
        String fileName = "/Users/chenfei/temp/my_store.db";
        MVStore.Builder builder = new MVStore.Builder();
        builder.encryptionKey("my_h2".toCharArray());
        /**
         * 应用 LZF 算法在写入之前压缩数据。这将节俭
         * 大概 50% 的磁盘空间,但会减慢读写速度操作轻微
         * */
        builder.compress();
        // 禁用主动提交事务,须要手动提交。builder.autoCommitDisabled();
        // 设置 MVStore 为只读模式,不能进行写操作。// builder.readOnly();
        builder.pageSplitSize(500);
        builder.fileName(fileName);
        MVStore store = builder.open();
  1. open():应用 builder 中的配置选项创立 MVStore 实例。
        String fileName = "/Users/chenfei/temp/my_store.db";
        MVStore.Builder builder = new MVStore.Builder();
        MVStore store = builder.open();

生成 MVStore 实例的过程

如果是纯内存模式,它的 file header 就为空。只有是磁盘模式的时候才有 file header。

1、生成 MVMap
// 生成一个名为 cache_data 的 MVMap 对象
store.openMap("cache_data");

MVStore 执行 openMap 办法的时候,如果 map 不存在就新建,存在就间接关上。如果是纯内存模式的,则是新建。

2、MVMap 保留或者删除数据的过程

3、MVStore 提交的过程

在 MVStore 中增加或者是删除数据,为了效率都是在内存中执行的,并没有刷到磁盘上,如果要刷到磁盘上须要调用 commite 办法。

4、MVMap 查问的过程

如果大家对存储内核有趣味的话,能够退出 DawnSql 交换群,通知我,我会持续写下去。DawnSql 交换群,在 https://docs.dawnsql.com/ 的首页能够查看(关上有点慢,稍等一下就能够了)

阐明一点:有些敌人有疑难,为什么 DawnSql 抉择 h2 的存储内核,而不是去从新做一个?这里次要是为了高用性!h2 作为成熟的数据库存储内核,曾经在理论的我的项目中利用了多年,它是经得起考验的。如果新做存储内核,可能会给使用者带来高可用性下面的顾虑,所以咱们再三衡量后抉择更稳固可用性更高的计划。当然随着 DawnSql 的倒退和依据企业方的要求,咱们也能够对其进行批改和重构!

正文完
 0