分表后需要注意的那些事儿
还是先来简单回顾下上次提到了哪些内容:
- 分表策略:哈希、时间归档等。
- 分表字段的选择。
- 数据迁移方案。
而本篇文章的背景是在我们上线这段时间遇到的一些问题并尝试解决的方案。
问题产生
之前提到在分表应用上线前我们需要将原有表的数据迁移到新表中,这样才能保证业务不受影响。
![](/assets/blank.gif)
所以我们单独写了一个迁移应用,它负责将大表中的数据迁移到 64 张分表,而再迁移过程中产生的数据毕竟是少数,最后在上线当晚再次迁移过去即可。
一切想的很美好,当这个应用上线后却发现没这么简单。
数据库负载升高
首先第一个问题是数据库自己就顶不住了,在我们上这个迁移程序之前数据库的压力本身就比较大,这个应用一上去就成了最后一根稻草。
最后导致的结果是:所有连接了数据库的程序大部分的操作都出现超时,获取不到数据库连接等一系列的异常。
最后没办法我们只能把这个应用放到凌晨执行,但其实后面观察发现依然不行。
虽说凌晨的业务量下降,但依然有少部分的请求过来,也会出现各种数据库异常。
再一个是迁移程序的效率也非常低下,按照这样是速度,我们预估了一下迁移时间,大约需要 10 几天才能把三张最大的表(3、4亿的数据)迁移到分表中。
于是我们换了一个方案,将这个迁移程序在从库中运行,最后再用运维的方法将分表直接导入进主库。
因为从库的压力要比主库小很多,对业务的影响很小,同时迁移的效率也要快很多。
即便是这样也花了一晚上+一个白天的时间才将一张 1亿的数据迁移完成,但是业务上的压力越来越大,数据量再不断新增,这个效率依然不够。
兼容方案
最终没办法只有想一个不迁移数据的方案,但是新产生的数据还是往分表里写,至少保证大表的数据不再新增。
但这样对于以前的数据咋办呢?总不能不让看了吧。
其实对于数据的操作无非就分为 增删改查,就这四种操作来看看如何兼容。
新增
![](/assets/blank.gif)
新增最简单,所有的数据根据分表规则直接写入新表,这样可以保证老表的数据不再新增。
删除
删除就要比新增稍微复杂一些,比如用户想要删除他个人产生的一条信息(比如说是订单数据),有可能这个数据在新表也可能在老表。
![](/assets/blank.gif)
所以删除时优先删除新表(毕竟新产生的数据访问的频次越高),如果删除失败再从老表删除一次。
修改
![](/assets/blank.gif)
而修改同理,同样的会不确定数据存在于哪里,所以先要修改新表,失败后再次修改老表。
查询
查询相对就要复杂一些了,因为这些大表的数据大部分都是存放一个用户产生的多条记录(比如一个用户的订单信息)。
这时在页面上通常都会有分页,并且按照时间进行排序。
麻烦的地方就出在这里:既然是要分页那就有可能出现要查询一部分分表数据和原来的大表数据做组合。
所以这里的查询其实分为三种情况。
![](/assets/blank.gif)
- 首先查询的时候要计算这个用户所在分表中的数据可以分为几页。
- 第一步首先判断当前页是否可以在分表中全部获取,如果可以则直接从分表中取出数据返回(假设分页中总共可以查询 2 页数据,当前为第 1 页,那就全部取分表数据)。
- 如果不可以就要判断当前页数在分表中是否取不到任何一条数据,如果是则直接取老表数据(比如现在要取第 5 页的数据,分表中一共才只有 2 页数据,所以第 5 页数据只能全部从老表中获取)。
- 但如果分表和老表都存在一部分数据时,则需要同时取两张表然后做一个汇总再返回。
这种逻辑只适用于根据分表字段进行查询分页的前提下
我想肯定会有朋友提出这样是否会有性能问题?
同时如果在计算分表分页数量时出现并发写入的情况,导致分页数量不准从而对后续的查询出现影响该怎么处理?
首先第一个性能问题:
其实这个要看怎么取舍,为了这样的兼容目的其实会比常规查询多出几个步骤:
- 判断当前页是否可以在分表中查询。
- 当新老表中都有数据时候需要额外多查询一张大表。
第一个判断逻辑其实是在内存中计算,这个损耗我觉得完全可以忽略不计。
至于第二步确实会有损耗,毕竟多查了一张表。
但在分表之前所有的数据都是从老表中获取的,当时的业务也没有出现问题;现在多的只是查询分表而已,但分表的数据量肯定要比大表小的多,而且有索引,所以这个效率也不会慢多少。
而且根据局部性原理及用户的使用习惯来看,老表中的数据很少会去查询,随着时间的推移所有的数据肯定都会从分表中获取,逐渐老表就会成为历史表。
而第二个并发带来的问题我觉得影响也不大,一定要这个分页准的前提肯定得是加锁了,但为了这样一个不痒的小问题却带来性能的下降,我觉得是不划算的。
而且后续我们也可以慢慢的将老表的数据迁移到新表,这样就可以完全去掉这个兼容逻辑了,所有的数据都从分表中获取。
总结
还是之前那句话,这里的各种操作、方法不适合所有人,毕竟脱离场景都是耍牛氓。
比如分表搞的早,业务上允许一定的时间将数据迁移到分表那就不会有这次的兼容处理。
甚至一开始业务规划合理、团队架构师看的长远,一来就将关键数据分表存储那根本就不会有数据迁移这个流程(大厂有经验的团队可能,小公司小作坊都得靠自己摸索)。
这段期间也被数据库折腾惨了,数据库是最后一根稻草果然也不是瞎说的。
转载于:https://www.cnblogs.com/CQqf2019/p/11014695.html
分表后需要注意的那些事儿相关推荐
- 百亿级数据分表后怎么分页查询?
当业务规模达到一定规模之后,像淘宝日订单量在5000万单以上,美团3000万单以上.数据库面对海量的数据压力,分库分表就是必须进行的操作了.而分库分表之后一些常规的查询可能都会产生问题,最常见的就是比 ...
- 两个表点击分页的时候怎么判断点的是哪一个表_百亿级数据分表后怎么分页查询?...
当业务规模达到一定规模之后,像淘宝日订单量在5000万单以上,美团3000万单以上.数据库面对海量的数据压力,分库分表就是必须进行的操作了.而分库分表之后一些常规的查询可能都会产生问题,最常见的就是比 ...
- mysql分表后怎么索引_分库分表后的索引问题
摘要 最近遇到一个慢sql,在排查过程中发现和分库分表后的索引设置有关系,总结了下问题. 问题 在进行应用健康度盘点时,发现有个慢sql 如下 select brandgoodid from bran ...
- mysql为什么表大了要重建_为什么MySQL分库分表后总存储大小变大了?
[MySQL系列相关] 1.聊一聊关于MySQL的count(*) 1.背景 在完成一个分表项目后,发现分表的数据迁移后,新库所需的存储容量远大于原本两张表的大小.在做了一番查询了解后,完成了优化. ...
- mysql pdo 插入没效果_MySQL分库分表后用PHP如何来完美操作
当单表达到几千万时,查询一次要很久,如果有联合查询,有可能会死在那 分库分表主要就是解决这个问题,减小数据库的负担,缩短查询时间分库 1)按功能分 用户类库.商品类库.订单类库.日志类.统计类库... ...
- mysql 分表后如何扩展_MySQL横向扩展-分库分表解决方案总结
从业务场景看分库分表 互联网行业中,业务场景通常写少读多的情况居多,在MySQL的使用前期,读性能大多可以通过SQL优化来解决,但随着业务的持续发展,单纯依靠SQL的查询优化会越来越难以达到业务服务要 ...
- MySQL分表后,如何做分页查询?
MySQL分表方式分为垂直分表和水平分表,这两种分表形式都比较简单,简单理解垂直分表指的是:表的记录并不多,但是字段却很长,表占用空间很大,检索表的时候需要执行大量的IO,严重降低了性能.这时需要把大 ...
- mysql分页分表_mysql分表后 如何分页 (总共160个表1500万数据)
mysql分表后,有160个表,有1500万数据,要怎么做分页列表? 之前是想用union all合并160个表的结果集..但直接卡的数据都出不来.. 请问这里应该怎么做分页,谢谢~~~ 回复讨论(解 ...
- 数据库分库分表后,如何部署上线?
1. 引言 我们先来讲一个段子 面试官:"有并发的经验没?" 应聘者:"有一点." 面试官:"那你们为了处理并发,做了哪些优化?" 应聘者: ...
最新文章
- 办公室自动化系统_信息化管理建设 公司办公室用自动盖章机贵吗?
- 微软服务器每个月,2017年7月网络服务器调查 微软服务站点过半
- Android init.rc分析
- python3之后版本读取网页的内容
- Modbus以太网传输方式
- linux 随机10字符病毒,Linux系统随机10字符病毒的清除
- 上传文件时显示选择窗口
- 调查 1621 万互联网人:发现技术人基本是男性,还一半都单身
- win10换源安装opencv-python
- 2012怎么设置index.php,配置伪静态.htaccess去掉wordpress固定连接里的index.php
- 从零开始的车牌识别课题设计(一)
- android 的android httpClient详解
- vpay模式软件开发 vpay系统
- 中英文电子书下载:https://sobooks.cc/
- k8s中对pod设置限制只设置了limits
- 公历转农历C/C++代码
- PHP自动排班系统 源码+说明
- 精准营销、批量提取QQ群成员号码
- 03-OSPF OE2和OE1外部路由详解
- 大学python笔记整理_python学习笔记整理(一)