当前位置: 首页 > 科技观察

关于网易MySQL中间件的负载均衡策略和性能优化

时间:2023-03-13 21:01:20 科技观察

团队介绍网易乐德DBA组,负责网易乐德电商、网易邮箱、网易技术部数据库的日常运维,负责开发维护数据库私有云平台负责人,负责数据库及数据库中间件Cetus等的开发和测试。一、背景随着业务的爆发式增长,电商系统的读写压力越来越大,单节点MySQL实例的压力越来越大。单纯升级服务器硬件已经不能满足生产环境的需求。解决读请求压力,需要支持从库扩容;为了解决写请求的压力,增加多个节点进行数据分片,降低单节点MySQL实例的压力成为更好的选择。传统的分片是通过DAO层来完成的,但是DAO层在数据分片上存在很多问题。从业务角度看,配置修改需要重启服务,成本高;碎片化的结果集需要处理,业务逻辑变得更加复杂;功能比较简单。从数据库运维角度,难以统一配置管理;数据库升级、迁移等操作复杂。网易电商也面临着这些问题。为了彻底解决数据库瓶颈,网易乐德团队在实际生产中开发了自己的中间件Cetus。拥有正统基因,在MySQL-Proxy官方版本的基础上进行了全面修复和再创新。不久前已经开源,广泛应用于各个产品线,性能和稳定性都很好。Cetus兼容MySQL协议,前端应用无需修改即可通过Cetus访问数据库,方便DBA运维同学和开发同学使用,实现了数据库层面的横向扩展。目前Cetus有读写分离和分片两个版本,可以通过编译参数选择合适的版本。支持分布式事务、连接池、结果集压缩、安全管理、状态监控、TcpStream传输等多项对用户透明的功能。2.负载均衡策略和性能优化本文所讨论的负载均衡是指读流量的负载均衡,即后端如何将读流量分配给同一个MySQL集群中的各个DB。Cetus的负载均衡策略主要分为两部分:主从库之间读取流量的负载策略;从库之间读取流量的负载策略。在具体实现上,流量分配单元与Atlas等中间件略有不同,并进行了性能优化。以下章节将依次详细介绍。1.主从库读流量负载策略默认情况下,不在事务中的读流量,不强制通过注解路由到主库,或者不使用锁的读流量都会路由到从库优先,负载将在从库之间进行平衡。仅当没有从站可用时,读取流量才会路由到主站。在某些业务场景下,主库可以分担部分读流量,这就涉及到在主库和从库上对读流量配置负载策略。在Cetus中,可以配置参数read-master-percentage来指定路由到master库的读取流量的默认百分比。该参数取值范围为[0,100]。该值默认为0,即所有读流量会先路由到从库,当所有从库都不可用时再路由到主库;如果此参数设置为100,则所有读取流量将路由到主库;如果这个值设置为(0,100)时,会按照设置的比例进行路由。需要注意的是,这个值代表的是主库占所有从库的比例。2.从库间读流量负载策略路由从库间的流量负载均衡。目前Cetus从库之间的读流量负载策略只支持round-robin(RR)方式。在流量分配方面,Cetus也进行了优化。一些MySQL数据库中间件(如Atlas)会根据SQL的维度进行负载均衡,而不管SQL是从同一个连接发出的还是不同连接发出的。中间件将接收到的SQL按照策略依次发送给后端数据库。在实际使用中发现,在长连接的场景下,这种策略会造成大量的连接切换,从而导致session级变量的频繁调整,影响SQL的执行效率。所以Cetus对其进行了优化,并没有完全按照SQL的维度进行负载均衡。Cetus考虑到同一个连接连续发送SQL请求的情况,不会立即将当前SQL用完的Cetus和MySQL之间的连接返回到连接池中重新使用,而是持有很短的时间(256毫秒),这样以后仍然有SQL在执行,从而避免了会话级变量的调整,大大提高了SQL执行的效率。在长连接场景下,对优化前后的Cetus进行了简单的测试。通过测试发现,优化后的Cetus在长连接场景下读流量的吞吐量有明显提升。下图是docker环境下的简单测试对比:为了防止IO过高,简单修改了sysbench发送的SQL,限制了返回结果集的大小。在关闭transaction和prepare的情况下,每次使用100个线程测试60s,连续测试5次。结果如下:由于本地Docker性能较差,而sysbench模拟测试的语句比较简单,不涉及session变量的切换,所以对比效果不是很明显,性能这个测试只提高了大约30%。在长连接业务场景下,性能优化可能会更加明显。3、读流量路由策略总结在至少有一个从库可用的情况下,影响查询语句路由策略的主要因素有:在事务中查询;选择...进行更新或选择...锁定在共享模式;Cetus设置参数master-preferred=true,所有流量默认路由到master库;Cetus设置参数read-master-percentage来控制主从读流量负载;使用注释/*#mode=READWRITE*/或/*#mode=READONLY*/。默认情况下,读流量会先路由到从库,从库之间根据轮询策略进行负载均衡;一旦所有从库不可用,它们将被路由到主库。目前Cetus的各个从库不支持按权重加载。对于a、b、c点,Cetus会将查询语句直接路由到主库;对于d点,如果设置了read-master-percentage=100,所有的查询流量都会路由到主库;ifread-master-percentage=[0,100),Cetus会将读流量按照这个比例路由到主库和从库(注意这里的从库是指所有的从库,即比例指主库占所有从库的比例);对于e点,如果使用注释/*#mode=READWRITE*/,读取的流量会路由到主库;如果使用注释/*#mode=READONLY*/,则读流量会路由到从库,如果所有从库都不可用,则在使用时路由到主库。以上因素的优先级,注释优先***,其次是参数master-preferred,***是参数read-master-percentage。3.总结MySQL数据库中间件的主要特点是对客户端发送的SQL进行路由,负载均衡是路由策略的重要组成部分。通过了解Cetus的负载均衡机制,可以在后续的维护过程中更好的调优数据库中间件,更灵活的控制SQL路由。Cetus中间件开源地址:https://github.com/Lede-Inc/cetus/blob/master/doc/cetus-quick-try.md