MySQL主从架构复制:
在主server上每次进行可能引起数据变化的操作都要先记录到二进制文件中,并将数据同步到主server的磁盘上,与此同时还要通过端口(3306)将二进制日志发送到从server上,在从server上,从server会先将接受的二进制日志保存为中继日志(relay log),在从中继日志中进行读取,重新执行一遍操作,进行数据的复制
但一般来说,如果主server有多个cpu,当数据量变化很频繁时,可能会在每个cpu上都运行一个事务,而注server只能一个个的记录入二进制日志,还要发送给从server,而从server还要先记录到中继日志在进行读取复制数据,所以主从复制是异步进行的,从server多多少少会落后主server
除了异步模式外,MySQL主从复制和Drbd一样还存在同步模式和半同步模式
同步模式:主server发一个记录,从收到后响应再发第二个
半同步:一主多从中,从server会启动多个线程向每个从server发送记录,只要有一个从server收到后响应,就发第二个
注:MySQL在5.5之前是不支持同步的,在5.5后Google为mysql打了一个补丁后开始支持
对于从server来说是不应允许进行任何写操作的,否则会导致主从数据不一致
尽管主从同步不一致,但一般来说从server也不会落后太多,当要进行数据恢复时,先停止主sever,再对数据进行恢复;最后利用主server上的二进制日志进行即时点还原便可
但有时由于主server上执行了Flush logs或者执行了重启,而在从server上没有执行;这样往往导致主从server上的二进制日志个数不一致(如主上执行了100个语句产生了10个二进制日志,而在从上很可能只有一个二进制日志,)所以进行即时点还原时不能盲目对应
>show slave status;
显示此刻事件在中继日志中的位置,和当前从主server上复制的二进制日志文件名是什么,事件是什么
从server上需要二进制日志吗?
MySQL也支持多级复制:主——从1——从2
此时从1必须复制主的二进制日志,所以有中继日志;且从1还要负责将二进制日志发送给从2,所以从1必须有二进制日志(中继日志不能直接发送),而对从2来说,它只要有中继日志便可,不需要再读取中继日志进行数据复制时记录二进制日志
主从复制的作用:
- 实现数据的备份
- 实现远程容灾(主从之间往往相隔较远)
- 进行高可用(如主server突然坏了,可以让从server同步完自己落后于主server的数据后,立马顶上去,变成主server,并让支持写入功能)
- 分担负载(主server负责写入操作,让从server负责备份和读操作;或者让主负责读和写,从负责复制和读;一般来说读要多于写)
MySQL读写分离
做MySQL的读写分离,在主从前端必须有一个MySQL代理,此代理必须要能够理解前端用户的SQL语句,代理会根据用户的请求操作将写入的请求发给主,将读的操作请求发给从;甚至还可以加多个从server,在从server前端加一个Director(调度器)将从server做成一个LVS集群等,根据一定的算法负载分担到每个从server上,加快数据读取的性能
要实现MySQL的读写分离,可以用到的代理有:
- mysql-proxy
- amoeb (阿里巴巴开发的)
- cobar(阿里巴巴开发的)cobar是一个拆分工具
当为一主多从模型时,主server要为每个从server启动一个线程,进行二进制日志的发送,且主server还要负责数据的读/写;这样会造成主的压力太大,此时可以采取下面的模式:
让主负责写入,从1即不负责写也不负责读,只负责将主上的二进制日志复制为本地中继日志,然后读取复制数据产生二进制日志,再开启三个个线程往从2、从3、从4发送二进制日志便可
但是对从1来说它只需产生二进制日志,每必要复制数据啊(从1即不负责读也不负责写);但不复制数据产生写操作产生不了二进制日志,那给从2、3、4发啥?
此时从2可以使用Blackhole存储引擎,Blackhole类似于/dev/null当从1进行数据复制并写入磁盘时,Blackhole会直接将数据丢弃,然后响应一个数据已经记录;这样既不会产生额外的IO,也能产生二进制日志
当一个服务器压力过大时,一般有下面两种扩展:
scale out:加多台服务器,进行分担
scale on: 换用性能更好的服务器
而对MySQL数据库来说出还可以将一个大库拆分为几个小库(垂直拆分),让每个小库在不同的server上运行;并且对于数据来说,数据是有热区的,如果一个表中的数据被频繁使用导致服务器压力过大,还可以对这张表进行拆分(水平拆分)
但是无论是垂直拆分还是水平拆分都有一定的风险,所以能不拆分就别拆分