案例:MySQL主从复制与读写分离

简介: 案例:MySQL主从复制与读写分离

       既然如此,那就让我们开始享受今日这份晚宴吧🥘

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

 

MySQL主从复制原理

MySQL支持的复制类型:

  1. 基于语句的复制。在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。
  2. 基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。
  3. 混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

 

MySQL读写分离原理

🍖MySQL常见的读写分离分为两种:

  • 基于程序代码内部实现

在代码中根据select、insert进行路由分类,这类方法也是目前生产环境应用最广泛的。

  • 基于中间代理层实现

       代理一般位于客户端和服务器之间,代理服务器连接到客户端的请求后判断后转发到后端数据库,有两个代表性程序,MySQL-Proxy、Amoeba。

 

案例环境

       如图配置实验环境,关闭防火墙、selinux、配置IP地址。开始环境为MySQL已安装快照,MySQL搭建详情参考上边的配置。

搭建MySQL主从复制

配置时间同步

  • 主节点服务器建立时间同步环境。
1. [root@mysql ~]# yum -y install ntp              //安装ntp
2. [root@mysql ~]# vim /etc/ntp.conf               //配置ntp,加入下面两行配置
3. server 127.127.1.0
4. fudge 127.127.1.0 stratum 8
5. [root@mysql ~]# systemctl restart ntpd          //启动
6. [root@mysql ~]# systemctl enable ntpd
  • 两台从服务器进行同步
1. [root@1 ~]# yum -y install ntpdate
2. [root@1 ~]# ntpdate 192.168.1.101
3. 28 Jul 08:56:50 ntpdate[4665]: no server suitable for synchronization found

配置MySQL Master

  • 三台服务器启动MySQL服务,设置MySQL服务器的root密码。
1. [root@mysql ~]# systemctl start mysqld
2. [root@mysql ~]# mysqladmin -u root password 'pwd123'

注意:以下配置在主服务器下做。

  • 在/etc/my.cnf中修改或增加下面内容。
1. [root@mysql ~]# vim /etc/my.cnf
2. [mysqld]                                        //在mysqld配置项下添加三行配置
3. 
4. server-id = 11
5. log_bin = master-bin
6. log-slave-updates = true
7. [root@mysql ~]# systemctl restart mysqld        //配置后重启服务
  • 登录MySQL程序,给授权给从服务器。
1. [root@mysql ~]# mysql -uroot -p
2. mysql>  GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.1.%' IDENTIFIED BY '123456';
3. Query OK, 0 rows affected (0.01 sec)
4. 
5. mysql> flush privileges;
6. Query OK, 0 rows affected (0.00 sec)
7. 
8. mysql> show master status;
9. +-------------------+----------+--------------+------------------+-------------------+
10. | File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
11. +-------------------+----------+--------------+------------------+-------------------+
12. | master-bin.000001 |      410 |              |                  |                   |
13. +-------------------+----------+--------------+------------------+-------------------+
14. 1 row in set (0.00 sec)

配置从服务器

  • 在/etc/my.cnf中添加三行内容,开启中继日志功能。

🍝注意:两台从服务器都需要配置,并且三台的server_id不能相同。

1. [root@1 ~]# vim /etc/my.cnf 
2. [mysqld]                                    //在mysqld配置项下添加三行配置 
3. 
4. server_id = 22
5. relay-log=relay-log-bin
6. relay-log-index=slave-relay-bin.index
7. [root@1 ~]# systemctl restart mysqld
  • 登录MySQL配置时间同步

master_log_file为主服务器的File参数。

master_log_pos为主服务器的Position参数。

1. [root@1 ~]# mysql -uroot -p
2. ......//省略部分内容
3. mysql> change master to master_host='192.168.1.101',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=410;
4. Query OK, 0 rows affected, 2 warnings (0.03 sec)
  • 启动时间同步并查看slave状态(确认两个yes)。停止服务使用"stop slave;"命令。
1. mysql> start slave;                         //启动服务
2. Query OK, 0 rows affected (0.00 sec)
3. 
4. mysql> show slave status\G                  //查看Slave状态
5. *************************** 1. row ***************************
6.                Slave_IO_State: Waiting for master to send event
7.                   Master_Host: 192.168.1.101
8.                   Master_User: myslave
9.                   Master_Port: 3306
10.                 Connect_Retry: 60
11.               Master_Log_File: master-bin.000001
12.           Read_Master_Log_Pos: 410
13.                Relay_Log_File: relay-log-bin.000002
14.                 Relay_Log_Pos: 284
15.         Relay_Master_Log_File: master-bin.000001
16.              Slave_IO_Running: Yes            //此项应为yes
17.             Slave_SQL_Running: Yes            //此项应为yes
18.               Replicate_Do_DB: 
19.           Replicate_Ignore_DB:

       🍤配置从服务器1.102后记得配置从服务器1.103哦

验证主从复制

  • 在主、从服务器上登录MySQL,都查看一下数据库。
1. [root@mysql ~]# mysql -u root -p
2. mysql> show databases;
3. +--------------------+
4. | Database           |
5. +--------------------+
6. | information_schema |
7. | mysql              |
8. | performance_schema |
9. | test               |
10. +--------------------+
11. 4 rows in set (0.01 sec)
  • 在主服务器创建库。
1. mysql> create database test_db;
2. Query OK, 1 row affected (0.00 sec)
  • 两台从服务器查看数据库,显示数据库相同,则主从复制成功。
1. mysql> show databases;
2. +--------------------+
3. | Database           |
4. +--------------------+
5. | information_schema |
6. | mysql              |
7. | performance_schema |
8. | test               |
9. | test_db            |
10. +--------------------+
11. 5 rows in set (0.00 sec)

搭建MySQL读写分离

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

安装Java环境

  • 安装Java环境
1. [root@localhost ~]# mount /dev/cdrom /media
2. mount: /dev/sr0 写保护,将以只读方式挂载
3. [root@localhost ~]# cp /media/jdk-6u14-linux-x64.bin /root
4. [root@localhost ~]# chmod +x jdk-6u14-linux-x64.bin 
5. [root@localhost ~]# ./jdk-6u14-linux-x64.bin                    //根据提示按回车键即可
6. ......//省略部分内容
7. Do you agree to the above license terms? [yes or no]            //输入yes
8. yes
9. ......//省略部分内容
10. Press Enter to continue.....                                    //输入回车键即可
11. 
12. Done.
13. [root@localhost ~]# mv jdk1.6.0_14/ /usr/local/jdk1.6
  • 配置文件后面加入以下内容
1. [root@localhost ~]# vim /etc/profile
2. export  JAVA_HOME=/usr/local/jdk1.6
3. export  CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
4. export  PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin:$PATH:$HOME/bin
5. export  AMOEBA_HOME=/usr/local/amoeba
6. export  PATH=$PATH:$AMOEBA_HOME/bin
  • 执行并查看版本;java环境已经配置成功。
1. [root@localhost ~]# . /etc/profile
2. [root@localhost ~]# java -version
3. java version "1.6.0_14"
4. Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
5. Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)

安装并配置Amoeba

1. [root@localhost ~]# mkdir /usr/local/amoeba
2. [root@localhost ~]# tar zxf /media/amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
3. [root@localhost ~]# chmod -R 755 /usr/local/amoeba/
4. [root@localhost ~]# /usr/local/amoeba/bin/amoeba
5. amoeba start|stop                               //显示此内容说明Amoeba安装成功

配置Amoeba读写分离

  • Master、Slave1、Slave2中开放权限给Amoeba访问。注意:三台mysql服务器都要开放权限。
1. mysql> grant all on *.* to test@'192.168.1.%' identified by '123.com';
2. Query OK, 0 rows affected (0.00 sec)
  • 在Amoeba主机上编辑配置文件。
1. [root@localhost ~]# cd /usr/local/amoeba/
2. [root@localhost amoeba]# vim conf/amoeba.xml
3.           <property name="user">amoeba</property>                   //修改><内用户为amoeba
4.           <property name="password">123456</property>               //修改><内密码为123456

🍒同一文件内,以下配置文件中,🍒注意删除注释🍒。

1.                <property name="defaultPool">master</property>          //修改><内为master
2. 
3.                <!--                                                    //此为注释注意需要删除!!!
4.                <property name="writePool">master</property>            //修改><内为master
5.                <property name="readPool">slaves</property>             //修改><内为slaves
6.                 -->                                                     //此为注释注意需要删除!!!
  • 编辑第二个配置文件
1. [root@localhost amoeba]# vim conf/dbServers.xml 
2.                          <property name="user">test</property>              //修改><内用户为test
3. 
4.                         <!--  mysql password                                //此为注释注意需要删除!!!
5.                         <property name="password">123.com</property>        //修改><内密码为123.com
6.                         -->                                                 //此为注释注意需要删除!!!

🍳注意:同一文件内,修改master、name、和主机即可。

1.         <dbServer name="master"  parent="abstractServer">                                   //name修改为master
2.                 <factoryConfig>
3.                         <!-- mysql ip -->
4.                         <property name="ipAddress">192.168.1.101</property>                 //IP地址修改为192.168.1.101
5.                 </factoryConfig>
6.         </dbServer>
7. 
8.         <dbServer name="slave1"  parent="abstractServer">                                   //name修改为slave1(数字1)
9.                 <factoryConfig>
10.                         <!-- mysql ip -->
11.                         <property name="ipAddress">192.168.1.102</property>                 //IP地址修改为192.168.1.102
12.                 </factoryConfig>
13.         </dbServer>
14.        
15.         <dbServer name="slave2"  parent="abstractServer">                           //name修改为slave2(数字2),以下内容复制slave1的6行内容,修改name和IP地址即可
16.                 <factoryConfig>
17.                         <!-- mysql ip -->
18.                         <property name="ipAddress">192.168.1.103</property>                 //IP地址修改为192.168.1.103
19.                 </factoryConfig>
20.         </dbServer>
21. 
22.         <dbServer name="slaves" virtual="true">
23.                 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
24.                         <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
25.                         <property name="loadbalance">1</property>
26. 
27.                         <!-- Separated by commas,such as: server1,server2,server1 -->
28.                         <property name="poolNames">slave1,slave2</property>                 //修改><内为slave1,slave2
29.                 </poolConfig>
30.         </dbServer>
  • 启动Amoeba软件

🍲修改配置无误后,启动Amoeba,默认端口为tcp8066。

1. [root@localhost amoeba]# bin/amoeba start&                                          //关闭可以使用stop&命令
2. [root@localhost amoeba]# netstat -antpt | grep java
3. tcp6       0      0 127.0.0.1:18003         :::*                    LISTEN      5406/java           
4. tcp6       0      0 :::8066                 :::*                    LISTEN      5406/java                  
5. tcp6       0      0 192.168.1.110:35868     192.168.1.103:3306      ESTABLISHED 5314/java           
6. tcp6       0      0 192.168.1.110:47544     192.168.1.101:3306      ESTABLISHED 5314/java           
7. tcp6       0      0 192.168.1.110:58650     192.168.1.102:3306      ESTABLISHED 5314/java

验证读写分离

  • 测试主机上安装mysql
1. [root@localhost ~]# yum -y install mysql
2. ......//省略部分内容
3. [root@localhost ~]# mysql -u amoeba -p123456 -h 192.168.1.110 -P8066        //通过代理访问MySQL
4. ......//省略部分内容
5. 
6. MySQL [(none)]>
  • 在Master(1.101)上创建一个表,同步到各个服务器上,然后关掉两台从服务器(1.102/1.103)的Slave功能,再插入区别语句测试。
1. [root@mysql ~]# mysql -uroot -ppwd123
2. ......//省略部分内容
3. mysql> use test_db
4. Database changed
5. mysql> create table AAA (id int(10),name varchar(10));
6. Query OK, 0 rows affected (0.02 sec)

(1)此刻两台从服务器的test_db库中应同步出一个名为AAA的表

1. mysql> show tables;
2. +-------------------+
3. | Tables_in_test_db |
4. +-------------------+
5. | AAA               |
6. +-------------------+
7. 1 row in set (0.00 sec)

(2)两台从服务器(1.102、1.103)关闭slave功能。注意:生产环境中一般不允许关闭!

1. mysql> stop slave;
2. Query OK, 0 rows affected (0.00 sec)

(3)主服务器(1.101)上插入一条数据。

1. mysql> insert into AAA values('101','zhang3');
2. Query OK, 1 row affected (0.00 sec)

(4)两台从服务器上分别插入一条数据。

🍭注意:在1.102主机的配置如下:

1. mysql> use test_db;
2. Database changed
3. mysql> insert into AAA values('102','li4');
4. Query OK, 1 row affected (0.00 sec)

🍭注意:在1.103主机的配置如下:

1. mysql> use test_db;
2. Database changed
3. mysql> insert into AAA values('103','wang5');
4. Query OK, 1 row affected (0.00 sec)

测试机——读操作

(1)在client主机上第一次的查询结果如下。

1. MySQL [(none)]> use test_db
2. Database changed
3. MySQL [test_db]> select * from AAA;
4. +------+-------+
5. | id   | name  |
6. +------+-------+
7. |  103 | wang5 |
8. +------+-------+
9. 1 row in set (0.01 sec)

(2)第二次查询结果如下。

1. MySQL [test_db]> select * from AAA;
2. +------+------+
3. | id   | name |
4. +------+------+
5. |  102 | li4  |
6. +------+------+
7. 1 row in set (0.00 sec)

(3)第三次查询结果如下。

1. MySQL [test_db]> select * from AAA;
2. +------+-------+
3. | id   | name  |
4. +------+-------+
5. |  103 | wang5 |
6. +------+-------+
7. 1 row in set (0.00 sec)

🥞经过三次操作只能查询到从服务器中的内容,由此看来读操作成功。

测试机——写操作

  • 在Client主机(1.111)上插入一条语句。
1. MySQL [test_db]> insert into AAA values('111','zhao6');
2. Query OK, 1 row affected (0.01 sec)

       但是在Client主机上查不到,最终只能在master(1.101)上才能查到这条语句内容,说明写操作在Master服务器上。

  • 在Master(1.101)主机上查看内容。
1. mysql> select * from AAA;
2. +------+--------+
3. | id   | name   |
4. +------+--------+
5. |  101 | zhang3 |
6. |  111 | zhao6  |
7. +------+--------+
8. 2 rows in set (0.00 sec)

       由此证明,已经实现了MySQL的读写分离,目前所有的写操作都全部在Master(1.101)上,用来避免数据的不同步;所有的读操作都分摊给Slave(从服务器),用来分担数据库压力。

  • 如果两台从服务器开启slave功能数据将被同步过去,测试机中操作能分别查到以下内容。
1. MySQL [test_db]> select * from AAA;
2. +------+--------+
3. | id   | name   |
4. +------+--------+
5. |  102 | li4    |
6. |  101 | zhang3 |
7. |  111 | zhao6  |
8. +------+--------+
9. 3 rows in set (0.00 sec)
10. 
11. MySQL [test_db]> select * from AAA;
12. +------+--------+
13. | id   | name   |
14. +------+--------+
15. |  103 | wang5  |
16. |  101 | zhang3 |
17. |  111 | zhao6  |
18. +------+--------+
19. 3 rows in set (0.00 sec)

        🍡首先感谢各位大佬的关注,谢谢各位的指点。各位没点关注的大佬,点点关注,我们相互学习,闭门造车是行不通滴。学海无涯苦作舟,那就这样了,晚宴结束时间已到,各位我们八月见啦。ヾ( ̄▽ ̄)Bye~Bye~


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
3月前
|
SQL 关系型数据库 MySQL
Mysql数据恢复—Mysql数据库delete删除后数据恢复案例
本地服务器,操作系统为windows server。服务器上部署mysql单实例,innodb引擎,独立表空间。未进行数据库备份,未开启binlog。 人为误操作使用Delete命令删除数据时未添加where子句,导致全表数据被删除。删除后未对该表进行任何操作。需要恢复误删除的数据。 在本案例中的mysql数据库未进行备份,也未开启binlog日志,无法直接还原数据库。
|
10月前
|
SQL 关系型数据库 MySQL
如何实现 MySQL 的读写分离?
本文介绍了 MySQL 读写分离的实现方式及其主从复制原理,解释了如何通过主从架构提升读并发能力。重点分析了主从同步延时问题及解决方案,如半同步复制、并行复制等技术手段,并结合实际案例探讨了高并发场景下的优化策略。文章还提醒开发者在编写代码时需谨慎处理插入后立即查询的情况,避免因主从延时导致的数据不一致问题。
1180 44
如何实现 MySQL 的读写分离?
|
8月前
|
关系型数据库 MySQL 大数据
大数据新视界--大数据大厂之MySQL 数据库课程设计:MySQL 数据库 SQL 语句调优的进阶策略与实际案例(2-2)
本文延续前篇,深入探讨 MySQL 数据库 SQL 语句调优进阶策略。包括优化索引使用,介绍多种索引类型及避免索引失效等;调整数据库参数,如缓冲池、连接数和日志参数;还有分区表、垂直拆分等其他优化方法。通过实际案例分析展示调优效果。回顾与数据库课程设计相关文章,强调全面认识 MySQL 数据库重要性。为读者提供综合调优指导,确保数据库高效运行。
|
10月前
|
SQL 网络协议 关系型数据库
MySQL 主从复制
主从复制是 MySQL 实现数据冗余和高可用性的关键技术。主库通过 binlog 记录操作,从库异步获取并回放这些日志,确保数据一致性。搭建主从复制需满足:多个数据库实例、主库开启 binlog、不同 server_id、创建复制用户、从库恢复主库数据、配置复制信息并开启复制线程。通过 `change master to` 和 `start slave` 命令启动复制,使用 `show slave status` 检查同步状态。常见问题包括 IO 和 SQL 线程故障,可通过重置和重新配置解决。延时原因涉及主库写入延迟、DUMP 线程性能及从库 SQL 线程串行执行等,需优化配置或启用并行处理
257 40
|
10月前
|
关系型数据库 MySQL 数据库
RDS用多了,你还知道MySQL主从复制底层原理和实现方案吗?
随着数据量增长和业务扩展,单个数据库难以满足需求,需调整为集群模式以实现负载均衡和读写分离。MySQL主从复制是常见的高可用架构,通过binlog日志同步数据,确保主从数据一致性。本文详细介绍MySQL主从复制原理及配置步骤,包括一主二从集群的搭建过程,帮助读者实现稳定可靠的数据库高可用架构。
583 9
RDS用多了,你还知道MySQL主从复制底层原理和实现方案吗?
|
10月前
|
存储 SQL 关系型数据库
服务器数据恢复—云服务器上mysql数据库数据恢复案例
某ECS网站服务器,linux操作系统+mysql数据库。mysql数据库采用innodb作为默认存储引擎。 在执行数据库版本更新测试时,操作人员误误将在本来应该在测试库执行的sql脚本在生产库上执行,导致生产库上部分表被truncate,还有部分表中少量数据被delete。
281 25
|
10月前
|
SQL 存储 关系型数据库
MySQL主从复制 —— 作用、原理、数据一致性,异步复制、半同步复制、组复制
MySQL主从复制 作用、原理—主库线程、I/O线程、SQL线程;主从同步要求,主从延迟原因及解决方案;数据一致性,异步复制、半同步复制、组复制
1105 11
|
10月前
|
SQL 关系型数据库 MySQL
数据库数据恢复——MySQL简介和数据恢复案例
MySQL数据库数据恢复环境&故障: 本地服务器,安装的windows server操作系统。 操作系统上部署MySQL单实例,引擎类型为innodb,表空间类型为独立表空间。该MySQL数据库没有备份,未开启binlog。 人为误操作,在用Delete命令删除数据时未添加where子句进行筛选导致全表数据被删除,删除后未对该表进行任何操作。
|
12月前
|
关系型数据库 MySQL 数据库
docker高级篇(大厂进阶):安装mysql主从复制
docker高级篇(大厂进阶):安装mysql主从复制
292 24
|
12月前
|
NoSQL 关系型数据库 Redis
《docker高级篇(大厂进阶):1.Docker复杂安装详说》包括:安装mysql主从复制、安装redis集群
《docker高级篇(大厂进阶):1.Docker复杂安装详说》包括:安装mysql主从复制、安装redis集群
336 14