MySQL 读写分离、分库分表、归档、不停服数据迁移
1、缓存和数据库方案的选择
=》方法论:是否与用户有关,如果跟用户有关,使用数据库,否则用缓存。
缓存:电商商品系统,搜索等 =》任意用户访问内容都一样
数据库:订单系统、账户系统、购物车系统 =》 每个用户数据都不一样
2、MySQL应对高并发读写方案
读写分离:增加更多副本,提供读流量的均摊
分片:业务维度拆分到不同机器DB
分库分表:同业务流量穿透到不同机器DB =》 数据量大则分表,并发高就分库
问题:同账户不同进程同时写入,可能会存在并发冲突=》此时通过去重、加锁解决。
3、读写分离技术

A: 读写请求组件方案
纯手工:根据读写指定不同数据源
组件方式:Sharding-JDBC,组件集成应用程序,自动请求路由到数据库实例 =》 优点:无需关注分库分表逻辑;缺点:各个系统都需要配置路由规则
代理方式:应用层和数据库层增加一组数据库代理实例,例如MyCat,Atlas,MaxScale等; =》缺点:中间件稳定性和流量多一层穿透
B: 配置多个从库的HA方案
HAProxy+Keepalived
C: 读写分离数据不一致性解决
主从同步延迟正常<1ms,非核心服务使用该模式
方案一:前端体验优化 =》视觉欺诈:操作完成展示广告信息或完成信息,再给用户查询
方案二:核心服务采用主DB =》 更新数据库和查询放入同一事务,规避主从不一致问题

5、归档技术

批量删除
select max(id) from orderswhere timestamp < SUBDATE(CURDATE(),INTERVAL 3 month); delete from orderswhere id <= ?order by id limit 1000;
问题:历史单删除后,MySQL磁盘空间并没有减少?产生碎片,利用率低;
原因:每个表是B+数,物理上每条记录存放在磁盘文件中,这些记录通过一些位置指针构成一棵B+树;删除记录时候,只是将B+树中相关指针完成删除。
-- 新建一个临时订单表 create table orders_temp like orders; -- 把当前订单复制到临时订单表中 大于3个月前的数据 insert into orders_temp select * from orders where timestamp >= SUBDATE(CURDATE(),INTERVAL 3 month); -- 修改替换表名 rename table orders to orders_to_be_droppd, orders_temp to orders; -- 删除旧表 drop table orders_to_be_dropp

要求:稳定运行几周时间,不断检查,确保不能有旧库写成功,新库写失败情况出现。 对比程序不能出现新旧两个库数据不一致的情况
难点:比对两个随时变换的数据库中的数据,没有类似复制状态机理论。

浙公网安备 33010602011771号