金仓数据库 KingbaseES 客户端编程接口侧负载均衡技术解析

伴随互联网、大数据、物联网、人工智能等技术的演进,万物互联已成为一种主流发展趋势,各行各业都在积极地将数字化融入到自身的发展中,大数据量、高并发量、高可用性、高一致性等业务场景成为常态。然而,越来越大的业务系统数据量以及随之变大的数据库操作开销,逐渐成为整个业务系统的性能瓶颈。
实现方案
常见方案解析
在大数据量、高并发场景下,已很难基于单节点继续提升性能。各厂商纷纷转向集群,将负载均衡的路由单节点驶向多节点,并给出不同的解决方案:

这些方案适用于不同场景及业务,各有优劣。金仓的解决方案就属于上表中“客户端编程接口侧负载均衡”。
金仓方案
作为数据库厂商,金仓发布了多种解决方案来应对复杂且多变的业务需求,其中客户端编程接口侧负载均衡技术配合数据库读写分离集群应用于高并发业务场景,能显著提升系统的高可用性和整体吞吐量。
该方案通过在客户端编程接口内部实现根据业务 SQL 类型和当前事务状态把 SQL 路由到数据库集群中的不同节点,并保持对应用透明,最终达到负载均衡的访问数据库集群。金仓客户端编程接口内部直接识别语句类型和事务读写状态,把写语句发给主机执行,把读事务中的读语句负载均衡的分发给所有备机节点执行,以减轻单个数据库节点的负载压力,提高数据库集群整体的处理性能。

金仓采用嵌入自身客户端编程接口侧的、基于语句级的动态负载均衡技术,实现了对前端开放式应用请求的高效、智能负载均衡,既充分利用了数据库服务器的算力,又提高了数据库系统的并发处理能力,保证应用的访问质量。
(1) 将负载均衡算法嵌入在自身的客户端编程接口中,无需专门的路由节点,因此可避免路由操作本身带来的请求转发耗时,提高路由操作本身的效率,缩短应用请求的处理时间。

(2) 采用 SQL 语句级(而非数据库连接级)的细粒度路由单位,可适应多应用负载混合共用统一数据库、及应用负载动态变化的应用场景,保证请求路由分配的场景适应性。
SQL 语句级路由单个会话执行效果演示:

SQL 语句级路由多个并发会话执行效果演示:

(3) 采用基于 CPU、内存、数据库连接数度量的数据库服务器实时负载情况的动态负载均衡算法,实现对数据库集群节点算力的均衡使用,确保请求路由分配的均衡性。
基于数据库实时负载的动态负载均衡执行效果演示:

技术揭秘
节点读写分工,缓解争用现象
在事务处理过程中,以下四种操作分别对应不同的节点执行:
如果事务中只有读操作,通过金仓客户端编程接口驱动将事务中的语句分发到 Slave 节点中执行。
如果事务中只有写操作,通过驱动分发器将整个事务内的所有语句都分发到 Master 节点中执行。
如果事务中开始是读,后续有写操作,则将开始的读操作分发到 Slave 节点中执行,直到写操作后,该事务中的所有 SQL 将在 Master 节点中执行。
对于无法识别读写类型的,将发送到 Master 节点中执行。
双重语句分发策略,满足不同业务需求
单语句事务:每条语句都是一个独立的事务,所以读语句分发备机没有问题。
多语句事务:读语句处于事务内,分发需要考虑事务隔离级别。
金仓数据库支持的三种隔离级别:可重复读,读提交,序列化。严格意义上这三种隔离级别均不允许读语句分发,因为可能出现不可重复读或者读不到已提交的内容。但如果事务内的语句就不分发的话,多个 Slave 节点就被浪费了。因为无论是应用还是框架基本上都是用事务控制的,因此金仓客户端编程接口提供了参数 TransactionDispatchStrategy 来控制事务内语句分发策略。
事务内语句分发策略有一下两种(默认是 2):
1 表示事务内的所有语句都只发主机,完全不分发备机;
2 表示事务内遇到写语句之前的读语句,可以分发备机,遇到写语句之后就只发主机。
读语句可分发节点选择策略,解决异步备机数据延迟问题
我们知道主备库实质是基于副本的,那么主备之间就可能存在数据差异,为此金仓提供同步复制的方式,客户端编程接口也对应提供控制查询语句的分发节点选择策略的参数(性能优先,默认是 1):
1 表示所有节点均可分发:仅看是不是可用的在线节点,是就可以分发,不考虑备机的数据延迟,最大化分发,负载效率最好,但可能出现备机数据延迟造成的主备读取数据不一致。属于弱一致性,适用不要求强一致的应用,比如历史数据分析。
2 表示只发主机同步备机:异步备机只做 HA,读语句可分发到主机和同步备机,最大化读取一致性,但无法利用异步备机负载,性能有损耗,属于强一致性,适用要求强一致的应用。
多个备机负载均衡,提升查询吞吐量
金仓客户端编程接口可通过参数控制读语句发给主机的比例,方便根据具体主备机器性能差异来分配负载。所有的 Slave 节点用于读操作。
当读取操作较多时,驱动分发器将通过多种负载均衡算法,比如基于语句执行数的负载,基于接数的负载,和基于响应时间的负载,将读操作均衡分布在所有有效的 Slave 节点中执行,降低 Master 节点负载,通过 Slave 节点负载均衡,提高查询性能。
定时心跳检测,出现脑裂及时止损
客户端编程接口侧负载均衡本意主要解决的是数据库接入层的高可用和负载均衡,对于脑裂无法直接解决。为此金仓客户端编程接口提供两重机制减少脑裂发生后双写造成的数据损失。
通过驱动内部的顺序检测机制,可以保证新建连接只会连接到第一个主机上,此时不会发生脑裂双写问题。
对于连接池中的已有连接,有可能已经在使用第二个主机,这部分连接认为自己还是有效的,此时可能发生双写。为此我们引入定时检测机制,判断一个集群内是否出现超过 1 个主机的情况,如果检测到脑裂发生,现有连接会被强制关闭,并抛出脑裂异常警告让业务人员可以及时干预。
功能影响
读写分离对事务隔离性的影响

读写分离对写后读一致性的影响

评论