数据库服务能力提升是一项系统性的工程,在不同的应用场景下,用户对于数据库各项能力的关注点也不同,如:读写延迟、吞吐量、扩展性、可靠性、可用性等等。国内不少数据库系统通过系统架构优化、硬件设备升级等方式,来解决性能的问题,但随着集群规模的逐渐扩大,对系统健壮性的要求也越来越高。
本文主要介绍AntDB-M(AntDB内存引擎)如何通过CheckPoint等技术研发设计,简化业务系统架构,提升数据服务质量,从而提升整体数据库系统的可靠性与可用性。
CheckPoint的设计目标是在不影响业务的前提下,对数据库的数据做一份快照,该快照可用于服务的快速恢复。AntDB数据库对于CheckPoint的设计原则是高效、简洁。
AntDB-M的CheckPoint功能包括随时、定时触发。一次触发会对所有表都进行CheckPoint。CheckPoint不允许并发进行,若前者还未完成,则新发起的请求会失败。如果表比较多,可以开启并发处理,并发量最大为表个数。成功后,AntDB-M会在指定目录输出两类文件:1)数据文件,每个表一个;2)一个表清单文件,包含发起CheckPoint的事务编号,以及所有表清单。
我们也可以使用CheckPoint文件进行数据库的快速加载。表清单文件可以编辑,用来选择需要加载的表。
下文介绍CheckPoint是如何实现其设计目标以及设计要求的。
1.不影响业务 CheckPoint在执行过程中,不能阻塞数据库服务的正常访问。这意味着在CheckPoint的过程中,数据是一直在发生变化的。为了不阻塞对数据的修改,保障导出数据的一致性,我们在此引入CheckPoint状态和表缓存来解决这个问题。
(1)CheckPoint状态 AntDB-M与CheckPoint的相关状态分为三个:1)数据导出;2)导出文件处理;3)导出完成。状态“1-数据导出”代表正在将内存中的数据导出到文件。这个状态对于保障导出数据的一致性非常重要。后文将介绍如何参考该状态对数据一致性进行保障。
(2)AntDB-M表缓存
AntDB-M在数据管理上分为两部分:1)表缓存;2)表数据(含表元数据)。通常情况下,所有对数据的修改只会修改“2-表数据”。表缓存只在状态为“1-数据导出”时进行AntDB-M服务的CheckPoint。 (3)导出过程及数据一致性保障
AntDB-M按如下步骤,来实现CheckPoint的导出,并确保导出数据的一致性。
⚫ 状态设置
在进行CheckPoint时,我们可以先将AntDB-M服务的CheckPoint状态设置为“1-数据导出”。一旦进入该状态,AntDB-M将开始对表缓存进行特殊处理。
⚫ 未提交事务数据备份
进入“1-数据导出”状态后,我们需在开始导出数据前,将当前所有未提交事务相关记录的原始数据保存一份到表缓存中。表缓存中的这份数据能够确保未提交事务的数据不会被导出,这是保障数据一致性的措施之一。
⚫ 表缓存修改
一旦进入CheckPoint的“1-数据导出”状态,所有数据的增、删、改将同时修改表缓存和表数据。操作类型不同,表缓存的动作也不同,但表数据的操作逻辑保持不变。
-insert :在表缓存中记录下新插入数据的记录ID(后文会介绍记录ID)。
-delete :在表缓存中记录下被删除数据的记录ID,以及记录数据。
-update :在表缓存中记录下被更新数据的记录ID,以及记录数据。对于多次更新,只有第一次更新进入表缓存。
(4)导出表数据到文件
在表数据的处理上,我们将除了CheckPoint过程中新创建的数据块,其余都全量导出到文件中。由于服务是不阻塞等待的,所以在这个过程中表数据会被持续更新。在此,我们并不关心数据块中的数据是否一致,数据的一致性将在后续步骤5处理。
(5)利用缓存更新文件
由前文2、3两点可知,在CheckPoint状态为“1-数据导出”期间,所有变更在表缓存中都有记录。在表数据导出到文件后,使用表缓存的记录更新文件,这样就保证了数据的一致性。即CheckPoint文件就是进入CheckPoint“1-数据导出”状态的时间点的一个数据快照。这里的更新可能存在随机写,但CheckPoint过程较快,随机写的数据量不大,其造成的影响基本可以忽略。
文件更新规则:
-insert:删除
-update:用原记录复原
-delete:用被删除记录复原
2.高效、简洁
CheckPoint的高效体现在两个方面:1)导出高效;2)导入高效。下文介绍实现简洁、高效的相关设计。
(1)全量导出
AntDB-M的CheckPoint为全量导出,与MySQL Innodb的CheckPoint有着很大的不同。下面将从4个方面来介绍为什么采取全量导出。
⚫ 内存开销压力
作为一款内存数据库,AntDB-M的所有数据都存放于内存之中,不需要考虑数据消耗过多内存的问题(仅数据本身而言)。因此我们不需要因为数据占用内存而实时地考虑将数据导出到文件。
⚫ 高可用保障
作为一款高可用分布式数据库,AntDB-M采用了多副本机制,因此我们可以通过多服务达到高可用的目的。数据的导出主要是为了降低服务重启时较长的加载时间以及主从数据同步时间,所以CheckPoint文件并不是高可用的主要手段。即CheckPoint文件导出不要求较高的实时性,较低的导出频率对高可用的影响不大。
⚫ 读写性能
影响数据导出、导入效率的最大因素为磁盘的读写性能,磁盘采取顺序读写的效率最高。因此我们在进行数据导出、导入时,不对数据在内存、文件间做格式转换,直接进行读写的效率最高。如果做增量同步,就可能会出现频繁的随机读写、复杂的转换及文件存储空间占用等问题。这些都对效率的提升、系统的复杂度有着极大的负面影响。
⚫ 导出时间
由于AntDB-M的内存结构设计非常紧凑、内存地址无关,因此数据可以不做转换地进行导出、导入。数据导出、导入的效率非常高,一次导出时间可控制在接受时间范围内。
综合以上几点,AntDB-M采取全量导出具有更大的效率、成本优势。
(2)地址无关
AntDB-M的内存结构非常紧凑,这避免了数据空间的浪费。导出的数据量,除了必要的数据存储空间,不需要额外的管理空间。另外一个实现高效的导出、导入的设计就是地址无关,这避免了在导出、导入时大量的地址映射转换。
⚫ 记录ID
记录ID是内存结构中一个非常重要的设计。所有数据记录都有一个唯一的记录ID。通过对记录ID进行简单、高效的取模、取余运算即可获取到记录所在的内存地址。这使得表数据的存储可以与地址无关,确保导出、导入时不需要做地址转换。
⚫ 多级管理
AntDB-M中每个表都有各自独立的表空间,每个表空间采取三级管理。其中,第一、二级均为只存在于内存中的地址空间,第三级为地址无关的数据块。在导出时,我们只需导出数据块即可。在导入时,按照内存块的顺序,我们需在内存中申请好三级内存空间,并建立三级空间之间的关系。在这部分,数据量很少,速度很快。
由于数据块内的内容地址无关,我们在导出时将数块整体写入文件,在导入时将文件中的数据直接原样读入到对应内存数据块中即可。这样就极大提升了导出、导入效率。
⚫ 空闲记录
数据块的空闲地址的管理数据也是在数据块本身上记录,不需要额外的管理单元。所有空闲记录构成一个双向链表,只需额外记录最后一个空闲位置即可。另外,我们需要对每行记录保留额外的1个字节标识当前记录状态。
通过以上设计,数据块的管理在紧凑、简洁的同时,效率也非常高。
(3)溢出列
AntDB-M以溢出列的方式对可变长度列进行单独管理,有自己的内存空间及结构。数据块中仅保存固定长度列,以及溢出列的长度、记录ID。
溢出列的结构设计和数据块类似,同样保持多级、地址无关的设计。同时,为了节省内存和实现高效,溢出列每行长度固定,不同列长度可能不同。每行额外保留一个记录ID,当长度超过1行长度时,记录数据的下一行保存位置。
(4)索引
AntDB-M支持两种索引:1)Hash;2)Btree。CheckPoint导出时只会导出索引的元数据。数据会在内存中重新构造。
(5)CheckPoint文件结构
CheckPoint最终会将每个表单独生成一个文件,大致分为5个部分:1)表元数据;2)溢出列;2)数据块;4)列元数据;5)索引。
1.DDL限制
CheckPoint期间禁止进行DDL变更。DDL会造成表元数据、以及数据的变更,极大地影响到内存开销以及系统的复杂度。而DDL操作频率和CheckPoint频率一般不高且时间可控,因此可以对DDL操作进行限制。限制DDL操作不会对业务系统产生较大的影响。
2.存储要求
数据的导出、导入对磁盘有较高的读、写性能要求。因此我们需要较高性能的磁盘,最好是SSD盘。
3.导出错峰
假定磁盘写入速度400M/S,那么100G的数据导出大概需要256秒。因此我们在一台主机上部署多个服务时,可以错峰导出,避免单个服务导出时间过长。数据导出过程会有一份数据放入表缓存,避免造成内存压力。
关于AntDB数据库
AntDB数据库始于2008年,在运营商的核心系统上,为全国24个省份的10亿多用户提供在线服务,具备高性能、弹性扩展、高可靠等产品特性,峰值每秒可处理百万笔通信核心交易,保障系统持续稳定运行近十年,并在通信、金融、交通、能源、物联网等行业成功商用落地。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。