分库分表之后如何通过非分片键操作

1、场景

今天看到一个场景,比如一个表,表名字是award_use_risk,作用是记录奖品使用的记录,用作风控。表结构如下:

这个表,只是分库,没有分表,db分成4个库,分别是db0-db4。

我的第一反应是根据terminal no或者prize guid,具体看业务逻辑进行分表操作,这样增加、修改、删除都可以通过分片算法定位到哪个库。

后来看到业务场景里面,需要定时删除前一天的风控数据,这种情况下,条件里面只有时间,没有分片键,如何定位每个库呢?

梳理一下:

  1. 根据prize guid进行分片路由,比如prize guid%1024/256,结果0-3,正好我们是四个库,没有问题
  2. 如果删除前一天的所有风控记录,怎么办,这个时候没有prize guid,如何分片?delete from award_use_risk where gmt_create 大约昨天,我们要的就是这个sql语句在每个库执行一遍,不能路由,因为路由不确定哪个库执行,哪个库没有执行。

2、思路

为了确定删除的时候在哪个库,我们不能用prize guid,只能用确定的数字0-3去定位每个库执行一遍,这样我们的分片路由键就必须是一个确定范围的数字,0,1,2,3,称之为data id。

在删除的时候,for 循环,以此传入0,1,2,3,就可以轮询删除每个库里面前一天的数据了。

那么插入呢?我们用data id,每个风控记录,都需要生成这个data id,我们就根据prize guid%1024/256,计算出data id,进行分库分表。ok了。

3、共性问题

上面的案例可以通过冗余字段解决,但是对于一些不带分片键的条件查询,并不是通用方案,我们一起看看非分片键过滤,如何解决:

例如按照状态和时间范围来查询订单表 orders,常见的SQL 这样的。

方案一:直接查询

这样好处是代码简单,但是坏处显而易见,在不带分片字段的情况下,中间件不知道数据具体都在哪个分片上,故而会将查询sql以并发的形式发给所有的分片数据库,造成了数据库的性能下降明显,严重影响了核心业务对数据库的需求,而且在某些情况下还会导致内存溢出,虽然可以建立合适的索引提高性能。

方案二:指定数据库节点读取

Mycat可以指定数据库节点,多线程读取每个数据节点,虽然提高了性能,但是效果并不理想。

方案三:异构索引,空间换时间

计算机领域的问题,都可以通过分而治之或者增加一层解决。这个问题,我们为了提高效率,增大空间,比如订单信息表进行分库分表之后,为了查询买家订单,我们需要根据买家id查询,明显不会走分片键,所以在

创建修改订单的时候,另外创建一个表,这个表按照买家id进行分库分表,查询的时候,根据买家id查询到订单id,然后再去订单表找订单信息。流程如下:

åºäºè®¢åç´¢å¼è¡¨æ¥è¯¢ä¹°å®¶è®¢å
这个方案可以,但是不够通用,如果我们根据时间、状态等信息组合查询呢?

 

方案四:实时数仓

我的思路就是监听数据库的变化,有很多中间件可以实现(Canal+Kafka),根据数据库的binlog,

实时创建数据仓库,把数据归集在一起,方便查询,避免分库分表带来的复杂性。

 

4、回顾分库分表的弊端

1.事务支持

​ 分库分表后,就成了分布式事务了。如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价; 如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担。

2.复杂查询

​ 分库分表后将无法进行join操作,查询禁止不带切分的维度的查询,即使中间件可以支持这种查询,可以在内存中组装,但是这种需求往往不应该在在线库查询,或者可以通过其他方法转换到切分的维度来实现。

解决这个问题的一些方法:

全局表

全局表,也可看做是 "数据字典表",就是系统中所有模块都可能依赖的一些表,为了避免跨库Join查询,可以将 这类表在每个数据库中都保存一份。这些数据通常

很少会进行修改,所以也不担心一致性的问题。

字段冗余

利用空间换时间,为了性能而避免join查询。例:订单表保存userId时候,也将userName冗余保存一份,这样查询订单详情时就不需要再去查询"买家user表"了。

数据组装

在系统层面,分两次查询。第一次查询的结果集中找出关联数据id,然后根据id发起第二次请求得到关联数据。最后将获得到的数据进行字段拼装。

 

备注:

1.目前营销中心分库分表后的id,并没有用雪花算法,而是一个数据库的sequence表记录了id的next value,从而做到全局不重复。配置如下:

2. 营销中心的非分片键查询?

 

 

 

 

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页
评论

打赏作者

hanruikai

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值