欧易

欧易(OKX)

国内用户最喜爱的合约交易所

火币

火币(HTX )

全球知名的比特币交易所

币安

币安(Binance)

全球用户最多的交易所

深度|带领国产数据库走向世界,POLARDB底层逻辑是什么?

时间:2022-10-10 18:12:27 | 浏览:1299

阿里妹导读:在刚刚结束的乌镇世界互联网大会上,阿里云自主研发的POLARDB云原生数据库当选世界互联网领先科技成果,凭实力站上C位。这个”包管“了北京市每天800万人次的公交出行的下一代分布式数据库到底有多强大?我们请阿里云智能数据库事业部

阿里妹导读:在刚刚结束的乌镇世界互联网大会上,阿里云自主研发的POLARDB云原生数据库当选世界互联网领先科技成果,凭实力站上C位。这个”包管“了北京市每天800万人次的公交出行的下一代分布式数据库到底有多强大?我们请阿里云智能数据库事业部总经理鸣嵩跟大家一起聊聊。

POLARDB 是阿里云自主研发的下一代云原生分布式数据库。POLARDB 100%兼容MySQL、PostgreSQL等开源数据库,高度兼容Oracle语法,使用RDS服务的客户不需要修改应用代码,可以一键迁移到POLARDB,体验更大的容量,更高的性能,更低的成本,和更灵活的弹性。目前POLARDB是阿里云增速最快的数据库产品,广泛应用于互联网金融、政府便民工程、新零售、教育、游戏、社交直播等行业。

作为基于计算与存储分离架构的新一代云原生数据库,POLARDB的计算节点里主要实现了 SQL 解析和优化、以及查询并行执行与无锁高性能事务处理,计算节点之间通过高吞吐的物理复制协议同步内存状态。而存储层基于分布式文件系统PolarFS,通过ParallelRaft共识算法实现多数据副本间的强一致性,在存储层进行存储引擎的多版本页管理来支持全集群跨计算节点的Snapshot Isolation隔离级别。

基于计算与存储分离的先进架构

计算节点与存储节点之间通过理解数据库语义的智能互联协议将filter和projection等算子从计算层下推到存储层执行。为了保证事务和查询语句的低延迟,同时降低计算节点之间状态同步的延迟,计算节点和存储节点之间使用25Gb高速RDMA网络互联,采用Bypasskernel的用户态网络协议层进行通讯。基于计算与存储分离的先进架构,POLARDB可以从1个计算节点(2个CPU核)弹性伸缩到16个计算节点(最高达到1000核)的事务扩展能力,单实例存储容量从10GB按使用量弹性扩展到100TB。

计算节点与存储节点分离的架构设计给POLARDB带来了实时的水平扩展能力。由于单个数据库实例的计算能力有限,传统的做法是通过搭建多个数据库副本来分担压力,从而提供数据库Scale out 的扩展能力。然而,这种做法需要存储多份全量数据,并且频繁同步日志数据造成了过高的网络开销。此外,在传统数据库集群上,增加副本需要同步所有增量数据,这带来了同步延迟上涨的问题。

POLARDB 将数据库文件以及Redo log 等日志文件存放在共享存储设备上,确保主实例和所有副本共享同一份全量数据和增量日志数据。节点间只需要同步内存里的元数据信息,通过MVCC机制的保证,就能支持跨节点读取数据的一致性,非常巧妙地解决了主实例和副本之间的数据同步问题,大大节约了跨节点的网络开销,降低副本间的同步延迟。

提升事务性能 POLARDB内核层面优化揭秘

为了提高事务性能,POLARDB 在内核层面进行了大量优化。把一系列性能瓶颈用无锁(lockless)算法以及各种并行优化算法进行改造,减少甚至消除各种锁之间的相互冲突,大大增加了系统的scalability 能力。同时,我们依托处理双十一这种大规模高并发场景下的经验, 在 POLARDB 上实现了对库存等热点数据进行优化的功能。对于简单重复的查询,POLARDB支持直接从存储引擎获取结果,从而减少了优化器及执行器的开销。

此外,进一步优化已经高效的物理复制。比如,我们在重做日志加了一些元数据,以减少日志解析CPU开销. 这个简单优化减少了了60%日志解析时间。我们也重用 一些数据结构,以减少内存分配器的开销。 POLARDB运动了一系列算法来优化日志应用,比如只有在buffer pool中的数据页面 才需要日志应用。同时我们也优化了了page cleaner and double write buffer,大大减少这些工作的成本. 这一系列优化使得在性能上 POLARDB 远超 MySQL ,在sysbencholtp_insert等大量并发写入的基准评测中达到最高6倍于MySQL 的性能。

支持并行查询(Parallel Query)

为了提高子查询和join等复杂查询(例如TPC-H基准评测)的能力,POLARDB的查询处理器支持并行查询(parallel query),可以将一个查询同时在多个或所有可用CPU核上进行执行。并行查询能够将一个查询任务(当前只支持SELECT语句)划分为多个子任务,多个子任务可以并行进行处理,整体采用Leader-Worker的并发模型。Leader线程负责生成并行查询计划,协调并行执行过程的其他组件,并行执行计划会包括并行扫描、多表并行连接、并行排序、并行分组、并行聚集等子动作。

Message queue是leader线程和worker线程的通讯层,worker线程通过message queue向leader线程发送数据,而leader线程也会通过message queue向worker线程发送控制信息。Worker线程负责真正的执行任务。Leader线程解析查询语句生成并行计划,然后同时启动多个worker线程进行并行任务处理,为了高效的执行查询,Worker上的执行不需要进行再次优化,而是直接从Leader上来拷贝生成好的计划分片。这需要实现执行计划树上所有节点的拷贝。worker线程在进行扫描,聚集,排序等操作后将中间结果集返回给leader,leader负责收集来自worker的所有数据集,然后进行适当的二次处理(比如merge sort,二次group by 等操作),最后将最终结果返回给客户端。

Parallel Scan层会结合存储引擎的数据结构特征来实现工作负载的均衡。如何将扫描数据划分成多个分区,使得所有的工作线程尽可能的均匀的工作是数据分区划分的目标。在以B+树作为存储结构的存储引擎里,划分分区的时候,是先从根上来划分,如果根上不能划分出足够多的分区(>= 并行度),将会继续从下一层进行划分。而如果我们需要6个分区的话,根节点最多分出4个分区,所以就需要继续搜索下一层来进行分区。以此类推。在实际实现并行查询的过程中,为了能让多个工作线程更加均匀的分配扫描段,会在B+树里尽可能的多划分分区,这样如果某个工作线程由于过滤性比较高会优先完成当前分区,那么它会自动attach下一个分区继续执行,通过自动attach的方式来实现所有线程的负载均衡。

新一代基于代价的优化器

云上客户的业务是多样化的,如果执行计划选错会导致慢查询。为了系统性地解决这些问题,POLARDB推出了新一代的基于代价的优化器。POLARDB里实现新的直方图Compressed Histogram对高频率数据进行自动探测并构建精确描述,在选择率计算时考虑数据频率和取值空间,解决实际应用中普遍存在的数据倾斜场景。

POLARDB大量基于改良的直方图进行代价估算,比如估算表和表join的结果大小,是join代价和join order优化的决定性因素,MySQL只能根据经验公式粗略的估算,无论是有索引时的rows_per_key,还是无索引时的默认参数值,估算的误差都较大,这些误差会在多表连接的过程中不断放大,导致生成效率低下的执行计划。

在POLARDB中使用直方图对重合部分进行合并计算,并根据不同的直方图类型适配不同的estimation算法,大大提高了估算精度,帮助优化器做出更优的join order选择。在随机生成的正态分布数据测试中,多表联合查询优化后可提速2.4-12倍,TPC-H测试中多个查询的join order发生变化,性能提升77%-332%。POLARDB也使用直方图优化了record_in_range的逻辑,MySQL对于有索引的过滤条件采用index dive来估算区间的记录数,这个操作在OLTP短查询中CPU占比较高。在使用基于直方图估算替换index dive后,在淘宝电商核心业务中,绝大多数的查询查询响应时间减少一半。

自研分布式文件系统PolarFS:高可靠、高可用、与数据库协同设计

POLARDB的存储层采用的是阿里云自主研制的分布式文件系统PolarFS。PolarFS是国内首款面向DB应用设计的采用了全用户空间I/O栈的低延迟高性能分布式存储系统(参见VLDB 2018 上的文章 PolarFS: An Ultra-low Latency and Failure Resilient Distributed FileSystem for Shared Storage Cloud Database),其具备与本地SSD硬盘架构相当的低延迟高性能I/O能力,同时也以分布式集群的方式提供了优异的存储容量与存储性能的扩展能力。

而PolarFS作为一款与POLARDB深度协同的存储基础设施,其最核心的竞争力不仅体现在性能和扩展性方面,更深层次的则是在面临有许多挑战性的POLARDB客户业务需求和规模化的公有云研发运维过程中而长期积累形成的一系列高可靠、高可用、与数据库协同设计的存储技术。

为了支持POLARDB在多个计算节点之间分发查询且保持全局的Snapshot Isolation语义,PolarFS支持存储POLARDB存储引擎B+树动态生成的多版本(Multi-version page)。为了减少读写冲突,现代数据库一般都通过以MVCC并发控制为框架来提供RC、SI、SSI等不同的事务隔离级别,在MVCC机制下,B+树的每个页面会动态维护一系列的版本,并发执行中的多个事务允许各自访问一个页面的不同版本。

在POLARDB集群里,由于跨节点复制同步延迟的存在,每个计算节点B+树的页面可能是不同版本的,这时多版本存储可以为各节点提供其所对应版本。在POLARDB中,计算节点向PolarFS写入一个页面的同时要提供该数据页的版本信息(LSN),PolarFS不仅存储数据页的同时还要存储数据版本元信息;计算节点读取数据页时,也会提供版本信息从存储获取相应的数据页(历史)版本。POLARDB数据库层定期会将集群所有计算节点版本号的低水位线发送给PolarFS,PolarFS会基于此版本号清理不再使用的历史版本。

保证数据可靠性是POLARDB所有设计的底线。在实际的分布式系统中,硬盘、网络与内存等硬件、固件或软件的bug等问题可能会造成数据错误,从而给数据可靠性保障带来各种挑战。存储端的可靠性问题来自静默错误(lost write、misdirected write,block c