个人博客地址 https://www.texixi.com/2019/0…
方案
项目背景
在现在题库架构下,针对新购买的 1300W 多道数据进行整合,不影响现有功能。由于数据量偏多,需要进行数据的切分
目标场景
兼容旧的功能
对 1300 多 W 数据进行分库分表
需要对旧的数据进行整合
老师端选题组卷 可以根据 学段、学科、知识点、难度、题型 来筛选
学生端根据老师端所选题目获取对应的题目
对 3 年内以后扩展的增量数据预留数量空间
数据样例
学段
数据量
小学
1285336
初中
6655780
高中
6144072
学段学科
数据量
初中数学
1869524
初中化学
1356224
初中英语
288440
切分方案一
切分为 3 个库,分别是小学、初中、高中 数据占比如上
每个库切分 10 个表 根据(学科 + 首级知识点)%10
每个库一个总表
缺点:例:用到不同知识点时,需要多表获取数据
优点:数据分布较为平均
切分方案二(采用)
切分为 3 个库,分别是小学、初中、高中 数据占比如上
每个库切分 10 个表 (全部 10 个学科) 根据 学科区分,例:数学表、物理表
每个库一个总表
缺点:数据不大平均,数据量多的例数学有 186W 多、英语 28W 多
优点:当有用到组卷等需要筛选多知识点题目时,不用多表查询
数据 id 自增区间划分
小学 1- 2 亿
中学 2- 3 亿
高中 3 亿起
关联关系图
根据知识点获取题目流程
自增 id
对原有的 id 区间段不做处理
对切分后的 id 自增段进行规划
兼容旧功能
解决的问题
新旧数据有重复的知识点、题目
新旧数据的结构不一样
对旧的题库功能代码的修改
两套题库合并主键冲突问题
兼容旧功能 方案一(个人推荐)
有操作的旧的数据洗入新的结构,旧的数据只为兼容原有的功能数据,不做显示。
优点:不用变动数据结构,最新的购买的数据结构较为清晰。易维护扩展,因为目前旧的数据已经整合了两套数据
缺点:需要修改全部旧有的功能代码(针对新的数据结构)
兼容旧功能 方案二
把新购买的数据整合进老的数据结构,同时保留三批数据,需要处理所有表的主键冲突、三批各表数据去重
优点:
旧有代码只修改数据结构切分的部分,不用全部修改功能代码
缺点:
数据较乱,三套不同的数据同时存在数据库
需要处理新的结构整合进旧的数据结构,同时需要处理主键冲突,
代码上需要处理对应的数据
问题点
测试环境和正式环境图片存放在那里?100 多 G,上传 cdn 需要几十天时间,有 4000 多 W 张,目前 cdn 不支持打包上传
解决方案:购买单独服务器,主备,存放图片
测试 db 正式 db 1300 多 w 目前占用 100G 左右, 需要存放空间
解决方案:测试环境新加硬盘,新加 db 实例端口 3307,正式环境 db 存放在图片服务器
代码设计模式
采用适配器模式(原先的代码结构不变)
类图
调研内容
中间件 MYCAT(未使用)
什么是 MYCAT
一个彻底开源的,面向企业应用开发的大数据库集群
支持事务、ACID、可以替代 MySQL 的加强版数据库
一个可以视为 MySQL 集群的企业级数据库,用来替代昂贵的 Oracle 集群
一个融合内存缓存技术、NoSQL 技术、HDFS 大数据的新型 SQL Server
结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
一个新颖的数据库中间件产品
MYCAT 特性
== 支持库内分表(1.6)==
== 支持单库内部任意 join,支持跨库 2 表 join,甚至基于 caltlet 的多表 join==
支持全局序列号,解决分布式下的主键生成问题。
== 分片规则丰富 ==,插件化开发,易于扩展。
基于 Nio 实现,有效管理线程,解决高并发问题。
== 支持通过全局表,ER 关系的分片策略,实现了高效的多表 join 查询 ==
支持分布式事务(弱 xa)。
支持 SQL 黑名单、sql 注入攻击拦截
== 支持 MySQL、Oracle、DB2、SQL Server、PostgreSQL 等 DB 的常见 SQL 语法 ==
== 遵守 Mysql 原生协议 ==,跨语言,跨平台,跨数据库的通用中间件代理。
== 基于心跳的自动故障切换,支持读写分离,支持 MySQL 主从,== 以及 galera cluster 集群。
可以大幅降低开发难度,提升开发速度
具体看 mycat 官网
Mycat 注意事项
全局表一致性检测 1.6 版本开始支持(一致性的定时检测)
分片 join(尽量避免使用 Left join 或 Right join, 而用 Inner join)
Mycat 原理
应用要面对很多个数据库的时候,这个时候就需要对数据库层做一个抽象,来管理这些数据库,而最上面的应用只需要面对一个数据库层的抽象或者说数据库中间件就好了,这就是 Mycat 的核心作用。
分片分析、路由分析、读写分离分析、缓存分析等,然后将此 SQL 发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
Mycat 应用场景
读写分离,配置简单
分表分库,对于超过 1000 万的表进行分片,最大支持 1000 亿的单表分片
报表系统,借助于 Mycat 的分表能力,处理大规模报表的统计
文章整理
应用场景 那些适合,那些不适合 https://www.cnblogs.com/barry…
使用说明 https://juejin.im/post/59c325…
总表使用 mysql MERGE 引擎 (不考虑)
合并的表使用的必须是 MyISAM 引擎
表的结构必须一致,包括索引、字段类型、引擎和字符集
对于增删改查,直接操作总表即可。
数据切分原则
能不切分尽量不要切分。
如果要切分一定要选择合适的切分规则,提前规划好。
数据切分尽量通过数据冗余或表分组(Table Group)来降低跨库 Join 的可能。
由于数据库中间件对数据 Join 实现的优劣难以把握,而且实现高性能难度极大,业务读取尽量少使用多表 Join。
尽可能的比较均匀分布数据到各个节点上
该业务字段是最频繁的或者最重要的查询条件。