一、基本概念
概念1 :单个库
概念2 :瓷砖化
分片解决了“数据量太大”的问题,也就是通常所说的“水平分割”。
分片部署后,将面临“数据路由”这一新问题,数据将访问哪个库? 路由选择规则通常有三种方法。
(1)范围:范围
优点:简单,易于扩展。
优点:各围堰的压力不均匀(新号段更活跃)。
)2) zs dkl :混列
优点:简单、数据均衡、负载均匀。
缺点:迁移很麻烦(2库扩展3库数据迁移)。
(3)统一路由服务)路由器-配置-服务器
优点:灵活性强,业务和路由算法解耦。
缺点:每次访问数据库时增加一次查询。
大多数互联网公司采用的方案zsdkl路由。
概念3 :分组
分组解决“提高可用性、性能”的问题。 分组通常以主从方式实现。
互联网数据库的实际软件体系结构是“分片和分组”。
数据库软件体系结构有什么关系呢? 至少需要考虑以下四点。
如何提高数据库的读取性能,以确保数据的可用性? 大多数APP读取多,写入少,读取最先遇到瓶颈。 如何提高可扩展性以确保一致性? 2、如何确保数据的可用性?
解决可用性问题的想法是冗余。
如何确保站点的可用性? 冗余网站。
如何保证服务的可用性? 冗长的服务。
如何确保数据的可用性? 冗余数据。
数据冗余带来的副作用是一致性问题。
如何确保数据库“读取”的可用性?
冗余库。
冗余库会带来什么副作用?
读写有延迟,数据可能不一致。
上图是许多互联网公司mysql的架构,写操作仍然是单点的,不能保证写操作的可用性。
如何确保数据库的“写”可用性?
冗余写入库。
采用双主相互准备的方式,可以冗长地写库。
冗余写入库会带来什么副作用?
有双重写入同步、数据冲突的可能性。 例如,“自我增加标识”同步冲突)。
有两种常见的解决方案可以解决同步冲突:
1 ) 2个写入库以不同的初始值、同一步骤增加id。 1写入库的id为0、2、4、6…; 2库的id为1、3、5、7…;
)不使用数据的id,业务层生成自己的id,保证数据不冲突;
据说AlibabaCloud (阿里巴巴云)的RDS服务具有很高的可写性,它是如何实现的呢?
他们采用的方式类似于“双主同步”。 库中已经没有了。
虽然还是双大师,但只有一个大师提供读写服务。 另一个主机是“shadow-master”,只用于确保高可用性,平时不提供服务。
主场挂了,shadow-master顶了,虚拟IP漂移,对业务层透明,不需要人工干预。
此方法的优点:
(1)读写没有延迟,没有
一致性问题;(2)读写高可用;
不足是:
(1)不能通过加从库的方式扩展读性能;
(2)资源利用率为50%,一台冗余主没有提供服务;
画外音:所以,高可用RDS还挺贵的。
三、如何扩展读性能?
提高读性能的方式大致有三种,第一种是增加索引。
这种方式不展开,要提到的一点是,不同的库可以建立不同的索引。
如上图:
(1)写库不建立索引;
(2)线上读库建立线上访问索引,例如uid;
(3)线下读库建立线下访问索引,例如time;
第二种扩充读性能的方式是,增加从库。
这种方法大家用得比较多,存在两个缺点:
(1)从库越多,同步越慢;
(2)同步越慢,数据不一致窗口越大;
第三种增加系统读性能的方式是,增加缓存。
常见的缓存架构如下:
(1)上游是业务应用;
(2)下游是主库,从库(读写分离),缓存;
如果系统架构实施了服务化:
(1)上游是业务应用;
(2)中间是服务;
(3)下游是主库,从库,缓存;
业务层不直接面向db和cache,服务层屏蔽了底层db、cache的复杂性。
不管采用主从的方式扩展读性能,还是缓存的方式扩展读性能,数据都要复制多份(主+从,db+cache),一定会引发一致性问题。
四、如何保证一致性?
主从数据库的一致性,通常有两种解决方案:
(1)中间件
如果某一个key有写操作,在不一致时间窗口内,中间件会将这个key的读操作也路由到主库上。
(2)强制读注
“双主高可用”的架构,主从一致性的问题能够大大缓解。
第二类不一致,是db与缓存间的不一致。
这一类不一致,之前聊过,本文不再展开。
另外建议,所有允许cache miss的业务场景,缓存中的KEY都设置一个超时时间,这样即使出现不一致,有机会得到自修复。
------------------------------------------------------------------------------------------------------------------
转自微信公众号-架构师之路