MySQL主从复制与读写分离( 主从复制原理 、读写分离原理 、配置 MySQL 主从复制 、配置 MySQL 读写分离)_只有一个服务器 数据库 主从复制-程序员宅基地

技术标签: 服务器  mysql  数据库  

一、 MySQL主从复制与读写分离简介

在实际的生产环境中,如果对数据库的读和写都在同一个数据库服务器中操作,无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,一般来说 都是通过主从复制(Master-Slave)来同步数据,再通过读写分离来提升数据库并发负载能力的方案来进行部署与实施。

MySQL数据库自身提供的主从复制功能可以方便的实现数据的多处自动备份,实现数据库的拓展。多个数据备份不仅可以加强数据的安全性,通过实现读写分离还能进一步提升数据库的负载性能。

如图所示,一台主 MySQL 服务器带两台从 MySQL 服务器做数据复制,前端应用在进行数据库写操作时,对主服务器进行操作,在进行数据库读操作时,对两台从服务器进行操作,这样大量减轻了对主服务器的压力。

二、 MySQL主从复制原理

MySQL 的主从复制和 MySQL 的读写分离两者有着紧密联系,首先要部署主从复制,只有主从复制完成了,才能在此基础上进行数据的读写分离。

2.1 MySQL 支持的复制类型
基于语句的复制。在主服务器上执行的 SQL 语句,在从服务器上执行同样的语句。MySQL 默认采用基于语句的复制,效率比较高。
基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。
混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。
全局事务标识符 GTID(Global Transaction Identifier,GTID)
基于SQL语句的方式是最直接的方式,也是目前默认的复制方式,后来的三种是MySQL 5以后才出现的复制方式。

2.2 MySQL复制的工作过程

在这里插入图片描述

 1、在每个事务更新数据完成之前,Master 将这些改变记录进二进制日志。写入二进制日志完成后,Master 通知存储引擎提交事务。

2、Slave 将 Master 的 Binary log 复制到其中继日志(Relay log)。首先,Slave 开始一个工作线程——I/O 线程,I/O 线程在 Master 上打开一个普通的连接,然后开始 Binlog dump process。Binlog dump process 从 Master 的二进制日志中读取事件,如果已经跟上 Master,它会睡眠并等待 Master 产生新的事件。I/O 线程将这些事件写入中继日志。

3、SQLslave thread(SQL 从线程)处理该过程的最后一步。SQL 线程从中继日志读取事件,并重放其中的事件而更新 Slave 数据,使其与 Master 中的数据保持一致。只要该线程与 I/O 线程保持一致,中继日志通常会位于 OS 的缓存中,所以中继日志的开销很小。 复制过程有一个很重要的限制,即复制在 Slave 上是串行化的,也就是说 Master 上的并行更新操作不能在 Slave 上并行操作。

三、 配置MySQL主从复制

 MySQL主服务器设置

[root@master ~]# vim /etc/my.cnf
server-id=1               ##主从ID号不能相同
log-bin=master-bin        ##主服务器日志文件
log-slave-updates=true    ##从服务器更新二进制文件


[root@master ~]# systemctl restart mysqld

为从服务器创建一个账户,便于从服务器从主服务器进行日志同步

[root@master ~]# mysql -uroot -p
mysql> grant all on *.* to 'slave'@'%' identified by '123456';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
##这个报错是说您的密码不符合当前策略要求我们修改密码策略和长度就可以,下面是修改方法

mysql> set global validate_password_policy=0;

mysql> set global validate_password_length=1;

mysql> grant all on *.* to 'slave'@'%' identified by '123456';

mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |      435 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

从服务器设置

[root@slave ~]# vim /etc/my.cnf
server-id=2
relay-log=relay-log-bin                  ##从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin-index    ##定义relay-log的位置和名称
read-only=1                              ##是否只读,1 代表只读, 0 代表读写
#super-read-only=1                       ##将超管也设置为只读,看自身情况设置


[root@slave ~]# systemctl restart mysqld

[root@slave ~]# mysql -uroot -p
mysql> change master to master_host='192.168.100.2',master_user='slave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=435;

mysql> start slave;

mysql> show slave status\G;

参数说明

master_host:主数据库的IP地址;
master_port:主数据库的运行端口;
master_user:在主数据库创建的用于同步数据的用户账号;
master_password:在主数据库创建的用于同步数据的用户密码;
master_log_file:指定从数据库要复制数据的日志文件,通过查看主数据的状态,获取File参数;
master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据的状态,获取Position参数;
master_connect_retry:连接失败重试的时间间隔,单位为秒。

 

测试主从同步

在主服务器创建一个数据库看看是否可以同步到从服务器上

主
mysql> create database aaa;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| aaa                |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+


从
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| aaa                |
| abc                |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+

MySQL读写分离原理

读写分离就是只在主服务器上写,只在从服务器上读。基本的原理是让主数据库处理事务性查询,而从数据库处理 select 查询。数据库复制被用来把主数据库上事务性查询导致的变更同步到集群中的从数据库。

在这里插入图片描述

目前较为常见的 MySQL 读写分离分为两种。

1、基于程序代码内部实现
在代码中根据 select、 insert 进行路由分类,这类方法也是目前生产环境应用最广泛的。
优点是性能较好,因为在程序代码中实现,不需要增加额外的设备作为硬件开支;
缺点是需要开发人员来实现,运维人员无从下手。

2、基于中间代理层实现
代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有两个代表性程序。

  MySQL-Proxy。MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行 SQL 判断,虽  然是 MySQL 官方产品,但是 MySQL 官方并不建议将 MySQL-Proxy 用到生产环境。

  Amoeba。 Java 语言开发,阿里巴巴将其用于生产环境。它不支持事务和存储过程。

通过程序代码实现 MySQL 读写分离自然是一个不错的选择,但是并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的 Java 应用,如果在程序代码中实现读写分离对代码改动就较大。

五、 搭建MySQL读写分离

Amoeba(变形虫)项目开源框架于 2008 年发布一款 AmoebaforMySQL 软件。这个软件致力于 MySQL 的分布式数据库前端代理层,它主要为应用层访问 MySQL 的时候充当 SQL 路由功能,并具有负载均衡、高可用性、SQL 过滤、读写分离、可路由到相关的目标 数据库、可并发请求多台数据库。通过 Amoeba 能够完成多数据源的高可用、负载均衡、 数据切片的功能。

在主机 Amoeba 上安装 Java 环境

Amoeba 基于是 jdk1.5 开发的,所以官方推荐使用 jdk1.5 或 1.6 版本,高版本不建议使用。

[root@amoeba ~]# yum -y remove java
[root@amoeba ~]# tar zxvf jdk-8u351-linux-x64.tar.gz 
[root@amoeba ~]# mv jdk1.8.0_351/ /usr/local/java 
[root@amoeba ~]# vim  /etc/profile
export JAVA_HOME=/usr/local/java
export JRE_HOME=/usr/local/java/jre
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$JAVA_HOME/bin:$AMOEBA_HOME/bin
export CLASSPATH=./:/local/java/lib:/usr/local/java/jre/lib

[root@amoeba ~]# source /etc/profile

[root@amoeba ~]# java -version

安装amoeba

下载amoeba
[root@amoeba ~]# wget https://jaist.dl.sourceforge.net/project/amoeba/Amoeba%20for%20mysql/3.x/amoeba-mysql-3.0.5-RC-distribution.zip
[root@amoeba ~]# unzip amoeba-mysql-3.0.5-RC-distribution.zip
[root@amoeba ~]# mv amoeba-mysql-3.0.5-RC /usr/local/amoeba
[root@amoeba ~]# chmod 755 /usr/local/amoeba/ -R

[root@amoeba ~]# vim /usr/local/amoeba/jvm.properties 
JVM_OPTIONS="-server -Xms1024m -Xmx1024m -Xss256k"

[root@amoeba ~]# /usr/local/amoeba/bin/launcher
[root@amoeba ~]# netstat -anptu | grep 8066

配置授权用户

主服务器:配置写权限

mysql> grant all on *.* to 'amoeba'@'192.168.100.%' identified by '123456'; 
mysql> flush privileges;

查看
mysql> show grants for amoeba@'192.168.100.%';

配置amoeba配置文件

[root@amoeba ~]# vim /usr/local/amoeba/conf/amoeba.xml

 

 

 配置数据库服务配置文件

[root@amoeba ~]# vim /usr/local/amoeba/conf/dbServers.xml

 

配置文件修改完成后,重新启动Amoeba,并查看状态

[root@amoeba ~]# kill -9 9280
[root@amoeba ~]# /usr/local/amoeba/bin/launcher  &
[root@amoeba ~]# netstat -anptu | grep 8066

客户机上的测试

[root@server2 ~]# yum -y install mariadb*
[root@server2 ~]# systemctl start mariadb
[root@server2 ~]# mysql -uamoeba -p123456 -h 192.168.100.6 -P8066

#通过amoeba登录数据库 -u用户名 -p密码 -h 访问地址为amoeba服务器 -P amoeba端口号

主从同步验证

在主服务器上新建test数据库和表tt

mysql> create database test;
Query OK, 1 row affected (0.01 sec)
mysql> use test
Database changed
mysql> create table tt(name char(10), id int(3) primary key auto_increment);
Query OK, 0 rows affected (0.02 sec)
mysql> desc tt;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| name  | char(10) | YES  |     | NULL    |                |
| id    | int(3)   | NO   | PRI | NULL    | auto_increment |
+-------+----------+------+-----+---------+----------------+

在从服务器上都可查看到test和表tt(主从复制的效果)

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| tt             |
+----------------+
1 row in set (0.00 sec)

关闭从服务器的从状态

mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)

在客户端进行写入操作:
客户端:也无法查看,只能写入主服务器

MySQL [(none)]> insert into test.tt values('a',1);
Query OK, 1 row affected (0.02 sec)

MySQL [(none)]> select * from test.tt;
ERROR 1146 (42S02): Table 'test.tt' doesn't exist

只能在主服务器查看,从服务器无法查看
主服务器:

mysql> select * from tt;
+------+----+
| name | id |
+------+----+
| a    |  1 |
+------+----+
1 row in set (0.00 sec)

从服务器:

mysql> select * from test.tt;
ERROR 1146 (42S02): Table 'test.tt' doesn't exist

在从服务器上写入数据
slave1:

mysql> insert into tt values('bb',2);
Query OK, 1 row affected (0.01 sec)
#从服务器上可以查看
mysql> select * from tt;
+------+----+
| name | id |
+------+----+
| bb   |  2 |
+------+----+

slave2:

mysql> select * from test.tt;
+------+----+
| name | id |
+------+----+
| aa   |  1 |
| cc   |  3 |
+------+----+

客户端可以轮流读取到从服务器的数据

在这里插入图片描述

 而主服务器上不会存储从服务器的数据,依旧是从客户端写入的数据。

mysql> select * from tt;
+------+----+
| name | id |
+------+----+
| a    |  1 |
+------+----+

实现了读写分离。

开启主从同步之后,主服务器上写入的数据同步到从服务器,客户端也能读取主服务器数据了,但从服务器上的数据不会到主服务器上。

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from test.tt;
+------+----+
| name | id |
+------+----+
| a    |  1 |
+------+----+
1 row in set (0.01 sec)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_58131623/article/details/130419210

智能推荐

芯片验证从零开始系列(一)——芯片验证概论-程序员宅基地

文章浏览阅读1w次,点赞7次,收藏78次。芯片验证从零开始系列(一)——芯片验证概论芯片开发流程动态验证技术静态验证技术Emulation和FPGA原型开发由于最近一个比赛要用到UVM验证,顺便多一门以后求职的手艺,准备系统地学习一下SV和UVM,也可以为之后的毕业论文和发展方向做一些准备。芯片开发流程1)市场人员和客户沟通确定用户需求2)系统设计人员按照功能划分为各个子系统3)子系统由设计团队开发实现4)验证人员对设计功能展开验证,发现设计缺陷,交由设计人员修正5)验证没有出现漏洞后,交由后端人员进行综合,布局布线6)后端人员将_芯片验证

RabbitMQ详解(一):RabbitMQ相关概念_obpmq-程序员宅基地

文章浏览阅读8.9k次,点赞24次,收藏26次。RabbitMQ是目前非常热门的一款消息中间件,不管是互联网大厂还是中小企业都在大量使用。作为一名合格的开发者,有必要对RabbitMQ有所了解,本系列是RabbitMQ快速入门文章,主要内容包括RabbitMQ是什么、RabbitMQ核心概念、五种消息模型、用Docker安装RabbitMQ等。_obpmq

HTML 网页自动刷新_html多线程刷新网页-程序员宅基地

文章浏览阅读5.2k次,点赞2次,收藏24次。HTML网页自动刷新方法在进行HTML网页编写的过程中,往往需要及时的编写反馈,反复的在编辑器和浏览器窗之间进行切换是一个很繁琐的事情,如果在编辑器上使用插件,我也不太愿意,繁琐而且不安全。下面介绍三种不需要插件的自动刷新方法。第一种使用meta标签在html的文档头中,在<head>标签中添加meta属性,像下面“ <meta http-equiv="refresh" content="10">其中前面是刷新所需的meta标识,后面的content是刷新的秒数。第二_html多线程刷新网页

使用@EventListener注解,只启动一次监听事件_@eventlistener 被启动了2次-程序员宅基地

文章浏览阅读726次。背景:当在写一个Spring项目时,配置了事件监听器,在项目启动的时候会自己启动一次,之后如果再调用Controller接口的时候,他还会自己再启动,这个时候我们的业务场景只需要启动一次该怎么办呢?解答: @EventListener public void listener1(ApplicationEvent event) { //解决controller调用接口的时候多次启动event实例 ContextRefreshedEvent event1 = _@eventlistener 被启动了2次

python脚本编程:实时监控日志文件_linux实时监控日志 python-程序员宅基地

文章浏览阅读5k次。用python可以很小巧轻便的实时监控日志文件增量刷新,根据某些关键字进行匹配,方便做运维异常告警代码import timeimport re# specify log file pathlog_path = "my.log"# open file and monitor newst linenumber = 0position = 0with open(log_path,..._linux实时监控日志 python

svn 分支(branch)和标签(tag)管理-程序员宅基地

文章浏览阅读1.4w次,点赞12次,收藏61次。svn的分支管理_svn 分支

随便推点

用 Hadoop 进行分布式并行编程, 第 3 部分_hdfs dfs -copyfromlocal /home/hadoop/temp/* /tempd-程序员宅基地

文章浏览阅读706次。Hadoop 是一个实现了 MapReduce 计算模型的开源分布式并行编程框架,借助于 Hadoop, 程序员可以轻松地编写分布式并行程序,将其运行于计算机集群上,完成海量数据的计算。在本文中,详细介绍了如何部署 Hadoop 分布式运行环境,如何让程序分布式运行于多台普通的计算机上,如何使用 IBM MapReduce Tools 轻松地将 MapReduce 程序部署到 Hadoop 分_hdfs dfs -copyfromlocal /home/hadoop/temp/* /tempdir

Linux进阶 apache服务器;虚拟主机_虚拟机安装开启httpd服务-程序员宅基地

文章浏览阅读309次。1.关闭防火墙systemctlstopfirewalld(暂时关闭,重启后恢复)修改前------将index.html改为hello.html。2.设置宽容模式setenforce0(暂时性设置)配置同一ip不同端口的虚拟主机访问apache服务器。(1)安装httpd(先挂载,用yum安装)(4)修改配置文件httpd.html。(3)创建文件hello.html。(2)启动httpd服务。(5)重启httpd服务。(5)重启httpd服务。(5)重启httpd服务。..._虚拟机安装开启httpd服务

软件测试随笔-程序员宅基地

文章浏览阅读73次。记录一些软件测试工作中的想法。1)软件测试岗位价值在IT行业里是比较低的,为了更好的体现自身价值,我认为软件测试从业者应该比业务更懂技术,比技术更懂业务。同时具备很好的沟通协调能力。让自己变成万能胶。2)软件测试体现价值的点:1.发现bug2.提供信心3.提供信息4.预防缺陷3)软件测试一定要考虑测试的覆盖率4)测试工作要体现测试技术,而不是测试工..._软件测试随笔

VB程序设计教程(第四版) 龚沛曾_龚沛曾vb.pdf-程序员宅基地

文章浏览阅读1.6w次,点赞17次,收藏47次。VB程序设计教程(第四版) 龚沛曾 课后习题答案目录第一章课后答案第二章课后答案第三章课后答案第四章课后答案第五章课后答案第六章课后答案第七章课后答案第八章课后答案....第一章课后答案1、简述Visual Basic的特点。答:(1)具有基于对象的可视化设计工具(2)事件驱动的编程机制(3)提供易学易用的应用程序集成开发环境(4..._龚沛曾vb.pdf

Matlab神经网络语音增强,基于BP神经网络的语音增强研究-程序员宅基地

文章浏览阅读452次。曰髯?分类号:论文编号:2丛坦丝旦生丛密级:公开贵州大学2009届硕士研究生学位论文基于即神经网络的语音增强研究学科专业:电路与系统研究方向:模式识别导师:刘宇红教授研究生:周元芬中国贵州’贵阳2009年5月摘要-5Abstract-6第一章绪言11.1引言11.2语音增强的意义与研究现状21.2.1语音增强的目的21.2.2语音增强的意义21.2.3国内外语音增强研究现状41.2.4语音增强的算..._基于神经网络的语音增强

java.lang.ClassNotFoundException: org.springframework.core.io.Resource 解决办法-程序员宅基地

文章浏览阅读1.7w次。问题描述: 在使用maven依赖项spring MVC、Hibernate和Struts2构建REST web项目之后,我将项目进行打包 “ProcjectName.war”,并通过tomcat manager html页面将其上传到 Linux 的tomcat 服务器,它可以正常工作。但是当我尝试在本地tomcat服务器 (Windows平台)上部署war时,我从tomcat catali..._org.springframework.core.io.resource