MYSQL主从复制和读写分离

本文详细介绍了MySQL的主从复制模式(异步、全同步、半同步),以及如何实现主从复制和读写分离,包括配置、时间同步和常见问题。同时提到了Mysql-proxy和Amoeba等开源工具在读写分离中的应用。

mysql主从复制和读写分离:

主从复制:主mysql上的数据,新增,修改库,表,表里的数据,都会同步到从mysql上

Mysql的主从复制的模式:

1.异步复制:mysql的默认复制就是异步复制。只要执行完之后,客户端提交事务,主mysql会立即把结果返回给从服务器,主mysql并不关心从mysql是否已经接受,并且处理。

主一旦崩溃,主mysql的事务可能没有传到从mysql,这个时候强行把从提升为主,可能到新的主mysql,数据不完整。(很少见,工作当中异步复制)

2.全同步复制:主库执行完成一个事务,所有的从库都执行了该事务之后才会返回客户端。

因为需要等待所有从库全部执行完成,性能必然下降。(对数据一致性,和数据完整要求很好的场景)

3.半同步复制:介于异步复制和全同步复制之间。主库执行完一个客户端提交的事务之后,至少等待一个从库接受并处理完成之后才会返回给客户端。半同步在一定程度上提高了数据的安全性。也会有一定的延迟。

这个延迟一般是一个tcp/ip的往返时间。(从发送到接受的时间,单位是秒),半同步复制最好在电视的网络中使用。

时间<1ms:round-trip time RTT

架构主从复制和读写分离:

mysql1主 192.168.120.80

mysql2从 192.168.120.90

mysql3从 192.168.120.100

test1读写分离的服务器 192.168.120.70

test2客户端 192.168.120.110

三台mysql安装时间同步工具

yum install ntp -y

Mysql主从服务器时间同步----

##主服务器设置##

修改主服务器的时间同步配置文件

vim /etc/ntp.conf

--末尾添加--

server 127.127.120.0 #设置本地是时钟源,注意修改网段

fudge 127.127.120.0 stratum 8 #设置时间层级为8(限制在15内)

数字越小,时间精确度越高,设置fudge 8 时间等级是8,最高到15。从本地获取时间源同步,不走网络。

刷新

systemctl restart ntpd

两台从服务器配置

##两台从服务器设置##

service ntpd start

/usr/sbin/ntpdate 192.168.120.80 #进行时间同步

crontab -e

*/30 * * * * /usr/sbin/ntpdate 192.168.120.80

三台服务器一起查看时间 date

主服务器的mysql配置

修改配置文件

vim /etc/my.cnf

log-bin=master-bin

binlog_format = MIXED

log-slave-updates=true

写入到自己的二进制日志

刷新

systemctl restart mysqld

进入主数据库

mysql -u root -p123456

给从库授权

GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.120.%' IDENTIFIED BY '123456';

刷新

FLUSH PRIVILEGES;

查看当前主服务器的状态信息通过位置点同步

从服务器1:

修改配置文件

vim /etc/my.cnf

relay-log=relay-log-bin:

指定了从服务器上中继日志的基本文件名。在这个例子中,

中继日志的文件名将以 "relay-log-bin" 开头。

relay-log-index=slave-relay-bin.index:

指定了中继日志索引文件的名称。中继日志索引文件用于记录中继日志文件的顺序和位置。

在这个例子中,索引文件名为 "slave-relay-bin.index"。

relay_log_recovery=1

默认是0,1开启中继日志的护肤。从服务器出现异常或者崩溃,从服务会从主服务器的二进制的争取读取和应用中继日志。同步

刷新

systemctl restart mysqld

从服务器2

vim /etc/my.cnf

刷新

systemctl restart mysqld

进入这两个从服务器数据库:

CHANGEmastertomaster_host='192.168.120.80',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604;

#配置同步,注意 master_log_file 和 master_log_pos 的值要与Master查询的一致

启动同步

start slave;

查看 Slave 状态

show slave status\G;

确保 IO 和 SQL 线程都是 Yes,代表同步正常。

Slave_IO_Running:YES:负责和主库的IO通信

Slave_SQL_Running:YES:负责自己的slave mysql进程

主服务器创建库和表,从服务器同步创建

从服务器创建库和表,主服务器没有响应

Slave io running no

  1. 网络问题
  2. my.cnf 配置文件写错了
  3. CHANGEmastertomaster_host='192.168.233.21',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604; 要么是文件名错了,要么位置偏移量不对
  4. 防火墙的安全机制的问题

主从复制是单向的,只能从主复制到从服务器。

主从复制延迟问题

  1. 网络延迟
  2. 主从硬件设备(CPU主频、内存IO、硬件IO)
  3. 同步复制而不是异步复制

解决方案:

  1. 硬件方面,主库一般来说不需要动的太多,从库的硬件配置要更好。提升随机写的性能。硬盘可以考虑换成固态的。升级cpu的核数,扩展一下内存。尽量使用物理机(不要用云服务器)
  2. 网络层面:主从服务器都配置在一个局域网内,尽量避免跨网段和跨机房。
  3. 架构方面:读写分离,把写入控制在主库,从库负责读,降低从库的压力
  4. 配置方面:mysql配置。从配置文件的角度实现性能最大化

追求安全性的配置:

innodb_flush_log_at_trx_commit=1

#每次事务提交时都会刷新事务日志。以确保持久性,最高级别的数据安全性,但是会影响性能,默认就是1。

0 就是事务提交时不会立刻刷新,而是每秒刷新一次。可以提高性能,但是发生故障会导致数据丢失。

2 事务提交时,事务日志不会写入硬盘而是保存在系统缓存,不会进行刷新。一定的安全性和性能。内存要求比较高。

(生产中默认是1)

sync_binlog=1

#1也是默认值。每次提交事务之后,直接把二进制日志刷新到磁盘,可以确保日志的持久性。占用比较高的性能,但是安全性能搞。

0二进制日志写入到缓存,也不会刷新日志。故障发生也会丢失数据,内存的要求也提高了

3每3个事务执行一次刷新到磁盘,提高性能,但是一旦崩溃,数据会大量丢失

追求性能化:

sync_binlog=0

innodb_flush_log_at_trx_commit=2

logs-slave-updates=0

从库的更新不会写入二进制日志。(不建议)

innodb_buffer_pool_size 300M 500G

innodb存储引擎的缓冲池大小,设置的s数值越高,可以提高innodb的性能

更多的数据和索引都可以缓存在内存当中。减少磁盘的访问次数。对系统内存要求比较高

主从复制的工作过程:

  1. 主节点的数据记录发生变化都会记录在二进制日志
  2. Slave节点会一定时间内对主库的二进制日志文件进行探测,看其是否发生变化,如果有变化,从库会开启一个I/O的线程请求的主库的二进制事件
  3. 主库会给每一个I/O的线程启动一个dump,用于发送二进制事件给从库,从库通过I/O线程获取更新,slave_sql负责将更新写入到从库本地。实现主从一致

主从复制:

  1. 只能在主库上发生,然后同步到从
  2. 复制过程是串行化过程,在从库上复制是串行的,主库的并行更新不能在从库上并行操作
  3. 主从复制的设计目的就是为了在主库上写,在从库上查。读写分离,实现高可用

读写分离:

要实现读写分离,必须要先实现主从复制

读写分离:所有的写入操作都在主库,从库只负责读。(select)如果有更新,是从主库复制到从库。

为什么要有读写分离:

  1. 数据库在写入数据时,比较耗时(写10000条数据,3分)
  2. 数据库在读的时候,速度很快(读10000条,4.96秒)

读写分离之后,数据的写入和读取是分开的,哪怕写入的数据量比较大,但是不影响查询的效率。

什么场景下需要读写分离:
数据库不是一定需要读写分离的,只有在某些程序在使用数据库过程中,更新少,但是查询较多,这种情况可以考虑读写分离。

读和查的需求差不多,也可以考虑读写分离

生产库一般都会做读写分离

测试库一般不管

在工作中,数据库的读写不会在同一个库中完成。即不安全,也不能满足高可用,也不能实现高并发。工作中都会做读写分离。

Mysql读写分离的原理:

  1. 根据脚本实现。在代码中实现路由分类。select insert进行路由分类。这种方式是最多的。

性能好,在代码中就可以实现,不需要额外的硬件设备

缺点:开发实现的,跟我们无关,如果大型的复杂的应用,设计改动的代码非常多

  1. 基于中间代理层实现:

Mysql-proxy自带的开源项目,基于自带的lua脚本。这些lua脚本不是现成的,腰子姐,不熟悉他的内置变量写不出来的

atlas 360内部做自己使用的代理工具。每天的读写请求承载量可以到几十亿条。支持事务,支持存储过程。

Amoeba 陈思儒,之前在阿里就职,是由java开发的一个开源团建。不支持事务,也不支持存储过程。但是Amoeba还是用的最多的,功能比较强大的软件

<think>嗯,用户想知道MySQL在分布式系统中如何配置主从复制读写分离,以及它们的原理。首先,我需要回忆主从复制的基本流程。主库记录二进制日志,从库通过IO线程读取这些日志,然后SQL线程重放,对吧?这确保了数据一致性。不过用户可能还需要知道具体的配置步骤,比如修改my.cnf文件,创建复制用户,还有CHANGE MASTER命令这些步骤。 然后是读写分离的部分。主库处理写操作,从库处理读操作,这样可以提升性能。但用户可能关心如何实现自动的读写分离,可能需要中间件或者框架支持,比如MyCat或ShardingSphere。这部分需要解释清楚原理,以及配置方法。 另外,用户可能对主从复制的同步机制有疑问,比如异步、半同步全同步的区别,以及各自的优缺点。异步可能性能好但有数据丢失风险,半同步则是在两者之间平衡。需要解释这些模式适用场景。 还有,读写分离带来的数据一致性问题。主从同步有延迟的话,读从库可能拿到旧数据。需要讨论如何解决,比如强制读主库或者监控延迟。用户可能在实际应用中遇到这个问题,所以解决方案很重要。 最后,用户可能想知道高可用性的扩展,比如主库故障时的切换,或者如何监控复制状态。这部分可以提到MHA或者Keepalived这样的工具,帮助提升系统的可靠性。 现在要确保回答结构清晰,分步骤讲解配置,再讲原理,最后讨论注意事项扩展。同时需要引用提供的资料,比如引用[2]提到动态切换分库分表,可能主从配置有关联。但用户的问题更聚焦在主从复制读写分离,所以重点应该放在这里。需要检查引用内容是否相关,适当引用。比如引用[3]提到集中式授权,可能权限配置有关,但可能不太直接相关。可能更多参考引用[2]关于分库分表的动态切换,但主从复制是基础,需要明确区分。 还要生成相关问题,比如主从延迟如何处理,半同步配置,或者读写分离中间件的选择。这些问题能帮助用户深入理解。确保回答中的LaTeX格式正确,数学表达式用$...$,独立公式用$$...$$,并且正确使用引用标记。</think>### MySQL主从复制读写分离的实现原理与配置 #### 一、主从复制核心原理 1. **二进制日志(Binlog)机制** 主库将所有数据变更操作记录到二进制日志中,格式为$binlog\_format=ROW|STATEMENT|MIXED$[^1]。从库通过I/O线程实时拉取主库的Binlog,并写入本地中继日志(Relay Log)。 2. **数据同步流程** $$ \begin{aligned} &\text{主库写入} \rightarrow binlog \xrightarrow[\text{网络传输}]{\text{I/O线程}} relay\ log \xrightarrow{\text{SQL线程}} \text{从库数据} \\ &\Delta t_{同步} = t_{网络} + t_{SQL解析} + t_{从库写入} \end{aligned} $$ 延迟主要受网络带宽、从库硬件性能事务复杂度影响[^2]。 #### 二、配置步骤详解 1. **主库配置** (`my.cnf`) ```ini [mysqld] server-id=1 log-bin=mysql-bin binlog_format=ROW ``` 2. **从库配置** (`my.cnf`) ```ini [mysqld] server-id=2 relay-log=mysql-relay ``` 3. **建立复制链路** ```sql -- 主库创建复制账号 CREATE USER 'repl'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; -- 从库执行 CHANGE MASTER TO MASTER_HOST='master_ip', MASTER_USER='repl', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154; ``` #### 三、读写分离实现方案 1. **中间件方案** 使用MyCat/ProxySQL等中间件,配置规则: ```sql -- 写路由 INSERT/UPDATE/DELETE -> 主库 -- 读路由 SELECT -> 从库(支持负载均衡) ``` 2. **客户端分离方案** 在ORM框架(如MyBatis)中通过注解指定数据源: ```java @DataSource("master") public void insertData(...); @DataSource("slave") public List<Data> queryData(...); ``` #### 四、关键注意事项 1. **复制延迟问题** - 强制读主库:`/* FORCE_MASTER */ SELECT ...` - 并行复制:设置`slave_parallel_workers=8` - 半同步复制:`rpl_semi_sync_master_timeout=1000` 2. **高可用扩展** 采用MHA+Keepalived实现主库故障自动切换,VIP漂移时间可控制在10-30秒[^3]。 ```mermaid graph TD A[应用层] --> B{SQL类型} B -->|写操作| C[主库] B -->|读操作| D[从库集群] C --> E[Binlog] E --> F[从库I/O线程] F --> G[Relay Log] G --> H[从库SQL线程] ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值