亿级大表分库分表实战总结( 三 )


而pk2和pk1由于历史原因 , 存在一一对应关系 , 可以仅保留一份映射表即可 , 只存储pk1和pk2两个字段 。
3.1.2 搜索平台索引存储搜索平台索引 , 可以覆盖剩余20%的零散查询 。
这些查询往往不是根据分表键进行的 , 或者是带有模糊查询的要求 。
对于搜索平台来说 , 一般不存储全量数据(尤其是一些大varchar字段) , 只存储主键和查询需要的索引字段 , 搜索得到结果后 , 根据主键去mysql存储中拿到需要的记录 。
当然 , 从后期实践结果来看 , 这里还是需要做一些权衡的:
1)有些非索引字段 , 如果不是很大 , 也可以冗余进来 , 类似覆盖索引 , 避免多一次sql查询;
2)如果表结构比较简单 , 字段不大 , 甚至可以考虑全量存储 , 提高查询性能 , 降低mysql数据库的压力 。

这里特别提示 , 搜索引擎和数据库之间同步是必然存在延迟的 。所以对于根据分表id查询的语句 , 尽量保证直接查询数据库 , 这样不会带来一致性问题的隐患 。
3.1.3 数据同步一般新表和旧表直接可以采用 数据同步 或者 双写的方式进行处理 , 两种方式有各自的优缺点 。
亿级大表分库分表实战总结

文章插图
 
一般根据具体情况选择一种方式就行 。
本次项目的具体同步关系见整体存储架构 , 包括了四个部分:
1)旧表到新表全量主表的同步
一开始为了减少代码入侵、方便扩展 , 采用了数据同步的方式 。而且由于业务过多 , 担心有未统计到的服务没有及时改造 , 所以数据同步能避免这些情况导致数据丢失 。
但是在上线过程中发现 , 当延迟存在时 , 很多新写入的记录无法读到 , 对具体业务场景造成了比较严重的影响 。(具体原因参考4.5.1的说明)
因此 , 为了满足应用对于实时性的要求 , 我们在数据同步的基础上 , 重新在3.0.0-SNAPSHOT版本中改造成了双写的形式 。
2)新表全量主表到全量副表的同步
3)新表全量主表到映射表到同步
4)新表全量主表到搜索引擎数据源的同步
2)、3)、4)都是从新表全量主表到其他数据源的数据同步 , 因为没有强实时性的要求 , 因此 , 为了方便扩展 , 全部采用了数据同步的方式 , 没有进行更多的多写操作 。
3.2 容量评估在申请mysql存储和搜索平台索引资源前 , 需要进行容量评估 , 包括存储容量和性能指标 。
具体线上流量评估可以通过监控系统查看qps , 存储容量可以简单认为是线上各个表存储容量的和 。
但是在全量同步过程中 , 我们发现需要的实际容量的需求会大于预估 , 具体可以看3.4.6的说明 。
具体性能压测过程就不再赘述 。
3.3 数据校验从上文可以看到 , 在本次项目中 , 存在大量的业务改造 , 属于异构迁移 。
从过去的一些分库分表项目来说 , 大多是同构/对等拆分 , 因此不会存在很多复杂逻辑 , 所以对于数据迁移的校验往往比较忽视 。
在完全对等迁移的情况下 , 一般确实比较少出现问题 。
但是 , 类似这样有比较多改造的异构迁移 , 校验绝对是重中之重!!
因此 , 必须对数据同步的结果做校验 , 保证业务逻辑改造正确、数据同步一致性正确 。这一点非常非常重要 。
在本次项目中 , 存在大量业务逻辑优化以及字段变动 , 所以我们单独做了一个校验服务 , 对数据的全量、增量进行校验 。
过程中提前发现了许多数据同步、业务逻辑的不一致问题 , 给我们本次项目平稳上线提供了最重要的前提保障!!
3.4 最佳实践3.4.1 分库分表引起的流量放大问题在做容量评估的时候 , 需要关注一个重要问题 。就是分表带来的查询流量放大 。
这个流量放大有两方面的原因: