Mysql数据库——主从复制与读写分离

目录

前言

一、主从复制

1.主从复制的定义

2.Mysql主从复制支持的类型

3.主从复制的过程

4. 主从复制出现的问题

5.解决方法

二、读写分离

1.读写分离的定义

2.读写分离的作用

3.读写分离作用场景

3.1基于程序代码内部实现

3.2基于中间代理层实现

4.主从复制与读写分离

三、搭建主从复制

1.实验环境准备

2.主从服务器时间同步

2.1主服务器时间同步配置

2.2从服务器时间同步配置

3.主服务器配置主从复制

4.从服务器配置主从复制

5.同步数据

5.1主服务器

5.2从服务器

6.总结

四、搭建读写分离

1.实验环境准备

2.部署JDK环境

3.安装Amoeba服务

4.主从服务器授权给Amoeba

5.修改Amoeba服务配置(读写分离(负载均衡))

5.1修改服务配置

5.2修改数据库配置

5.3后台运行Amoeba服务

6.客户端配置

7.测试

7.1Slave 1 从服务器配置 

7.2Slave 2 从服务器配置

7.3Master 主服务器配置

7.4验证

7.5开启主从复制

五、总结

1.主从复制

1.1主从复制的定义

1.2主从复制支持的类型

1.3主从复制的过程

1.4 主从复制出现的问题

1.5解决方法

2.读写分离

2.1读写分离作用

2.2读写分离软件


前言

主从复制和读写分离架构

  • 在企业应用中,成熟的业务通常数据量都比较大
  • 单台Mysql在安全性、高可用性和高并发方面都无法满足实际的需求
  • 配置多台主动数据库服务器以实现读写分离

主从复制和读写分离是为解决数据中的高并发

一、主从复制

1.主从复制的定义

主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库。在赋值过程中,一个服务器充当主服务器,而另外一台服务器充当从服务器。
当一台从服务器连接到主服务器时,从服务器会通知主服务器从服务器的日志文件中读取最后一次成功更新的位置。然后从服务器会接收从哪个时刻起发生的任何更新,然后锁住并等到主服务器通知新的更新

2.Mysql主从复制支持的类型

  • STATEMENT:基于语句的复制。在服务器上执行sql语句,在从服务器上执行同样的语句,mysql默认采用基于语句的复制,执行效率高。
  • ROW:基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。
  • MIXED:混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

3.主从复制的过程

  • Master节点将数据的改变记录成二进制日志(bin log),当Master上的数据发生改变时,则将其改变写入二进制日志中。
  • Slave节点会在一定时间间隔内对Master的二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/O线程请求 Master的二进制事件。
  • 同时Master节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至Slave节点本地的中继日志(Relay log)中,Slave节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,即解析成 sql 语句逐一执行,使得其数据和 Master节点的保持一致,最后I/O线程和SQL线程将进入睡眠状态,等待下一次被唤醒。

Dump thread线程用于监听IO线程的请求,将二进制的日志文件中更新的数据发送给Slave从服务器进行操作 

注意

  • 中继日志通常会位于 OS 缓存中,所以中继日志的开销很小。
  • 复制过程有一个很重要的限制,即复制在 Slave上是串行化的,也就是说 Master上的并行更新操作不能在 Slave上并行操作。

主从复制过程的简易理解:

  • 主服务器Master通知存储引擎,进行存储数据,Dump thread备份线程开始备份数据,将备份的数据文件保存为binlog二进制日志文件格式;
  • 从服务器请求与主服务器进行数据同步,Dump thread线程响应从服务器的请求,将binlog二进制日志文件传输给从服务器,从服务器接收到二进制日志文件并将二进制日志文件存放于relaylog中继日志文件中(中继日志文件可以理解为一个存放数据的站点),因为数据库不能直接处理中继日志的数据文件,要使用SQL语句进行读取,使得中继日志中存放的日志文件便于数据库进行读取拷贝数据,SQL语句解译后将数据存放于数据库中,至此主从复制过程结束。

总结:两个日志(二进制日志binlog、中继日志relaylog),三个线程(Dump thread、IO thread、SQL thread)

4. 主从复制出现的问题

  • Master服务器高并发,形成大量事务
  • 网络延迟
  • 主从硬件设备导致(CPU、内存IO、硬盘IO)
  • 异步复制

5.解决方法

  • 从库优化Mysql参数。比如增大InnoDB_buffer_pool_size(内存池)让更多操作在Mysql内存中完成,减少磁盘操作
  • 从库优化高性能主机。比如高性能的CPU、内存加大。避免使用虚拟云主机,使用物理主机,这样提升了I/O读写性。
  • 从库优化SSD磁盘
  • 网络优化,避免跨机房实现同步(主从复制尽量选择在同一局域网内)

二、读写分离

1.读写分离的定义

读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库

2.读写分离的作用

  • 数据库的写操作是比较耗时
  • 数据库的读操作很快
  • 读写分离解决的是数据库的写入,影响了查询的效率

3.读写分离作用场景

数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。

3.1基于程序代码内部实现

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

  • 优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支
  • 缺点是需要开发人员来实现,运维人员无从下手。

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

3.2基于中间代理层实现

代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有以下代表性程序。

  • MySQL-Proxy。MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行SQL 判断。
  • Atlas。是由奇虎360的Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。
  • Amoeba。由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。

由于使用MySQL Proxy 需要写大量的Lua脚本,这些Lua并不是现成的,而是需要自己去写。这对于并不熟悉MySQL Proxy 内置变量和MySQL Protocol 的人来说是非常困难的。
Amoeba是一个非常容易使用、可移植性非常强的软件。因此它在生产环境中被广泛应用于数据库的代理层。

4.主从复制与读写分离

在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能满足实际需求的。无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。有点类似于rsync,但是不同的是rsync是对磁盘文件做备份,而mysql主从复制是对数据库中的数据、语句做备份。

读写分离必须建立在主从复制上

三、搭建主从复制

1.实验环境准备

Master 主服务器:192.168.241.11

Slave 1 从服务器1:192.168.241.22

Slave 2 从服务器2:192.168.241.23

systemctl stop firewalld
setenforce 0
#主从服务器均关闭防火墙和核心防护

yum install ntp -y
#主从服务器均安装ntp时间同步服务

2.主从服务器时间同步

时间同步为保证同步数据一致性和完整性

2.1主服务器时间同步配置

[root@master ~]#vim /etc/ntp.conf 
[root@master ~]#vim /etc/ntp.conf 
[root@master ~]#sed -n '59,60p' /etc/ntp.conf 
server 127.127.241.0
#设置本地是时钟源,注意修改网段
fudge 127.127.241.0 startum 8
#stratum代表时间同步的精准性  设置时间层级为8(限制在15内)
[root@master ~]#service ntpd start
Redirecting to /bin/systemctl start ntpd.service
[root@master ~]#service ntpd status
Redirecting to /bin/systemctl status ntpd.service
● ntpd.service - Network Time Service
   Loaded: loaded (/usr/lib/systemd/system/ntpd.service; disabled; vendor preset: disabled)
   Active: active (running) since 四 2024-03-28 14:15:29 CST; 5s ago
  Process: 5064 ExecStart=/usr/sbin/ntpd -u ntp:ntp $OPTIONS (code=exited, status=0/SUCCESS)
 Main PID: 5065 (ntpd)
   CGroup: /system.slice/ntpd.service
           └─5065 /usr/sbin/ntpd -u ntp:ntp -g

3月 28 14:15:29 master ntpd[5065]: Listen normally on 4 virbr0 192.168....23
3月 28 14:15:29 master ntpd[5065]: Listen normally on 5 lo ::1 UDP 123
3月 28 14:15:29 master ntpd[5065]: Listen normally on 6 ens33 fe80::de6...23
3月 28 14:15:29 master ntpd[5065]: Listening on routing socket on fd #2...es
3月 28 14:15:29 master systemd[1]: Started Network Time Service.
3月 28 14:15:30 master ntpd[5065]: refclock_newpeer: clock type 241 invalid
3月 28 14:15:30 master ntpd[5065]: 127.127.241.0 interface 127.0.0.1 ->...e)
3月 28 14:15:30 master ntpd[5065]: 0.0.0.0 c016 06 restart
3月 28 14:15:30 master ntpd[5065]: 0.0.0.0 c012 02 freq_set kernel 0.000 PPM
3月 28 14:15:30 master ntpd[5065]: 0.0.0.0 c011 01 freq_not_set
Hint: Some lines were ellipsized, use -l to show in full.
[root@master ~]#date
2024年 03月 28日 星期四 14:15:52 CST

2.2从服务器时间同步配置

service ntpd start
#开启ntp服务
Redirecting to /bin/systemctl start ntpd.service

/usr/sbin/ntpdate 192.168.241.11
#与主服务器同步时间
28 Mar 14:16:49 ntpdate[3703]: the NTP socket is in use, exiting

date
2024年 03月 28日 星期四 14:17:10 CST


crontab -e
#开启计划任务
*/15 * * * * /usr/sbin/ntpdate 192.168.241.11
#每十五分钟与192.168.241.11主服务器的时间进行同步

crontab -l
*/15 * * * * /usr/sbin/ntpdate 192.168.241.11

3.主服务器配置主从复制

[root@master ~]#vim /etc/my.cnf
#mysql数据库配置文件
[root@master ~]#sed -n '25,28p' /etc/my.cnf
server-id = 1
log-bin=master-bin
#主服务器开启二进制文件
binlog_format= MIXED
#二进制文件输入模式为混合输入
log-slave-updates=true
#允许slave从服务器复制数据时可以写到自己的二进制日志(授权给从服务器可以进行主从复制)
[root@master ~]#systemctl restart mysqld.service
#重启数据库
[root@master ~]#mysql -uroot -p123456
mysql> grant replication slave ON *.* to 'myslave'@'192.168.241.%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)
#给从服务器授权
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
#刷新数据库
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |      604 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
#Position这个位置偏移量是个重点  关系到主从复制是否可以执行

4.从服务器配置主从复制

vim /etc/my.cnf

sed -n '25,28p' /etc/my.cnf

server-id = 2
#注意id与Master的不同,两个Slave的id也要不同
relay-log=relay-log-bin
#开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index
#定义中继日志文件的位置和名称,一般和relay-log在同一目录
relay_log_recovery=1
#如果为1的话  代表可以保证数据的完整性
#当 slave 从库宕机后,假如 relay-log 损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的 relay-log,并且重新从 master 上获取日志,这样就保证了relay-log 的完整性。默认情况下该功能是关闭的,将 relay_log_recovery 的值设置为 1 时, 可在 slave 从库上开启该功能,建议开启。
systemctl restart mysqld.service 
#重启mysqld服务
mysql -uroot -p123456

mysql> change master to master_host='192.168.241.11',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604;
#配置从服务器和主服务器同步  注意 master_log_file 和 master_log_pos 的值要与Master查询的一致
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;
#启动同步,如有报错执行 reset slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G;
#查看Slave状态
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.241.11
                  Master_User: myslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000001
          Read_Master_Log_Pos: 604
               Relay_Log_File: relay-log-bin.000002
                Relay_Log_Pos: 321
        Relay_Master_Log_File: master-bin.000001
             Slave_IO_Running: Yes
                #负责与主机的io通信
            Slave_SQL_Running: Yes
              #负责自己的slave mysql进程
        #确保 IO 和 SQL 线程都是 Yes,代表同步正常。
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 604
              Relay_Log_Space: 526
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 04b457a0-e5b0-11ee-a5c5-000c29514bb5
             Master_Info_File: /usr/local/mysql/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

ERROR: 
No query specified

一般Slave_IO_Running为No的可能(存放同步不了的问题)

  • 网络不通
  • my.cnf配置存在问题
  • 密码、file文件名、pos偏移量不一致
  • 防火墙和核心防护是否关闭 

5.同步数据

5.1主服务器

mysql> create database class;
Query OK, 1 row affected (0.02 sec)

5.2从服务器

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| class              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.02 sec)

6.总结

主从复制重点:两个日志和三个线程

两个日志

  • 二进制日志
  • 中继日志

三个线程

  • Dump thread
  • IO thread
  • SQL thread

四、搭建读写分离

1.实验环境准备

Master 主服务器:192.168.241.11

Slave 1 从服务器1:192.168.241.22

Slave 2 从服务器2:192.168.241.23

Amoeba 服务器:192.168.241.24

客户端:192.168.241.24

2.部署JDK环境

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

准备jdk-6u14-linux-x64.bin软件包

[root@amoeba ~]#ls
amoeba-mysql-binary-2.2.0.tar.gz  jdk-6u14-linux-x64.bin
[root@amoeba ~]#mv amoeba-mysql-binary-2.2.0.tar.gz /opt/
[root@amoeba ~]#mv jdk-6u14-linux-x64.bin  /opt/
[root@amoeba ~]#cd /opt/
[root@amoeba opt]#chmod +x jdk-6u14-linux-x64.bin 
[root@amoeba opt]#./jdk-6u14-linux-x64.bin

Please enter "yes" or "no".
Do you agree to the above license terms? [yes or no]
yes


Press Enter to continue.....


[root@amoeba opt]#ls
amoeba-mysql-binary-2.2.0.tar.gz  nginx-1.18.0
jdk1.6.0_14                       nginx-1.18.0.tar.gz
jdk-6u14-linux-x64.bin            php-7.1.10
mysql-5.7.20                      php-7.1.10.tar.bz2
mysql-boost-5.7.20.tar.gz

[root@amoeba opt]#vim /etc/profile
[root@amoeba opt]#sed -n '78,82p' /etc/profile
export JAVA_HOME=/usr/local/jdk1.6
#指定jdk路径
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
#运行路径(包含了库、依赖包、调用jdk执行文件等)
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
#通过jdk调用Amoeba服务
export AMOEBA_HOME=/usr/local/amoeba
#指定Amoeba路径
export PATH=$PATH:$AMOEBA_HOME/bin
#可以在bash环境中读取Amoeba配置

[root@amoeba opt]#mv jdk1.6.0_14/ /usr/local/jdk1.6
#将jdk移动至指定目录下
[root@amoeba opt]#ls /usr/local/
bin  games    jdk1.6  lib64    mysql  php   share
etc  include  lib     libexec  nginx  sbin  src
[root@amoeba opt]#. /etc/profile
#刷新环境变量
[root@amoeba opt]#java -version
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)

3.安装Amoeba服务

准备amoeba-mysql-binary-2.2.0.tar.gz软件包

[root@amoeba opt]#ls
amoeba-mysql-binary-2.2.0.tar.gz  nginx-1.18.0
jdk-6u14-linux-x64.bin            nginx-1.18.0.tar.gz
mysql-5.7.20                      php-7.1.10
mysql-boost-5.7.20.tar.gz         php-7.1.10.tar.bz2
[root@amoeba opt]#ls /usr/local/
bin  games    jdk1.6  lib64    mysql  php   share
etc  include  lib     libexec  nginx  sbin  src
[root@amoeba opt]#mkdir /usr/local/amoeba
[root@amoeba opt]#tar xf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
#解压Amoeba服务到指定目录/usr/local/amoeba目录下
[root@amoeba opt]#ll /usr/local/amoeba/
总用量 48
drwxr-xr-x. 2 root root    63 3月  28 15:25 benchmark
drwxr-xr-x. 2 root root   131 2月  29 2012 bin
-rw-r--r--. 1 root root  3976 8月  29 2012 changelogs.txt
drwxr-xr-x. 2 root root   243 3月  28 15:25 conf
drwxr-xr-x. 3 root root  4096 3月  28 15:25 lib
-rw-r--r--. 1 root root 34520 8月  29 2012 LICENSE.txt
-rw-r--r--. 1 root root  2031 8月  29 2012 README.html
[root@amoeba opt]#chmod -R 755 /usr/local/amoeba/
[root@amoeba opt]#ll /usr/local/amoeba/
总用量 48
drwxr-xr-x. 2 root root    63 3月  28 15:25 benchmark
drwxr-xr-x. 2 root root   131 2月  29 2012 bin
-rwxr-xr-x. 1 root root  3976 8月  29 2012 changelogs.txt
drwxr-xr-x. 2 root root   243 3月  28 15:25 conf
drwxr-xr-x. 3 root root  4096 3月  28 15:25 lib
-rwxr-xr-x. 1 root root 34520 8月  29 2012 LICENSE.txt
-rwxr-xr-x. 1 root root  2031 8月  29 2012 README.html
[root@amoeba opt]#/usr/local/amoeba/bin/amoeba
amoeba start|stop
#显示start  stop即安装成功

4.主从服务器授权给Amoeba

mysql> grant all on *.* to cxk@'192.168.241.%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)

5.修改Amoeba服务配置(读写分离(负载均衡))

5.1修改服务配置

[root@amoeba opt]#cd /usr/local/amoeba/
[root@amoeba amoeba]#ls
benchmark  bin  changelogs.txt  conf  lib  LICENSE.txt  README.html
[root@amoeba amoeba]#cd conf/
[root@amoeba conf]#ls
access_list.conf  dbserver.dtd   functionMap.xml  rule.dtd
amoeba.dtd        dbServers.xml  log4j.dtd        ruleFunctionMap.xml
amoeba.xml        function.dtd   log4j.xml        rule.xml
[root@amoeba conf]#cp amoeba.xml amoeba.xml_bak
[root@amoeba conf]#ls
access_list.conf  dbserver.dtd     log4j.dtd            rule.xml
amoeba.dtd        dbServers.xml    log4j.xml
amoeba.xml        function.dtd     rule.dtd
amoeba.xml_bak    functionMap.xml  ruleFunctionMap.xml
[root@amoeba conf]#vim amoeba.xml
[root@amoeba conf]#sed -n '30p' amoeba.xml
					<property name="user">amoeba</property>
                         #Amoeba服务的服务名
[root@amoeba conf]#sed -n '32p' amoeba.xml
					<property name="password">123456</property>
                                  #Amoeba服务的密码
[root@amoeba conf]#sed -n '115p' amoeba.xml
		<property name="defaultPool">master</property>
                              #默认的池为master
[root@amoeba conf]#sed -n '117,119p' amoeba.xml
		<!-- -->
		<property name="writePool">master</property>
                        #可写的池为master
		<property name="readPool">slaves</property>
                        #可读地址池为slaves

5.2修改数据库配置

[root@amoeba conf]#cp dbServers.xml dbServers.xml_bak
#备份数据库的配置文件
[root@amoeba conf]#ls
access_list.conf  dbserver.dtd       functionMap.xml  ruleFunctionMap.xml
amoeba.dtd        dbServers.xml      log4j.dtd        rule.xml
amoeba.xml        dbServers.xml_bak  log4j.xml
amoeba.xml_bak    function.dtd       rule.dtd
[root@amoeba conf]#vim dbServers.xml
[root@amoeba conf]#sed -n '22,24p' dbServers.xml
			<!-- mysql schema 
			<property name="schema">test</property>
                         #修改默认进入cxk库 以防mysql中没有cxk库时,会报错
		        -->	
[root@amoeba conf]#sed -n '25,29p' dbServers.xml
			<!-- mysql user -->
			<property name="user">cxk</property>
			               #数据库用户名
			<!--  mysql password -->
			<property name="password">123456</property>
                            #数据库密码
[root@amoeba conf]#sed -n '44,49p' dbServers.xml
	<dbServer name="master"  parent="abstractServer">
                   #设置主服务器的名Master
		<factoryConfig>
			<!-- mysql ip -->
			<property name="ipAddress">192.168.241.11</property>
                   #设置主服务器的地址
		</factoryConfig>
	</dbServer>
[root@amoeba conf]#sed -n '51,61p' dbServers.xml
	<dbServer name="slave1"  parent="abstractServer">
                   #设置从服务器1的名slave1
		<factoryConfig>
			<!-- mysql ip -->
			<property name="ipAddress">192.168.241.22</property>
                   #设置从服务器1的地址
		</factoryConfig>
	</dbServer>
	<dbServer name="slave2"  parent="abstractServer">
                   #设置从服务器2的名slave2
		<factoryConfig>
			<!-- mysql ip -->
			<property name="ipAddress">192.168.241.23</property>
                   #设置从服务器2的地址
		</factoryConfig>
[root@amoeba conf]#sed -n '64,67p' dbServers.xml
            <dbServer name="slaves" virtual="true">
                      #修改可读地址池为slaves
            <poolConfig class="com.meidusa.amoeba.server.MultipleServ    erPool">
			<!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
                              #这里是指负载均衡的查询方式 1表示轮询 2表示加权轮询 3表示hash
			<property name="loadbalance">1</property>
                              #这里默认是轮询
[root@amoeba conf]#sed -n '69,70p' dbServers.xml
			<!-- Separated by commas,such as: server1,server2,server1 -->
			<property name="poolNames">slave1,slave2</property>
                              #从服务器地址池 从服务器名称为slave1 slave2

5.3后台运行Amoeba服务

[root@amoeba conf]#log4j:WARN log4j config load completed from file:/usr/local/amoeba/conf/log4j.xml
2024-03-28 18:29:50,998 INFO  context.MysqlRuntimeContext - Amoeba for Mysql current versoin=5.1.45-mysql-amoeba-proxy-2.2.0
log4j:WARN ip access config load completed from file:/usr/local/amoeba/conf/access_list.conf
2024-03-28 18:29:51,290 INFO  net.ServerableConnectionManager - Amoeba for Mysql listening on 0.0.0.0/0.0.0.0:8066.
2024-03-28 18:29:51,290 INFO  net.ServerableConnectionManager - Amoeba Monitor Server listening on /127.0.0.1:43129.



[root@amoeba ~]#lsof -i:8066
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    6479 root   60u  IPv6  74923      0t0  TCP *:8066 (LISTEN)
[root@amoeba ~]#netstat -natp|grep java
tcp6       0      0 127.0.0.1:43129         :::*                    LISTEN      6479/java           
tcp6       0      0 :::8066                 :::*                    LISTEN      6479/java           
tcp6       0      0 192.168.241.24:43180    192.168.241.23:3306     ESTABLISHED 6479/java           
tcp6       0      0 192.168.241.24:53350    192.168.241.11:3306     ESTABLISHED 6479/java           
tcp6       0      0 192.168.241.24:48824    192.168.241.22:3306     ESTABLISHED 6479/java 

6.客户端配置

[root@amoeba ~]#yum install mariadb-server.x86_64 mariadb -y
[root@amoeba ~]#systemctl start mariadb.service
[root@amoeba ~]#mysql -uamoeba -p123456 -h192.168.241.24 -P8066
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| class              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

mysql> use class;
Database changed
mysql> create table test(id int(15),name varchar(8),hobby varchar(40));
Query OK, 0 rows affected (0.02 sec)

7.测试

mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
#关闭两台从服务器的主从复制

7.1Slave 1 从服务器配置 

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| class              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use class;
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> insert into test values(1,'cxk','ctrl');
Query OK, 1 row affected (0.00 sec)

7.2Slave 2 从服务器配置

mysql> use class;
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_class |
+-----------------+
| test            |
+-----------------+
1 row in set (0.00 sec)
mysql> insert into test values(2,'wyb','skateboarding');
Query OK, 1 row affected (0.01 sec)

7.3Master 主服务器配置

mysql> use class;
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_class |
+-----------------+
| test            |
+-----------------+
1 row in set (0.01 sec)

mysql> insert into test values(3,'xzq','sing');
Query OK, 1 row affected (0.00 sec)

7.4验证

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| class              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

mysql> use class;
Database changed
mysql> show tables;
+-----------------+
| Tables_in_class |
+-----------------+
| test            |
+-----------------+
1 row in set (0.00 sec)

mysql> select * from test;
+------+------+---------------+
| id   | name | hobby         |
+------+------+---------------+
|    2 | wyb  | skateboarding |
+------+------+---------------+
1 row in set (0.01 sec)

mysql> select * from test;
+------+------+-------+
| id   | name | hobby |
+------+------+-------+
|    1 | cxk  | ctrl  |
+------+------+-------+
1 row in set (0.01 sec)

mysql> select * from test;
+------+------+---------------+
| id   | name | hobby         |
+------+------+---------------+
|    2 | wyb  | skateboarding |
+------+------+---------------+
1 row in set (0.00 sec)

mysql> select * from test;
+------+------+-------+
| id   | name | hobby |
+------+------+-------+
|    1 | cxk  | ctrl  |
+------+------+-------+
1 row in set (0.01 sec)

因为关闭了主从复制,此时读到的只能是Amoeba服务分配的两个从服务器中的数据

7.5开启主从复制

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test;
+------+------+---------------+
| id   | name | hobby         |
+------+------+---------------+
|    2 | wyb  | skateboarding |
|    3 | xzq  | sing          |
+------+------+---------------+
2 rows in set (0.06 sec)

mysql> select * from test;
+------+------+-------+
| id   | name | hobby |
+------+------+-------+
|    1 | cxk  | ctrl  |
|    3 | xzq  | sing  |
+------+------+-------+
2 rows in set (0.00 sec)

mysql> select * from test;
+------+------+---------------+
| id   | name | hobby         |
+------+------+---------------+
|    2 | wyb  | skateboarding |
|    3 | xzq  | sing          |
+------+------+---------------+
2 rows in set (0.01 sec)

mysql> select * from test;
+------+------+-------+
| id   | name | hobby |
+------+------+-------+
|    1 | cxk  | ctrl  |
|    3 | xzq  | sing  |
+------+------+-------+
2 rows in set (0.05 sec)

开启主从复制后,从服务器会和主服务器进行同步,因此两个从服务器都拥有了主服务器的数据

五、总结

1.主从复制

1.1主从复制的定义

主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库。在赋值过程中,一个服务器充当主服务器,而另外一台服务器充当从服务器。

1.2主从复制支持的类型

  • STATEMENT:基于语句的复制。
  • ROW:基于行的复制。
  • MIXED:混合类型的复制。

1.3主从复制的过程

两个日志

  • 二进制日志
  • 中继日志

三个线程

  • Dump thread
  • IO thread
  • SQL thread

1.4 主从复制出现的问题

  • Master服务器高并发,形成大量事务
  • 网络延迟
  • 主从硬件设备导致(CPU、内存IO、硬盘IO)
  • 异步复制

1.5解决方法

  • 从库优化Mysql参数。比如增大InnoDB_buffer_pool_size(内存池)让更多操作在Mysql内存中完成,减少磁盘操作
  • 从库优化高性能主机。比如高性能的CPU、内存加大。避免使用虚拟云主机,使用物理主机,这样提升了I/O读写性。
  • 从库优化SSD磁盘
  • 网络优化,避免跨机房实现同步(主从复制尽量选择在同一局域网内)

2.读写分离

读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。

读写分离是建立在拥有主从复制的数据上的,有主从复制的数据库才可以建立读写分离 

2.1读写分离作用

  • 数据库的写操作是比较耗时
  • 数据库的读操作很快
  • 读写分离解决的是数据库的写入,影响了查询的效率

2.2读写分离软件

  • MySQL-Proxy
  • Atlas
  • Amoeba

下面是在工作中遇到的一些问题及解决办法 

3.读写分离使用什么方式怎么使用 

  • 通过amoeba代理服务器,实现只在主服务器上写,只在从服务器上读;
  • 主数据库处理事务性查询,从数据库处理select 查询;
  • 数据库复制被用来把事务查询导致的变更同步的集群中的从数据库

4.如何查询主从同步状态是否成功

在从服务器数据库上输入 show slave status\G 查看主从信息查看里面有IO线程的状态信息,还有master服务器的IP地址、端口事务开始号。
当 Slave_IO_Running和Slave_SQL_Running都是YES时 ,表示主从同步状态成功

5.如果I/O不是yes,如何排查错误原因

  • 首先排查网络问题,使用ping 命令查看从服务器是否能与主服务器通信
  • 再查看防火墙和核心防护是否关闭(增强功能)
  • 接着查看从服务slave是否开启
  • 两个从服务器的server-id 是否相同导致只能连接一台
  • master_log_file master_log_pos的值跟master值是否一致

6.Show slave status

  • IO线程的状态信息
  • master服务器的IP地址、端口、事务开始的位置
  • 最近一次的错误信息和错误位置
  • 最近一次的I/O报错信息和ID
  • 最近一次的SQL报错信息和id

7.主从复制慢(延迟)可能存在的问题

  • 主服务器的负载过大,被多个睡眠或 僵尸线程占用  导致系统负载过大,从库硬件比主库差,导致复制延迟
  • 主从复制单线程,如果主库写作并发太大,来不及传送到从库,就会到导致延迟
  • 慢sql语句过多
  • 网络延迟

8.主从复制版本问题

若主从版本不一致,从的版本一定要高于主,保证可以向下兼容
因为若主的版本更新,低版本的从无法兼容的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/497206.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis命令介绍

一、redis启动&#xff1a; 本地启动&#xff1a;redis-cli 远程启动&#xff1a;redis-cli -h host -p port -a password Redis 连接命令 1 AUTH password 验证密码是否正确 2 ECHO message 打印字符串 3 PING 查看服务是否运行 4 QUIT 关闭当前连接 5 SELECT index 切换…

UI设计案例,B端后台界面设计教程

B端产品是为“组织”提供服务&#xff0c;以业务为中心&#xff0c;追求时效性&#xff0c;在视觉上&#xff0c;内容为王&#xff0c;视觉为功能让步&#xff0c;追求简洁、清晰、克制、理性的视觉风格。B 端产品业务比较复杂&#xff0c;页面内容也会较多&#xff0c;B端界面…

Python与人工智能:气象领域的数据处理与模型优化

Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;在数据处理、科学计算、数学建模、数据挖掘和数据可视化方面具备优异的性能&#xff0c;这些优势使得Python在气象、海洋、地理、气候、水文和生态等地学领域的科研和工程项目中得到广泛应用。可以…

LLM资料:中文embedding库

Highlight&#xff08;重点提示&#xff09; 理解LLM&#xff0c;就要理解Transformer&#xff0c;但其实最基础的还是要从词的embedding讲起。 毕竟计算机能处理的只有数字&#xff0c;所以万事开头的第一步就是将要处理的任务转换为数字。 面向中文的开源embedding库在自然…

MQ集合了

消息队列&#xff0c;FIFO &#xff1a;异步 解耦 削峰 复杂度上升 幂等 重复消费 消息丢失 / 可用性降低 mq故障 / 一致性要求 mq对比&#xff1a; activeMQ&#xff1a;jms规范&#xff0c;支持事务 xa协议 rabbitMQ&#xff1a;erlang 性能&#x1f44c; 高并发 多语…

react-router v6的Link组件relative属性解释

Link组件有一个名为relative的属性,值为route或path,默认为route 当Link的to为两个点时,配置relativeroute|path会有不同的效果, 之前由于路径嵌套不够深,看不出区别,于是尝试加深路径,一眼就看出了区别 官方解释 | React Router6 中文文档 下方代码请看根路径/cd及其二级路…

C++优先队列——priority_queue,函数对象,labmda表达式,pair等

头文件&#xff1a;#include<queue> 内部使用堆来实现&#xff0c;在需要或得最大的几个值或最小的几个值而不关心整个数组的顺序时非常好用。 用法&#xff1a; priority_queue<int, vector<int>, greater<int>>q; 第一个参数为堆中存储的元素。 …

vue 借助vue-amap插件对高德地图的简单使用

需求&#xff1a;实现点击获取经纬度、定位、对特殊位置标点及自定义信息窗体功能。 高德地图的官网API&#xff1a;概述-地图 JS API 1.4 | 高德地图API vue-amap的中文文档&#xff1a;组件 | vue-amap 实现&#xff1a; 1、安装vue-amap插件 npm install vue-amap --save…

AI预测福彩3D第20弹【2024年3月28日预测--第4套算法重新开始计算第6次测试】

今天继续对第4套算法进行测试&#xff0c;测试的目的主要是为了记录统计两套方案的稳定性和命中率&#xff0c;昨天的第二套方案已命中。今天是第5次测试&#xff0c;同样测试两个方案。废话不多说&#xff0c;直接上结果。 2024年3月28日福彩3D的七码预测结果如下 …

武忠祥《660题》高效刷题包+资料分享

660题的难度书虽然比较难&#xff0c;对于基础的考察比较深入&#xff0c;所以&#xff0c;有没有一种可能&#xff0c;做题太慢&#xff0c;是因为基础不好导致的&#xff01; 所以再继续做下去&#xff0c;就没有什么意义了&#xff0c;因为这就像是用一把钝刀去砍树&#x…

mybatis搭建开发环境

1.创建maven工程 2.配置pom.xml <!--数据库驱动--> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version> </dependency> <!--Mybatis--> <depend…

vscode使用sftp上传

1.用vscode打开项目 2.安装一下这个sftp 3.使用快捷键 ctrlshiftP 打开指令窗口&#xff0c;输入 sftp:config&#xff0c;选中回车&#xff0c;在当前目录中会自动生成 .vscode 文件夹及 sftp.json 4.修改sftp.json文件配置&#xff0c;改成以下&#xff08;默认的参数可能上传…

八种顺序读写函数的介绍(fput/getc;fput/gets;fscanf,fprintf;fwrite,fread)

一&#xff1a;读写的含义的解释&#xff1a; 读&#xff08;读出&#xff09;&#xff1a;即从文件里面读出数据----------->和scanf从键盘里面读出数据类似 写&#xff08;写入&#xff09;&#xff1a;即把数据写入文件里面----------->和printf把数据写入到屏幕上类…

【leetcode】双“指针”

标题&#xff1a;【leetcode】双指针 水墨不写bug 我认为 讲清楚为什么要用双指针 比讲怎么用双指针更重要&#xff01; &#xff08;一&#xff09;快乐数 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数…

Unity 窗口化设置

在Unity中要实现窗口化&#xff0c;具体设置如下&#xff1a; 在编辑器中&#xff0c;选择File -> Build Settings。在Player Settings中&#xff0c;找到Resolution and Presentation部分。取消勾选"Fullscreen Mode"&#xff0c;并选择"Windowed"。设…

Linux:Jenkins:参数化版本回滚(6)

上几章我讲到了自动集成和部署 Linux&#xff1a;Jenkins全自动持续集成持续部署&#xff08;4&#xff09;-CSDN博客https://blog.csdn.net/w14768855/article/details/136977106 当我们觉得这个页面不行的时候&#xff0c;需要进行版本回滚&#xff0c;回滚方法我这里准备了…

Linux 反引号、单引号以及双引号的区别

1.单引号—— 单引号中所有的字符包括特殊字符&#xff08;$,,和\&#xff09;都将解释成字符本身而成为普通字符。它不会解析任何变量&#xff0c;元字符&#xff0c;通配符&#xff0c;转义符&#xff0c;只被当作字符串处理。 2.双引号——" 双引号&#xff0c;除了$,…

LangSAM项目优化,将SAM修改为MoblieSAM,提速5~6倍

Language Segment-Anything 是一个开源项目&#xff0c;它结合了实例分割和文本提示的强大功能&#xff0c;为图像中的特定对象生成蒙版。它建立在最近发布的 Meta 模型、segment-anything 和 GroundingDINO 检测模型之上&#xff0c;是一款易于使用且有效的对象检测和图像分割…

定时任务 之 cron 表达式

Cron 表达式产生的背景&#xff1a;在Unix系统中&#xff0c;用户经常需要设置一些周期性被执行的任务&#xff0c;如定期备份文件、发送邮件等。为了满足这种需求&#xff0c;Unix系统提供了crontab命令&#xff0c;允许用户定义任务的时间表&#xff0c;并在指定的时间点自动…

实现实时查询并带有查询结果列表的输入框

这个功能主要是实现了一个可以实时查询结果的搜索框&#xff0c;并具备点击外部关闭搜索结果框体的功能&#xff0c;除了v-show和transition依托于vue实现以外其余功能都基于原生JS实现。 效果图&#xff1a; 该功能的实现主要是很久之前面试被问到过&#xff0c;当时没有做出…