Mysql 5.0之后,支持经过binary log(二进制日志)以支持主从复制。复制容许未来自一个MySQL数据库服务器(master)的数据复制到一个或多个其余MySQL数据库服务器(slave),以实现热备份、读写分离、水平扩展、统计分析、远程数据分发等功能。二进制日志中存储的内容称之为事件,每个数据库更新操做(Insert、Update、Delete,不包括Select)等都对应一个事件。html
图-MySQL基于binlog主从复制mysql
主要分为3个步骤:
第一步:master在每次准备提交事务完成数据更新前,将改变记录到二进制日志(binary log)中(这些记录叫作二进制日志事件,binary log event,简称event)
第二步:slave启动一个I/O线程来读取主库上binary log中的事件,并记录到slave本身的中继日志(relay log)中;
第三步:slave还会起动一个SQL线程,该线程从relay log中读取事件并在备库执行,从而实现备库数据的更新。spring
因为网络延迟、机器性能、大事务、锁、MySQL参数设置等存在的问题,可能使得主从数据存在延迟,须要考虑好应该在什么场景下来用MySQL主从同步,建议是通常在读远远多于写,并且读的时候通常对数据时效性要求没有那么高,采用主从同步。解决的具体作法有:优化MySQL配置参数、分库、并行复制、强一致性业务强制路由主库。具体作法能够参考:简书-mysql读写分离和解决主从同步延时问题、掘金-mysql同步(复制)延迟的缘由及解决方案、CSDN-完全终结MySQL同步延迟问题sql
MySQL复制默认是异步的,主库写入事务在生成Events并写入到Binlog文件以后,写入线程是不等待的,或者能够说主库并不知道从库是否是已经收到或处理了这些Binlog。在这种状况下,若是主库挂了,有可能没有任何一个从库能够收到已经在主库提交的事务,而此时若是高可用架构将业务从主库切换到了从库,则可能会致使从库丢失主库上面发生的不少修改。数据库
如何解决?能够采用半同步复制策略,是介于全同步复制与全异步复制之间的一种,主库只须要等待至少一个从库节点收到Flush Binlog到Relay Log文件便可,主库不须要等待全部从库给主库反馈,同时这里只是一个收到的反馈,而不是已经彻底执行而且提交的反馈,这样就节省了不少时间。具体过程能够参考:高效开发运维-MySQL半同步复制apache
经过数据冗余将数据库读写操做分散到不一样的节点上,数据库主机经过主从同步将数据复制到从机,每台数据库服务器都存储了全部的业务数据,其中主机负责写操做,从机负责读操做。适合并发量大,读远大于写的场景,数据实时性不那么严格的业务。通常经过上述binlog复制来实现,所以存在上述延迟问题。缓存
如何将读写操做区分开来,而后访问不一样的数据库服务器?通常有客户端代码封装实现,如Sharding-JDBC、TDDL和服务端中间件封装如Cobar、MyCat两种。具体分析能够参考:芋道源码-浅谈高性能数据库集群——读写分离安全
常见的作法有如下几种:服务器
数据库记录数达到多少许级须要考虑分库分表?阿里巴巴《Java开发手册》推荐“单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表,若是预计三年后的数据量根本达不到这个级别,请不要在建立表时就分库分表”。事实上该数值的评估与MySQL的配置以及机器的硬件有关。具体分析能够参考:占小狼的博客-MySQL单表数据不要超过500万行:是经验数值,仍是?网络
拆分后,数据库多是分布式在不一样实例和不一样的主机上,join将变得很是麻烦。并且基于架构规范,性能,安全性等方面考虑,通常是禁止跨库join的。那该怎么解决?
所谓全局表,就是有可能系统中全部模块均可能会依赖到的一些表。比较相似咱们理解的“数据字典”。为了不跨库join查询,咱们能够将这类表在其余每一个数据库中均保存一份。同时,这类数据一般也不多发生修改(甚至几乎不会),因此也不用太担忧“一致性”问题。
这是一种典型的反范式设计,在互联网行业中比较常见,一般是为了性能来避免join查询。字段冗余能带来便利,是一种“空间换时间”的体现。但其适用场景也比较有限,比较适合依赖字段较少的状况。最复杂的仍是数据一致性问题,这点很难保证,能够借助数据库中的触发器或者在业务代码层面去保证。
例如A库中的tab_a表和B库中tbl_b有关联,能够定时将指定的表作同步。固然同步原本会对数据库带来必定的影响,须要性能影响和数据时效性中取得一个平衡,这样来避免复杂的跨库查询,能够经过ETL工具来实施。
在系统层面,经过调用不一样模块的组件或者服务,获取到数据并进行字段拼装。简单字段组装的状况下,咱们只须要先获取“主表”数据,而后再根据关联关系,调用其余模块的组件或服务来获取依赖的其余字段(如例中依赖的用户信息),最后将数据进行组装。一般,咱们都会经过批量查询以及缓存来避免频繁RPC通讯和数据库查询的开销。
按业务拆分数据库以后,不可避免的就是“分布式事务”的问题。以往在代码中经过spring注解简单配置就能实现事务的,如今则须要花很大的成本去保证一致性。具体解决方案参考:分布式事务
能够参考:美团技术团队-大众点评订单系统分库分表实践,闲鱼技术-21世纪了还愚公移山?数据库这么迁移更稳定!,程序猿DD-推荐一个不错的分库分表实践!
能够参考:
Hollis-SpringBoot 2.x ShardingSphere分库分表实战
参考资料