关于微服务跨数据库联合查询的一些解决思路

本文来说下关于微服务跨数据库联合查询的一些解决思路


问题由来

在这里插入图片描述


解决思路

下面提供几个思路仅供参考


表字段冗余

想必大家已经很熟悉,几乎每天都会打交道,不用多讲。

需要指出的是冗余字段不能太多,建议控制在2-4个左右。否则会出现数据更新不一致问题,一旦冗余字段有改动,极容易产生脏数据。

解决思路

建立同步机制,必要时采取人工补偿措施。

所以,合理的字段冗余是润滑剂,减少join关联查询,让数据库执行性能更高更快。


聚合服务封装查询

简单来说,就是把不同服务的数据统一组装在一个新的服务里做聚合,对外提供统一入口API接口查询。通俗来说下,就是以前在同一个数据库里面的表之间使用join来关联,现在可能这些表不在同一个数据库上了,怎么办,可以把每一个数据库里面的数据查询出来,最后使用java等语言把最终需要的结果拼装起来。反正是需要最终的结果,没法join了,用java来拼呗

聚合服务的数据组装是以API接口调用来实现,一般不建议直连数据库连表查询。这样做的好处是减少服务间调用次数以及查询库表压力。

在实际的业务开发中,我们经常碰到类似的需求,而聚合服务不失为一种较彻底的服务解耦实现方式。


表视图查询

如果涉及到不同数据库表之间的join查询,可以在其中某一数据库的表上建立视图(view)关系,这种方式非常高效,只需要开发一个简单接口对外提供服务就可以了,而且省去聚合服务带来调用、查询、聚合的复杂性。

前提条件

  • 数据库需要部署在同一台服务器上
  • 数据库账户密码必须相同,也就是在同一个schema下

另外表视图查询这种方式,是一种紧耦合的设计方式,不利于程序扩展,除非你很确定将来业务变动不大,可以考虑使用。以笔者经验来看,不适合大规模使用。


多数据源查询

这种方式是一种比较技术化的思路,简单来说就是一个微服务配置多个数据库源(DataSource),进行数据源来回切换进行库表查询,以达到获取不同数据的目的。

实现思路

  • 利用DynamicDataSource
  • 利用Spring的AOP动态切换数据源
  • 利用Spring的依赖注入方式管理Bean数据源对象

分库分表:使用数据库中间件

Sharding-Shpere

想必做过分库分表的同学对他一定不陌生,其出身来至当当开源项目sharding-jdbc。非常有限的跨库查询解决方案,目前在京东内部已经广泛使用。sharding-jdbc创始人张亮已加入京东,sharding-jdbc还在不停的迭代,目前更名为sharding-shpere,已经入Apache顶级项目,进行孵化,非常看好它。

在这里插入图片描述

Mycat

一个彻底开源的,面向企业应用开发的大数据库集群,支持事务、ACID、可以替代MySQL的加强版数据库;一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群;一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server;结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品;一个新颖的数据库中间件产品。

在这里插入图片描述


本文小结

本文介绍了一些现在常用的解决微服务跨库的解决方案,所有服务的划分是十分重要的。

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
微服务数据库设计 单独的数据库: 单独的数据库微服务设计的⼀个关键是数据库设计,基本原则是每个服务都有⾃⼰单独的数据库,⽽且只有微服务本⾝可以访问这个数据库。它是基于下 ⾯三个原因。 优化服务接⼝:微服务之间的接⼝越⼩越好,最好只有服务调⽤接⼝(RPC或消息),没有其他接⼝。如果微服务不能独享⾃⼰的数据 库,那么数据库也变成了接⼝的⼀部分,这⼤⼤拓展了接⼝范围。 错误诊断:⽣产环境中的错误⼤部分都是和数据库有关的,要么是数据出了问题,要么是数据库的使⽤⽅式出了问题。当你不能完全控 制数据库的访问时,会有各种各样的错误发⽣。它可能是别的程序直接连到你的数据库或者是其他部门直接⽤客户端访问数据库的数 据,⽽这些都是在程序中查不到的,增加了错误排查难度。如果是程序中的问题,只要修改了代码,那么这个错误就不会再有。⽽上⾯ 提到的错误,你永远都没法预测它们什么时候还会再次发⽣。 性能调优:性能调优也是⼀样,你需要对数据库有全权控制才能保证它的性能。如果其他部门⼀定要访问数据库,⽽且只是查询的话, 那么可以另外创建⼀份只读数据库,让他们在另⼀个库中查询,这样才不会影响到你的库。 理想的设计是你的数据库只有你的服务能访问,你也只调⽤⾃⼰数据库中的数据,所有对别的微服务的访问都通过服务调⽤来实现。当然, 在实际应⽤中,单纯的服务调⽤可能不能满⾜性能或其他要求,不同的微服务都多少需要共享⼀些数据。 共享数据: 共享数据: 微服务之间的数据共享可以有下四种⽅式。 静态表: 静态表: 有⼀些静态的数据库表,例如国家,可能会被很多程序⽤到,⽽且程序内部需要对国家这个表做连接(join)⽣成最终⽤户展⽰数据,这样 ⽤微服务调⽤的⽅式就效率不⾼,影响性能。⼀个办法是在每个微服务中配置⼀个这样的表,它是只读的,这样就可以做数据库连接了。当 然你需要保证数据同步。这个⽅案在多数情况下都是可以接受的,因为以下两点: 1. 静态的数据库表结构基本不变:因为⼀旦表结构变了,你不但要更改所有微服务数据库表,还要修改所有微服务的程序。 2. 数据库表中的数据变化不频繁:这样数据同步的⼯作量不⼤。另外当你同步数据库时总会有延迟,如果数据变化不频繁那么你有很多 同步⽅式可供选择。 只读业务数据访问: 只读业务数据访问: 如果你需要读取别的数据库⾥的动态业务数据, 理想的⽅式是服务调⽤。如果你只是调⽤其他微服务做⼀些计算,⼀般情况下性能都是可 以接受的。如果你需要做数据的连接,那么你可以⽤程序代码来做,⽽不是⽤SQL语句。如果测试之后性能不能满⾜要求,那你可以考虑在 ⾃⼰的数据库⾥建⼀套只读数据表。数据同步⽅式⼤致有两种。如果是事件驱动⽅式,就⽤发消息的⽅式进⾏同步,如果是RPC⽅式,就⽤ 数据库本⾝提供的同步⽅式或者第三⽅同步软件。 通常情况下,你可能只需要其他数据库的⼏张表,每张表只需要⼏个字段。这时,其他数据库是数据的最终来源,控制所有写操作以及相应 的业务验证逻辑,我们叫它主表。你的只读库可以叫从表。 当⼀条数据写⼊主表后,会发⼀条⼴播消息,所有拥有从表的微服务监听消息 并更新只读表中的数据。但这时你要特别⼩⼼,因为它的危险性要⽐静态表⼤得多。第⼀它的表结构变更会更频繁,⽽且它的变更完全不受 你控制。第⼆业务数据不像静态表,它是经常更新的,这样对数据同步的要求就⽐较⾼。要根据具体的业务需求来决定多⼤的延迟是可以接 受的。 另外它还有两个问题: 1. 数据的容量:数据库中的数据量是影响性能的主要因素。因为这个数据是外来的,不利于掌握它的流量规律,很难进⾏容量规划,也 不能更好地进⾏性能调优。 2. ** 接⼝外泄**:微服务之间的接⼝本来只有服务调⽤接⼝,这时你可以对内部程序和数据库做任何更改,⽽不影响其他服务。现在数 据库表结构也变成了接⼝的⼀部分。接⼝⼀旦发布之后,基本是不能更改的,这⼤⼤限制了你的灵活性。幸运的是因为另外建了⼀套 表,有了⼀个缓冲,当主表修改时,从表也许不需要同步更新。 除⾮你能⽤服务调⽤(没有本地只读数据库)的⽅式完成所有功能,不然不管你是⽤RPC⽅式还是事件驱动⽅式进⾏微服务集成,上⾯提到 的问题都是不可避免的。但是你可以通过合理规划数据库更改,来减少上⾯问题带来的影响,下⾯将会详细讲解。 读写业务数据访问: 读写业务数据访问: 这是最复杂的⼀种情况。⼀般情况下,你有⼀个表是主表,⽽其他表是从表。主表包含主要信息,⽽且这些主要信息被复制到从表,但微服 务会有额外字段需要写⼊从表。这样本地微服务对从表就既有读也有写的操作。⽽且主表和从表有⼀个先后次序的关系。从表的主键来源于 主表,因此⼀定先有主表,再有从表。 上图是例⼦。假设我们有两个与电影有关的微服务,⼀个是电影论坛,⽤户可以发表对电影的评论。另⼀个是电影商店。"movie"是共享

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值