代理位于数据库和应用程序之间的网络代理服务,转发客户端的请求到DB,收到DB回包在转发到客户端,提供多种能力,支持:读写分离、负载均衡、一致性级别、连接池、过载保护功能。对外提供地址:主地址和集群地址、自定义地址
1、连接地址:
https://help.aliyun.com/zh/polardb/polardb-for-mysql/user-guide/connection-address?spm=a2c4g.11186623.0.0.44301b63I2VB5b
2、读写分离
请求转发逻辑参考:
https://help.aliyun.com/zh/polardb/polardb-for-mysql/user-guide/read-or-write-splitting-2?spm=a2c4g.11186623.0.0.39df2328N1C3y1
3、负载均衡策略:
基于活跃请求数:统计连接地址下每个DB节点的活跃连接数
基于连接数:统计连接地址下每个DB的当前连接数
基于库表:根据请求涉及的Database的DB节点的访问权限
基于权重动态负载
主库是否接受读:开启和RO节点一样,承担读请求
Hint使用(优先级最高,不受事务和一致性约束)
事务拆分:PolarDB MySQL版提供了事务写前读拆分(默认值,即原来的事务拆分功能)和事务全(写前读、写后读)拆分两个级别的事务拆分能力:
事务写前读拆分
Proxy会将事务中第一个写请求前的读请求发送到只读节点,从而减轻主节点的负载。
全(写前读、写后读)拆分
前读拆分对于事务中写之后的读仍然会路由到主节点,这种情况下负载仍然不太均衡,为彻底解决事务带来的负载均衡问题,PolarDB MySQL版推出事务全拆分能力,可以使得事务中的读操作都路由到只读节点且获得正确的结果。进一步减轻主节点的压力
开启事务语句回包的时候,track当前session的事务id
proxy通过内部同步事务id,使得属于同一会话的不同后端连接上的事务id保持一致,使得只读上能看到当前事务未提交的数据,
track当前session写lsn
有读请求时,proxy通过比较当前会话lsn和各节点当前已同步的lsn,决定一个读请求能否路由到对应节点
受一致性约束,如果ro的lsn不满足的话,写后读请求路由到主库
4、一致性级别
https://help.aliyun.com/zh/polardb/polardb-for-mysql/user-guide/consistency-levels?spm=a2c4g.11186623.0.0.2ce6518fXE0GbZ
polardb采用基于redo log异步物理复制方式在主库与只读库间做数据同步,主库更新后,相关的更新会apply到只读库
最终一致性:不保证查询结果正确性,性能最好
会话一致性:只能满足一个会话内的请求是一致的,不能保证不同会话间的一致性,当所有读节点都无法满足一致性要求时,会把该读请求路由到主库,
1、主库执行update返回OK包track写lsn得到session lsn
2、ro节点应用主库的redo log,更新buffer pool 更新lsn得到ro synced lsn(ro节点会每隔2ms推送lsn)
3、比较session lsn和synced lsn,大于session lsn则请求到该ro节点
全局一致性:保证正确性,性能最差
每个读请求到proxy,先去主库探测一下最新LSN位点、作为该请求期望的lsn,作为该请求期望的lsn,当有只读节点的lsn大于期望的lsn,再将请求到该ro节点,那么就能保证该请求能够读到这个请求发起那个时刻已完成的更新,如果在设置的超时时间内没有满足的ro,则路由到主库或者报错
5、连接池
会话级连接池
事务级连接池
会话级连接池
当用户的连接断开的时候,代理会判断当前连接是否是一个idle的连接,如果是idle的话,那么代理会将代理与DB之间的连接保留在连接池中一段时间,如果这时用户新的连接过来的话,就会直接先从连接池里获得(命中条件:用户名,客户端ip,dbname等)如果有的话就直接使用,从而减少与DB的建连开销,如果没有可用的连接的话,则走正常流程,重新与DB建立一个连接,
话级连接池并不能减少数据库的并发连接数。该优化只能通过降低应用与数据库的建连速率来减少MySQL主线程的开销,从而更好地处理业务请求,但是连接池里空闲的连接会短暂占您的连接数。
事务级连接池
主要用于减少业务的连接数、以及减少短连接场景下频繁新建连接带来的负载、客户端可以与代理建立大量连接、而同时代理到DB只创建少量连接
当用户发送请求时、代理将从连接池中选取符合条件的()连接进行请求到DB、并在当前事务结束后将连接放在连接池
未开启事务级连接池时,每条由客户端发起的连接都需要在后端主节点和所有只读节点上各创建一个对应的连接。,开启事务级连接池后,当客户端发送请求时,会先与PolarDB代理建连,代理不会马上将其与后端数据库建连,而是先从事务级连接池里查找是否存在可用的连接(判断是否为可用连接的条件:user、dbname和系统变量这3个参数值是否一致)。若不存在,代理会与数据库创建一个新连接;若存在,则从连接池里直接拿出并使用,并在当前事务结束后将该连接放回事务级连接池,方便下个请求继续使用
连接池的选择
1)若业务使用的多为长连接且连接数较少,或者业务本身已具备较好的连接池,那么您可以不使用PolarDB的连接池功能。
2)若业务使用的连接数较多(如连接数需求上万)或使用的是Serverless服务(即连接数会随着业务端服务器的扩容而线性增加),且确认您的业务不涉及上述事务级连接池使用限制的场景,那么您可以选择开启事务级连接池。
3)若业务使用的纯短连接,且业务使用场景中包含上述事务级连接池使用限制的场景,那么您可以考虑开启会话级连接池。