之前做项目时,业务拆分粒度比较大,数据库也自然而然的拆分了,这当中遇到最主要的问题就包含数据相关问题,比如:字典数据问题,我们知道在列表展示数据的时候通常会用到字典数据,假如字典数据做同步那么直接关联查询就可以搞定,如果字典数据不做同步,那么又该怎么实现列表数据展示?本节内容我就分布式系统中数据库存储的热点问题进行梳理。
我以我熟悉的房产领域业务来进行说明,比如二手房交易的业务,简化后如下图所示:
第一步:房东在中介挂牌
第二步:购房人来中介找房
第三步:房东、中介、购房人三方签约
第四步:购房人向房东付购房款
在这个二手房业务里面,我将他划分为房源服务、主体服务、签约服务、支付服务。各个服务对应的数据单元如下:
在房源微服务中,房源表有行政区划代码(areacode)这个字段,表示这个房源坐落在那个行政区域。在主体微服务中,中介表也存在areacode这个字段,表示中介所注册的行政区域。
行政区域是国家统一规划的,轻易不怎么改变,只是在区域资源整合的时候才会有变化,并且得需要国家部门审批,所以一般来说我们当作字典数据用
服务拆分后,数据库也随之拆分,由此带来了一些复杂的问题,比如行政区域字典表数据怎么存储,怎么同步,怎么关联查询,这些问题就不可避免了。
跨库关联查询问题
场景一
在单体应用时代,areacode这个表和房源、中介表同属一个库,直接做关联查询即可。业务拆分后,数据库独立了,这个时候做关联查询就不可行了,那么怎么解决这个问题?
首先,我们可以想到利用“冗余思想”,在房源、中介表添加冗余字段,也就是存储一个areaname(行政区划名称)字段,这样做的不好的地方是,行政区划代码名称改了后,业务表中无法改变。
其次,还是利用“冗余思想”,直接在房源和主体数据库添加areacode表,此表只适用于各自数据单元内的关联查询,当areacode(通常在通用服务)所属微服务里发生数据改变时,需要使用消息中间件异步刷新所有订阅了areacode表数据的冗余表中的数据。
场景二
假如我有一个房地产业务大平台,涵盖期房、二手房、租赁业务,我想查询这套房子生命周期内期房购买人、二手房买卖人以及租赁人信息,这些业务数据分布在各个微服务中,这种基于某一维度或某一主题的数据查询,这种情况也需要跨库关联查询。
面对这种情况,我们无法跨越多个微服务来统计这些数据,但是我们可以面向不同业务主题建立分布式数据库,例如我们可以建立“房屋干系人”数据库,它的数据来自于不同业务领域的微服务。可以采用数据库日志捕获技术和领域事件驱动机制,从各个业务端服务将数据准时汇集到主体数据库。然后建立面向主体数据库查询的微服务,这样就可以查询同一套房源的所有干系人数据了。还可以根据主题设计分布式数据库的分库主键,以提高大数据量下的数据查询效率。
热点高频数据问题
像areacode数据,同时面向多个应用,需要有很高的并发能力。这个问题常用的解决方式是使用Redis缓存,这样不仅降低数据库压力,还可以提高数据的访问性能。只需要关注下下数据库和缓存的数据一致性即可。
还有像模糊查询的高频数据,可以选择ElasticSearch搜索引擎技术。
分布式数据库怎么选择问题
- 方案一
原生分布式数据库方案,一次性写入多副本 - 方案二
集中式数据库、数据库中间件,比如:MySQL和MyCat - 方案三
集中式数据库、分库类库
数据库的数据同步和复制问题
数据拆分后,为了实现数据的迁移、数据备份、不同业务渠道向数据中台的复制、以及不同主题的数据整合的需要,数据库同步和复制就变成不可或缺的了。
常用数据同步方式:
- ETL工具
- 定时程序提取数据
分布式架构一般采取数据库日志捕获技术(CDC),根据数据库增量日志提取数据库增量数据,实现准实时的数据复制和传输。
分布式架构在解决问题的同时,也让系统变得更加的复杂,仅数据相关的问题就需要我们深入研究,这篇文章只是其中的几个问题,其实数据库领域是非常复杂的,还需加强学习,继续加油!