天天看点

高性能架构-高性能数据库集群:读写分离高性能数据库集群:读写分离

高性能数据库集群:读写分离

01 | 导读

1、实践中,为了设计出优秀的架构,除了掌握这些基础知识外,还需要掌握业界已经成熟的各种架构模式,在此基础上根据业务和团队情况进行优化和调整。

2、高性能数据库集群有两种方式:读写分离和分库分表

1)读写分离:本质是将访问压力分散到集群中的多个节点,但是没有分散存储压力。

2)分库分表:既可以分散访问压力,又可以分散存储压力。

02 | 读写分离原理

1、读写分离的基本原理是将数据库读写操作分散到不同的节点上

高性能架构-高性能数据库集群:读写分离高性能数据库集群:读写分离

2、读写分离的实现

1)数据库服务器搭建主从集群,一主一从,一主多从

2)主机负责读写操作,从机只负责读操作。

3)主机通过复制将数据同步到从机,每台数据库都存储了所有的业务数据。

4)读写分离实现逻辑并不复杂,但引入了设计复杂度:主从复制延迟和分配机制。

03 | 复制延迟

1、问题

1)MySQL主从复制延迟可能达到1秒,大量数据同步可能延迟1分钟,可能会出现主库写入数据,从库读取不到的问题。例如:注册。

2、解决方法1:写操作后的读操作指定发给数据库主服务器

1)该方式和业务强绑定,对业务入侵和影响较大,若新手不知道既定规则,容易出现bug。

3、解决方法2:读从机失败后再读一次主机

1)即二次读取,二次读取和业务无绑定,只需要对底层数据库访问API进行封装即可,实现代价小;

2)不足之处:如果有很多二次读取,将大大增加主机的读操作压力。例如黑客暴力破解,将产生大量二次读取。

4、解决方法3:关键业务读写操作全部指向主机,非关键业务采用读写分离。

1)例如:用户管理系统中,注册+登录的业务读写操作访问主机;

2)而用户的介绍、爱好、等级采用读写分离。

3)用户修改介绍后,查询时还是旧介绍,相对于无法登陆,用户是可以容忍的。

04 | 分配机制

1、读写分离,访问不同的数据库服务,有两种方式:程序代码封装和中间件封装。

2、程序代码封装

1)在代码中抽象一个数据访问层(“中间层封装”),实现读写分离和数据库服务器连接的管理。例如基于Hibernate 进行简单封装,实现读写分离。
高性能架构-高性能数据库集群:读写分离高性能数据库集群:读写分离
2)程序代码封装的特点:
1. 实现简单,可以根据业务做定制化功能。
	2. 每个编程语言都需要实现一次,无法通用,若业务中包含多个编程语言写的多个子系统,则重复开发量较大。
	3. 故障情况下,主从切换,可能需要所有系统修改配置,并重启。
           
3)开源方案:淘宝的TDDL(TaoBao Distributed Data Layer)。它是一个通用的数据访问层,所有功能封装在jar包中提供给业务代码调用。
高性能架构-高性能数据库集群:读写分离高性能数据库集群:读写分离

3、中间件封装

1)中间件定义
1. 中间件封装指的是独立一套系统出来,实现读写分离和数据库服务器连接的管理。
	2. 中间件对业务服务器提供SQL兼容的协议,业务服务器无须自己进行读写分离。
	3. 对业务服务器来说,中间件就是一个数据库服务器。
           
高性能架构-高性能数据库集群:读写分离高性能数据库集群:读写分离
2)数据库中间件方式的特点
1. 能支持多种编程语言,对业务服务器提供标准的SQL接口
	2. 中间件要支持完整的SQL语法和数据库服务器的协议,实现比较复杂,细节特别多,很容易出bug,需要较长时间才能稳定。
	3. 中间件自己不执行真正的读写操作,但是所有的数据库操作请求都要经过中间件,中间件的性能要求很高。
	4. 数据库主从切换对业务服务器无感知,数据库中间件可以探测数据库服务器的主从状态。(写一条数据,成功为主,失败为从)
           

3)数据库中间件的复杂度要比程序代码封装高出一个数量级,一般情况下建议采用程序语言封装的方式,或者使用开源数据库中间件。

4)开源方案:

1. MySQL官方推荐的MySQL Router(用于替代MySQL Proxy)。其主要功能有读写分离、故障自动切换、负载均衡、连接池等。
	2. 360的开源数据库中间件Atlas,它是基于MySQL Proxy实现的。
	3. mycat。
           
高性能架构-高性能数据库集群:读写分离高性能数据库集群:读写分离

05 | 小结

1、不要一有性能问题就上读写分离,而是应该先优化,例如优化慢查询,调整不合理的业务逻辑,引入缓存等,只有确定系统没有优化空间后,才考虑读写分离或者集群。

2、适用和不适用的情况

1)适用情况:读写分离适用单机并发无法支撑并且读的请求更多的情形。
		1. 在单机数据库情况下,表上加索引一般对查询有优化作用却影响写入速度,读写分离后可以单独对读库进行优化,写库上减少索引,对读写的能力都有提升,且读的提升更多一些。
	2)不适用的情况:
		1. 如果并发写入特别高,单机写入无法支撑,就不适合这种模式。
		2. 通过缓存技术或者程序优化能够满足要求
	3)使用缓存时, 按照2-8原则,选出占访问量80%的前20%的请求条件缓存,因为大部分人的查询不会每次都查询非常多条件,以手机为例,查询苹果加华为的可能占很大一部分
           

3、SQL走从库还是走主库,如何防止新手将大量本该走从库的SQL,走主库,造成主库压力过大。

1)默认读走从库,写走主库,特殊情况才由程序员制定,可以代码指定,可以配置指定,这样就不会出现大量sql都走主库了。

参考文献:

[1] 李运华. 从0开始学架构[M]. 极客时间, 2018.

[2]图片取自【从0开始学架构】专栏