Spring Boot业务系统如何实现海量数据高效实时搜索( 二 )


在查询历史数据表时,可以限制查询条件如必须选择日期范围,日期范围不能超过N个月等等从而减轻查询压力 。处理历史存量数据比较简单,因为历史数据一般不会变更了,所以一般只需要两个步骤进行归档:

  • 迁移满足限定数据到指定历史归档表
  • 根据主键分批删除业务原表数据,从而降低业务数据量
这里需要强调一下,不能一次性删除所有数据,因为数据量太大可能会引发超时,锁表,长事务等问题,而是应该根据ID分批删除,例如每次删除500或1000条数据 。操作步骤如下:
SELECT MAX(id) AS maxId FROM t WHERE create_time < '指定时间'查出满足归档条件的数据最大id,接下来就可以分批归档和删除了,初始化 startId=0,每次归档500条
select * into t_bak from t where id > startId and id <= maxId limit 500查询归档表获取最大id:maxBakId,赋值给startId方便下次分批归档删除
select max(id) from t_bak数据删除:
delete from t where id <= maxBakId重复上面的归档删除操作,直至startId到maxId结束
2.2 读写分离和热点缓存大部分的业务系统场景都是读多写少,读写比一般都在几十左右,平均每发生几十次查询请求,才有一次更新请求 。换句话来说,数据库需要应对的绝大部分请求都是只读查询请求 。针对这种情况我们可以通过读写分离方案来降低数据库压力 。
Spring Boot业务系统如何实现海量数据高效实时搜索

文章插图
图片
主库负责执行应用程序发来的所有数据更新请求,然后异步将数据变更实时同步到所有的从库中去,这样,主库和所有从库中的数据是完全一样的 。多个从库共同分担应用的查询请求 。
对于一些高频访问的热点数据,我们可以提前预处理使用redis缓存,这样也可以有效降低数据库的压力 。
2.3 同步异构数据源我们知道MySQL会随着数据量增大而查询变慢,那么我们换成其他数据源来完成OLAP查询场景不就得了 。特别是在当下大数据时代,现在互联网公司一般都具备与之规模相对应的大数据服务或者平台,那么作为业务开发者要善于应用公司大数据能力,减轻业务数据库压力 。比如我们可以把数据同步到ES、HBASE等平台 。
使用elasticsearch来实现海量数据搜索就是一个不错的选择,elasticsearch是一个基于Lucene的搜索服务器 。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口 。Elasticsearch是用JAVA开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎 。能够达到实时搜索,稳定,可靠,快速,安装使用方便 。但是如何实现MySQL数据同步elasticsearch呢?
答案是阿里的开源项目Canal,就是用来解决异构数据源数据同步这个问题的,Canal项目利用了MySQL数据库主从同步的原理,将Canal Server模拟成一台需要同步的从库,从而让主库将binlog日志流发送到Canal Server接口 。Canal项目对binlog日志的解析进行了封装,我们可以直接得到解析后的数据,而不需要理会binlog的日志格式 。而且Canal项目整合了zookeeper,整体实现了高可用,可伸缩性强
Spring Boot业务系统如何实现海量数据高效实时搜索

文章插图
图片
2.4 分库分表如果通过以上:历史数据归档、数据同步异构数据源、读写分离、热点缓存都不能解决MySQL单表数据压力的,这时我们只能拆分数据表,即把单库单表数据迁移到多库多表中 。这也是一线流量互联网公司需要面对的,你试想一下淘宝双11那几天要上架多少商品,产生多少订单,这已经不是前面的方案所能解决了,只能分库分表了 。当然分库分表是一个复杂的操作,也不是三言两语就能全面讲清楚的,且也不是我们今天主要议题,所以我这里粗略概述一下,感兴趣的可自行查阅相关资料 。
垂直拆分
垂直拆分就是按照业务拆分,我们将电商数据库拆分成三个库,订单库、商品库 。支付库,订单表在订单库,商品表在商品库,支付表在支付库 。这样每个库只需要存储本业务数据,物理隔离不会互相影响 。
水平拆分
按照垂直拆分方案,现在我们已经有三个库了,平稳运行了一段时间 。但是随着业务增长,每个单库单表的数据量也越来越大,逐渐到达瓶颈 。
这时我们就要对数据表进行水平拆分,所谓水平拆分就是根据某种规则将单库单表数据分散到多库多表,从而减小单库单表的压力 。


推荐阅读