1.基于哈希的存储引擎BitCask
常见模型是BitCask
并发下的数据库文件读写:
本来想使用FileLock,但是后来发现 FileLock是进程间的,并不能用于同一个JVM多个线程之间的同步:
File locks are held on behalf of the entire Java virtual machine.
* They are not suitable for controlling access to a file by multiple
* threads within the same virtual machine.
2.LSM (Log Structured Merge Trees)
日志结构合并树,LSM 作为核心的文件组织方法现在已经被应用到大量的产品中。HBase、Cassandra、LevelDB、SQLite,甚至 MongoDB 3.0 版本在收购 Wired Tiger 引擎之后都是由 LSM 算法驱动的。
LSM使磁盘尽可能的产生顺序访问,而不是分散的随机访问
LSM基本结构:
- 内存中的MemTable:一般用跳跃表来组织;当MemTable达到一定大小后,将其冻结起来变成Immutable MemTable,然后开辟一个新的MemTable用来记录新的记录。而Immutable MemTable则等待转存到磁盘
- 内存中的Immutable MemTable:只能读不能写的内存表;
- 磁盘中的SSTable:存储的就是一系列的键值对
- Bloom Filter:提高Key在不在SSTable的判定速度
布隆过滤器和动态缓存有点像,不过都是数据结构很典型的例子,使用空间大幅度的降低了时间的使用。
bloom 借助的是一个大大大的位表以及多个hash函数,例如图中,将{x,y,z}的用3个hash函数映射到位表中。那么位表中有n个位置有标1,(3<=n<=9)。
- 如果这个时候来了个w,w经过3个hash函数,对应到位表上的位置有一个映射的值为0,那么说明w肯定不在{x,y,x}中。
- 如果w的3个hash函数映射后,都为1,并不能够说明w在{x,y,z}中。有可能是类似上图4,5,6位置格,而那些格是有不同的值映射出来的。
基本的LSM算法
从概念上讲,基本 LSM 算法很简单。批量写入被顺序地保存到一组较小的索引文件而不是一个很大的索引结构(将会使文件系统内部分散或者增加写入放大)。所以每一个文件都包含一小段时间的变化。在写入后每一个文件都被排序,所以在之后查找的时候会快很多。文件是不可变的,它们也从不更新。新的更新将会被写入新的文件。读取检查所有的文件,并定期将文件合并从而减少文件的数量。