前言
保存数据的方法多种多样,最直接的方法是在内存中建一个数据结构,保存数据。比如用一个List,每当收到一条数据就向List中追加一条记录。
这个方案非常简单,性能良好,但问题是数据存放在内存中,一旦服务器停机或重启,数据就会永久丢失。
为了解决数据丢失问题,可以把数据持久化存放在非易失存储介质(比如硬盘)中。可以使用磁盘的文件,每当收到一条数据就向文件中 Append 一行。这是一个持久化存储数据的解决方案,但如果磁盘损坏呢? RAID是一个单机冗余存储方案,那如果主机损坏呢?
网络存储是一个解决方案,通过软件层进行存储副本的复制。似乎我们可以解决数据安全问题,但是做存储副本复制过程中是否能保证副本之间的一致性?
TcaplusDB的开发人员考虑到了这些存储问题,在本期的知识库中,TcaplusDB君将介绍TcaplusDB的存储分配策略,关于数据的读写逻辑我们将会在下期的知识库中进行介绍。
存储空间分配的基本策略
- TcaplusDB优先使用数据文件的前1G的空间。原因是存储引擎启动时,会将数据文件的前1G空间通过mmap映射到内存中,访问效率较高,而剩余的空间中数据是直接对接文件IO的方式访问的;
- 数据的Key比数据的Value更有权利优先使用前1G的空间。原因是通常情况下Key的访问频率要比Value高。当前1G空间中原先分配给Key使用的空闲块不足时,会将前1G空间中原先分配给Value使用的空闲块挪给Key使用;
- 所有数据的Key尽量存放在一起。这是因为我们有很多Key遍历的场景(比如数据迁移),Key放在一起,可以一定程度上加快遍历的过程,减少磁盘IO;
- 空闲块的查找策略为Best-Fit,即找满足需求的最小空闲块,目的是为了尽可能的让数据存在同一块中,避免数据的Split。
存储空间的详细分配过程参见下图(下图拆分成了两个部分,两幅图通过虚线框的”尝试从文件空间分配“节点联系在一起):
存储空间详细分配过程图
从文件空间中分配图
策略设计的考虑
存储引擎根据空间分配策略,会先分配数据Value的存储空间,写入数据Value部分后,再分配数据Key的存储空间,并写入数据Key部分。之所以是这样的顺序,有两方面的原因:
- 数据Key的头部需要记录它所指向的Value的存储地址,需要先分配Value的存储空间,得到Value的存储地址头,再写Key;
- 数据访问入口是Key,按照这个顺序,Key写成功,我们也基本可以认为Value也是写成功了,可以减少数据不一致的情况。
最后
我们已经了解了 TcaplusDB 的存储分配策略,后续我们将揭开更多TcaplusDB设计的特殊奥秘。