关于java:使用查询分离后从20s优化到500ms

31次阅读

共计 2521 个字符,预计需要花费 7 分钟才能阅读完成。

大家好,我是不才陈某~

在后面一篇文章中提到过对于业务主表读写迟缓的解决方案:冷热拆散,有不理解的请看:业务主表读写迟缓如何优化?

冷热拆散诚然是一个性价比高的解决方案,但也并不是银弹,依然有诸多限度,比方:

  1. 查问冷数据慢
  2. 业务无奈批改冷数据
  3. 冷数据多到肯定水平零碎仍旧扛不住

此时如果须要解决以上问题,能够采纳另外一种计划:应用 查问拆散 优化业务主表数据大查问迟缓的问题

什么是查问拆散?

查问拆散从字面上来说非常容易了解,其实就是在写数据时保留一个备份数据到另外的存储系统,在查问时间接从另外的存储系统中获取数据,如下图:

以上只是简略的架构图,其中有些细节还是须要深究,如下:

  1. 什么时候触发查问拆散?
  2. 如何实现查问拆散?
  3. 查问数据的存储系统选型?
  4. 查问数据如何应用?

查问拆散的实用场景?

当你在理论业务中遇到以下情景,则能够思考应用查问拆散解决方案。

  • 数据量大;
  • 所有写数据的申请效率尚可;
  • 查问数据的申请效率很低;
  • 所有的数据任何时候都可能被批改;
  • 业务心愿咱们优化查问数据的性能。

曾做过 SaaS 客服零碎的架构优化,零碎里有一个工单查问性能,工单表中寄存了几千万条数据,且查问工单表数据时须要关联十几个子表,每个子表的数据也是超亿条。

面对如此宏大的数据量,跟后面的冷热拆散一样,每次客户查问数据时几十秒能力返回后果,即使咱们应用了索引、SQL 等数据库优化技巧,成果仍然不显著。

工单表中有些数据是几年前的,客户说这些数据波及诉讼问题,须要持续放弃更新,因而咱们无奈将这些旧数据封存到别的中央,也就没法通过后面的冷热拆散计划来解决。

最终咱们采纳了查问拆散的解决方案,才得以将这个问题顺利解决:将更新的数据放在一个数据库里,而查问的数据放在另外一个零碎里。因为数据的更新都是单表更新,不须要关联也没有外键,所以更新速度立马失去晋升,每次客户查问数据时,500ms 内就可失去返回后果。

什么时候触发查问拆散?

简略的来说就是什么时候应该保留一份数据到查询数据库中,其实也就是数据异构的过程,具体文章能够看我后面一篇文章:数据异构就该这样做,yyds~

这里介绍三种形式,如下:

  1. 同步建设
  2. 异步建设
  3. binlog 形式

1、同步建设

批改业务代码:在写入惯例数据后,同步建设查问数据。

该种计划优缺点也非常明显:

长处:查问数据的一致性和实时性失去了保障

毛病:业务代码侵入比拟强;减缓写操作的效率

2、异步建设

批改业务代码:写入数据后,异步建设查问数据

该种计划的优缺点如下:

长处:不影响主流程

毛病:数据一致性存在问题

3、binlog 的形式

该种计划也是业界罕用的一种计划,对于代码是无侵入的,通过监听数据库日志的形式建设查问数据,如下:

该种计划的优缺点如下:

长处:不影响主流程;代码侵入为 0

毛病:数据一致性存在问题;架构绝对简单

如何实现查问拆散?

对于上述三种计划都算是比拟常见的计划,对于第一种同步的形式比较简单,这里不再介绍;对于第三种 binlog 的形式在数据异构的文章中介绍过,详情见:数据异构就该这样做,yyds~

这篇文章来介绍一下异步的形式,异步的形式有很多,能够放在内存中进行操作,然而这有些弊病:

  1. 数据过多,内存无限
  2. 服务重启,内存数据将会失落

因而最终咱们能够抉择 MQ 的形式,那么此时就波及到了 MQ 的技术选型,这里给两个倡议:

  1. 如果你的公司曾经用了 MQ,那么间接接着用即可
  2. 如果公司目前未引入 MQ,则须要架构组考量选型了,对于 MQ 的选型能够看我之前文章:聊聊 MQ 技术选型

当然一旦引入了 MQ 还须要思考的问题很多,如下:

1、MQ 忽然宕机了怎么办?

MQ 宕机意味着查问数据不能持续建设了,咱们能够在写入数据的同时给该条数据加一个标记字段(已搬运、未搬运),当 MQ 启动后,查问所有未搬运的数据,持续建设查问数据

这里的计划很多,依照业务理论状况考量

2、音讯的幂等生产

音讯的幂等生产肯定要保障,防止数据反复建设,比方:主数据的订单 A 更新后,咱们在查问数据中插入了 A,可是此时零碎出问题了,零碎误以为查问数据没更新,又把订单 A 插入更新了一次。

3、音讯的时序性问题

比方某个订单 A 更新了 1 次数据变成 A1,线程甲将 A1 的数据搬到查问数据中。不一会儿,后盾订单 A 又更新了 1 次数据变成 A2,线程乙也启动工作,将 A2 的数据搬到查问数据中。

所谓的时序性就是如果线程甲启动比乙早,但搬运数据动作比线程乙还晚实现,就有可能呈现查问数据最终变成过期的 A1

查问数据的存储系统选型?

既然为了解决表数据量大查问迟缓的问题,必定是不能选用关系型数据库了,那么还有其余抉择吗?

内存数据库尽管性能十分高,比方 Redis,然而不适宜海量数据,太费钱了

那么这里比拟实用的有如下三种:

  1. MongoDB
  2. HBase
  3. Elasticsearch

这里选型还是要依据本人公司业务抉择,如果曾经有在用的,则间接用即可;另外就是抉择本人相熟的,比方当初咱们设计架构计划时,为什么抉择用 Elasticsearch,除 ES 对查问的扩展性反对外,最要害的一点是咱们团队对 Elasticsearch 很相熟。

查问数据如何应用?

查问数据很简略,每个数据库都有对应的 API,间接调用查问

然而,这里有一个问题:数据查问更新完前,查问数据不统一怎么办?,给出两种计划:

  1. 在查问数据更新到最新前,不容许用户查问。(咱们没用过这种设计,但我的确见过市面上有这样的设计。)
  2. 给用户提醒:您目前查问到的数据可能是 1 秒前的数据,如果发现数据不精确,能够尝试刷新一下,这种提醒用户个别比拟容易接受。

总结

本篇文章介绍了表数据量大查问迟缓的一种解决方案:查问拆散,但这也不是银弹,依然是存在一些有余,比方表数据量大,写入迟缓怎么办?这个前面文章再介绍吧

当然查问拆散还有一个重要的问题:历史数据如何迁徙?这个解决也是非常简单,然而也有许多须要思考的点,后文介绍

举荐浏览(求关注,别白嫖!)

  1. 数据异构就该这样做,yyds~
  2. 权限零碎就该这么设计,yyds
  3. 实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式对立认证受权!
  4. 从实现原理来讲,Nacos 为什么这么强?
  5. 阿里限流神器 Sentinel 夺命连环 17 问?
  6. openFeign 夺命连环 9 问,这谁受得了?
  7. Spring Cloud Gateway 夺命连环 10 问?
正文完
 0