云数据库实现计算存储分离,支持计算与存储的独立扩展,其用户还可以享受按量付费等特性。这使得基于云数据库的系统更加高效、灵活。因此,构建并使用云原生数据库的势头愈演愈烈。另一方面,云化存储服务已经是云的标准能力,存储侧提供兼容通用的文件接口,并且不对外暴露持久化、容错处理等复杂细节,其易用性和规模化带来的高性价比使得云存储成为了云上系统的第一选择。在通用云存储服务上构建云数据库,无疑是一种既能够享受规模化云存储红利,又能够通过可靠云存储服务实现降低维护成本、加速数据库开发周期的方案。 然而,考虑到云存储和本地存储之间的特性差异,在将本地数据库迁移到云上构建云数据库时,如何有效使用云存储面临了许多挑战。对此,我们在论文里分析了基于B-tree和LSM-tree的存储引擎在云存储上部署时面临的挑战,并提出了一个优化框架CloudJump,以希望能够帮助数据库开发人员在基于云存储构建数据库时使系统更为高效。我们以云原生数据库PolarDB为案例,展示了一系列针对性优化,并将部分工作扩展应用到基于云存储的RocksDB上,以此来演示CloudJump的可用性。
更详细的内容请参阅论文《PolarDB-CloudJump: Optimizing Cloud Database For Cloud Storage》。
背景
我们讨论的云存储主要基于弹性分布式块存储,云中其他类型的存储服务,例如基于对象的存储,不在本文的讨论范围内。共享云存储(如分布式块存储服务加分布式文件系统)可以作为多个计算节点的共享存储层,提供QoS(服务质量)保证、大容量、弹性和按量付费定价模型。对于大多数云厂商和云用户来说,拥有云存储服务比构建和维护裸机SSD集群更有吸引力。因此,与其为云本机数据库构建和优化专用存储服务,不如利用现有云存储服务构建云本机数据库,这是一种非常可行的选择。此外,随着云存储服务几乎实现了标准化,相应的开发、迁移变得更加快速。
图1展示了本地数据库(不含备份)与shared-storage云原生数据库的系统结构,AWS Aurora首先引导了这种从本地数据库向shared-storage云原生数据库的迁移。它将数据库分为存储层和计算层,并可以独立扩展每一层。为了消除了传输数据页中产生的沉重的网络开销,它进一步定制了存储层,在数据页上应用重做日志,从而不再需要在两层之间传输数据页。无疑这种设计在云中提供了一种非标准存储服务,只能由Aurora的计算层使用。 另一种方案是依赖标准化接口的云存储服务迁移或构建获得云数据库,这也是本文的研究目标。前面已经提到过,这样做的优势主要在于的可以实现系统的快速开发、平滑迁移、收纳标准化规模化存储服务的原有优势等。此外,特别是在我们项目(PolarDB)的硬件环境、已有背景下,兼顾服务可靠性和开发迭代需求,针对进行云存储服务特性进行性能优化是最迫切的第一步。
挑战与分析
云存储和本地SSD存储在带宽、延迟、弹性、容量等方面存在巨大差异,例如图2展示了在稳态条件下本地SSD与云存储I/O延时、带宽与工作线程关系,它们对数据库等设计有着巨大影响。此外,共享存储的架构特性也会对云存储带来影响,如多个节点之间的数据一致性增加了维护cache一致性开销。
通过系统实验、总结分析等,我们发现CloudJump面临以下技术挑战:
- 远程分布式存储集群的访问导致云存储服务的I/O延迟高;
- 通常聚合I/O带宽未被充分利用;
- 在具有本地存储的单机上运行良好但需要适应云存储而导致特性改变的传统设计,例如文件cache缓存;
- 长链路导致各种数据库I/O操作之间的隔离度较低(例如,日志刷写与大量数据I/O的竞争);