1.简介:

对于很多大型网站来说,在所处理的业务中,其中有70%的业务是查询(select)相关的业务操作,剩下的则是写(insert、update、delete,只要能对MySQL的数据造成更改的操作都叫写操作)操作。在使用负载均衡集群之后,可以很大程度的提升网站的整体性能,但是最终的数据处理的压力还是会落到MySQL数据库上,所有很有必要使用一些技术来提升MySQL的负载能力。(读写分离)

写专门交给写服务器处理(一般网站来说写是比较少的 读写比 4:1) 那么需要把读的任务分配多台服务器来完成的架构,就叫做读写分离。

值得注意的是读写分离和主从复制不是一个概念
主从复制是实现读写分离的方式, 读写分离依赖于主从复制,但是主从复制不一定是为了读写分离,可以是为了容灾。读写分离和主从复制也不是一个层面的东西,读写分离是编程层面的一种解决方案,主从复制是数据库提供的一个功能。

2.实现原理:

mysql 读写分离的导致一致性 mysql读写分离是什么_数据库

  1. 主数据库接收到客户端发送的写请求
  2. 对数据库执行写操作 并在 bing log(binary log) 记录日志
  3. I/O线程,将主库的binlog日志拷贝到自己本地,写入一个中继日志(relay log)中
  4. sql线程读取并执行relay log中的信息,也就是在自己本地再执行一遍sql
  5. 主从复制完成

3.实现方式

  1. 依靠中间件(比如:MyCat)
    应用程序连接到中间件,中间件帮我们做SQL分离
  2. 应用程序自己去做分离
    主要是利用Spring提供的路由数据源,以及AOP。

相对而言,应用程序层面去做读写分离最大的弱点(不足之处)在于无法动态增加数据库节点,因为数据源配置都是写在配置中的,新增数据库意味着新加一个数据源,必然改配置,并重启应用。当然,好处就是相对简单。

4.可能出现的问题:

  1. mysql主从同步延时问题:
    从库同步主库数据的过程是串行化的,也就是说主库上并行操作,在从库上会串行化执行,由于从库从主库拷贝日志以及串行化执行sql特点,在高并发情况下,从库数据一定比主库慢一点,是有延时的,所以经常出现,刚写入主库的数据可能读不到了,要过几十毫秒,甚至几百毫秒才能读取到。
  2. 主库宕机
    如果突然主库宕机了,然后恰巧数据还没有同步到从库,那么有些数据可能在从库上是没有的,有些数据可能就丢失了。
4.1应对方式

mysql实际上有两个机制,一个是半同步复制,用来解决主库数据丢失问题,一个是并行复制,用来解决主从同步延时问题。

  • 半同步复制:semi-sync复制,指的就是主库写入binlog日志后,就会将强制此时立即将数据同步到从库,从库将日志写入自己本地的relay log之后,接着会返回一个ack给主库,主库接收到至少一个从库ack之后才会认为写完成。
  • 并发复制:指的是从库开启多个线程,并行读取relay log中不同库的日志,然后并行重放不同库的日志,这样库级别的并行。

5.使用场景

即使MySQL用半同步复制和并行复制等问题来应对可能出现的问题,但延迟问题依然可能存在,建议是一般在读远远多于写,而且读的时候一般对数据时效性要求没有那么高,使用。

6.总结

  1. 物理服务器增加,负载能力增加
  2. 主从只负责各自的写和读,很大程度的缓解X锁和S锁争用。
  3. 可以做容灾,主数据库宕机时可以立即切换到从库达到快速恢复服务的目的。
  4. 主从复制可能出现延迟,插入数据时立马查询可能查不到。
  5. 特殊情况插入操作后必须查询到的情况下,保险起见应强制读主库