镇江专业网站制作,简单的网站建设公司的模板,各大公司开源网站,html5网站模板移动端写在前面
本文一起看下MySQL是单机存在的问题#xff0c;以及为了解决这些问题所提出的各种解决方案。
1#xff1a;从单机到集群
并非业务发展初期我们就直接使用集群来支撑业务#xff0c;而是简单的使用单机版本#xff0c;但是随着业务的发展#xff0c;单机的各种…写在前面
本文一起看下MySQL是单机存在的问题以及为了解决这些问题所提出的各种解决方案。
1从单机到集群
并非业务发展初期我们就直接使用集群来支撑业务而是简单的使用单机版本但是随着业务的发展单机的各种问题就会一点一点的暴露出来那么单机都有哪些问题呢主要如下
1:容量有限扩容困难myisam最大256TInnodb最大64T
2读写压力过大即QPS过高时会严重影响业务
3可用性不足宕机导致服务不可用自然对于每个问题目前都有对应的解决方案分别看下。
1:容量有限扩容困难 -》 分库分表
2读写压力过大即QPS过高时会严重影响业务 -》主从复制解决
3可用性不足宕机导致服务不可用 -》故障转移主从切换参考下图
接下来分别看下。
2主从复制
通过主从复制解决读写压力大问题。
2.1主从复制发展历史
1:2000年3.23版本引入 22002年4.0.2版本引入relay log分离处io线程和sql线程 32010年引入半同步复制 。 4:2016年5.7版本引入了mrgMySQL group replication
2.2主从复制的原理
主从复制需要依赖于binlog文件binlog文件由MySQL server层负责写入作用就是数据备份以及复制从库使用io线程从主库中拉取日志并将日志写到relay log中sql thread负责重放binlog中的修改到从库从而实现数据复制参考下图
其中binlog支持的格式 有三种statementrowmixed其中statement是记录原始的执行sql这种方式可能会导致从库同步时的数据不一致不建议使用row会详细记录影响到每一行可以保证同步数据的正确性mix混合二者。生产环境建议使用row。
以上是传统的异步复制以及半同步复制MySQL在5.7版本还引入了mrg即多节点组成一个集群并且多节点支持同时写入支持动态伸缩内部使用paxos分布式协议但由于其复杂性以及稳定性不足bug多等问题目前实际使用的用户还并不多所以MySQL的复制发展历程大概为主从异步复制-主从半同步复制-mgr其中主从异步复制和主从半同步复制都是基于主从的架构的但mgr可以理解为多主架构了支持多写但是要解决的问题都是一致的即解决读写压力大问题。 这里mgr可以作为了解的只是重点还是顺着主从复制这条线来学习因为这才是当前的主流使用方式。 2.3主从复制不足
1主从复制延迟
2无法解决高可用
3应用测需要配合读写分离框架增加编码的复杂度2.4主从复制应用在业务中
方案1直接在程序中配置多个数据源然后在service层根据操作的类型选择不同的数据源写走主读走从。 方案2基于AbstractRoutingDatasource自定义路由数据源写走主读走从。
以上方案1和方案2都存在写完读问题比如在一个事务中先走主库更新了id1的数据假设修改同步到从库需要10ms但3ms后程序继续执行走从库读取了id1的数据此时就会出现查不到的情况这就比较奇怪了问题的根源在于在一个事务中在发生了写操作之后还切换数据源如果是发生写之后不再进行切换数据源的动作写完读的问题就解决了这就引出了我们的方案3.
方案3shardingsphere-jdbc master-slave 。
以上的方案对业务代码都是有侵入性的想要解决这个问题可以考虑方案4。
方案4数据库中间件mycat等。 这种方案不需要修改应用程序但部署和运维的成本比较高且有额外的机器成本。
3高可用
3.1为什么要高可用
提供failover的能力当主节点宕机时整个集群只会抖一下之后就恢复正常这个抖一下其实就是主从切换。这里变为新主的节点又可以分为冷备份和热备份冷备份即平时是用不到的等到主挂了之后顶上去热备份就是平时也对外提供读服务在主宕机之后变为新主对外提供读写服务。 冷备份就好像漂亮国副总统平时啥也不干充当总统的小跟班替总统发个言什么的但是当总统挂了或者被弹劾下台之后副总统就会变为总统瞬间拥有无限大的权利。 3.2高可用常见的策略
根据系统对高可用要求级别的不同有不同的策略主要如下
策略1多个实例不在一个主机/机架上 策略2跨机房部署 策略3两地三中心部署机房距离800公里以上
一个机房一般会有几十个甚至上百上千个机架相同的机架可能使用同一根网线和电源而一个机架上可以有很多的刀片服务器主机每个刀片服务器主机又可以切分处很多的虚拟主机再者机房可以分布在不同的区域如下图
3.2高可用的定义和指标
高可用的可用性也有高有低该如何描述呢自然是单位时间内提供服务的时长这个时间越长则可用性就越好主要有如下专业术语
SLI: service level indicator,即单位时间内请求得到正常响应的百分比
SLOservice level object,是为了更好的量化SLO而定义的指标表示单位时间内服务可用时长的百分比也就是我们常见到的几个9
SLAservcei level aggrement,是一个保证达到某SLO的承诺。服务提供企业如阿里云在与客户端签订协议时保证达到某个SLO这个协议的SLA当达不到SLO时做出怎样的赔偿等如下模拟协议瞎写的啊我阿里云承诺如果服务SLO达不到2个9则赔偿客户《大帅哥公司》一百万元人民币特此声明。所以这里最重要的其实就是SLO了其通过几个9来量化服务的可用性如下 1年365天8,760小时 2个9(99%)8,760小时*(1-99%)87.6小时即每年有87.6小时服务是不可用的
3个98,760小时*(1-99.9%)8.76小时即每年有8.76小时服务是不可用的
4个98,760小时*(1-99.99%)0.876小时52.6分钟即每年有52.6分钟服务是不可用的几个9的计算方法为1-百分比然后取以10为底的对数之后取绝对值如99%就是lg1-0.99|-2|2,所以就是2个9。99.9%就是lg(1-0.999)|-3|3所以就是3个9。 3.2高可用的方案
3.2.1手动切换
当出现问题时手动该配置手动修改程序完成切换这种方式缺点如下
1:比较废人
2修复时间不可控影响业务
3可能导致数据不一致其中3是比较严重的一个问题因为我们无法确认当前手动提升为主库的从库是否完成了和主库的数据同步如果是没有则会造成数据丢失。即出现了数据的不一致。
3.2.2MHA
master high available,是一个MySQL的故障主从切换的高可用软件优点如下
1:30s内完成主从故障切换
2不需人工参与完全自动化
3基于ssh通过自动拉取宕机主节点binlog保证数据的一致性不足
1:需要至少3个节点
2需要配置ssh信息应该不算不足吧3.2.3MGR
多节点集群基于paxos协议多节点数据复制每个节点都有一份完整的数据优点如下:
1:灵活度高支持单主和多主单主故障能够自动选注多主支持多节点同时写入提高写能力
2:伸缩扩展性强当加入新节点自动加入集群并同步数据直到数据同步完成
3多写能够提高数据写能力
4容错有节点宕机不影响集群且能防止脑裂使用的场景
1:希望拥有数据弹性复制的场景 如完整的数据原来在3个节点上现在希望在5个节点上
2分片复制其中1如下图
2如下图
3.2.4mysql innodb cluster
对mgr的改进增加了mysql router作为客户端流量的入口结构如下图: 组件如下
mysql shell:管理MySQL cluster
mysql router:数据库中间件角色代理mgr集群提供负载均衡连接的故障转移可以认为MySQL router是为mgr量身打造的组件如果考虑或正在使用mgr的话一定要配合MySQL router。4分库分表
通过分库分表来解决容量限制当然不仅仅解决此问题的问题。
4.1为什么要做数据库拆分
1:单实例容量的限制
2当单实例数据过多时导致B树索引的层数多查询性能降低
3数据过多备份数据恢复难度大可能不可控
4成为高并发系统的性能瓶颈比如一定会执行如下的操作
1:ddl,比如加一列加索引数据多操作时长将不可控
2系统越来越慢时主从延迟会越来越大系统越来越不稳定因此既然都是因为数据多而导致以上种种的问题那么我们就需要让数据变小怎么变小呢当然不能真的删除所以只能分分库分表。
4.2都有哪些拆分方式
任何领域一般都会有一些指导原则简单将就是避坑指南如编程领域就有面向对象的设计原则 和gof23种设计模式 。这里的指导原则简单将就是避坑指南是扩展立方体分为xyz三个轴如下图 分别如下
X轴将系统复制多份如前面的主从复制MGR等属于X轴的范畴
Y轴按照业务拆分因为Y轴是垂直的所以也叫做垂直拆分我猜的
Z轴将数据分片因为Z轴是水平的所以也叫做水平拆分我猜的.4.2.1垂直拆分
垂直拆分即扩展立方体模型的Y轴按照业务进行拆分具体到数据库领域分为拆库和拆表。
拆库 将一个数据库按照业务拆分成多个数据库在以下的场景中可能使用到这种方式
1:一个大的单体项目逐渐转微服务一般微服务的第一步就是要拆库如果是库在在一起的那是假的微服务
2容量限制需要拆分
3流量比较平均希望打散流量因为拆库之后对系统的原有功能会产生影响比如之前的多表查询中的表可能会被分到不同的库中所以在进行拆分之前要做好如下的准备工作
1评估影响的范围以及修改方案
2新数据库的准备配置数据的迁移
3修改后程序的上线数据库的上线
4上线后出现问题的应急方案拆表 拆表是一张大表通过拆分列分成若干张小表如下所示:
因为此时表结构都有了很大的变化所以这种拆分方式的影响更大可能无异于程序的重构要慎用最好是不用。
4.2.2水平拆分
对应的是扩展立方体的Z轴即分片即将数据分散成多份存储这样就可以将分散流量并且降低单表的数据量提升查询速度水平拆分分为如下三种
1:分库将表的数据分成若干份分散到若干个数据中
2分表将表的数据分散到多个表中每个表存储一部分数据但所有存储分片数据的表还都是在一个数据库中
3分库分表结合分库和分表即存储分片数据的表即有在同一个库中的也有在新库中的水平拆分适用于如下场景
1:数据量过大单表索引树过高IO次数多导致查询速度慢
2数据量大导致数据备份难度大导致主从延迟大简单的分片我们就可以按照ID取模的方式来进行如下图示例
当然具体如何分片需要通过具体的业务场景来分析比如报表分析一般是按照一定的时间范围来统计的所以此时就可以考虑按照时间来分片。
4.2.2.1分库还是分表?
如果是条件允许建议直接使用分库而非分表原因如下:
1:分表后最终所有的表还是在同一个数据库上依然共享同一台服务器的资源而其中IO资源随着数据量的增大很有可能成为系统瓶颈但是如果是分库的话可以很好的规避这个问题提高系统的并行数据处理能力
2但事无绝对如果是IO资源自然充足则可以优先考虑分表而非分库这样对业务代码的影响相对减小并且单个数据库的维护成本也更低5公司业务实践
5.1表单的垂直拆分
介绍下业务背景我司有一个表单产品即低代码平台。当通过后台设计一个表单后就会在数据库中生成一个对应的表如下图
其中表结构可能如下
CREATE TABLE xxx_db22_00sqhcwc (BUSINESS_ID varchar(36) NOT NULL,BUSINESS_DATA_JSON text,2c98843980b276790180b62bf9fe16ed varchar(36) DEFAULT NULL,2c98843980b276790180b62bf9fe16ee varchar(255) DEFAULT NULL,...cae6b1f90a7e4300931ea582cb15e139 text,COMM_CREATE_TIME datetime DEFAULT NULL,fe14ebad5aec42fcba56e82f26a59bbd text,labelIds text,MODIFY_TIME datetime DEFAULT NULL,AREA_CODE varchar(10) DEFAULT 0,PRIMARY KEY (BUSINESS_ID),
) ENGINEInnoDB DEFAULT CHARSETutf8mb3其中的字段BUSINESS_DATA_JSON是用来存储数据的原始信息使用json格式存储像下边这样
[{df5abbcc7bfd402e88a58ebacb5fdf7b: {row1: {cell_fe14ebad5aec42fcba56e82f26a59bbd: {photo: [],allOps: [{key: 0,name: 合格,selected: false,score: 0},...],curr: {key: ,name: 请选择,score: 0}},cell_cae6b1f90a7e4300931ea582cb15e139: {photo: [],allOps: [{key: 0,name: 合格,selected: false,score: 0},...],curr: {key: ,name: 请选择,score: 0}}}}}
]如果是表单比较复杂比如有大量的拍照控件或者是用户需要录入大量的信息时该json就会变大数据大小从几k到几十k不等。而我们知道innodb存储引擎是索引组织表即其数据就是存储在索引中的而当行数据比较大时每个B树的数据页能够存储的数据就会变少甚至出现跨页存储的情况比如数据json大于16k时一个页放不下就会出现这种情况了而当B树的数据页变多之后就会导致B树的层数变多不断的分裂而变高直接导致的问题就是查询数据时的IO次数变多因此会直接影响到查询数据的性能。基于此进行了如下的拆分将主要的列分到单独的表中如下
CREATE TABLE xxx_db22_00sqhcwc_read (BUSINESS_ID varchar(36) NOT NULL,2c98843980b276790180b62bf9fe16ed varchar(36) DEFAULT NULL,2c98843980b276790180b62bf9fe16ee varchar(255) DEFAULT NULL,...cae6b1f90a7e4300931ea582cb15e139 text,PRIMARY KEY (BUSINESS_ID),
) ENGINEInnoDB DEFAULT CHARSETutf8mb3在_read表中只保留了主要的字段这样当执行数据查询时就可以通过_read表来查询了。看到这里不知道你有没有这样的疑问你前面说垂直拆分特别是垂直拆分的分表对系统的影响巨大最好不要使用这里确有用到了这种方式你们是怎么解决的呢是这样子的因为涉及到的业务只是数据查询并没有复杂的业务处理所以只需要简单的定义多数据源 就可以解决问题了。
5.2统计表的水平拆分
之前一家公司是做智能路由器的当时公司大概有100万个智能路由器设备设备每天会定时的上报数据每周产生的数据量大概是在一亿条基于此定义了以周为单位的分片逻辑定义了非常多的周表像下图
对于跨周的数据统计只需要多次查询后在业务代码中进一步处理即可。
6如何迁移数据 迁移就好像给高速飞行的飞机更换某个损坏的引擎是一个非常容易出问题的操作要慎重和小心 一旦引入了分库分表不管是垂直拆分还是水平拆分肯定就要涉及到数据的迁移本部分就一起来看下都有哪些数据迁移方式每种迁移方式的优点和缺点是什么在实际工作中我们又应该如何来进行选择。
6.1全量
全量方式是通过mysqldump 导出全量,然后在导入到新库中去如果是异构的数据库则需要开发程序完成导入。其优点和缺点如下
优点就是简单
缺点:操作时间长可能会导致比较长时间的停机此期间系统将无法对外提供服务适用的场景
1:数据不是特别的多用户使用低峰期就可以完成迁移对用户的影响很小
2非核心业务一段时间的停机对用户无影响6.2全量增量
这种方式不同于全量的地方在于在真正的停机同步数据之前先按照时间同步历史数据然后在最后一天同步新产生的数据以及修改更新的数据这样停机期间需要同步的数据就大大减小。优点和缺点如下
优点停机时间可控相对较短对用户的影响小
缺点操作过程相对复杂且最后一步到底哪些数据更新了或者是删除了如果是没有明显的字段来标示这类数据是无法迁移的6.3binlog全量增量
这种方式需要一个中间件来模拟MySQL的从库从主库拉取binlog完成数据同步这种方式需要中间件的支持当前的中间件有shardingsphpere-scaler。优点和缺点如下
优点1:支持异构系统2:简化操作复杂度复杂度已经由中间件本身实现3停机时间可控一般会非常短因为最终只需要同步一小段的binglog只需要追上主库的binlog即可
缺点7框架和中间件
当我们分库分表之后一般有如下的方式来适配新的数据库结构
1:自己写程序这种方式开发成本高并且容易有比较多的bug优点是可定制性强如果是人力资源充足的话可以考虑这种
2框架即别人帮我们写好的程序直接用在项目中
3中间件介于应用和数据库之间起一个中介的作用一般是一个模拟的MySQL server。
4分布式数据库即数据库本身就支持分库分表等各种分布式方案以上的1一般我们可以不予考虑234的关系如下图
分别看下每种方案相关的技术都有哪些。
7.1框架
7.1.1TDDL
淘宝自用数据库框架开源过一段时间目前闭源。
7.1.2apache shardingsphere-jdbc
shardingsphere 项目三个主要功能中的一个如下图
目前这种方式也是业界采用最多的一种方式占比应该在百分之九十以上。具体原因我们后面分析。
7.2中间件
中间件相对来说就比较多了主要有如下几种
1:cobarjava阿里巴巴团队开发目前已停止维护
2mycatjava基于cobar二次开发解决了cobar存在的一些问题
3OneProxy(C)某数据库界大牛基于C语言开发分布式数据库中间件专注于性能和稳定性商业收费
4vitnesss(GO)youtube一款分布式数据库中间件架构非常复杂
5altas(GO)360团队开发稳定性欠佳
6kingshard(GO)360 altas团队某成员基于go开发稳定性欠佳
6ShardingSphere-proxyjava后起之秀当前在维护升级中。7.3分布式数据库
TIDB开源polardb,oceanbase,等。
7.4哪种方案用到多
在前面提到了分布式数据库框架方案是用的最多的在百分之九十以上我司就是下面我们就看下如果要在当前的线上系统引入相关方案的话都需要考虑哪些因素
1:分布式数据库框架如果想要确定这种方案的话可能只需要几个架构师项目坐在一起讨论一下即可之后只会带来一定的开发和测试工作量。
2分布式数据库中间件如果是要确定这种方案的话就相对要麻烦些了因为涉及到后期的维护问题所以就需要几个部门DBA部门开发部门运维部门等坐在一起讨论下在系统上线后由哪个部门负责维护另外既然是引入中间件肯定是需要额外的机器来部署的因此会产生机器的成本并且多了一层也会降低数据操作的性能这个问题也需要在实际的环境中考虑和验证。
3分布式数据库这种方式就是直接更换数据库了是动静最大的一种就需要公司的CTO各部门的领导甚至公司的高层领导共同讨论得出结果。因此从以上各种方案的考虑因素也可以很轻松的得出为什么选择分布式数据库框架方案成为主流了。
写在后面
多知道一点
数据的分类管理
不同的数据的管理策略是不同的因此我们就需要有一套自己的数据分类管理这里一起来看下。
1:热数据对于比较新的数据如一周内被查询和修改的概率很高这种数据我们叫做热数据我们在将其存储的数据库的同时也加载到内存中。
2温数据对于相对比较旧的数据如一周到半年被查询和修改的概率较低这种数据我们叫做温数据一般只需要存储在数据库中提供查询即可。
3冷数据对于比较旧的数据如半年以上到2年使用廉价的磁盘配合MySQL的archive类的存储引擎如tokudb压缩比在几十分之一,几乎不会查询所以不提供直接的查询如果是用户需要则可以通过工单的形式由客服人员提供数据然后将这些数据从数据库中物理删除
4冰数据对于非常旧的数据如2年以上直接使用硬盘磁带等三方独立介质存储并且不提供任何的查询方式当然所有数据从数据中物理删除。参考文章列表
MyCat是什么 。
常用数据库中间件汇总 。
一文读懂什么是SLI、SLO、SLA 。
Apache Sofware Foundation 下载apache相关软件。
archive.apache.org 下载apache相关软件。
分布式数据库中间件—TDDL的使用介绍 。
为什么几乎所有的开源数据库中间件都是国内公司开源的并且几乎都停止了更新 。