MySQL时间序列存储引擎的设计与实现

运维 数据库运维
功能层是存储引擎的核心,由于设计目标的不同,存储引擎的功能层所提供的功能也是不同的。比如innobase引擎的功能层,提供了事务ACID/数据存储/元信息管理/MVCC等一系列功能,提供完整的数据库功能;再如CSV存储引擎,仅提供字符类型的行存储。这些不同功能的存储引擎组件,在MySQL的框架下,提供多种多样的服务。

作者简介

姜宇翔,携程技术保障中心高级研究员。具有十多年数据库领域开发经验,曾参与国产自主品牌达梦数据库版本4到版本7开发的全过程,具有丰富的数据库知识和开发经验。

加入携程后,主攻MySQL的源码研究和改造,在MySQL的存储引擎/主从复制/审计等领域皆有贡献,并对各种特性需求,进行针对性的功能开发。

当我们使用MySQL的时候,经常感慨多引擎下数据管理的灵活。不论是innobase这样带有ACID特性的数据引擎后端,还是black hole这样吃掉数据什么也不做的数据引擎后端,都在不同场合发挥着自己的作用。

享受着各种存储引擎带来的便利时,我们也注意到MySQL的存储引擎开发在国内还是一片蓝海。毕竟这种以插件方式加载到MySQL的数据后端,是一个较深涉及到底层的领域,数据库底层开发在国内也只有一少部分开发者走在这条路上。这不能不说是一个遗憾的事情。

携程技术保障中心的MySQL时间序列存储引擎缘起于一次讨论,讨论的议题是关于哪个时间序列数据库更适合携程环境。在这次日常的自由讨论中,有人突发奇想的提出,我们是否可以开发一个MySQL的时间序列存储引擎?没有已有的时间序列数据部署的繁琐,没有那些各具特色的接口调用,不需要熟悉新的系统,还是以SQL的方式来进行数据的访问。

首先,让我们看看OpenTSDB是什么样的情况。下图便是OpenTSDB的部署与运行图示。OpenTSDB的后端存储是HBASE,需要在各个server上部署信息收集的前端,通过dashboard展示信息。对于现有的时间序列数据库,每一个都有自己的部署与运行方案。而这些方案并不具备架构上的通用性。 

 

 

 

我们所期望的架构是除了底层的存储组件不同,对于MySQL的用户来说没有什么不同。已有的大部分运维经验(HA、复制、备份等等)和已有的开发经验(插入、删除和更新的操作)都可以继承自之前的积累,这是任何一个使用MySQL的公司所希望的情况。就如下图所展示的架构,对于上层用户来说,感觉不到太多的变化。用户可以通过标准的SQL编写自己的应用客户端来完成数据的采集和展示,提高灵活性。

经过以上的考量,产生了我们的试验产品,存储引擎CFL(ctrip fast log),该引擎能够以快速的日志方式进行数据的记录。其完成后就如下图所示,满足之前所设想的种种情况。 

 

 

 

技术介绍

从层次结构来看,MySQL的存储引擎分为两个部分。一是实现存储功能相关的组件,该层提供存储引擎的具体功能(增删改查),我们称之为功能层;一是和MySQL插件接口对接的组件,该层将MySQL的功能调用转换为存储引擎的功能调用,我们称之为接口层。如下图所示,数据库的操作(诸如增删改查等操作)将通过引擎管理层达到存储引擎的接口层,再由接口层到达功能层。 

 

 

 

功能层

功能层是存储引擎的核心,由于设计目标的不同,存储引擎的功能层所提供的功能也是不同的。比如innobase引擎的功能层,提供了事务ACID/数据存储/元信息管理/MVCC等一系列功能,提供完整的数据库功能;再如CSV存储引擎,仅提供字符类型的行存储。这些不同功能的存储引擎组件,在MySQL的框架下,提供多种多样的服务。

介绍携程时间序列存储引擎的功能层将从两个主要方面介绍。一是功能层的架构,也就是运行时涉及到的对象和这些对象的作用;一是进行持久化的存储,该部分将说明在文件层面,数据是如何存储的。

架构

CFL的架构设计目标是尽可能的提高数据的插入效率,因此并行处理的想法需要贯穿始终。其机制为,不同会话并行的将数据向表对象中插入;表对象通过缓冲区保存插入的数据,当缓冲区写满之后,缓冲区加入磁盘写入队列,通过专门的写盘线程并发的写入磁盘。

下图为携程时间序列存储引擎的架构: 

 

 

 

存储

在设计存储的时候,根据时序数据库的特点,首先考虑的是插入的效率,然后是快速的故障恢复。针对插入效率,在设计数据结构时,采用严格的顺序写入策略,以此来保证连续插入的效率。这样不论在传统硬盘还是在SSD硬盘上,都可以高效的写入。针对快速故障恢复,通过控制写入顺序(依次写入数据、索引和控制信息),实现快速的恢复。***考虑实现上的简易性,采用索引和数据分别存储的方式,降低在同一文件中进行存储管理的控制。 

 

 

 

接口层

程序片段

如下代码片段为接口层部分。

MySQL提供的基类handler,存储引擎需要提供继承自该类,并实现基类中如ha_open/ha_close等功能函数的类。 

 

 

 

继承handler类的携程时间序列数据库的类。 

 

 

 

接口层架构

该部分将以ha_cfl为例,说明MySQL存储引擎管理层和引擎接口之间的关系。 

 

 

 

操作发送给会话后,会话从引擎管理层获取到ha_cfl的对象,将操作转化为对ha_cfl接口的调用,该步骤完成了SQL到存储引擎接口的对接。

ha_cfl接口接到调用后,将调用转化为对表对象的操作,完成handler接口功能到表对象的实现的对接。

效果

通过对时间序列数据进行针对性的开发,CFL存储引擎的插入性能相对于InnoDB和MyISAM引擎有很大的提高。

引擎\insert线程

1线程(ips)

3线程(ips)

6线程(ips)

CFL

3700

5700

8400

MyISAM

3300

4500

6000

InnoDB

1900

2100

3000

2核ssd虚拟机

  

ips:insert per second 

总结

由于本次开发为探索性质的开发,时间上或者人力上的限制使产品还不够完善,不论是设计还是实现上都存在需要改进的地方。如,创建表时对时间戳类型使用和索引列的指定存在限制,导致无法创建多列索引,仅能够创建时间索引。存储结构的限制导致删除和更新无法快速灵活的进行。

但在资源有限的情况下,完成一个概念完整和实现完整的产品。而且正是通过这次探索性开发,打开了MySQL存储引擎的一扇大门,不论从整体架构到实现细节都有深入研究,积累了很多经验。携程技术保障中心DBA团队希望这些经验在将来能够为国内的MySQL社区提供帮助。 

责任编辑:庞桂玉 来源: 携程技术中心
相关推荐

2010-06-13 13:50:02

MySQL存储引擎

2010-05-21 10:58:19

MySQL存储引擎

2019-01-14 14:25:25

MySQL存储逻辑架构

2022-09-12 07:17:20

redis命令redissynce

2010-05-21 16:10:28

2018-06-14 10:44:59

MySQLMyISAMInnoDB

2018-09-11 10:30:18

MySQL存储引擎数据备份

2015-05-20 10:05:10

Ceph分布式文件系统序列化

2010-05-14 17:44:47

MySQL数据库

2021-08-10 14:29:06

MySQL数据库存储

2023-11-22 08:35:34

存储引擎bitcask

2022-01-04 09:15:28

存储Bitcask引擎

2010-05-21 15:53:30

2011-05-03 10:09:37

MySQL存储引擎

2020-02-18 16:07:17

物联网表存储数据库

2012-03-20 11:16:24

MySQLMyISAM

2018-08-31 10:53:25

MySQL存储引擎

2009-02-02 09:31:25

MySQL存储引擎MyISAM

2010-11-23 11:27:53

MySQL MyISA

2018-10-16 14:26:22

分布式块存储引擎
点赞
收藏

51CTO技术栈公众号