全栈开发之MySQL主从同步,读写分离后可能引发的问题

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 全栈开发之MySQL主从同步,读写分离后可能引发的问题

背景


我们的业务场景是写少读多,一开始采用的是单库完成数据的读写操作。随着数据的增多,从开始的0到十万再到百万级,一路经过索引优化,SQL优化等操作,勉强撑住基本的查询,然而写操作与读操作相互影响,动不动就把数据库服务器的CPU打满。。


当面临这种问题时,一般有两种解决的思路:垂直扩展(换更高配置的机器:CPU、内存、磁盘、带宽等)与水平扩展(加机器,多数据库服务实例,最好是同等配置)。垂直扩展在初期可以暂时解决问题,但随着投入成本的增加,后续可能并不能达到预期的收益,不是长久之计。水平扩展可通过一些相对较低配置的机器构成一个集群提供服务,从而分散单库的压力,实现基本的扩展。


image.png

这里就介绍下关系型数据库 MySQL 的可扩展性:当需要增加资源以执行更多工作时,系统能够获得划算的同等提升(equal bang for the buck)的能力。 MySQL 的可扩展性又分为写扩展和读扩展,显然,我们这里更多地讨论读扩展:我们采用了主从同步、读写分离的方案解决前面提到的数据库服务性能问题,关于主从复制的搭建就不多作介绍了,后面附上之前文章的链接;每当引入新的技术时,必然会带来新的问题,这里就重点讨论下采用 MySQL 主从同步,读写分离后可能引发的问题以及相应的解决方法。


当无法容忍任何延迟时怎么办?


无论是基于语句的复制,还是基于行的复制,都是通过在主库上记录二进制日志,在从库上重放日志的方式实现异步的数据复制。既然是异步复制,那么就会出现主从的数据不一致的情况,即存在延迟。可是在有些特殊的场景下,我们的业务要求零延时(相信我,你肯定会遇到这类情况),这时候怎么办?答案也很简单,很直接:强制读主库。


在落地实现层面,我们使用中间件 ShardingSphere 实现了读写分离。那么,关于如何强制读主库, ShardingSphere 也提供了对应的解决方案,核心代码如下:


// 强制路由主库完成读取
try (
    HintManager hintManager = HintManager.getInstance();
) {
    hintManager.setMasterRouteOnly();
    // 下面调用自己业务查询的方法,会切换到主库进行查询
    ...
}


想忽略某些表不进行同步怎么办?


为了降低主从数据库服务器的负载,有些数据表可能就根本不需要同步到从库,比如一些存放原始数据的临时表,它们不参与任何的业务,这时候就需要对这类表进行过滤。

编辑 MySQL 配置文件 vi /etc/my.cnf ,添加如下内容,忽略指定的数据库表即可。

replicate-wild-ignore-table=db.tb_raw_data


同步出错了怎么办?


导致同步出错的原因会有很多,比如突然断电、主从库服务意外停止等,这时候首先应停止从库 stop slave ,然后可能还需要通过 binlog 以及主从库的同步位置、复制事件进行排查;在实际中我们遇到的同步出错更多的是一开始的管理不规范,比如从库停止同步,报错信息有:


  • 1032:从库中找不到要更新的记录;
  • 1062:从库中出现主键冲突;


在说明同步出错的解决方法之前,我们先分析下上述的同步出错是什么原因导致的。当时,经过排查发现:有人直接在从库上进行了诸如数据导入与删除的操作。这个太危险了,所以后来我们的从库对开发人员专门创建账户,仅开放了查询权限,再后来从库直接不允许通过公网访问。以防止从库被人为意外修改,从而引发数据不同步。


接下来,讨论下上述人为导致的同步出错问题如何解决,其实,最直接简便的便是跳过错误了。


编辑 MySQL 配置文件 vi /etc/my.cnf ,添加如下内容,忽略指定的错误编号。

slave_skip_errors=1032,1062

修改配置文件后重启从库,会自动同步并跳过错误,待从库赶上主库时,再将跳过错误的配置移除,重启服务即可。


当然,还可以配置跳过错误的个数:set GLOBAL SQL_SLAVE_SKIP_COUNTER=n; # n为正整数,有几个错误,就跳过几个


同步延迟了怎么办?


当数据量突然增大时(瞬间大批量数据写入主库时),主从同步延迟不断增大。。这种情况我们曾经遇到过,当时通过多线程(并行)复制的手段解决了这一问题,使从库快速赶上主库。


  • 查看当前是否已使用了多线程
mysql> SHOW VARIABLES LIKE '%slave_parallel%'; 
+------------------------+----------+
| Variable_name          | Value    |
+------------------------+----------+
| slave_parallel_type    | DATABASE |
| slave_parallel_workers | 0        |
+------------------------+----------+
2 rows in set (0.00 sec)

slave_parallel_workers 为0,表明当前是单线程同步,那么可以改为多线程提升同步效率。

  • 修改为多线程同步:4
mysql> STOP SLAVE SQL_THREAD;SET GLOBAL slave_parallel_type='LOGICAL_CLOCK';SET GLOBAL slave_parallel_workers=4;START SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.01 sec)
  • 查看当前是否已使用了多线程
mysql> SHOW VARIABLES LIKE '%slave_parallel%'; 
+------------------------+---------------+
| Variable_name          | Value         |
+------------------------+---------------+
| slave_parallel_type    | LOGICAL_CLOCK |
| slave_parallel_workers | 4             |
+------------------------+---------------+
2 rows in set (0.01 sec)

Note:使用多线程复制时,需要注意数据库的版本应高于5.5。

mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.7.28    |
+-----------+
1 row in set (0.00 sec)


当需要将一个从库提升为主库怎么办?


正常情况下,这里的将从库提升为主库的操作还是比较简便的。


  1. 停止向旧主库写入;
  2. 让从库追赶上主库;
  3. 将一台从库配置为新的主库;
  4. 将从库与写操作指向新的主库,然后开启主库的写入。


从库越多越好吗?


我们实际采用的是一主多从的存储架构,在有少量写和大量读时,这种配置是非常给力的,可以把读分摊到多个从库上,那么这时就会产生一个疑问,我们的从库可以再多加几个吗,可以无限扩展吗?显然,可以多加几个从库,但并不能无限扩展。


一个从库对主库造成的开销是很低的。主要包括:启用二进制日志的开销、网络IO开销、唤醒复制线程发送事件的开销等。但是当从库的数量增加到一定数量,会对主库造成过大的负担,甚至主从之间的带宽成为瓶颈,引发从库的数据同步延迟等问题,所以 MySQL 的读扩展并不能无限扩展。


如何通过复制扩展写操作?


很不幸,复制只能扩展读操作,无法扩展写操作。。


如果真的希望扩展写操作,基本只有分库分表了,或者类似我们如今微服务的数据隔离设计,一个服务一个库,每个微服务管好自己的数据,即按照业务分库。我们用到的中间件 ShardingSphere 本身除了支持读写分离,也支持分库分表,不过实际中我们并没有走这一步,毕竟分库分表后必然又会引入新的复杂性。


从库同步账号的密码忘记了怎么办?


因为主从复制也不是每天都要进行配置,我们的读写分离1主2从,运行了一年之后想要再增加第3台从库,这时突然发现忘记了之前配置从库使用的复制账号与密码信息,这就尴尬了。。


不怕,我们可以看下以前配置主从时用的复制账号信息,在每个从库服务器上,都有一个 master.info 文件,里面有我们需要的信息(^▽^)。


cat /var/lib/mysql/master.info

这样,就找回了复制账号与密码信息;此时,你在细品以下:这是个安全隐患。因此,一定要注意 /var/lib/mysql/master.info 这个文件的权限控制。


总结


实际上,通过实践 MySQL 主从同步、读写分离的读扩展架构,共涉及1主3从四台数据库服务器,帮我们实现了在多个核心数据表单表数据过亿的情况下依然具从良好的查询性能。以上关于主从复制、读写分离的问题都是我们在实际实践中真实遇到的问题,这里做个简单整理。MySQL的主从复制是一门很大的学问,值得我们做进一步的探索。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
5天前
|
消息中间件 canal 关系型数据库
Maxwell:binlog 解析器,轻松同步 MySQL 数据
Maxwell:binlog 解析器,轻松同步 MySQL 数据
38 11
|
2月前
|
关系型数据库 MySQL Linux
mysql 主从同步 实现增量备份
【8月更文挑战第28天】mysql 主从同步 实现增量备份
37 3
|
2月前
|
消息中间件 关系型数据库 MySQL
实时计算 Flink版产品使用问题之使用CTAS同步MySQL到Hologres时出现的时区差异,该如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
2月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
133 0
|
2月前
|
SQL 存储 关系型数据库
实时计算 Flink版产品使用问题之同步MySQL多张表的过程中,内存释放依赖于什么
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
2月前
|
SQL 存储 关系型数据库
MySQL主从同步延迟原因与解决方法
MySQL主从同步延迟原因与解决方法
135 0
|
2月前
|
SQL 关系型数据库 MySQL
mysql读写分离,主从同步
本文介绍了如何在Laravel项目中配置数据库读写分离,并实现MySQL主从同步。主要步骤包括:在`config/database.php`中设置读写分离配置;为主机授予从机访问权限;配置各MySQL服务器的`/etc/my.cnf`文件以确保唯一的`server-id`;以及通过SQL命令设置主从关系并启动从服务。文章还针对一些常见错误提供了排查方法。最后通过验证确认主从同步是否成功。[原文链接](https://juejin.cn/post/6901581801458958344)。版权所有者为作者佤邦帮主,转载请遵循相关规定。
|
18天前
|
NoSQL 关系型数据库 MySQL
微服务架构下的数据库选择:MySQL、PostgreSQL 还是 NoSQL?
在微服务架构中,数据库的选择至关重要。不同类型的数据库适用于不同的需求和场景。在本文章中,我们将深入探讨传统的关系型数据库(如 MySQL 和 PostgreSQL)与现代 NoSQL 数据库的优劣势,并分析在微服务架构下的最佳实践。
|
20天前
|
存储 SQL 关系型数据库
使用MySQL Workbench进行数据库备份
【9月更文挑战第13天】以下是使用MySQL Workbench进行数据库备份的步骤:启动软件后,通过“Database”菜单中的“管理连接”选项配置并选择要备份的数据库。随后,选择“数据导出”,确认导出的数据库及格式(推荐SQL格式),设置存储路径,点击“开始导出”。完成后,可在指定路径找到备份文件,建议定期备份并存储于安全位置。
160 11
|
2月前
|
弹性计算 关系型数据库 数据库
手把手带你从自建 MySQL 迁移到云数据库,一步就能脱胎换骨
阿里云瑶池数据库来开课啦!自建数据库迁移至云数据库 RDS原来只要一步操作就能搞定!点击阅读原文完成实验就可获得一本日历哦~
下一篇
无影云桌面