分库分表中间件的高可用实践讲解

ShardingSphere-Proxy分库分表实战与优化指南 分布式数据库中间件是解决海量数据存储与查询的关键技术,其核心原理是通过分库分表将数据分散到多个物理节点。ShardingSphere-Proxy作为透明化访问的实现方案,采用独立进程架构模拟数据库协议,使开发者无需感知底层数据分布。该技术通过SQL解析、路由引擎和结果归并等模块,有效解决单表数据量过大导致的性能瓶颈问题。在电商、金融等高并发场景中,配合Docker等容器化部署方式,能快速实现水平扩展。本文重点解析分片算法配置、分布式事务处理等实战技巧,并给出JVM调优、Prometheus监控等生产级优化方 阅读详情

前言

分库分表中间件在我们一年多的锤炼下,基本解决了可用性和高性能的问题(只能说基本,肯定还有隐藏的坑要填),问题自然而然的就聚焦于高可用。本文就阐述了我们在这方面做出的一些工作。

哪些高可用的问题

作为一个无状态的中间件,高可用问题并没有那么困难。但是尽量减少不可用期间的流量损失,还是需要一定的工作的。这些流量损失主要分布在:

(1)某台中间件所在的物理机突然宕机。      
(2)中间件的升级和发布。

由于我们的中间件是作为数据库的代理提供给应用的,即应用把我们的中间件当做数据库,如下图所示:


所以出现上述问题后,业务上很难通过重试等操作去屏蔽这些影响。这就势必需要我们在底层做一些操作,能够自动的感知中间件的状态从而有效避免流量的损失。

中间件所在物理机宕机的情况

物理机宕机其实是一种常见现象,这时候应用一瞬间就没了响应。那么跑在上面的sql肯定也是失败了的(准确来说是未知状态,除非重新查询后端数据库,应用无法得知准确的状态)。这部分流量我们肯定是无法挽救。我们所做的是在client端(Druid数据源)能够快速的发现并剔除宕机的中间件节点。

发现并剔除不可用节点

通过心跳去发现不可用节点

自然而然的我们通过心跳来探查后端中间件的存活状态。我们通过定时创建一个新连接ping(mysql的ping)一下然后立马关闭来做心跳(这种做法便于我们区分正常流量和心跳流量,如果通过保持一个连接然后一直发送类似select '1'的sql这种方式的话区分流量会稍微麻烦点)。 


为了防止网络抖动造成的偶发性connect失败,我们在三次connect都失败后才判定某台中间件处于不可用状态。而这三次的探活却延长了错误感知时间,所以我们三次connect的时间间隔是指数级衰减的,如下图所示: 
为何不在第一次connect失败后,连续发送两次connect呢?可能考虑到网络的抖动可能会有一个时间窗口,如果在时间窗口内连续发了3次,出了这个时间窗口网络又okay了,那么会错误的发现后端某节点不可用了,所以我们就做了指数级衰减的折衷。

通过错误计数去发现不可用节点

上述的心跳感知始终有一个时间窗口,当流量很大的时候,在这个时间窗口内使用这个不可用节点的都会失败,所以我们可以使用错误计数去辅助不可用节点的感知(当然这个手段的实现还在计划中)。 


这边有一个注意的点是,只能通过创建连接异常来计数,并不能通过read timeout之类的来计算。原因是,read timeout异常可能是慢sql或者后端数据库的问题导致,只有创建连接异常才能确定是中间件的问题(connection closed也可能是后端关闭了这个连接,并不代表整体不可用),如下图所示:

一个请求使用若干个连接导致的问题

由于我们需要保证事务尽可能小,所以在一个请求里面多条sql并不使用同一个连接。在非事务(auto-commit)情况下,运行多少条sql就从连接池里面取出多少连接,并放回。保证事务小是非常重要的,但是这在中间件宕机的时候会导致一些问题,如下图所示: 


如上图所示,在故障发现窗口期中(即还没有确定某台中间件不可用时),数据源是随机选择连接的。而这个连接就有一定1/N(N为中间件个数)的概率命中不可用中间件导致一条sql失败进而导致整个请求失败。我们做一个计算:

假设N为8,一个请求有20条sql,
那么在这个期间每个请求失败的概率就为(1-(7/8)的20次方)=0.93,
即有93%的概率会失败!       

更为甚者,整个应用集群都会经历这个阶段,即每台应用都有93%的概率失败。 一台中间件宕机导致整个服务在十几秒内基本所有请求基本都失败,这是不可忍受的。

Linux服务器开发高级架构师系统学习视频链接:C/C++Linux服务器开发/Linux后台架构师/进阶学习视频

关于中间件学习视频资料获取点击:中间件学习资料。

采用sticky数据源解决问题

由于我们不能瞬间发现并确认中间件不可用,所以这个故障发现窗口肯定存在(当然,错误计数法会在很大程度上缩短发现时间)。但理想状况下,宕机一台,只损失1/N的流量就好了。我们采用了sticky数据源解决了这个问题,使得在概率上大致只损失1/N的流量,如下图所示: 


而配合错误计数的话,总流量的损失会更小(因为故障窗口短)
如上图所示,只有在故障时间内随机选择到中间件2(不可用)的请求才会失败,再让我们看下整个应用集群的情况。 
只有sticky到中间件2的请求流量才有损失,由于是随机选择,所以这个流量的损失应用在1/N。

中间件升级发布过程中的高可用

分库分表中间件的升级发布不可避免。例如bug fix以及新功能添加等都需要重启中间件。而重启的时间也会导致不可用,与物理机宕机的情况相比是其不可用的时间点是可知的,重启的动作也是可控的,那么我们就可以利用这些信息去做到流量的平滑无损。

让client端感知即将下线

在笔者所知的很多做法中,让client端感知下线是引入一个第三方协调者(例如zookeeper/etcd)。而我们并不想引入第三方的组件去做这个操作,因为这又会引入zookeeper的高可用问题,而且会让client端的配置更加复杂。平滑无损的大致思路(状态机)如下图所示: 

让心跳流量感知下线而正常流量保持

我们可以复用之前client端检测不可用的逻辑,即让心跳的新建连接失败,而正常请求的新建连接成功。这样,client端就会认为Server不可用,而在内部剔除调这个server。由于我们只是模拟不可用,所以已经建立的连接和正常新建的连接(非心跳)都是正常可用的,如下图所示:


心跳连接的创建在server端可以通过其第一条执行的是mysql的ping而正常流量第一条执行的是一条sql来区分(当然我们采用的Druid连接池在新建连接成功以后也会ping一下,所以采用了另一种方式区分,这个细节在这里就不阐述了)。

三次心跳失败后,client端判定Server1失败,需要将连接到server1的连接销毁。其思路是,业务层用完连接返回连接池的时候,直接给close掉(当然这个是简单的描述,实际操作到Druid数据源也是有细微的差别的)。


由于配置了一个connection最长保持时间,所以在这个时间之后肯定会对Server1的连接数为0 由于线上流量也不低,这个收敛时间是比较快的(进一步的做法,其实是主动去销毁,不过我们尚未做这个操作)。

如何判定下线Server再也没有流量

在上述小心翼翼的操作之后,在Server1下线的过程中,是不会有流量损失的。但是我们在Server端还需要判定何时不会再有新的流量,这个判定标准即是Server1没有任何一个client端的连接。 这也是上面我们在执行完sql后销毁连接从而可以让连接数变为0的原因,如下图所示: 


当连接数为0后,我们就可以重新发布Server1(分库分表中间件)了。对于这一点,我们写了个脚本,其伪代码如下所示:

while(true){
	count =`netstat -anp | grep port | grep ESTABLISHED | wc -l`
	if(0 == count){
		// 流量已经为0,关掉服务器
		kill Server
		// 发布升级服务器
		public Server
		break
	}else{
		Sleep(30s)
	}
}

将这个脚本接入发布平台,即可进行滚动式上下线了。
现在可以解释下recover_time为何要较长了,因为新建连接也会导致脚本计算出来的 connection count数量增加,所以需要一个时间窗口不去建立心跳,从而能让这个脚本顺利运行。

recover_time其实是非必要的

如果我们将心跳创建的端口号和正常流量的端口号分开,是不需要recover_time的,如下图所示: 


采用这种方案的话,会在很大程度上降低我们client端代码的复杂度。
但是这样无疑又给client端增加了一个新的配置,对使用人员就又多了一个负担,还得在网络上多一次开墙的操作,所以我们采取了recover_time的方案。

中间件的启动顺序问题

前面的过程是一个优雅下线的过程,但我们发现我们的中间件才上线的时候在某些情况下也不会优雅。即在中间件启动时候,如果对后端数据库刚建立的连接建立上去后由于某些原因断开了,会导致中间件的reactor线程卡住一分钟左右,这段时间无法服务,造成流量损失。所以我们在后端数据库连接全部创建成功后,再启动reactor的accept线程从而接收新的流量,从而解决这一问题,如下图所示: 

数据优化——分库分表(三)中间件讲解 分库分表中间件的类型,PROXY模式,CLIENT模式,sharding 阅读详情

相关推荐

分库分表中间件-Mycat

一、分库分表概念 1.为什么要使用分库分表? 移动互联网时代,海量的用户每天产生海量的数量,比如:用户表、订单表、交易流水表。 以支付宝用户为例,8亿;微信用户更是10亿。 订单表更夸张,比如美团外卖,每天都是几千万的订单。 淘宝的历史订单总量应该百亿,甚至千亿级别,这些海量数据远不是一张表能Hold住的。 事实上MySQL单表可以存储10亿级数据,只是这时候性能比较差,业界公认MyS...

u011640572的博客 717

关于分布式系统的高可用总结(不限于某个中间件)

纵观现在使用的分布式架构,不管服务于什么业务形式,高可用都是绕不开的一个话题,我把高可用分为自己业务应用的高可用(业务开发同学来保证)和中间件(nosql数据库,关系型数据库,消息中间件)的高可用,高可用方案是互通的,可以相互借鉴。

m0_69874463的博客 572

分库分表中间件Sharding-JDBC详解

分库分表中间件Sharding-JDBC详解1. 分库分表概述1.1 为什么需要分库分表1.2 分库分表的方式1.2.1.垂直分表1.2.2.垂直分库1.2.3.水平分库1.2.4.水平分表1.3 分库分表问题分析1.3.1 事务一致性问题1.3.2 跨节点关联查询1.3.3 跨节点分页、排序函数1.3.4 主键避重1.3.5 公共表2. Sharding-JDBC详解2.1 Sharding-JDBC简介2.2 Sharding-JDBC性能对比2.3 Sharding-JDBC原理分析3. 实现验证3.

靖节先生的博客 3315

高可用中间件之Keepalived的原理介绍与部署实践

Keepalived是一个用c语言编写的路由软件。这个实验的主要目标是为Linux系统和基于Linux的基础设施提供简单而健壮的负载平衡和高可用性工具。本文介绍了其基本原理以及讲解了部署单vip和双vip的详细步骤

fruitless的博客 1479

分库分表常见中间件介绍和ShardingSphere极速认知+实战内容

大话业界常见数据库分库分表中间件介绍Cobar(已经被淘汰)TDDL: 淘宝根据自己的业务特点开发了TDDL(Taobao Distributed Data Layer),它是基于JDBC规范,没有Server,以client-jar的形式存储,引入项目即可使用。开源的功能比较少,阿里内部使用为主。MyCat: Java语言编写的Mysql数据网络协议开源的中间件,它的前身是Cobar,遵守Mys...

yyyy11119的博客 4287

学习笔记:分库分表之中间件Mycat实战

点关注,不迷路! 本文已整理成文档! 文章目录1.数据切分概念垂直切分水平切分2.什么是Mycat应用场景3.Mycat中的核心概念及配置核心概念安装与配置linux安装4. MyCat配置配置Mycat环境参数配置Mycat逻辑库与用户配置逻辑库(schema)逻辑表配置配置分片(dataNode)配置物理库分片映射(dataHost)表切分规则配置5.Mycat读写分离实战6.Mycat 全局序列号 最近也整理了一些资料!分享给需要面试刷题的朋友,也祝愿大家顺利拿到自己想要的offer,这份资料主要.

豆汁 5236

消息中间件如何实现高可用

消息中间件实现高可用的方式有很多种,常见的方法包括:

weixin_43106895的博客 499

信息隐藏 数字图像空域隐写与分析技术的实现

【代码】信息隐藏 数字图像空域隐写与分析技术的实现。

Yungoal的博客 470

高级运维学习(九)高可用中间件的配置与实现

Keepalived检测每个服务器节点状态,当服务器节点异常或工作出现故障, Keepalived将故障节点从集群系统中剔除,故障节点恢复后,Keepalived再将其加入到集群系统中所有工作自动完成,无需人工千预

2301_79227925的博客 918

V-rep机器人仿真(Win10):UR5+RG2+Kinect+YOLOV3+DDPG+Pytorch(第四部分:YOLOV3图像识别)

这是一个V-rep机器人仿真实验,较为简单,适合初学者在入门图像识别、机器学习、机器人学的内容时进行学习与训练。 实验涉及的内容有:V-rep机器人仿真,YOLOV3图像识别,强化学习DDPG,UR5机械臂及RG2机械手,Kinect摄像头。 使用环境:Win10,Pytorch0.4,V-rep 整个实验一共由多篇文章组成,本文是第四部分。 第四部分:YOLOV3图像识别 文章目录第四部分:YO...

weixin_42158966的博客 5838

CentOS7无网环境实战:MySQL8.0完整离线安装与避坑指南(附依赖包下载)

本文详细介绍了在CentOS7无网环境下MySQL8.0的完整离线安装流程,包括依赖包获取、系统预处理、MySQL二进制安装、服务配置与优化等关键步骤。特别针对离线安装的特殊需求,提供了从依赖包下载到服务调优的全链路解决方案,帮助用户在企业内网或隔离环境中高效部署MySQL数据库。

bush的博客 176

七大主流中间件高可用方案全解析:架构设计原理与实战指南

本文系统梳理了七大主流中间件的高可用实现方案:MySQL基于MHA/MGR实现主从复制与自动切换;Nacos采用Raft协议构建自愈集群;Redis通过哨兵和集群模式分别应对主从切换与水平扩展需求;RocketMQ利用NameServer解耦路由管理;Elasticsearch通过分片副本机制实现数据冗余;Nginx借助Keepalived+VIP完成主备切换;RabbitMQ则采用镜像队列保证数据一致性。文章对比分析了各方案的技术特点、适用场景及优劣,并指出高可用设计需结合具体业务需求。

qq_46371374的博客 1651

【Halcon】双目立体视觉引导机械手有序抓取,案例分享

本文介绍了一个基于双目视觉的工件定位与抓取系统。该系统使用两个工业相机组成双目视觉系统,通过标定获取相机参数,采用模板匹配算法识别任意摆放且可能交叠的工件。重点阐述了三维坐标获取方法,特别是通过Z方向高度实现有序抓取的策略。文章详细说明了系统搭建、双目标定、模板创建等关键步骤,并展示了特征点匹配和定位结果。该案例为初学者和开发者提供了双目视觉系统的基本实现参考,展示了机器视觉与机械手协同工作的典型应用场景。

机器视觉从业者 2490

实践为主,理论够用,腾讯高工手码MySQL高阶宝典震撼开源

MySQL 提到MySQL大家脑子里首先出现的肯定是MySQL优化,我们都知道mysql数据库优化是多方面的,原则是减少系统的瓶颈,减少资源的占用,增加系统反应的速度。一般我们是从MySQL 5.7版本的存储引擎增强,硬件、操作系统、配置参数优化、设计规范优化几个层面来全面优化MySQL服务器。 但对于一个企业级的系统来说,优化MySQL服务器固然重要,但数据库系统的可用性也是不能抛开的。数据库系统一旦出现问题无法提供服务,所有系统都可能无法继续工作,而不像软件中部分系统出现问题可能影响的仅仅只是某个功

m0_65569079的博客 156

银河麒麟V10+QT6.0中文输入法环境搭建全攻略(附镜像加速技巧)

本文提供了在银河麒麟V10操作系统上为QT6.0搭建中文输入法环境的完整实战指南。文章详细介绍了从系统准备、镜像源优化、QT6安装器获取与加速安装,到编译Fcitx5输入法插件依赖库、深度配置环境变量与项目的全流程。重点分享了使用国内镜像源加速安装的技巧,解决了国产化开发中QT应用无法输入中文的常见难题,旨在帮助开发者快速构建稳定高效的开发环境。

weixin_29204749的博客 394

Altium Designer (AD) 设计软件高频面试题及参考答案(3万字长文)

在Altium Designer(AD)中,设计复用是一种关键的策略,它允许设计师在多个项目中重复使用经过验证的设计元素,如原理图符号、PCB布局、元器件封装和设计规则集。在Altium Designer (AD) 中,手动布线和交互式布线是PCB设计中常见的两种布线模式,它们提供了设计师对布线路径的直接控制,特别是在处理复杂或关键信号路径时尤为有用。在Altium Designer (AD) 中进行电路级仿真是一项重要的设计验证步骤,它允许设计师在实际制造之前对电路的行为进行预测和分析。

大模型大数据攻城狮的专栏 4783

36w字!腾讯高工甩出MySQL速成手册,基础架构调优三飞

MySQL MySQL作为目前最受欢迎的数据库,一直以来就被很多的企业及开发者所青睐。它与其他数据库相比,不仅易学易用而且拥有许多成熟的高可用架构方案!大势所趋之下不管你是软件开发和数据库管理人员都必须要搞懂MySQL!想要精通MySQL你就必须知道如何设计一个高可用可扩展的企业级MySQL数据库集群以及高性能高可用MySQL调优方法。但大多数人对于MySQL的学习却不知道如何入手,对MySQL也是知其然而不知其所以然,那么怎么学?不要这不还有互联网雷锋(小编我)嘛! 今天要与大家介绍的文档出自一位腾讯

Java圈全能架构师的博客 392

如何使用PostgreSQL数据库进行数据仓库的ETL操作

本文旨在为数据工程师、数据库管理员和分析师提供使用PostgreSQL进行数据仓库ETL操作的全面指南。ETL流程的基本原理PostgreSQL在ETL中的独特优势实际ETL实现的技术细节性能优化和最佳实践常见问题的解决方案首先介绍ETL和PostgreSQL的基本概念然后深入探讨核心技术和实现方法接着提供实际案例和代码示例最后讨论优化技巧和未来趋势ETL:提取(Extract)、转换(Transform)、加载(Load)的缩写,描述数据从源系统移动到目标数据仓库的过程。

2502_91592937的博客 873

介绍一下分库分表

数据平滑迁移 业务不能停服,数据不能丢失 双写顺序错误导致数据不一致;这个问题其实很典型。热点数据问题 数据倾斜导致部分分片压力过大 某个用户 / 商家订单量占比超过 50% 1. 热点数据单独分片2. 读写分离3. 缓存热点数据 提前识别热点数据;看你简历里写了海量数据优化经验,那咱先聊个场景:假设现在有个电商订单表,数据量干到 2 亿了,查询越来越慢,数据库连接池动不动就满了。跨库关联查询 1. 字段冗余2. 数据同步到 ES 做聚合查询3. 应用层多次查询 避免跨库 JOIN,用 ES 做复杂查询。

dc6p3Swvf的博客 196

13. MIC配置

恒玄BES2700,支持3个MIC。

雪飞_海 928

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

MySQL之从单机到集群

SLI: service level indicator,即单位时间内请求得到正常响应的百分比SLO:service level object,是为了更好的量化SLO而定义的指标,表示单位时间内服务可用时长的百分比,也就是我们常见到的几个9SLA:servcei level aggrement,是一个保证达到某SLO的承诺。服务提供企业,如阿里云,在与客户端签订协议时,保证达到某个SLO,这个协议的SLA,当达不到SLO时,做出怎样的赔偿等,如下模拟协议(瞎写的啊!

wang0907的博客 1173

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

MySQL数据库运维进阶:从高可用架构到分库分表的实战指南

数据库高可用性是保障业务连续性的核心,其基础在于主从复制机制。该机制通过二进制日志实现数据异步同步,但默认的异步复制存在数据丢失风险,因此衍生出半同步复制、组复制等技术以提升数据一致性。理解复制原理不仅有助于构建稳定的数据同步链路,更是实现读写分离、负载均衡等架构扩展能力的前提。在实际生产环境中,主从延迟是常见挑战,其根因可能涉及网络瓶颈、SQL执行效率或并行复制配置。深入排查这些问题需要综合运用监控工具与性能分析手段。随着数据规模增长,单机性能瓶颈显现,此时需从SQL优化转向架构拆分。分库分表作为应对海量

weixin_28726671的博客 249

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

【ShardingJDBC】【笔记】---- ShardingSphere 入门到精通

一套开源的分布式数据库中间件解决方案有三个产品:Sharding-JDBC 和 Sharding-Proxy定位为关系型数据库中间件,合理在分布式环境下使用关系型数据库操作Apache ShardingSphere(Incubator) 是一套开源的分布式数据库中间件解决方案组成的生态圈,它由 Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar(规划中)这 3 款相互独立,却又能够混合部署配合使用的产品组成。

记录生活 1326

分库分表基本概念讲解

分库分表之后,比如我们要插入一条数据,该插入到哪一张子表中呢,查询某条数据又该从哪一张子表查呢?这有很多的中间件来帮我们完成这些事情阿里的TDDL,DRDS和cobar开源社区的民间组织的MyCAT360的Atlas按照架构类型划分Client模式Proxy模式。

qq_46248151的博客 1007

为什么要分库分表?用过哪些分库分表中间件?不同的分库分表中间件都有什么优点和缺点?...

  为什么要分库分表(设计高并发系统的时候,数据库层面该如何设计)?用过哪些分库分表中间件?不同的分库分表中间件都有什么优点和缺点?如何对数据库如何进行垂直拆分或水平拆分的?   其实这块肯定是扯到高并发了,因为分库分表一定是为了支撑高并发、数据量大两个问题的。而且现在说实话,尤其是互联网类的公司面试,基本上都会来这么一下,分库分表如此普遍的技术问题,不问实在是不行,而如果你不知道那也实在...

weixin_30896763的博客 419

学习分库分表的前置知识:高可用系统架构理论与实践

一致性 (Consistency):所有节点必须同时返回相同的数据。可用性 (Availability):非故障节点在合理时间内返回合理的响应。分区容错性 (Partition Tolerance):即使网络分区发生,系统仍然能够正常工作。构建高可用系统架构是一项复杂的任务,涉及读写分离、CAP 定理的应用以及数据分片等多种技术手段。通过合理的架构设计和工具选型,可以在保障系统稳定性的同时,提升性能和可扩展性。

lfeishumomol的博客 934
上一篇: Linux上TCP的几个内核参数调优
下一篇: DPDK uio 分析 丨DPDK的优势及学习总结
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值