开发者学堂课程【应用视角出发的数据库流量治理 :应用视角出发的数据库流量治理(二)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/1212/detail/18212
应用视角出发的数据库流量治理
五、动态读写分离
数据库的一个动态读写分离能力可以将一个弱读请求动态的隔离至只读实例中提升一个主库的稳定性并且提升应用的一个吞吐量,是今天重点介绍内容。到底在什么场景下可能会用到从应用视角出发的一个动态读写分离的能力,首先先了解一下读写分离的一个概要或场景,首先先讲一下什么是读写分离?读写分离可以将数据库可以拆分成一个 RDS的主库以及一个从库。主库主要是负责一些增删改的操作,然后从库负责处理一些查询的操作,这样的架构企业就是一个独显工地的架构,从应用市场出发可以想到几个场景,首先最关键的其实就是稳定性的问题,举个例子,线上经常碰到比较大的客户的请求,可能数据库返回上万条的一个可能甚至是几百兆的一个查询数据,查询的一个元数据,有的时候可能直接导致的数据库的一个 cpu 被打满,这时就会影响主库的一个稳定性,数据库的稳定性都被影响从而导致整个应用出现了一些充满等一系列的问题,甚至这个时候如果整个数据库行夯住了,甚至是整个微服系统,不仅仅是一个微服应用会出现问题。
这个场景下稳定性就显得非常重要,如果这时有一些大的查询请求,可以让他分流至只读实例上,这样就会保证主库的稳定性,同时也会提高应用的吞吐量以及性能。第二款就是刚才提到的性能,在业务处理的过程中其实有时对数据库的读操作可能会多于写操作,同时如果某些业务可能对查询结果实质性并不那么高,那可以容忍秒级的一些同步的延迟,那么在系统性能优化的时候就可以考虑引入一些读写分离的方案,只读实例可以承担主库的压力来提高应用的性能,还有就是数据库横向扩容时也是这样的一个效果,就是如果有少量的带有大量的,底下某些单个实力可能没有办法承接压力,那就可以扩容来一些只读实例,来承接的一个只读的一个流量,MC 这块提供了一个动态读写分离的能力,有三个特点,下面会结合控制台详细的讲一下。首先是无侵入性,是无需修改一行代码;第二块就是精细化路由,一句话来解释就是可以按照请求条件接口 SQL,或者应用或者服务,多个层次,多个条件来进行只读实例的路由达标的能力,之前聊到读写分离的时候,业务对数据一致性或者主从同步的延时没有那么敏感的产品,可以直接用独显管理方案,如果一个应用里面大部分接口是又改又查的,那如果保证不了绘画的一致性,读写分离方案可能显得非常鸡肋,每一个应用中只有查询的接口的个数可能是非常少的,所以如果真的要用上其实 mac 这一块还提供了一个强制性的模式,可以指定接口指定事物来保障,必须在主动同步完成之后来进行读路由,提到这么多,大家就会觉得读写分离确实是一个比较好的能力,那么系统该如何用起来?系统用起来成本到底有多高?是否要改业务代码?刚才提到无侵入性,用一个简单的代码来演示一下从而有一个更好的体感。
首先这是一个容器服务上面的 demo,其实是查询、增删改查操作,
这是一个主库,创建了两个只读实例,然后在数据库里面看一下表结构,主库里面有很多数据,自然从库里面肯定也是,因为主从同步,从库里面也有这么多数据,挑一个数据可以看到主从同步的一个延时,目前是零毫秒的延时,从库这边看到从库数据跟主库是一模一样的,主从同步会使他的结果保持一致,是一个不属于的情况,为了演示,这边构造了另外一个主库,他也可以作为一个只读,为了演示读写分离的场景,在这边构造一样的表但是里面数据显示不一样的,待会儿可以看一下效果:
如果读写分离的页面就在应用治理的一个数据库中,数据库治理目前有这么多:
这之前介绍场景有四个,洞察、数据库灰度、这个洞察其实可以配置一些线路能力,还有一个是读写分离能力,应用只要是基于德鲁伊,目前是一个连接词,使用登录连接池就可以看到德鲁伊的一个数据源,使用登录连接池就直接接入 mac 就能支持动态读写分离能力。只需两个步骤,第一步,就是首先开启数据库读写分离能力,然后这边填入一个 rm,就是从主库找到有从库的地址复制下来,然后构造成一个 rm,从库地址,只需要配置即可,确定这边可以看到是否将这个应用的作业分离开启,状态是开启,
只读实例的 rm,仅需配置即可。高阶的规则这边只需开启即可,开启后应用他就会默认的将所有的只读接口路由至的一个只读实例上,刚才也提到这就是无侵入性的一个表示。刚才也提到精细化路由是这样的一个场景,先演示一下这样配置的效果:
从主库查到的数据
看到从从库这边查到一个数据,如果效果不是很明显,可以直接用另外一个主库,刚才搞了两个主库就是为了这个效果,可以用另外主库的一个地址,如果他里面的数据跟现在数值是不一样的,效果可能这样更明显一点,只需要找到他的一个地址,
然后再查一下,可以看到这边查出来的结果,就是一个另外主库的数据,原来结果是主库正常的数据,现在查出来是另外一个,就是写的 rm 的那个数据,也就是说读写分离能力这一块只需要配置一个只读实例的 rm 即可,这一块就是从库里面读出来的数据就是这样,那所有写的操作还是操作回只读实例,查数据都是在此地方查,操作还是都在只读实例中操作,库也可以看到的一个接入,四个洞察也可以看到一些效果,可以看到如下地址
现在就基本上简单的演示完成了,只要开启这样的读写分离能力,那么当前应用的所有的读操作都会被路由置 Rds 的一个只读实例,就是填的一个 u l的一个数据库,然后写的操作都是操作的主实例中。
接下来精细化路由到底如何体现,举例说明,在看到这么多的 SQL,delete、select 或者有多种 select 的语句,当发现一些场景,比如某个 select 语句,查的一个非常慢,那如何将指定的select语句路由至的只读实例,演示如下:规则可以认为上面两个配置是一个应用级别的配置,下面的规则可以针对接口来配置,接口有涉及到web、 rpc以及SQL,web、 rpc 其实并不是一个 SQL 语句,但是如果配了一个 Web 级别的一个多元接口的规则,然后开启,这个web接口下面的所有的执行到的 SQL 语句中的读操作都会被路由至只读实例中,如果觉得外边 web 语句太粗,甚至可以精细化到 SQL 的级别,可以选择一个 select 语句,开启规则即可,就会指示将这一条 select 的语句路由至只读实例中,这是第二款精细化路由的一个理解。
其实这个场景是非常多的,举个例子,线上的许多应用比如购物车,发现当流量上来之后,发现查询购物车的语句完全就可以通过只读实例来,同时可能购物车还要查询购物车语句是非常重要的一个语句,如果还会有一些场景,比如说购物车中查询激活的地址,额外的查询并不是那么重要的,可以直接路由至只读实例中;如果查询已经添加到购物车的一个商品,要查询商品,它的对一致性要求是非常高的,举个例子就是添加自己心仪的一个物品到购物车中,再到购物车里面去刷新购物车列表的时候,如果把查询购车这个语句的一个 SQL 请求,把路由至只读实例,并且此时主从同步并且卡在可能有一定的延时,那用户的体验就会非常的不好,比如添加一件心仪的物品至购物车,在刷购物车页面时发现刚才添加的物品并没有出现,这时用户就会开始焦虑,回到查询中,其实像查询购物车中的商品场景的接口或者说 SQL 对一致性要求是比较高的,通用的一个读写分离能力无非就是要么把这个 SQL 只读实例,要么就是路由器只读实例就要忍受主从同步的延时,不一致性的问题。此时 mace 有强一致性的模式,这样的配置,假设正式数据库只要开启这样的配置,它就会保证这条查询语句路由至只读实例的前提是主从同步已经完成,也可以看到后端内容,可以看到一些数据、信息,其实原理非常简单,在需要路由的弱读请求之前内部会有一个机制,会保证主从同步完成之后才会将强一致模式下的一个路由的 SQL 接口接至适合的查询接口,路由器只读实例中就可以保证接口的强一致性能力。
其实这一块就是即将发布的数据库的读写分离的能力,从应用视角出发,有三个特点:一是无侵入性。即无需修改银行代码,只要在控制台打开规则,就能生效。二是精细化路由。目前支持多个维度 web 服务,rpc 服务以及 SQL 多个维度,有个规则的配置可开可关,并不是说应用它开启所有接口还是甚至可以进化到应用的某条 SQL 语句或者是某个 web 的一个接口,或者说某个业务的接口,业务的服务或者业务的接口涉及到的 SQL 语句,开启读写分离能力,甚至会精细化到支持某个 SQL 的某个参数符合某些条件下然后开启读写分离能力,是后面会推出的。
大部分的场景就是降低主库的延时,将一些慢调用或者说返回量大的 SQL 路由至电视的一个只读实例上,同时,对一些敏感的业务,他们可能有的时候也需要使用读写分离能力来提升主库的稳定性,但是他又要保证一致性,那他就会通过配置强意志保证的一个规则在保证业务不影响用户体验的前提下来尽可能提升应用性能主库的一个读写分离。
接下来线上比较影响稳定性的一个问题,就是慢调用的一个慢 SQL 如何治理,SQL 语句处理时间长,因为在数据库里面的处理时间长将会导致应用的业务接口出现大量慢调用,需要及时找到有问题的一个慢 SQL,对其进行治理。mace 这边其实有四个洞察可以帮助自动识别初 SQL,并且对一些慢 SQL 应用,通过配置线程数纬度的一个留空或者说配置降级,当初就 SQL 的时候,可以把它限制在同一时刻内执行的一个 SQL 数量上防止过多的 MYSQL 语句把应用的资源耗尽。这是第一。第二,读写分离能力,确实是比较慢的,一些 SQL 可以把它路由至只读实例中来提升应用整体的稳定性。
现在介绍一下 SQL 的一个慢 SQL 治理,一个留空或者说并发隔离或者同等价钱能力,而且这一块的能力其实就是源自于应用,可以发现及时发现有问题的一些慢 SQL,并且把它隔离至指定的一个并发的一个线程上或者说把他的一个限流量,也可以通过热点参数的能力来进行一个留空,因为目前是可以做到自动识别出 SQL 请求中访问的一个参数,并且对其中进行访问热度的一个参数时进行排序,然后对最高的参数来进行一个留空,举个例子,比如一些特殊的热点访问,热门的抢购的单品也对他配置一些单独的一个留空,比如说黑大刷、黑产刷单的一些场景,某个用户 ID限流,参数可以使 SQL 中这个访问中任意带有业务属性的一个条件,这都是可以的。
接下来,有SQL的数值,接下来直接来配置,设置阈值看看效果,这边请求是一直在打的,可以看到这边肯定是一直在访问时开始限流了,看一下效果,
前后可能会要晚一会才会出来,可以看到流量开始限流了,并且他通过了 qPS,配了一些规则,这边还有隔离、垄断、热点、读写分离能力,这些可以去尝试,
这边通过一个简单的代码,可以发现 SQL 然后再通过一些线程能力,来保证现场的稳定性制度,最后提一下,还有因为从应用视角出发的一个身负治理是一个完整的方案,
刚才两个场景讲完后其实还有连接池的治理,针对德鲁伊等,提前一些策略,比如说,换连接剔除、访问控制、体现建联等等操作它可以满足,各个场景下来一些需求,比如换连接剔除,是从连接池视角出发,及时发现有异常的连接然后进行剔除,回收可以保证连接是整体的稳定性跟访问控制面向数据库实例,表的禁写等访问控制进行操作;提前建联,在流量到达之前保存连接在最小值之上,来保证启动过程一个流量平滑,防止大量请求卡在获取链接的过程上,数据库灰度和读写分离能力。