省流:
bug1:sharding-jdbc老版本的范围查询:只支持between and的查询方式,对于>=和<= 的查询,是无法路由到分片的。
bug2:通过dockerfile进行镜像构建并运行时,不统一和MySQL的时区,对于带时间范围的数据查询会存在误差。
前言(废话):
公司最主要的项目是一个很大的整体,各个模块的功能都维护在一个项目内。在项目做了分布式部署,以及数据库的读写分离后,是能够应对日常的流量的。但是,一些问题也纷至沓来:项目的启动速度过慢、结构复杂、维护困难等!
基于已有的问题,最终讨论得出的方案的就是进行服务拆分,将现有的基础架构转换为:多节点部署的主项目+多个独立业务边界的服务。第一轮拆分:账单服务、资产服务!我主要负责的就是账单服务!
账单服务,需要基于基础的订单数据,做多样化的数据清洗展示,因此存在多张数据量在3000w以上的表。即使在命中最优索引的情况下,查询速度还是令人难以接受,且缓存在有些场景中还是不太适用,所以最终决定在进行服务拆分时引入分表。
这个时候,就出现了很纯的bug了!
bug1 - sharding-jdbc版本不支持的范围查询:
原本的要求是新的项目需要引用已有的一个依赖,也就是做一个版本的管理!在依赖当中,是已经有sharding-jdbc的版本了:
<!-- https://mvnrepository.com/artifact/org.apache.shardingsphere/sharding-jdbc-core -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>4.0.0-RC1</version>
</dependency>
由于原本的项目当中,已经存在对一个表的分表操作,所以我就只需要找猫画虎,不怎么需要动脑子!
大致就是需要在配置当中添加分表的相关信息,配置完后大致的信息如下(控制台输出):
大致就是:需要进行分表的表名、物理表是哪些,查询的逻辑表是哪个,分表的规则,分片算法、分片键。
全部都弄好后,啪唧一下启动运行、测试。查询速度倒是挺快,但是数据大了很多(因为原表数据还未处理,相当于存了两份)。然后打开sharding的日志输出发现,并没根据where条件去路由到对应的表,而是在每个表都查了一次。
然后开始找资料,在官网并没有找到相关的描述。我就看之前的开发写的代码,毕竟都已经上线了,不能有错吧,然后一看日志输出,好家伙,也是每个分片都查一次,因为数据没有重复所以一直没人发现问题。后面网上找资料,发现同版本的用了范围查询的都是用between and,好嘛,死马当活马医了换过来运行测试,居然就ok了!
我嘞个豆啊,万万没想还有这么个坑,然后我就尝试升级版本到4.1.1(这里我记得当时只切换sharding的版本会无法启动,需要把springboot的版本也升级了才可以),发现就能够支持>=和<=的查询了。最终和leader沟通过后也是觉得让我在账单服务中对部分版本较低的进行升级!
bug2 - 项目在docker内运行出现的数据误差:
这个问题真的,当时给我cpu都干冒烟了,因为本地看查询数据是没问题,我才弄到docker里面去的。
为了排查我还尝试过直接在服务器运行jar包,也是没有问题。之所以一直没想到时区的问题,是因为我看日志输出,是没问题的:
最后能改到是因为突然看到日志输出前面的时间和当前时间差了八个小时,想着加个时区把这个弄对了!
这是在最开始的dockerfile:
后面指定了时区再进行build就正常了:
总结:
开发还是得细心的!