国产数据库中读写分离实现机制

在数据库高可用架构下会存在1主多备的部署,备节点可以根据业务场景分发一部分流量以充分利用资源,并减轻主库的压力,因此在数据库的功能上需要读写分离来实现。

  • 充分利用备节点的资源,提升业务的吞吐量;
  • 防止运维等非业务查询访问主节点导致CPU飙升的场景,进而影响业务正常运行;
  • 在实现上考虑到主备时延过大的情况下,业务的容忍度以及规避措施;
  • 事务的处理上,更新操作在主节点而读在备节点,如何保证事务的一致性?

1、OceanBase数据库

OceanBase数据库的读写分离是由ODP(OceanBase Database Proxy)数据库代理实现的,读写分离就是数据在主节点修改后,数据同步到备节点,备节点提供数据的读取功能。OceanBase数据库支持读写分离到表的Partition级别,这也是原生的分布式数据库的优势。
在OceanBase数据库中使用读写分离功能,需要经过两部分设置:

  1. 设置SQL语句为弱读:所谓弱读是指读请求不要求读到最新的数据。对于正常的SQL为强读,使用弱读需要一定的设置。
  2. 修改路由策略:每个副本都可以提供弱读服务(主副本也可以提供读服务),通过设置路由策略,可以优先选择备副本。
1.1 弱读配置

1)在SQL语句中通过Hint

/*+READ_CONSISTENCY(WEAK)*/配置
select /*+READ_CONSISTENCY(WEAK)*/ * from t1;

2)通过OBProxy配置项obproxy_read_consistency设置

alter proxyconfig set obproxy_read_consistency = 1;

配置项默认值0表示强读、1表示弱读。SQL hint是语句级别的,配置项是实例级别的。通常可以配置多个OBProxy实例,选择其中部分OBProxy开启读配置作为运维查询使用。

1.2 修改路由策略

ODP通过配置项proxy_route_policy修改路由策略,通过设置为follower_first和follower_only可以让弱读请求优先发给备副本:

  • follower_first:优先选择备副本,如果备副本都不可用,选择主副本;
  • follower_only:选择备副本,如果备副本都不可用,断开和客户端的连接。

上述两个策略需要根据业务场景选择

2、PolarDB数据库

PolarDB MySQL版本的集群自带读写分离功能,在PolarDB控制台的数据库连接中配置读写模式,包括只读模式和可读可写模式(自动读写分离)。当配置可读可写模式后,写请求会自动转发到主节点,读请求会自动根据各节点的负载(当前未完成的请求数)转发到主节点或只读节点。

在这里插入图片描述

当客户端通过读写分离地址与数据库后端建立连接后,读写分离中间件会自动与主节点和各个只读节点建立连接。在同一个连接内(同一个session内),读写分离中间件会根据各个数据库节点的数据同步程度,来选择合适的节点,在保证数据正确的基础上(写操作之后的读有正确的结果),实现读写请求的负载均衡。另外,在配置可读可写模式后,可以配置主库是否接受读,当设置为否后,普通的读请求将不再发往主节点。而事务内,一致性要求的读请求仍会被发往主节点,以保证业务需求。另外,当所有只读节点出现故障后,读请求也会发往主节点。

在这里插入图片描述

同时读写分离模块自动对集群内的所有节点进行健康检查,当发现某个节点宕机或者延迟超过阈值(全局一致性读超时时间,取值范围:0~60000,默认为20ms)后,PolarDB将不再分配读请求给该节点,读写请求在剩余的健康节点间进行分配,以此确保单个只读节点发生故障时,不会影响应用的正常访问。当节点被修复后,PolarDB会自动将该节点纳回请求分配体系内。

2.1 请求转发逻辑

在配置了可读可写模式下,SQL语句的转发遵循以下规则:

  • 只发往主节点:DML和DDL操作、未开启事务拆分时所有事务请求、自定义函数、存储过程等;
  • 发往只读节点或主节点:非事务中的读请求、COM_STMT_EXECUTE命令等
  • 发往所有节点:所有系统变量的修改、COM_STMT_EXECUTE命令等

在这里插入图片描述

2.2 基于权重的动态负载均衡

PolarDB在可读可写(自动读写分离)模式下仅支持基于活跃请求数负载均衡的策略,优先选择最小活跃(并发)请求数的节点去路由请求,来保证多个只读节点间的负载均衡。该策略基本可以保证流量根据后端节点的负载均衡的路由到不同的后端节点上,即使后端节点的规格不一致,也能较好的进行负载均衡。

为了满足线上业务负载的多样性,PolarDB后续版本引入了基于权重的动态负载均衡策略,为每个节点配置不同的权重后,在后续的路由过程中,权重和并发请求数会同时作为参考标准去动态的调整最终的路由决策。在控制台“数据库代理服务配置”中,可以为不同的节点配置不同的权重,动态权重越大,节点的优先级越高,路由分发的流量也越大。

3、GaussDB数据库(for MySQL)

GaussDB(for MySQL)在创建数据库后,支持配置读写分离功能,通过代理地址将写请求自动访问主节点,读请求按照读权重配比或者活跃连接数情况分发到各个节点。在使用代理地址时,事务请求都会路由到实例的主节点,不保证非事务读的一致性,业务上有读一致性需求可以封装到事务中,可以使用事务拆分功能对事务中写之前的读请求进行拆分。

在GaussDB数据库控制台的数据库代理页面,新增数据库代理,包括代理模式、一致性级别、路由模式和添加的数据库节点。

  • 代理模式:支持读写模式和只读模式,只读模式下仅支持读请求业务,并且不支持DDL、DML操作和临时表操作;
  • 一致性级别:分为最终一致性和会话一致性,由于主备之间存在复制延迟,可能会导致每次读结果存在差异,默认情况只能保证最终一致性。当设置会话一致性后,保证在同一个会话内,保证每次读请求都是上一次更新操作后的结果。
  • 路由模式:包括权重负载和负载均衡,权重负载是根据设置的读权重比较分发请求,负载均衡是根据数据库节点的活跃连接数情况进行读请求分发。

在这里插入图片描述

另外,在SQL中通过hint方式指定发往主节点或只读节点。需要注意的是Hint注释仅作为路由建议,非只读SQL、事务中的场景不能强制路由到只读节点。

  • /FORCE_MASTER/强制路由到主节点;
  • /FORCE_SLAVE/强制路由到只读节点;
4、GoldenDB数据库

GoldenDB数据库的读写分离策略由连接实例级别的策略+语句级别的策略共同决定:

  • 在连接实例的服务端口进行配置,包括不开启读写分离、本地同城策略以及异地策略,其中本地同城策略需要配置权重;
  • SQL语句级别的读写分离策略,通过在SQL语句中增加hint实现,hint包括READMASTER、READBALANCE和READSLAVE

在这里插入图片描述

不同策略的组合如表所示:

在这里插入图片描述

另外,为避免只读数据节点读取的数据长时间和主数据节点不一致,当一个只读数据节点的延迟时间超过设置的延迟阈值,则不论该只读数据节点的读权重是多少,读请求都不会转发至该只读数据节点。在新版本的读写分离配置中,增加了“是否可读主”的配置,选择否后,当主备时延超过阈值时,依旧不会读主节点。

需要注意的是在多分片的实例中,当CN节点配置参数force_read_split后,开启读写分离时,显示的开启事务后,为了保证事务操作的一致性,事务内是不允许更新操作的,只允许只读事务,否则会提示“read-only transaction”的报错。

5、TDSQL数据库(for MySQL)

TDSQL数据库默认支持读写分离功能,包括3种读写分离的配置操作,其中非只读账号由参数gateway.mode.single_backend.rw_split控制:

  • 创建只读账号:创建账号时标记为只读,系统将根据只读策略将读请求发往备机,只读策略的配置分为以下场景:
    • 1:优先选择备机进行读操作,如果备机的延迟都大于设置的延迟,则从主机读取。
    • 2:只选择备机进行读操作,如果所有的备机都大于设置的延迟,则直接报错。
    • 3:只选择备机进行读取,忽略延迟参数,一般用于拉取binlog同步。
  • slave注释:参数rw_split=1,在SQL中增加slave模式的hint标签,将指定的SQL发往备机。比如在SQL中添加/slave/标记,该SQL会发送给备机。注意在mysql客户端使用时添加-c参数来解析注释,/slave/必须为小写,并且前后无空格。
//主机读//
select * from emp order by sal,deptno desc;
//从机读//
/*slave*/ select * from emp order by sal,deptno desc;
  • 全局自动读写分离:参数rw_split=2,配置该参数后会将读请求自动发送所有的备机。如果备机延迟较大,读到的数据可能会有延迟。如果是在事务中的读请求或者autocommit=0, begin/commit/rollback …等情况下,select也会发到主节点。

在这里插入图片描述

官方建议使用第1种和第2种方式配置读写分离,第三种配置方式会有一定程度的性能损耗。

6、OpenGauss数据库

openGauss数据库通过JDBC连接配置,支持一主多备情况下的读写分离,当URL中配置服务器地址时,可以通过URL中的属性标示targetServerType来区分JDBC返回的连接是否区分主机和备机。

  • Master:尝试连接到URL连接串中的主节点,如果找不到就抛出异常;
  • Slave:尝试连接到URL连接串中的备节点,如果找不到就抛出异常;
  • preferSlave:尝试连接到URL连接串中的备数据节点(如果有可用的话),否则连接到主数据节点;
  • any:尝试连接URL连接串中的任何一个数据节点,默认为“any”
##优先连接到备节点
jdbc:opengauss://node1,node2,node3/database?autoBalance=roundrobin&targetServerType=preferSlave
##只连接备机进行只读操作
jdbc:opengauss://node1,node2,node3/database?autoBalance=roundrobin&targetServerType=slave
##只连接主机进行读写操作
jdbc:opengauss://node1,node2,node3/database?autoBalance=false&targetServerType=master

OpenGauss数据库在一主多备的架构下,当主节点宕机的时候通过自主寻主的机制,找到主备切换后的新主。通过JDBC连接中的配置参数hostRecheckSecond,当主机状态发生更改时再次检查主机状态,快速地找到新的主机并恢复连接,默认值为10秒。JDBC连接流程如下:

在这里插入图片描述

  1. 设置参数开启targetServerType=xx。
  2. 判断输入的主机列表是否已经加入了候选主机列表中,如果不存在hostStatusMap中并且更新时间间隔超过10s(hostRecheckSecond)同时HostStatus状态也和现在一致,这时直接加入候选主机列表。
  3. 对列表进行遍历查找对应的节点信息,如果找到了,通过knownStatus查看状态是否一致,一致就执行sql查询语句,之后更新全局变量hostStatusMap及局部变量konwnStatus中存储。
  4. 当前操作的节点状态如果与用户选择的节点状态一致则返回主机连接,之后用户可以根据连接进行读或者写操作。
7、TiDB数据库

在TiDB数据库中读写分离通过follower read机制实现的,follower read是将TiKV读负载从Region的leader副本上offload到follower副本的负载均衡机制,以提升TiDB集群的吞吐能力并降低leader负载。TiDB的Follower Read功能开启通过变量tidb_replica_read配置:

set [session | global] tidb_replica_read = '<目标值>';
  • leader:默认值,将所有的读操作都发送给leader副本处理。
  • follower :选择Region的follower副本完成所有的数据读操作。
  • leader-and-follower:可以选择任意副本来执行读操作,此时读请求会在leader和follower之间负载均衡。
  • prefer-leader:优先选择leader副本执行读操作。当leader副本的处理速度明显变慢时,例如由于磁盘或网络性能抖动,TiDB将选择其他可用的follower副本来执行读操作。
  • closest-replicas:优先选择分布在同一可用区的副本执行读操作,对应的副本可以是leader或follower。如果同一可用区内没有副本分布,则会从leader执行读操作。
  • closest-adaptive:当一个读请求的预估返回结果大于或等于变量 tidb_adaptive_closest_read_threshold 的值时,TiDB会优先选择分布在同一可用区的副本执行读操作。
  • learner:选择learner副本执行读取操作。在读取时,如果当前Region没有learner副本,TiDB会报错。

Tidb数据库的Follower Read在实现机制上是follower节点使用Raft ReadIndex协议确保当前读请求可以读到当前leader上已经commit的最新数据。因此在TiDB层面,Follower Read只需根据负载均衡策略将某个Region的读取请求发送到follower节点。

8、总结

以上是几种国产数据库的读写分离实现,各个数据库厂商根据不同的业务场景在不同程度上实现了读写分离的功能,对比如下所示:

在这里插入图片描述

总体上而言,PolarDB、GaussDB和GoldenDB在读写分离的功能上更为完善,考虑到实例级别、SQL级别以及对事务的影响,还有在主备时延超过阈值时的处理。


参考资料:

  1. https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000819334
  2. https://help.aliyun.com/zh/polardb/polardb-for-mysql/user-guide/read-or-write-splitting-2
  3. https://support.huaweicloud.com/usermanual-gaussdbformysql/gaussdbformysql_11_0017.html
  4. https://www.goldendb.com/#/docsIndex/docs/instruction_TenantManagement
  5. https://cloud.tencent.com/privatecloud/document/123248530626207744/12325495623387545
  6. https://zhuanlan.zhihu.com/p/445545196
  7. https://docs.pingcap.com/zh/tidb/stable/follower-read#follower-read

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/722913.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

助力低空经济-eVTOL/无人机ADS-B航管应答机选型指南

一、低空经济概述 “低空经济”在今年全国两会首次写入政府工作报告。近日&#xff0c;工业和信息化部、科学技术部、财政部、中国民用航空局印发《通用航空装备创新应用实施方案&#xff08;2024—2030年&#xff09;》&#xff0c;提出到2030年&#xff0c;推动低空经济形成…

c语言回顾-结构体(2)

前言 前面讲了结构体的概念&#xff0c;定义&#xff0c;赋值&#xff0c;访问等知识&#xff0c;本节内容小编将讲解结构体的内存大小的计算以及通过结构体实现位段&#xff0c;话不多说&#xff0c;直接上干货&#xff01;&#xff01;&#xff01; 1.结构体内存对齐 说到计…

自建消息推送工具 Gotify 实现消息私有化通知

本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 之前分享了如何通过 Webhook 将 VPS 与 NAS 上部署的应用消息推送到钉钉、飞书、企业微信,但是对于部分用户来说,可能因为以下种种原因,不方便使用常见的办公 IM 软件来进行消息推送: 消息涉及隐私敏感信息,不希…

11.6.k8s实战-节点扩缩容

目录 一&#xff0c;需求描述 二、集群缩容-节点下线 1&#xff0c;节点下线案例说明 2&#xff0c;查看现有节点 3&#xff0c;查看所有名称空间下的pod ​编辑4&#xff0c;驱逐下线节点的pod 5&#xff0c;驱逐后再次查看pod 6&#xff0c;驱逐pod后再次查看节点信息…

新书速览|Ubuntu Linux运维从零开始学

《Ubuntu Linux运维从零开始学》 本书内容 Ubuntu Linux是目前最流行的Linux操作系统之一。Ubuntu的目标在于为一般用户提供一个最新的、相当稳定的、主要由自由软件构建而成的操作系统。Ubuntu具有庞大的社区力量&#xff0c;用户可以方便地从社区获得帮助。《Ubuntu Linux运…

熟练一种编程语言再学另一种语言时,叠的是buff还是debuff?

在大多数情况下&#xff0c;尤其是对于广泛使用的高级编程语言&#xff0c;它们之间存在正向的相互促进作用&#xff0c;熟练使用一种语言后再去学习另一种语言&#xff0c;大概率能叠个buff。 首先&#xff0c;学习编程语言的基础是通用的&#xff0c;比如软硬件和网络基础、算…

iOS原生APP开发的技术难点

iOS原生APP开发的技术难点主要体现在以下几个方面&#xff0c;总而言之&#xff0c;iOS原生APP开发是一项技术难度较高的工作&#xff0c;需要开发者具备扎实的编程基础、丰富的开发经验和良好的学习能力。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xf…

shell中的条件判断

在Linux操作系统中如何是用条件判断语句&#xff0c; 如上图所示&#xff0c;先定义一个变量变量值&#xff0c;再使用test $a hello来判断式子的正确与否&#xff0c;当结果正确的时候返回0&#xff0c;当结果错误时候结果返回1&#xff0c;可以是用echo $? 来获取并打印输出…

AI大模型会如何颠覆手机?

导语&#xff1a;大模型在手机端的落地&#xff0c;不仅仅是AI进入人类生活的开始&#xff0c;也是行业发生颠覆&#xff0c;新老巨头进行更替的时刻。 将大模型变小&#xff0c;再塞进手机&#xff0c;会给人们的生活带来怎样的影响&#xff1f; 最近&#xff0c;荣耀成为了…

数据结构历年考研真题对应知识点(单链表、双链表、循环链表)

目录 2.3线性表的链式表示 2.3.1单链表的定义 【单链表的应用(2009、2012、2013、2015、2016、2019)】 2.3.2单链表上基本操作的实现 【单链表插入操作后地址或指针的变化(2016)】 2.3.3双链表 【双链表中插入操作的实现(2023)】 【循环双链表中删除操作的实现(2016)】 …

Ubuntu20.04部署Qwen2.openvino流程

下载代码 里面包含依赖 git clone https://github.com/OpenVINO-dev-contest/Qwen2.openvino.gitpython环境配置 创建虚拟环境 conda create -name qwen2openvino python3.10 conda activate qwen2openvino安装依赖 pip install wheel setuptools pip install -r requirem…

C# OCCT Winform 选中模型改变状态

选中状态设置 _context new AIS_InteractiveContext(_viewer);var selectionDrawer new Prs3d_Drawer();selectionDrawer.SetColor(Colors.Selection);selectionDrawer.SetDisplayMode(1);selectionDrawer.SetTransparency(0.1f);_context.SetSelectionStyle(selectionDrawe…

基于PHP的民宿管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的民宿管理系统 一 介绍 此民宿管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端jquery.js和echarts.js。系统角色分为用户和管理员。用户可以在线浏览和预订民宿&#xff0c;管理员登录后台进行相关管理等。(在系统…

【TB作品】MSP430G2553,单片机,口袋板, 单相交流电压、电流计设计

题5 单相交流电压、电流计设计 设计基于MSP430的单相工频交流电参数检测仪。交流有效值0-220V&#xff0c;电流有效值0-40A。电压、电流值经电压、电流传感器输出有效值为0-5V的交流信号&#xff0c;传感器输出的电压、电流信号与被测电压、电流同相位。 基本要求如下 &#xf…

前端网站(二)-- 菜单页面【附源码直接可用】

菜单页面 开篇&#xff08;请大家看完&#xff09;&#xff1a;此网站写给挚爱&#xff0c;后续页面还会慢慢更新&#xff0c;大家敬请期待~ ~ ~ 轻舟所编写这个前端框架的设计初衷&#xff0c;纯粹是为了哄对象开心。除此之外&#xff0c;并无其它任何用途或目的。 此前端框…

基于Java的二手手机回收平台系统

开头语&#xff1a; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JavaJSPServlet 工具&#xff1a;IDEA/Eclipse、Navicat、Maven 系统展…

【C++提高编程-10】----C++ STL常用拷贝和替换算法

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

Chat-TTS chat-tts-ui 实机部署上手测试!Ubuntu服务器实机 2070Super*2 8GB部署全流程

项目介绍 开源的项目&#xff0c;感谢各位大佬的贡献&#xff01; 官方介绍&#xff1a;一个简单的本地网页界面&#xff0c;使用ChatTTS将文字合成为语音&#xff0c;同时支持对外提供API接口。A simple native web interface that uses ChatTTS to synthesize text into spe…

物联网技术-第3章物联网感知技术-3.3传感技术

目录 1.1什么是传感器 1.1.1生活中的传感器 1.1.2人的五官与传感器 1.1.3传感器的定义 1.1.4传感器的组成 1.2传感器的特性 1.2.1传感器的静态特征 1、灵敏度&#xff08;静态灵敏度&#xff09; 2.精度 3.线性度&#xff08;非线性误差&#xff09; 4.最小检测量&a…

SSRF服务端请求伪造

SSRF服务端请求伪造 SSRF漏洞原理 ​ SSRF(Server-Side Request Forgery:服务器端请求伪造) 一种由攻击者构造形成由服务端发起请求的一个安全漏洞;一般情况下&#xff0c;SSRF攻击的目标是从外网无法访问的内部系统。&#xff08;正是因为它是由服务端发起的&#xff0c;所…