1. 小表广播概念
业务中存在一些配置表,存储重要的配置,读多写少。实际业务查询中,很多业务表会和配置表进行联合数据查询,但在数据库水平拆分后,配置表是无法拆分的。
专车订单场景里,每个订单都有所属城市的属性 即城市编号 cityId ,订单库里有一个城市配置表 。订单表可以直接通过关联城市配置表得到城市信息。
分库分表之后,如何查询订单所属城市信息呢 ?
一个非常简单的想法:我们将城市表复制到所有的订单库分片里。
如图,新订单每个分片都包含城市配置表,这样就可以方便的进行关联。
接下来,我们需要讨论如何实现广播表 ,总不能每次更新都手工拷贝吧。
笔者提供两种方案:
- shardingsphere 配置广播表
- 中间件 Canal 同步小表
2. shardingsphere配置广播表
ShardingSphere 的广播表是指存在于每个分片数据源中的表。这些表的结构和数据在每个数据库中都完全一致。
这种表适用于数据量不大且需要与海量数据的表进行关联查询的场景,例如字典表、省份信息等。
对于广播表,ShardingSphere 不会对数据进行分片,所有节点的数据都是完全一致的。
当有新的插入、更新操作时,它们会实时在所有节点上执行,以保证各个分片的数据一致性。
查询操作只需要从一个节点获取,而不是从多个节点获取。同时,广播表可以与任何一个表进行 JOIN 操作。
我们使用 shardingsphere jdbc 5 做一个简单的测试进行验证。
参考我们的开源项目:
如图,sharding.yaml 即可配置广播表,我们配置的表是 :t_city ,然后在每一个分片中新增一个城市配置表。
添加一个测试例子,分别查询和修改广播表:
执行后,shardingsphere 之行 SQL 显示如下:
如上图,shardingsphere 在处理广播表遵循确实遵循两个原则:
1、 查询操作只需要从一个节点获取,而不是从多个节点获取 ;
2、 当有新的插入、更新操作时,它们会实时在所有节点上执行,以保证各个分片的数据一致性;
3. 中间件Canal同步小表
虽然,我们可以通过 shardingsphere 实现小表广播的功能,但实际上,在很多业务场景里,不同业务团队可能都需要这些配置表,但不同的业务团队不可能共用 shardingsphere 来管理他们的数据 ,此时就需要借助其他中间件的能力来实现小表广播。
上图,专车场景,架构团队管理架构库,通过中间件 Canal 将城市表的修改同步到不同的业务库(订单库、派单库、促销库)。
在使用 Canal 之前,也是需要全量同步的,只不过因为数据量极小 ,专车 DBA 同学会初始化全量数据。
4. 使用小表技巧
这篇文章,我们提到了实现小表广播的两种技巧,分别是:shardingsphere 配置广播表和中间件 Canal 同步小表 ,有没有其他的方式来处理这个问题呢 ?
别忘记了,我们可以使用微服务化的方式,将这些配置表的操作抽象成独立的服务,供其他业务方调用。
通过微服务的方式,可以推进其他业务团队的服务进行改进,将原来的业务表和配置表关联的操作拆成服务拼接的形式。
有的同学,可能会很好奇:那每次调用微服务,会不会让业务系统的性能很差。
1、配置表的写操作极小,业务系统可以将这些配置数据缓存起来 ,存储在本地 ,若缓存失效,则批量查询配置微服务。大家可以参考笔者的短信平台内部如何展示短信列表的缓存技巧。
2、加了缓存,可以通过 MQ 通知的机制来减少延迟。
笔者之所以写微服务的形式,是因为这是笔者见过的处理小表的一种极其常见的方式之一 。
没有完美的方案,只有合适的方案。