容器技术改变了应用交付、运行的方式,几乎各种Linux环境下的应用程序都可以使用容器来运行。但是否能在容器环境里运行数据库应用,以及数据库应用是否适合在容器里运行,一直都是大家很关注的问题,今天我们就来深入分析一下容器环境运行MySQL数据库的事。
在容器中运行数据库,能帮助用户提高服务器利用效率,降低基础架构成本,更快速地部署、更便捷地管理数据库服务。
根据云监控供应商Datadog的调查报告, Postgres、MongoDB和MySQL等数据库技术都位于容器上运行的十大技术之中——并且使用量还在增长。
MySQL容器化需要容器存储的有力支持
数据库实际上由两大组件组成:读取、写入和查询数据的应用,以及数据存储,我们通常称之为数据卷。MySQL等数据库应用所需的计算资源完全可以通过容器技术提供,是否能流畅运行MySQL数据库的关键在于容器存储方案。国内大多数用户在选择容器存储时,通常有以下几种方案:
- 新版本的Kubernetes可以支持块设备挂载至容器内部(该块设备可以来自服务器的物理磁盘,也可以来自传统的SAN阵列)
- 通过Ceph提供的CSI插件使用CephRBD或者CephFS
- 使用YRCloudFile提供的容器存储
大多数客户对容器存储的以下几点尤为关注:
- 数据可靠性
- 是否能通过容器编排平台快速完成存储资源的生命周期管理(创建、扩容、删除和回收等)
- MySQL在容器化环境中的容灾备份
- MySQL容器故障后,在新节点重新启动,其数据是否能快速访问
- MySQL使用容器存储的实际性能如何,是否能满足业务需求
关于用户关注的上述特性,我们在之前的文章中都有过介绍,在以后的文章里也会进一步描述。本文针对用户最关注的,MySQL基于不同存储的实际性能进行了实际测试和对比。
MySQL存储引擎和数据写入策略
在介绍实际测试性能之前,有必要介绍一下MySQL数据库的存储引擎,以及相关的写入策略,这对于数据库的实际使用性能有非常关键的影响。
MySQL存储引擎
MySQL数据库提供插件式的存储引擎,这个存储引擎提供了一系列标准的管理和数据读写服务的支持,不同的存储引擎有不同的特点,存储引擎对于业务开发人员而言是透明的。其中,InnoDB是著名的第三方存储引擎,后被Oracle收购,是MySQL数据库OLTP(Online Transaction Processing,在线事务处理)应用中使用最广的存储引擎,也是5.5.8版本后,MySQL默认的存储引擎,以下的测试就基于InnoDB存储引擎进行。
InnoDB刷数据策略
InnoDB中有一项设置——innodb_flush_method,这项设置负责控制InnoDB刷数据时所使用的系统调用。所谓刷数据,即将缓存在内存中或临时磁盘存储区域中的数据写入特定的日志及数据文件(log,如ib_logfile和数据库data file),完成持久化。
刷数据动作可能是因为内存区域已满并且系统需要释放一些空间而触发,或是因为事务完成更改的commit操作而触发,或者由需要终结所有未完成工作的关闭操作而触发。
innodb_flush_method的值对应着不同的系统调用,从而会触发不同的系统行为,经常使用的值包括:
- fsync:InnoDB使用fsync()系统调用将MySQL的数据和日志文件都刷到持久化存储中,fsync是InnoDB的模式设置。
- O_DIRECT:InnoDB使用O_DIRECT标识打开MySQL的数据文件,意味着MySQL数据将绕过pagecache,直接写入磁盘,并使用fsync()系统调用将MySQL数据和日志文件的元数据信息更新刷入磁盘。
- O_DIRECT_NO_FSYNC:只使用O_DIRECT方式,绕过pagecache,将数据直接写入磁盘,并在写操作时跳过fsync()更新日志的元数据信息。在8.0.14版本之后, MySQL会在创建文件、增加文件长度以及关闭文件时自动调用fsync()来更新MySQL文件在文件系统中的元数据信息。
YRCloudFile可以支持这种刷数据方式,即可以很好地确保每个数据都直接落盘,同时减少频繁调用fsync带来的开销,极大提升性能。
sysbench性能对比测试
在下面进行的性能对比的测试中,我们在MySQL容器中使用了以下几种存储方案进行对比:
- 将本地物理SSD盘挂载到MySQL容器中
- 将基于RoCE(RDMA over Converged Ethernet)的YRCloudFile集群中的PV挂载到MySQL容器中
- 将基于TCP的YRCloudFile集群中的PV挂载到MySQL容器中
- 将CephRDB的PV挂载到MySQL容器中
- 将CephFS的PV挂载到容器中
除物理SSD盘外,YRCloudFile和Ceph集群都采用以下四台相同的物理服务器进行搭建:
- CPU:Intel 4112 * 2
- 内存:64GB
- 系统盘:240GB * 2
- 元数据盘:960GB SSD * 2(CephRBD时不需要元数据盘)
- 缓存盘:960GB SSD * 2
- 数据盘:4TB SATA * 2
- 管理网络:1Gb * 2
- 存储网络:10Gb * 2
MySQL版本为8.0.14,使用InnoDB作为存储引擎,innodb_flush_method设为O_DIRECT_NO_FSYNC ;Ceph版本为mimic,Ceph基于filestore;sysbench版本为1.0.17,基于50个表,每个表中包含100万条数据的数据库进行oltp_write_only和oltp_read_write测试。
测试结果如下:
从测试结果看:
- 直接使用物理SSD时,由于是进行本地SSD读写,延时很低;且MySQL应用为了确保其操作的顺序性,主要是采用有限线程低并发进行顺序追加写,延时性能决定了单个MySQL的整体性能,因此无论YRCloudFile还是Ceph存储集群对单个MySQL实例而言,会受到延时影响,性能不如本地SSD盘。
- 另一方面,我们看到基于RoCE的YRCloudFile的性能已经接近本地SSD盘,基于TCP的YRCloudFile集群所提供的性能略低于RoCE的性能。
- 基于RoCE的YRCloudFile性能高于基于TCP的YRCloudFile性能,是CephRBD或CephFS性能的将近一倍。这是因为:1)YRCloudFile集群的元数据保存在本地SSD,相对于CephFS的元数据保存在RADOS中而言,其元数据读延时明显低于CephFS;2)基于RDMA的YRCloudFile绕过了系统内核,直接访问集群中的磁盘数据,进一步降低了延迟。
也许有读者会问,从单个MySQL实例的测试性能看,YRCloudFile分布式存储系统的优势如何体现呢?通过使用YRCloudFile,可以充分发挥集群中所有磁盘的性能,使整个集群支持更多的MySQL实例,而单块SSD盘的性能可以支撑的MySQL实例就有限得多了。此外,YRCloudFile也正在通过硬件offload,NVMe优化等方式,进一步缩短集群IO的延时,使集群IO的延时尽可能接近本地SSD的延时,从而使单MySQL实例的性能更加接近使用本地SSD运行MySQL的性能。
在这篇文章中,我们介绍了如何通过设置MySQL InnoDB的innodb_flush_method参数,使用YRCloudFile获得最佳的MySQL运行性能,并对比了在同等环境下,使用SSD、CephRBD、CephFS所获得的性能。在后续文章里,我们还会分享更多基于YRCloudFile运行各种中间件应用的最佳实践,以及相关的技术细节。