您的位置:首页 > 数据库 > MySQL

学习MySQL之主从复制与读写分离一篇就够了!(数据库并发能力的提升)

2020-10-28 08:42 1166 查看

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

文章目录

  • 1.2:MySQL主从复制的工作过程
  • 二:项目搭建:MySQL主从复制搭建
  • 二、修改服务器的配置
  • 2.1:主服务器:
  • 2.2:从服务器:
  • 2.3、效果验证
  • 三:MySQL之读写分离
  • 四:MySQL读写分离搭建
  • 4.3:客户机登录测试
  • 4.4:在主服务上插入内容不会同步(通过amoeba操作)
  • 本次项目压缩包
  • 一、主从复制

    将主数据库中的DDL和DML操作通过二进制日志(BINLOG)传输到从数据库上,然后将这些日志重新执行(重做);从而使得从数据库的数据与主数据库保持一致。

    1.1:MySQL主从复制原理

    1.11:MySQL的复制类型

    • 基于语句的复制

    在主服务器上执行的语句,从服务器执行同样的语句。

    • 基于行的复制
      把改变的内容复制到从服务器。
    • 混合类型的复制
      一旦发现基于语句无法精确复制时,就会采取基于行的复制。

    1.12:主从复制的作用

    主数据库出现的问题,可以切换到从数据库

    可以进行数据层层面的读写分离

    可以在从数据库上进行日程备份

    1.2:MySQL主从复制的工作过程

    • Binary log:主数据库的二进制日志
    • Relay log:从服务器的中继日志

    第一步:master在每个事务更新数据完成之前,将该操作记录串行地写入到binlog文件中。
    第二步:salve开启一个I/OThread,该线程在master打开一个普通连接,主要工作是binlog dumpprocess。如果读取的进度已经跟上了master,就进入睡眠状态并 20000 等master产生新的事件。I/O线程最终的目的是将这些事件写入到中继日志中。
    第三步:SQL Thread会读取中继日志,并顺序执行该日志中的SQL事件,从而与主数据库中的数据保持一致。

    二:项目搭建:MySQL主从复制搭建

    主服务器master从服务器slave
    192.168.158.10192.168.158.30

    2.1:设置时间同步

    2.11:主服务器

    • 安装时间功能
    [root@server1 ~]# yum -y install ntp
    
    修改时间服务的配置文件
    [root@server1 ~]# vim /etc/ntp.conf
    #合适位置插入
    server 127.127.1.0             //本地是时钟源 fudge
    127.127.1.0 stratum 8    //设置时间层级为8
    • 开启服务,并关闭防火墙
    [root@server1 ~]# systemctl stop firewalld
    [root@server1 ~]# setenforce 0

    2.12:从服务器:

    • 安装ntp包
    [root@server3 ~]# yum -y install ntp ntpdate
    • 开启服务,并关闭防火墙
    [root@server3 ~]# systemctl start ntpd
    [root@server3 ~]# systemctl stop firewalld
    [root@server3 ~]# setenforce 0
    • 进行时间同步
    [root@server3 ~]# /usr/sbin/ntpdate 192.168.158.10   #主服务器地址
    26 Oct 20:53:39 ntpdate[76504]: the NTP socket is in use, exiting

    二、修改服务器的配置

    2.1:主服务器:

    • mysql主服务器配置
    vim /etc/my.cnf
    server-id = 11               //指定id号,服务器的唯一标识,不能相同
    log-bin=master-bin           //主服务器日志文件
    log-slave-updates=true       //从服务器更新二进制日志
    • 重启服务
    [root@server1 ~]# systemctl restart mysqld
    • 登录数据库,给从服务器授权
    [root@server1 ~]# mysql -u root -pabc123
    mysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.158.%' IDENTIFIED BY '123123';      #授权从服务器访问主服务器
    Query OK, 0 rows affected, 1 warning (0.01 sec)
    
    mysql> flush privileges;     #刷新权限列表
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> show master status;   #查看主服务器状态
    +-------------------+----------+--------------+------------------+-------------------+
    | File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +-------------------+----------+--------------+------------------+-------------------+
    | master-bin.000001 |      864 |              |                  |                   |
    +-------------------+----------+--------------+------------------+-------------------+
    1 row in set (0.00 sec)
    #File和Position这两个值在后面配置从服务器的时候会用到,slave应从该点在master上进行新的更新

    2.2:从服务器:

    • 修改配置文件
    [root@server3 ~]# vi /etc/my.cnf
    server-id = 22
    relay-log=relay-log-bin
    relay-log-index=slave-relay-bin.index

    • 重启服务
    [root@server3 ~]# systemctl restart mysqld
    • 登录数据库,配置同步
    [root@server3 ~]# mysql -u root -pabc123   #登录数据库
    mysql: [Warning] Using a password on the command line interface can be insecure.
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 3
    Server version: 5.7.20 Source distribution
    
    Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> change master to master_host='192.168.158.10',master_user='myslave',master_password='123123',master_log_file='master-bin.000001',master_log_pos=864;  #配置同步
    Query OK, 0 rows affected, 2 warnings (0.02 sec)
    start slave;    //开启从服务
    show slave status\G;    //查看状态

    2.3、效果验证

    • 在主服务器上新建一个数据库,查看从服务器上是否有 test 库

    • 从服务器验证

    三:MySQL之读写分离

    3.1:读写分离的概述

    • 读写分离是高性能数据库集群的一种方式,其本质是将访问压力分散到集群中的多个节点,但是没有分散存储压力。
    • 业务服务器将写操作发给数据库主机,将读操作发给数据库从机通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。

    3.2:读写分离的基本原理

    • 数据库服务器搭建主从集群,一主一从、一主多从都可以。
    • 数据库主机负责读写操作,从机只负责读操作。
    • 数据库主机通过复制将数据同步到从机,每台数据库服务器都存储了所有的业务数据。

    3.3:怎么实现读写分离?

    • 实现MySQL读写分离的前提是我们已经将MySQL主从复制配置完毕
    • Mysql读写分离基本原理是让master数据库处理操作,slave数据库处理读操作。master将写操作的变更同步到各个slave节点。

    3.4:MySQL读写分离原理

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

    3.5:MySQL读写能提高系统性能的原因:

    • 物理服务器增加,机器处理能力提升,拿硬件换性能。
    • master直接写的是并发的,slave通过主库发来的binlog恢复是异步
    • salve可以单独设置一些参数来提升其读的性能
    • 增加冗余,提高可用性

    四:MySQL读写分离搭建

    4.1:配置amobeba服务器(20.0.0.44)

    • 读写分离安装java环境(amoeba软件基于java平台运行)
    • 关闭防火墙
    • 读写分离是在主从复制的基础上进行配置的,所以先搭建主从复制再搭建读写分离。
    • 准备5 台centos7虚拟机,其中三台搭建 Mysql服务器(一台为主服务器,其余两台为从服务器)
    • 一台虚拟机用来做 Amoeba,实现读写分离。
    • 一台做应用客户端,进行操作验证。
    服务器地址
    主服务器master192.168.158.10
    从服务器slave1192.168.158.30
    从服务器slave2192.168.158.40
    Amoeba服务器192.168.158.20
    客户机192.168.158.50

    4.2:项目操作

    4.21服务器授权

    #每台服务器都如此操作
    mysql> grant all privileges on *.* to 'test'@'192.168.158.%' identified by 'abc123';
    mysql> show grants for test@'192.168.158.%';
    mysql> flush privileges;

    4.21:Amoeba的配置

    1、关闭防火墙,挂载本地共享文件夹,把 jdk 安装包放在 /usr/local目录下

    [root@server2 ~]# tar zxf jdk-8u91-linux-x64.tar.gz
    [root@server2 ~]# mv jdk1.8.0_91/ /usr/local/java
    [root@server2 ~]# vi /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
    [root@server2 ~]# source /etc/profile
    [root@server2 ~]# java -version
    openjdk version "1.8.0_131"
    OpenJDK Runtime Environment (build 1.8.0_131-b12)
    OpenJDK 64-Bit Server VM (build 25.131-b12, mixed mode)

    4.22:安装amoeba

    [root@server2 ~]# unzip amoeba-mysql-3.0.5-RC-distribution.zip
    [root@server2 ~]# mv amoeba-mysql-3.0.5-RC /usr/local/amoeba
    [root@server2 ~]# chmod -R 755 /usr/local/amoeba/
    [root@server2 ~]vi /usr/local/amoeba/jvm.properties
    #JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss196k -XX:PermSize=16m -XX:MaxPermSize=96m"   #添加注释
    JVM_OPTIONS="-server -Xms1024m -Xmx1024m -Xss256k" #添加此行
    [root@server2 ~]# cd /usr/local/amoeba/bin/
    [root@server2 bin]# launcher
    [root@server2 bin]# netstat -anpt | grep 8066
    vi /usr/local/amoeba/conf/amoeba.xml
    <property name="user">test</property>   #28行修改
    <property name="password">123456</property>          #30行修改
    ······
    </property>
    <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>
    <property name="LRUMapSize">1500</property>
    <property name="defaultPool">master</property>     #修改
    <property name="writePool">master</property>       #修改
    <property name="readPool">slaves</property>        #修改
    <property name="needParse">true</property>
    </queryRouter>
    vi /usr/local/amoeba/conf/dbServers.xml
    <property name="user">test</property>     #26行修改
    <property name="password">abc123</property>     #28行修改
    ······
    <dbServer name="master"  parent="abstractServer">  #修改
    <factoryConfig>
    <!-- mysql ip -->
    <property name="ipAddress">192.168.158.10</property>        #主服务器ip
    </factoryConfig>
    </dbServer>
    
    <dbServer name="slave1"  parent="abstractServer">   #修改
    <factoryConfig>
    <!-- mysql ip -->
    <property name="ipAddress">192.168.158.30</property>         #从服务器1ip
    </factoryConfig>
    </dbServer>
    
    <dbServer name="slave2"  parent="abstractServer">   #修改
    <factoryConfig>
    <!-- mysql ip -->
    <property name="ipAddress">192.168.158.40</property>         #从服务器2ip
    </factoryConfig>
    </dbServer>
    
    <dbServer name="slaves" virtual="true">             #修改
    <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
    <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
    <property name="loadbalance">1</property>
    
    <!-- Separated by commas,such as: server1,server2,server1 -->
    <property name="poolNames">slave1,slave2</property>           #修改
    </poolConfig>
    </dbServer>
    [root@server2 bin]# cd /usr/local/amoeba/bin/
    [root@server2 bin]# launcher

    4.3:客户机登录测试

    [root@localhost ~]# yum -y install mariadb*
    [root@localhost ~]# systemctl start mariadb
    [root@localhost ~]# netstat -anpt | grep 3306
    tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      14846/mysqld
    [root@localhost ~]# mysql -utest -p123456 -h 192.168.158.20 -P 8066   #amoeba服务器地址,此处为大写的P

    4.31:在master新建库和表

    mysql> create database test;
    2 mysql> use test;
    3 mysql> create table abc(id int(2) not null primary key, name varchar(48), score char(48));
    4 mysql> show tables;

    4.32:在两台从服务器上看是否有库及表生成

    mysql> show databases;
    mysql> use test;
    mysql> show tables;
    mysql> select * from abc;

    4.33:两台从服务器停止服务

    mysql> stop slave;

    4.4:在主服务上插入内容不会同步(通过amoeba操作)

    • 主服务器

    因为停止了同步服务,所以从服务器不会同步到主服务器的内容

    mysql> insert into abc values(2,'lisi',89);
    • 从服务器
    mysql> select * from abc;
    #表为空

    4.41:读写分离

    • 从服务器1
    mysql> insert into abc values(3,'wangwu',60);
    mysql> select * from abc;

    从服务器2

    mysql> insert into abc values(4,'siri',60);
    mysql> select * from abc;
    • 分别在客户端上测试(第一次在从服务器1写入数据后读数据,第二次在从服务器2写入数据后读数据)
    MySQL [test]> select * from abc;
    MySQL [test]> select * from abc;
    • 在通过客户端连接数据库后写入的数据只有主会记录,然后同步给从-从服务器,从而实现读写分离
    MySQL [test]> insert into abc values(5,'cc',90);        #客户机
    mysql> select * from abc;                               #主
    mysql> select * from abc;                               #从1
    mysql> select * from abc;                               #从2
    • 在客户端上看不到新插入的数据,因为同步没有开启,只有主服务器上可以看到数据
    MySQL [test]> select * from abc;
    MySQL [test]> select * from abc;
    • 在开启同步后,主服务器上的数据会同步到各从服务器上中,但从服务器上的自己增加的数据不会同步,只有本地保存
    #从1
    mysql> start slave;
    mysql> select * from abc;
    #从2
    mysql> start slave;
    mysql> select * from abc;
    客户端:
    MySQL [test]> select * from abc;`

    本次项目压缩包

    链接: https://pan.baidu.com/s/1xyoaFgd0O1JkblmblwFcxw
    提取码: t15y

    若以上服务器拒绝接入,请先试着关闭防火墙,若有任何问题欢迎在评论区留言,谢谢啦

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: