文章目录
- 简介
- 为什么需要主从同步
- 主从同步的原理
- 总结
- 参考文献
简介
以MySQL数据库为例,在实际生产中,我们会如何对MySQL数据库进行性能优化呢?
比如说配合上Redis做缓存。Redis是一种高性能的内存数据库,而MySQL是一种基于磁盘文件的关系型数据库。Redis胜在读取速度极快,而MySQL虽然读取慢,但是可以持久化。因此实际工作中,我们经常将Redis作为缓存与MySQL配合使用。
当有数据请求进来时,会先从Redis里进行缓存查找,如果存在就直接取出,这样就不用再访问数据表,从而提升了读取的效率,也减少了后端数据库的访问压力。
基于Redis的这种缓存架构,是高并发架构中常用的一环。
除此之外,我们也可以对MySQL做主从架构进行读写分离,让主服务器(Master)处理写请求,从服务器(Slave)处理读请求,以此提升数据库的并发处理能力。
本节将会从以下几个方面来了解主从同步:
- 主从同步的作用
- 主从同步的原理和常见的问题
为什么需要主从同步
首先我们需要知道,并不是所有的应用都适合对数据库进行主从架构的设置,毕竟架构本身是有成本的。
如果你的目的是提升数据库并发访问的效率,那么首先应该做的是优化你的查询SQL和索引,这种方式简单且非常高效。其次才是采用缓存的策略,如引进Redis,利用Redis的高性能查询优势,将热数据保存在内存中,提升读取的效率。最后才是对数据库进行主从架构,进行读写分离。
上面三种方案,使用和维护的成本是由低到高的。
主从同步的设计在提高数据库吞吐量的同时,还有以下3个方面的作用。
- 读写分离
通过主从复制的方式来同步数据,通过读写分离来提高数据库的并发处理能力。
简单的说,就是一份数据被放在了多个数据库里,其中一个数据库是主库Master,负责所有写操作,其他的数据库是从库Slave,负责所有读操作。
当主库的数据被更新后,会自动的将数据同步到所有的从库。而我们通过客户端提交的数据读取申请,都会由从库来处理。这就是读写分离。
读写分离在互联网领域的作用很明显。因为互联网的应用大多是"读多写少",所以采用读写分离的方式,可以实现更高的并发访问。
原先所有的读写压力都是由一台服务器来承担,现在加入了多个兄弟来帮助它处理读请求,大大降低了主服务器的负担。同时提高了写和读流程的性能。
另外,我们还可以对从库做负载均衡,按策略将不同的读请求均匀的分配给不同的从库,进一步提升了读流程的性能。
而且,读写分离的架构下,也减少了锁表的影响,主库的写锁肯定是影响不到从库的读的。
- 数据备份
基于主从复制,将主库的数据复制到从库,相当于是一种热备份机制,即在不影响主库运行的情况下做的备份。更加保障安全。
- 高可用性
当主服务器出现故障或者宕机的情况下,可以迅速将一个从服务器切换成主服务器来履行职能,从而保障服务的正常运行,大大提高了容灾性。
关于高可用性的程度,确实是有一个指标可以来度量:正常可用时间/全年时间。
比如要达到全年99.999% 的时间都可用,就意味着系统在一年中的不可用时间不得超过 5.256 分钟。而且这5分钟里还包含了日常维护时的停机时间、系统崩溃时间等。
所以,更高的可用性,意味着更高的成本代价。日常生产中应该酌情选择。
主从同步的原理
首先我们需要了解数据库中的一个极其重要的日志文件,即binlog二进制日志,它记录了数据库所有更新的事件,
主从同步,就是基于binlog进行同步。在主从复制的过程中,存在3个线程,一个是主库线程,另外两个是从库线程。
二进制日志转储线程(binlog dump thread),是一个主库线程。当从库线程连接的时候,主库会将二进制日志发送给从库。而主库在读取更新事件时,则会将binlog上锁,待更新事件完成后,再将锁打开(考虑到数据一致性)。
从库IO线程用于连接主库,向主库发送更新binlog的请求。之后从库IO线程就可以读取到主库二进制日志转储线程发送过来的binlog,并拷贝到本地形成中继日志(Relay log)。
接着就是最后一个线程,从库SQL线程登场。它会读取从库保存下来的中继日志,并且执行日志中的更新事件,即将主库的更新事件在从库上再来一遍,从而使得从库的数据跟主库保持一致。
因此,主从同步的内容,实际上就是二进制日志(binlog)。
虽然叫做二进制日志,但它内部存储的是一个一个事件(Event),这些事件分别对应着数据库的更新操作,如insert、update和delete等。
另外,有的版本的MySQL默认是关闭二进制日志的,因此在进行主从同步的架构时,需要先检查服务器是否已经开启了二进制日志。
接着我们考虑一个问题,既然主从同步传输的是一个文件,那么进行传输的过程中必定是有网络延迟的,那么这个时间里,用户读取的从库数据就不是最新数据了,跟主库数据不一致,这种情况下该怎么办呢?
下一节会简单介绍一下这个问题。
总结
在配置主从架构的时候,如果想要采取读取分离的策略,可以选择自己编写程序,也可以通过第三方的中间件来实现。
自己编写程序还是有好处的,比如说我们可以自行判断什么样的查询可以在主库上,什么样的查询可以在什么样的从库上等。
中间件的话,胜在全面稳定,且使用简单,当然,在客户端和数据库之间添加一层中间件势必会带来一些性能的损耗,而且好用的商业中间件也是有成本的。开源的中间件的话,可以看看MaxScale,是MariaDB开发的MySQL数据中间件。如下图,使用MaxScale作为数据库的代理,通过路由转发来完成读写分离。同时配合上MHA工具来作为主从切换的工具(保障容灾),从而完成MySQL的高可用架构。
参考文献
- 35丨数据库主从同步的作用是什么,如何解决数据不一致问题?