目录
觉得有用的记得关注点赞加收藏哦 我的Docker专栏还有其他关于Dokcer的技术点哦~
一.主从概念
集群就是多台服务器做同样的事情
假设:我们搭了一个集群,有三台服务器,分别是aa,bb,cc,客户端发来了一条增加的请求 ,我们假设它有轮询规则,因为轮询随机将请求给到了cc服务器,但是客户端有发了一条请求要查询刚刚增加的数据,轮询随机给到了bb服务器去执行,结果bb服务器没有数据,也就出现了BUG。mysql不能使用这种方法因为要实现数据同步
我们可以用主从复制来解决这样的问题,用主从的话,我们就不叫mysql集群了,叫mysql主从,
主服务器负责增删改,并且把数据复制到从服务器,从服务器负责查询数据 ,如果是查询的请求我们可以按照轮询的规则,随机给到两台从服务器去处理请求,主从实现了读写分离
主从复制、读写分离一般是一起使用的。目的很简单,就是**为了提高数据库的并发性能**。
Master是主,SIalve是从,主服务器执行了的sql语句,会把sql语句写在日志里,从服务器有一个线程会一直接收主服务器的日志文件,因为从服务器有可能也在执行查询的请求,那么线程会把接收的数据写在自己本地的日志里,在由另一个sql线程执行日志文件里面的sql,那么从服务器就有和服务器一样的数据了。
## 主从复制的原理
①当Master节点进行insert、update、delete操作时,会按顺序写入到binlog中。
②Slave从库连接master主库,Master有多少个Slave就会创建多少个binlog dump线程。
③当Master节点的binlog发生变化时,binlog dump线程会通知所有的slave节点,并将相应的binlog内容推送给slave节点。
④I/O线程接收到 binlog 内容后,将内容写入到本地的 relay-log。
⑤SQL线程读取I/O线程写入的relay-log,并且根据 relay-log 的内容对从数据库做对应的操作。
mysql的主从复制中主要有三个线程:master(binlog dump thread)、slave(I/O thread 、SQL thread),Master一条线程和Slave中的两条线程。master(binlog dump thread)主要负责Master库中有数据更新的时候,会按照binlog格式,将更新的事件类型写入到主库的binlog文件中。
并且,Master会创建log dump线程通知Slave主库中存在数据更新,这就是为什么主库的binlog日志一定要开启的原因。
I/O thread线程在Slave中创建,该线程用于请求Master,Master会返回binlog的名称以及当前数据更新的位置、binlog文件位置的副本。
然后,将binlog保存在 「relay log(中继日志)」中,中继日志也是记录数据更新的信息。
SQL线程也是在Slave中创建的,当Slave检测到中继日志有更新,就会将更新的内容同步到Slave数据库中,这样就保证了主从的数据的同步。
主从复制的过程有不同的策略方式进行数据的同步:
1. 「同步策略」:Master会等待所有的Slave都回应后才会提交,这个主从的同步的性能会严重的影响。
2. 「半同步策略」:Master至少会等待一个Slave回应后提交。
3. 「异步策略」:Master不用等待Slave回应就可以提交。
4. 「延迟策略」:Slave要落后于Master指定的时间。
二.主从搭建
1.下载镜像
docker pull mysql/mysql-server:5.7
2.创建主从的配置文件,和数据存放位置
主
mkdir -p /home/data/mysql/master/{conf,data}
从
mkdir -p /home/data/mysql/slave/{conf,data}
conf目录
必须提前上传my.cnf文件到/data/conf目录 并且它与window中的配置文件my.ini后缀名是不一样
data目录
数据保存到宿主机中,下次需要的时候重启容器,原有数据都能被加载,不会丢失数据
3.上传数据库容器的配置文件my.cnf
必须提前上传my.cnf文件到/data/conf目录 并且它与window中的配置文件my.ini后缀名是不一样
master的 my.cnf是配置文件里面内容如下:
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
secure-file-priv=/var/lib/mysql-files
user=mysqlsymbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
##下面为添加的自定义配置
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
sql_mode= STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
max_allowed_packet=10M
default-time_zone='+8:00'
default_authentication_plugin=mysql_native_password
#主数据库配置
log-bin=mysql-bin
server-id=1
slave 的 my.cnf是配置文件里面内容如下:
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
##官方的配置
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
secure-file-priv=/var/lib/mysql-files
user=mysql# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
##下面为添加的自定义配置
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
# default: sql_mode= STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
# modeified:
sql_mode= STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
max_allowed_packet=10M
default-time_zone='+8:00'
default_authentication_plugin=mysql_native_password
#[必须]指定服务器标识ID,每台服务器唯一
server-id=2
我用的是连接工具 可以直接复制进去 , 你们可以用rz上传,显示没有rz命令可以去网上找选择方法
主数据库需要开启二进制日志 log-bin=mysql-bin
主从服务器都需要指定服务器标识ID server-id=1
4.创建Master
docker run -p 3999:3306 \
--name mysql-master \
-v /home/data/mysql/master/conf/my.cnf:/etc/my.cnf \
-v /home/data/mysql/master/data:/var/lib/mysql \
--privileged=true \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql/mysql-server:5.7-p是端口映射:3999是宿主机,3306是容器的端口,把3999映射到3306
(1).进入容器
docker exec -it mysql-master bash
(2).登录mysql 密码123456
mysql -uroot -p
(3).设置用户可以远程连接
grant all privileges on *.* to root@'%' identified by '123456';
(4).刷新
flush privileges;
(5).关闭防火墙
systemctl stop firewalld
(6).使用Nacicat连接mysql
5.创建Slave
docker run -p 3998:3306 \
--name mysql-slave \
-v /home/data/mysql/slave/conf/my.cnf:/etc/my.cnf \
-v /home/data/mysql/slave/data:/var/lib/mysql \
--privileged=true \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql/mysql-server:5.7-p是端口映射:3998是宿主机,3306是容器的端口,把3998映射到3306
(1).进入容器
docker exec -it mysql-slave bash
(2).登录mysql 密码123456
mysql -uroot -p
(3).设置用户可以远程连接
grant all privileges on *.* to root@'%' identified by '123456';
(4).刷新
flush privileges;
(5).使用Nacicat连接mysql
现在两台服务器/容器是没有关系的,我们要配置主从
三.配置主从
1.查看master查看数据库状态
show master status;
这是主服务器的状态值,
我们可以把mysql-bin.000005理解为日志文件的名字
Position:是日志文件的位置
2.去从服务器配置
(1).在开一个窗口进入从服务器,登录mysql,密码123456
docker exec -it mysql-slave bash
mysql -uroot -p
(2). 让从服务器连接到主服务器的日志文件
CHANGE MASTER TO MASTER_HOST='172.17.0.2', MASTER_PORT=3306, MASTER_USER='root',MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=154;
CHANGE MASTE TO:修改服务器的地址
CHANGE MASTER TO MASTER_HOST='172.17.0.2':是主服务器的IP
MASTER_PORT=3306,主服务器的端口
MASTER_USER='root':主服务器的用户
MASTER_PASSWORD='123456',主服务器的密码
MASTER_LOG_FILE='mysql-bin.000003',日志文件名称
MASTER_LOG_POS=586;日志文件地址
(3).在从服务器开启主从
start slave;
(4).查看状态
show slave status\G;
查询出来的内容
Slave_IO_State: Waiting for master to send event //正在等待主服务器发送的数据· Master_Host: 172.17.0.2 //主服务器的IP Master_User: root //主服务器的用户名 Master_Port: 3306 //主服务器的端口 Connect_Retry: 60 Master_Log_File: mysql-bin.000005 //主服务器的日志文件名称 Read_Master_Log_Pos: 154 Relay_Log_File: 9536d1aa1f98-relay-bin.000004 Relay_Log_Pos: 367 Relay_Master_Log_File: mysql-bin.000005 Slave_IO_Running: Yes //用来接收主服务器发送过来的sql文件 Slave_SQL_Running: Yes //执行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: 154 Relay_Log_Space: 794 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: 5ae98e24-d1ca-11ed-bc3e-0242ac110002 Master_Info_File: /var/lib/mysql/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)
三.主从同步
1.操作主服务器
创建一个数据库,在在数据库里面创建一个表
2.打开从服务器
刷新一下
从服务器也出现了一样的数据,已经实现了主从同步!!!!!!!!!!!
好啦 文章内容到这里就结束了 你学到了吗
觉得有用的记得关注点赞加收藏哦 我的Docker专栏还有其他关于Dokcer的技术点哦~
我敲BUG的Docker专栏:http://t.csdn.cn/ypXDz