拆表是一种常见的解决单表数据库瓶颈的方案,在实际的应用场景中能够部分解决单表的写压力和读压力,但是也会带来一些更复杂的影响: 聚合查询变得困难 拆分的键一旦选定,更改会非常困难 在本次实施的拆分方案中,数据特点是: 单表过亿 如何保证拆分的过程中不影响用户的操作? 用户新增一条数据 1.全部在旧表中 数据拆分的具体工作是要离线进行的,为了能保证用户数据在这样三种状态之下依然具有像单表中一样的一致性,需要业务层在处理当前用户数据时判断用户是否在迁移中,只有处于迁移状态之下,用户数据才需要特别处理。 迁移状态如何判断? 所以,如果用户处于迁移状态,则用户的数据一定存在于这个区域,暂且给此区域命名为 on_progress。 迁移状态下如何保证用户数据的正确性? 这样做的目的是什么? 处于迁移状态下的用户,on_progress 中保存了其所有数据,可以进行翻页操作,on_progress 中的所有数据会在离线状态下不断写入新表中,迁移完成之后,旧表中的数据将被删除,on_progress 中数据也将被清除,这样用户数据全部进入新表中,后续的所有操作将只在新表上进行。 on_progress 中的数据在不断写入新表的过程中,是按照由新–>旧或由旧–>新的顺序进行,在这个过程中: 用户删除一条数据 1)有可能该条数据已经写入新表中,所以删除操作要在新表中执行。 用户新增一条数据 1)on_progress 中的数据要始终和用户所有的操作同步来保证数据的正确性和一致性,因而 on_progress 需要写入一条数据。 on_progress 的选择 迁移完成之后,先删除旧表中的数据,然后再删除 on_progress 中有序集,所以,只要用户处于 redis 中,则此时一定是迁移中或迁移完成,如果在旧表中找到用户数据,则该用户一定还没有开始迁移,否则用户已经迁移成功。 需要注意的是,选用 redis 可能带来的问题是 redis 宕机会导致迁移中的数据无法回复(redis 未开持久化操作或其他原因导致数据不能恢复),只要用户在旧表中有数据存在,则用户删除或新增数据的操作一定也要在旧表中执行,再次恢复迁移时,要清除新表数据之后才能正常进行。 |