背景
并行查询(Parallel Query)是自PolarDB MySQL诞生伊始就致力于研发的企业级查询加速功能,这与PolarDB的产品定位密切相关,基于云原生的计算存储分离使底层数据量远突破单机容量的限制,而针对更海量数据的复杂分析、报表类业务也成为用户自然而然的需求,同时由于PolarDB是服务于在线业务(OLTP)的关系数据库系统,用户会希望分析业务能具有"在线"的能力,即针对最新鲜的数据进行实时甚至交互的查询,这也是现在概念上很火热的HTAP数据库的主要能力。
对线上海量实例的日常监控和运维中,我们发现云上计算资源的利用率普遍是偏低的(e.g CPU...),而利用闲置的CPU资源来做计算加速就是并行查询实现的事情,通过更充分的资源利用降低查询响应时间、提升用户体验的同时也提升了性价比。
关于并行查询的功能、特性、技术原理等,"并行查询的前世今生"这篇已做过详细的解读,今天这篇文章则主要聚焦于并行查询全新发布的下一代形态:弹性多机并行(Elastic Parallel Query)。
概念
顾名思义,多机并行意味着利用更多计算节点的资源完成查询,PolarDB的计算层是一写多读的部署方式,已有的并行查询是指在单个RW/RO节点内的多线程并行,这对于较小的数据量(几百GB)是比较ok的,但很多用户随着自身业务发展,数据开始到达了TB级别,有的甚至单表就有20~30TB,这已经超过了单个节点的处理能力,而多机并行正是为了应对这种场景,通过突破单机的CPU/IO瓶颈将整个计算层的资源打通,实现资源的全局均衡与全局利用。
看起来这和传统的MPP架构有些相似,通过将查询的子任务分发到多个节点来以高并发完成计算。但两者有着本质的不同:
- 传统的MPP架构是计算与存储耦合的,查询的子任务要下发到数据所在的节点完成本地化计算,再通过后续分发,到上层节点中完成聚合计算
- PolarDB基于云上基础设施实现了计存分离,任何节点都可以看到全量数据,这使极致的弹性和灵活的调度成为可能,例如实例的规格可以根据负载的需求即时或定时升/降,而无需做任何数据迁移,同时无状态的计算任务理论上可以分发到任意节点执行
弹性多机并行除了具有前者利用多节点并行的加速能力外,更重要的是,它会实时监控集群内的拓扑变化和资源使用,从而实现随计算资源的变化动态适配并行策略,无论是单个节点的规格提升(scale up)、或是引入了新的RO节点(scale out),都可以自适应的做并行度调整和子任务分发,在避免单节点计算热点的同时、尽可能保证按照用户指定的并行度完成查询,从而达到更高的资源利用率。
优势
延续了并行查询的特性,弹性并行查询具有如下的一些优势:
- 100%兼容性
并行查询基于MySQL开发,具有100%的MySQL兼容性,包括语法、类型、行为的全方位兼容,除了查询时间更短外,用户是感觉不到查询是否开启了并行的。
- 极致性价比
性价比来源于四个方面:
- 数据:复用了底层同一套业务数据做in-place分析加速,而无需单独维护一套额外副本,没有附加的存储成本
- 计算:基于原生的执行引擎实现,购买实例后默认的读写集群即可开启多机并行功能,除非需要加入更多节点完成计算,否则并无额外计算成本。
- 调度:通过自适应调度来提高资源利用率,举个简单的例子:一个查询在单节点并行时需要4个线程完成,但当前节点只剩3个线程资源,而其他节点仍有空闲,则可以通过跨机调度分发一个计算任务,利用闲置资源保证加速效果。
- 弹性:随实例规格的弹性变化实时调整并行策略,在"降本"的同时仍然保证"增效"能力
- 极低运维成本
用户在现有或新建集群中,只需勾选是否开启跨机并行、并设置单节点并行度即可,保持了极简配置、开箱即用的状态,无需业务侧修改任何代码,降低使用和维护复杂度。
- 实时在线分析
相对于RDS传统的主从binlog同步,PolarDB基于innodb的物理复制实现,节点间同步延迟在ms级或更低,这样即使查询下发到RO节点,也可得到100%新鲜度的实时数据,同时结合更高并行度的计算在更短时间内得到查询结果,可以让业务在第一时间获取到insight,满足企业快速发展中随时可能变化的业务需求。
- 灵活的应用模式
很多企业用户有在一套数据上进行多种类分析的需求,不同种类可能来源于不同业务部门,查询的特性也各不相同,例如针对大量数据的批量报表、针对部分数据的实时交互等。PolarDB一写多读的架构本身就很适合这样的多样化场景,不同业务可以通过使用不同节点构成的子集群实现物理隔离,而不同子集群可以通过设置不同的并行策略来应对相应的分析场景。
适用场景
弹性并行查询(ePQ)是并行查询(PQ)的下一代演进,同时也保持了对PQ的完全兼容,因此并行查询本身适用的场景[1],弹性并行仍然适用。除此之外,ePQ能应对的场景更加灵活而广泛:
-海量数据分析场景
前面已经提到,在更大数据量的情况下,单机的CPU/Memory/IO都可能遇到瓶颈,如果打破这个瓶颈,查询响应时间就可以继续线性提升。这里可能有同学会问,能不能通过升级单个节点的规格(最高88core)来实现对更大数据量的处理?跨机一定是必须的吗?答案是肯定的,原因在两方面:
- 即使是最大88核的规格,处理能力仍是有上限的,而且如果数据量到达TB级别,这个规格应对分析查询仍是不够的,只有扩展出去才能利用更大的总体资源
- 即使单机资源没有遇到瓶颈(多核大内存),在数据库内核中会存在很多共享资源(page hash/readview/pages...),查询中的worker线程会并发访问这些资源,导致并发控制带来的消耗,查询性能无法很好的线性扩展。但如果worker线程分布到多个节点中,争抢会降低很多,仍然可以保证良好的加速比
- 资源负载不均衡场景
集群内的多个只读节点,借助数据库代理的负载均衡能力可以使每个节点的并发连接数大致相同。但由于不同查询的计算复杂度、资源使用方式各有差异,基于连接数的load balance无法完全避免节点间负载不均衡的问题。同所有分布式数据库一样,热点节点也会对PolarDB造成一定的负面影响:
- 如果RO节点过热使得查询执行过慢,可能造成主节点无法purge undo log导致