高性能数据库集群-读写分离和分库分表
声明:学习完李运华《从 0 开始学架构》,有一种醍醐灌顶,豁然开朗的感觉。为了能够对其概念有一个深入的理解,并且掌握其总结的方法论。特意对本课程做一个提炼,形成自己的知识体系。毕竟能给别人讲清楚了,才能说明自己真的掌握了。本文的引用仅限自我学习如有侵权,请联系作者删除。
读写分离的应用场景是什么?
读写分离适用单机并发无法支撑并且读的请求更多的情形。在单机数据库情况下,表上加索引一般对查询有优化作用却影响写入速度,读写分离后可以单独对读库进行优化,写库上减少索引,对读写的能力都有提升,且读的提升更多一些。
不适用的情况:
1、如果并发写入特别高,单机写入无法支撑,就不适合这种模式。
2 、通过缓存技术或者程序优化能够满足要求。
如何实现读写分离?
读写分离的基本原理是将数据库读写操作分散到不同的节点上。基本架构图如下:
(1)数据库服务器搭建主从集群,一主一从、一主多从都可以。
(2)数据库主机负责读写操作,从机只负责读操作。
(3)数据库主机通过复制将数据同步到从机,每台数据库服务器都存储了所有的业务数据。
(4)业务服务器将写操作发给数据库主机,将读操作发给数据库从机
读写分离的设计点在哪里?
主从复制延迟和分配机制。
1、解决主从复制延迟有几种常见的方法
(1)写操作后的读操作指定发给数据库主服务器。这种方式和业务强绑定,对业务的侵入和影响较大。
(2)二次读取。读从机失败后再读一次主机,不足之处在于如果有很多二次读取,将大大增加主机的读操作压力。比如黑客暴力攻击。
(3)关键业务读写操作全部指向主机,非关键业务采用读写分离。
2、解决分配机制
将读写操作区分开来,然后访问不同的数据库服务器,一般有两种方式:程序代码封装和中间件封装。
(1)代码封装例如:淘宝的 TDDL(Taobao Distributed Data Layer,外号: 头都大了)是比较有名的。
(2)中间件封装:
现在开源如:MySQL 官方推荐 MySQL Router。MySQL Router 的主要功能有读写分离、故障自动切换、负载均衡、连接池等。
为何要分库分表?
读写分离分散了数据库读写操作的压力,但没有分散存储压力,当数据量达到千万甚至上亿条的时候,单台数据库服务器的存储能力会成为系统的瓶颈。
(1)数据量太大,读写的性能会下降,即使有索引,索引也会变得很大,性能同样会下降。
(2)数据文件会变得很大,数据库备份和恢复需要耗费很长时间。
(3)数据文件越大,极端情况下丢失数据的风险越高(例如,机房火灾导致数据库主备机都发生故障)。
总结:可以解决数据库连接资源不足、磁盘IO的性能瓶颈、检索数据耗时 和 消耗cpu资源等问题。
怎么业务分库?
垂直分库:业务分库指的是按照业务模块将数据分散到不同的数据库服务器。例如:
水平分库:业务可能按照区域分库(华中 、华北、华南),月份分库、季度分库。
业务分库的复杂度来源是什么?
复杂度主要在于垂直分库,将引入:
(1)join 操作问题。
(2)分布式事务问题。
(3)成本问题(一般基于演化原则,主要解决当前问题)
为何要分表?
将不同业务数据分散存储到不同的数据库服务器,能够支撑百万甚至千万用户规模的业务,但如果业务继续发展,同一业务的单表数据也会达到单台数据库服务器的处理瓶颈。
总结:是为了解决单表数据量太大,sql语句查询数据时,即使走了索引也非常耗时问题。此外还可以解决消耗cpu资源问题。
如何进行分表?
单表数据拆分有两种方式:垂直分表和水平分表。如下:
分表带来的复杂度体现在哪里?
垂直分表:
适合将表中某些不常用且占了大量空间的列拆分出去,垂直分表引入的复杂性主要体现在表操作的数量要增加。
水平分表:
(1)引入路由规则(范围路由、Hash 路由、配置路由)
范围路由的优点是可以随着数据的增加平滑地扩充新的表,缺点是分布不均匀。
Hash 路由的优点是表分布比较均匀,缺点是扩充新的表很麻烦,所有数据都要重分布。
配置路由优点是设计简单,使用起来非常灵活。缺点是必须多查询一次,会影响整体性能;而且路由表本身如果太大(例如,几亿条数据),性能同样可能成为瓶颈,如果我们再次将路由表分库分表,则又面临一个死循环式的路由算法选择问题。
(2)join 操作问题。
(3)count() 操作问题。解决办法有count() 相加或者记录数表来处理。
(4)order by 操作问题。
业务如何实现分库分表方案?
和读写分离一样可以采用:程序代码封装和中间件封装(mycat、shardingsphere等)
数据库问题优化步骤是什么?
1.做硬件优化。
2.先做数据库服务器的调优操作,例如增加索引,oracle有很多的参数调整。
3.引入缓存技术,例如Redis,减少数据库压力。
4.程序与数据库表优化,重构,例如根据业务逻辑对程序逻辑做优化,减少不必要的查询。
5.在这些操作都不能大幅度优化性能的情况下,不能满足将来的发展,再考虑分库分表,也要有预估性。