作者|10Sleep我们从应用的角度,对我们在访问和使用数据库时在稳定性治理、性能优化、效率提升等方面的一些实战进行了梳理和抽象。经验,对于每一个后端应用来说,数据库无疑是重中之重。我们希望通过我们的数据库治理能力,帮助大家更好的使用数据库服务。MSE数据库治理完整解决方案本文将详细介绍MSE数据库治理的热点功能、动态读写分离的设计与实现。一、读写分离概述数据库动态读写分离的常见场景:一个大客户的请求进来,查询数据库返回几万条几百兆的数据,数据库的CPU占用数据库直接满了。微服务应用的一些业务不是那么重要,但是查询数据库的逻辑很多,影响了数据库实例的稳定性,导致整体服务质量下降。在业务处理过程中,如果对数据库的读操作远多于写操作,那么在优化系统性能时可以考虑引入读写分离方案。一方面,只读库可以承受主库的压力。另一方面,可以有效避免数据更新带来的锁等待,提升微服务应用的性能。随着业务的增长,在一定的时候我们需要对数据库实例进行扩容。根据经验,大部分应用的读写比都在5:1以上,部分场景甚至大量高于10:1。在对数据库的写请求数量较少,而读请求数量较多的应用场景下,单个实例可能无法承受读取压力,甚至会对业务造成影响。可以了解到,数据库读写分离方案可以满足大部分企业在阿里云上的稳定性管理、性能提升和数据库扩展需求。了解读写分离实现的同学肯定会关注以下问题:MSE如何解决读写分离对业务的入侵?如何在不改动一行代码的情况下,让业务具备读写分离的能力。MSE是如何做到细粒度动态读写分离控制的?即使不知道这个业务接口真正的SQL是什么,我们也已经可以控制这个接口的读SQL访问只读实例。MSE如何解决读写分离带来的一致性问题?对于对一致性敏感的业务,如何保证一致性,满足业务在不同场景下对一致性级别的需求。2、MSE读写分离技术揭秘读写分离,就是把数据库拆分成主库和从库,即主库负责处理事务性的增删改查操作,而从数据库负责处理查询操作。光看读写分离的概念,第一感觉肯定是对业务有相当的侵入性,那么MSE是如何实现无侵入性的呢?(1)非侵入式:无需修改一行代码。MSE数据库管理能力使用JavaAgent技术动态增加用户数据源,注入动态读写分离能力,支持弱读请求运行时动态路由到只读实例。MSE在数据源层面实现了抽象,其中DynamicConnection和DynamicStatement会根据特定的规则实现Master/Slaver的切换,并根据SQL读写类型、事务状态和用户业务规则进行SQL路由,符合条件读SQL请求被转发到RDS只读实例。(2)精细化路由:根据请求条件、接口、SQL多级多条件,我们访问数据库往往是写DAO。在一些复杂的应用场景中,我们可能只知道DAO接口。在一些复杂的场景下,我们可能只知道DAO接口。我们只知道微服务的接口,连调用哪个DAO接口和SQL语句都不知道。即使运维角色参与设计,我们也很可能不知道是哪个微服务接口导致读请求导致数据库抖动。知道入口应用的某个uid。那么我们如何将业务接口中的读请求路由到只读实例呢?MSE数据库管理在应用层面提供了完整的callStack信息,让我们能够从应用的角度清晰的看到哪些SQL在内部由哪些接口执行。MSE使用链接传输技术,支持在入口微服务、微服务接口、DAO层面标记弱读请求,支持标记当前线程中的SQL调用、当前微服务中的SQL调用、满足流量条件的请求链所有SQL路由级别的调用和其他多个级别的弱读标记通过,最后传递给读写分离组件的路由引擎,判断SQL的路由依据。(3)强一致性模式:在指定接口和事务时,当数据库负载较高时,比如对大表进行DDL(如添加字段)操作或大批量插入数据时,延迟会非常严重,导致在读取失败时从只读实例中读取最新数据。MSE提供了一些解决上述问题的策略。某些接口或某些业务对具有非常高的一致性。我们可以通过规则配置告诉MSE,某些读接口在特定场景下被标记为强读请求。MSE内部使用了一些机制来保证读写分离的强一致性效果。(4)白屏能力:通过AccessLog实时感知读写分离具有读写分离能力,那么我们如何知道实现了读写分离,哪些应用、哪些请求分离为只读实例?MSE白屏能力提供了一套完整的AccessLog。Routingreadrequeststoread-onlyinstancesRoutingreadrequeststomasterinstance从容错、连接池管理到数据库灰度、动态读写分离。我们希望通过数据库治理能力,帮助用户的微服务更好地使用数据库,降低数据库使用成本,提高数据库访问的稳定性。MSE的数据库治理能力也需要越来越深入的客户场景和实施实践。如果您对MSE的数据库治理能力感兴趣,请联系我们。只有经过客户打磨的产品,才会越来越历久弥新。在构建数据库治理能力的同时,我们也在通过OpenSergo与社区一起构建数据库治理标准。
