在分布式系统中,每一台服务器都须要访问本地缓存、分布式MC缓存、分布式后台数据库,对于同一个业务模块,随着业务变复杂,须要定义愈来愈多的数据Model,按照必定的规则存储在本地缓存、分布式缓存以及后台数据库中。前端
目前,业界的数据访问层定位于应用程序与持久化数据库之间,好比淘宝的TDDL、IBatis Sharding等,主要完成数据的分库分表、读写分离等,本文的数据存储涵盖缓存、数据库、文件系统,现有的数据库DAL中间件、Redis客户端、MC客户端将做为本文的水平维度的Adaptor,主要解决的问题:数据库
数据访问在水平数据存储维度的一致性问题。后端
快速增长数据Model的能力。缓存
优雅、清晰、模块化的数据访问层代码。服务器
对于上节的问题,下面列举了水平和垂直维度抽象思考的例子。微信
假设水平维度:架构
部分热数据存储在本地缓存,本文使用EhCache。框架
部分热数据存储在前端缓存,本文使用MC。异步
全量数据存储在数据库缓存,本文使用MySQL。分布式
假设垂直维度:
数据模型FileMeta,须要同时存储在LocalCache、Redis和MySQL中。
数据模型BlockMeta,须要存储在LocalCache、MC中。
数据模型Context,须要存储在MC、MySQL中。
按照上面的分析,咱们画出系统两个维度正交设计图,以下:
咱们能够想到垂直维度定义N = 3个数据模型接口,水平维度定义N = 3个分层接口,可是水平维度和垂直维度是什么关系呢?
在本文的设计中,对问题作了进一步思考,水平维度的接口所有由垂直维度的数据模型接口组合(Composition)而成,完成全部业务只须要定义N + M + 1个接口,而不是N * M + 1个接口,多余的那个是DAL接口,完成数据访问层封装工做,第一节例子中的接口定义见下图:
上节主要介绍了接口设计,这里说一下实现,数据模型类很是简单,只要MC Client、TDDL、EhCache在不一样层完成相应接口实现,最重要的是DAL实现类,须要完成水平各个维度的策略存储,好比对一个Model,顺序写入MC和MySQL,根据业务实践经验,总结出3条设计原则:
每个数据模型都有CRUD方法,即数据操做的增删改查,对于MC或者LocalCache来讲,增长操做和修改操做多是一致的,这种状况也必须严格定义CRUD方法。
DAL层封装全部的数据访问,保证数据的一致性存储和可靠性,DAL层的实现调用ILocalCacheService、IMCService、IDAOService,根据不一样数据模型的存储策略,分别去调用缓存和数据库服务,数据模型若是仅存在MySQL或者MC,也须要在DAL层作封装,这样虽然对开发效率有必定影响,可是总体开发和维护成本下降不少。
DAL实现抽象出一个DALContext和一个Executor,对于不一样的数据模型,配置出不一样的DALContext,好比顺序存储在MC和MySQL或者同步写入MC异步写入MySQL,DAL也须要负责出错处理、水平维度的容灾切换等。
对于互联网后端应用来讲,最主要的功能就是处理数据,对DAL层的探索与优化是很是有价值的,基于本文提出的2-3法则,感兴趣的读者能够构建一个DAL开源项目,有两种思路。
第一种思路是:
定义数据模型以及存储配置策略规范,可使用相似protobuf的规范。
根据业务定义的数据模型和存储配置策略,生成业务代码。
开发者在此基础上扩充完善业务代码。
第二种思路是:
定义数据模型以及存储配置策略规范,可使用相似protobuf的规范。
开发DAL中间件(容器),根据业务定义的数据模型和存储配置策略,运行时完成全部的数据访问操做代理。
第一种相对容易,第二种比较复杂,读者能够本身选择其中一种。
本文首发于“微博平台架构”微信公众号,发布时有少许的文字润色和调整。
卫向军(@卫向军_微博),毕业于北京邮电大学,现任微博平台架构师,前后在微软、金山云、新浪微博从事技术研发工做,专一于系统架构设计、音视频通信系统、分布式文件系统和数据挖掘等领域。