数据无压缩是 MySQL 的痛点之一,当企业数据量不断增加,这便成为一大问题。MySQL 是 B+ 树的存储结构,这个结构已经有很多年的历史,但是有个不可绕开的点,就是 B+ 树的每个页内必然会有一定的空隙,这就导致企业需要考虑如何降低数据库存储成本。
而 OceanBase 的存储引擎是基于 LSM-Tree 自研的一套高级压缩的存储引擎,它和 B+ 树不同,其写入会先放在内存,当内存写到一定程度之后,会直接转储到磁盘,然后在每天的业务低峰时间(默认是凌晨两点),将当天的所有转储整理一遍,并且压缩好放在基线 SSTable (ROS) 数据里。通过这个被称作合并的过程,LSM 树存储结构的基线数据都是无空隙的,与 B+ 树的每个页中都会有一些空隙相比,把原有没经过压缩的数据压缩到 MySQL 的 1/4 到 1/5,甚至更高的压缩比,所以 OceanBase 天然压缩比就要比 MySQL 好,从而降低数据库存储成本。
此外,OceanBase 在 LSM-Tree 本身能力的基础之上,又进行了两次压缩,也极大降低数据库存储成本。
第一次压缩采用行列混存的存储格式,让数据在底层的微块(对应 MySQL 页的一个层次),由行存转成了列存,这样有非常多的好处,除了降低数据库存储成本,比如可以对列存的数据进行数据编码。
看图中的例子,我们在开发过程中经常会碰到重复率很高的字段,比如 RATE_ID 这个字段,就有 4 个值重复出现。这时我们就可以对应一个字典,比如图中的 ID 列的 1901321 对应 0。将这个字典存储好的情况下,这时候每个列只要存 0/1/2 之类的值,以此极大程度地压缩存储,降低数据库存储成本。在实际的程序中,有非常多类似这样的案例,OceanBase 会自适应为它们设计一套适合的 encoding 编码方法。
在经过第一次压缩之后,100G 的数据就有可能压缩成 30G。在这个基础之上,OceanBase 还会对 30G 的数据再进行一次通用压缩,给它再“瘦”一次身,再次降低数据库存储成本,这时候就是 LZ4 或者其他通用压缩算法。
经过第二次压缩后,这个数据可能就变成 15G 了。也就是说,在 MySQL 中100G 的数据可能到 OceanBase 上就只有 15G。在实践中,我们很多客户已经达到小于 15% 的比例,极大降低数据库存储成本。
有人说,OceanBase 这么高的压缩比,会不会对实时的读写产生影响,实际上是不会的。因为 LSM-Tree 的数据压缩发生在每天合并的时候,合并往往在凌晨两点之类的时间,用户可以自由选择业务低峰期。对于白天高频使用的时候,不会受到压缩带来的性能损耗,而能享受到高压缩比降低数据库存储成本的优势。