随着互联网技术的发展,微服务作为一种云服务的架构方式被越来越多的企业采用,使用微服务的架构进行开发,提供了产品的可靠性,可扩展性,降低维护成本,同时也可以支持按需伸缩服务。对于开发人员,微服务的代码量明显减少,遇到问题也更容易解决。
但同时微服务也带来了许多问题,例如:分布式部署的复杂度明显提升、接口调整的成本升高、对运维的需求也更高了。其中一个主要的问题是不同的服务使用独立的数据库,提高了数据使用的效率,但对于复杂的业务场景也带来了查询其他服务的数据的复杂度。
微服务和数据库
微服务架构的一个非常明显的功能就是一个服务所拥有的数据只能通过这个服务的API来访问。
在一个电商网站中,比如,OrderService占有一个数据库,里边有一张表ORDERS;CustomerService也有自己的数据库包含表CUSTOMERS。
通过这样的封装,微服务之间就解耦了。
在开发期间,开发人员可以独立修改自己服务的数据库shema而不需要与其他服务的开发协调勾兑。
在生产上,服务之间都是隔离的。比如,一个服务从来不会因为另外一个服务占有了数据库的锁而导致阻塞等待。
不幸的是,这种数据库的拆分让管理数据的一致性以及不同服务间跨表查询变得困难。
1.常见问题
目前的企业服务开发中,报表开发是比较常见的开发任务,一个业务单据上一般会引用很多的基础数据对象,少的有几个,多的可能有十几个,如此会引发3个常见问题:
1.1 界面显示数据翻译问题:
在界面显示上,报表引用的数据一般显示为名称或编码,但数据库中存储为对象的ID。
因此,后台服务在查询到单据数据后需要转换为编码或名称返回界面显示
1.2 多个服务关联查询问题:
在报表业务实现时,经常会出现关联多个服务查询的场景,例如在电商系统中,一个用户的订单,设计商品信息,支付信息、订单物流信息等。需要追溯多个对象进行查询。
1.3 数据导入问题:
报表业务中,存在很多数据导入的场景,而通过excel导入数据时,需要根据名称或编码翻译为ID然后插入数据库中。
2. 常见解决方案探讨
对于界面显示数据翻译问题,按微服务的开发方式,最简单的方案是,同步调用相关的服务进行数据翻译。例如,
如果搜索条件中包含A的条件,则先去服务A中搜索,得到所有结果的主键,在服务B中使用where A.id IN (ids) 再次查询
可以看出中间有几个引用的数据,就需要调用几次远程服务接口。一方面,开发复杂,每个表单都需要编写相关的翻译代码,另一方面,调用次数过多,导致时间消耗过长。
因此,实际业务中常见的解决方案有几种:
2.1 数据库中冗余字段方式
展示订单信息时,需要翻译用户、商品、支付、物流等基础数据属性时,可以在订单中直接冗余相关的名称字段。在保存数据中直接保存到数据库中
此方案的问题是,如果对应的基础数据对象修改了名称时,需要同步修改的数据。
数据同步方案:
- 从业务方案上,可以通过事件通知的方式,在相关的对象发生变动时,同步修改冗余字段的内容。或者定时同步冗余字段内容。
数据同步引发问题:
- 但当报表不断增加的情况下,一个数据的变动,可能引发十几个或更多的报表或其他基础数据的同步行为,计算过程复杂,对数据的更新操作压力会比较大。
- 同时通过事件的方式进行同步,对开发要求较高,配置错误时,会导致数据没有被更新,显示错误。
2.2 直接备份数据表的方式
可以通过定时拉取的或推送的方式从指定的数据中,同步表数据,在同步时可以通过指定字段或建立视图等方式,仅同步指定字段内容,减少同步数据和避开敏感数据。
引发问题:
- 此方案的问题与第一个方案类似,但微服务不断增多的情况下,每个微服务都要同步其他微服务的数据库表,需要同步的数据库表会越来越多,带来的消耗也会越来越大。数
- 据库之间的同步关系复杂度上升对运维的复杂度也会升高。
- 而且同步出现问题时,也会导致界面显示数据的不一致性。
2.3 统一数据中心查询方式。
通过统一的数据采集服务,将数据收归到统一的数据中心,其他业务服务需要查询数据时,调用统一的数据服务中心进行查询,可以在最大程度上降低要同步数据的复杂度,通过合并多个对象查询的方式提高访问速度。
这就属于OLAP(Online analytical processing),即联机分析处理范畴了,具体实现有:
- 使用搜索引擎
- 在从库上做各种报表分析操作,比如线上的A库和B库都实时同步到一个只读库中,然后在只读库里JOIN一下就搞定了。
3 统一查询方案说明
此方案的实现主要是组合了PaaS以下几个能力形成的:存储模型管理,元数据模型管理,统一的数据仓库,数据同步服务,数据查询服务。
存储模型管理:
负责提供数据存储模型的建立,由数据提供方建立对外的数据模型视图。可支持数据提供方根据数据的敏感性或是否仅内部使用属性等对提供的数据模型进行选择,仅提供可对外提供的必要数据属性。
1.支持查询数据视图的模型的管理,支持单表模型描述,也支持多表关联的复杂结构数据模型描述。
在进行查询视图定义时,支持对数据进行筛选,数据提供方指定提供数据属性范围。
其次,有可能的情况下需要数据来源方提供ID、时间戳、删除标记等属性。用于后续数据抽取服务时的增量抽取能力。
2.支持对来源数据库的连接管理,可由业务方提供只读的数据库账号,用于同步服务同步数据使用。支持模型与数据库的关系管理,支持单一数据库部署,和多租户多数据库的部署模式。
为支持多租户的部署模型,部分微服务会连接存在相同的表结构多个数据库,通过租户或其他参数进行数据的分库存储。因此,在数据源模型描述支持多个数据库的描述方式。模型视图上仅与数据源保持关系,在来源业务系统更换数据库或进行数据库隔离的情况下,不需要重新修改视图模型。
元数据模型管理:
元数据一般指用于描述数据的数据,包含对象模型,对象的属性模型(包括属性的数据类型,与其他对象的引用关系),以及对象的存储模型。来源业务系统通过存储模型管理中描述的数据仓库的模型,与元数据的存储模型对应,建立完整的业务系统的对象关系模型。
元数据模型支持属性标签描述,用于后续查询服务可根据统一的标签进行查询,例如根据ID返回名称时,只需要个业务提供方在模型中的名称属性设置标签为(name)即可通过统一的语句进行查询。
统一数据仓库:
使用支持高并发的分布式NoSQL数据库实现。支持按字段条件查询的方式获取数据。
数据同步服务:
通过多种方式从业务系统的数据库中拉取对应的数据同步到统一数据仓库中。
1.支持通过定时任务拉取数据方式。
2.通过binlog同步方式。
一般通过两种方式结合,binlog可以保障数据以最短时间同步到统一数据仓库中。当啊同步服务出现问题时,可以通过定时任务进行补偿。
数据查询服务:
- 通过元数据模型,提供基于元数据模型的查询服务。根据元数据模型描述,形成对应的数据模型查询语句,调用数据仓库的接口进行查询。
- 可根据标签,进行语句的扩展,例如查询名称为“张三”的用户,可以使用name = “张三”,或者 <lable:name> = “张三”的方式描述查询条件参数。查询服务接收到参数后,根据元数据模型,转换为存储模型的结构,调用数据仓库的服务接口进行查询。
统一查询方案的优势如下:
1.对原有业务系统无侵入,不需要修改业务服务的代码。
2.在定义查询视图时,可通过限制查询字段及增加查询条件的方式,对敏感数据进行过滤,避免出现数据问题。
3.查询视图与实际业务视图分离,业务系统可在修改自己的数据库同时,通过修改查询视图,保障对原有的查询视图属性不发生变化,避免影响其他服务的使用。
4.使用独立的数据仓库进行查询操作,避免影响原有业务数据库的性能。
5.通过使用NoSql数据库构建数据仓库,在例如界面主键翻译这种高并发操作的提高执行效率。当数据仓库性能下降时,比较传统的关系型数据库更容易动态增容扩展。
统一查询方案业务上推荐使用的场景有:
1.界面显示数据时的主键翻译为名称、编码。
2.支持公式或报表等需要同步模型配置查询数据的场景。
3.可以用于参照服务,参照服务的数据实效性要求不高,使用统一数据仓库有利于降低主数据库的业务压力。
参考链接:
https://zhuanlan.zhihu.com/p/47011506
https://segmentfault.com/q/1010000009053767