当单个数据库数据量达到必定程度后,咱们能够采用多个从库解决读请求的系统瓶颈。 而写请求的系统瓶颈每每须要经过分库解决。mysql
以用户订单场景为例,用户会有查询订单需求,因此订单的分库须要基于userID作切分。sql
商家对订单统计纬度也一样有需求,因此单一的基于userID作切分的场景不知足这个场景了。数据库
因而咱们须要采用反范式设计来知足两种场景的需求。 采用两份数据冗余,即一份数据基于UserId,一份数据基于PoiId。异步
既然咱们有了方案,需求指定具体的技术方案了。分布式
作数据冗余常见有三种方案:工具
这是最简单的实现方式,在用户下单后,基于分库规则一份请求按userId划分入库,一份请求按poiId划分入库,数据落库才进行下一步请求,数据一致性强。设计
可是整个请求耗时的时间是两个入库时间的总和,若是在业务高峰期,每每形成时延升高问题,不适用于对时延敏感的系统。中间件
将两个同步入库修改成异步入库,采用MQ异步消息投递方式实现,这样能够解决两次写入库带来的时间损耗,可是会引入MQ中间件,系统复杂度有必定的提高。队列
既然存在了异步队列,两个库之间存在数据不一致时间窗口,不适用于对数据一致性敏感对系统。开发
引入数据同步中间件,屏蔽了业务层实现数据同步,数据冗余的细节,而是交由底层同步中间件实现,使得开发人员专一于业务开发。
与第二种方案相比,中间件方式基于mysql的binlog实现,因此数据一致窗口更短,可靠性更高。
固然以上三种方式的后两种方式都是异步方式,在分布式场景下都会存在数据一致性问题,强一致性很难,通常业务系统都采用最终一致性。
为保证数据一致性能够采用:异步检测,异步修复。
采用离线工具,或定时任务,定时对离线数据源进行扫描,如发现数据不一致进行补偿修复。
数据源扫描粒度视对一致性要求的强度而定。可是大量的数据扫描,耗时较长,效率较低。
为下降全量数据扫描的效率问题,能够设计增量数据扫描方式,设置更适合系统负载的扫描时间窗口,提升扫描检测效率。
若是想更实时扫描,可引入同步扫描方式,引入MQ推送消息,在订阅者接收到消息时,触发数据扫描,扫描时间窗口期内数据,同时进行修正。