缘起

讲个创业故事,某一天老总想做一个HR的Saas系统,其中员工信息表,但不同员工信息表有一部分是相同的,也有一部分不同的。我们就把不同的放在一个json字段(Mysql 8.0以后支持)中,Dao用的Mybatis,以及MybatisGenerator生成的基础包访问DB,大家知道这个查询就会查询一条完整的数据,没法查几个字段。刚开始没啥,为了赶进度查询一条就一条吧,不用就行。后来试用开始,量上来就慢了,尤其一些扩展的字段都是在更多详情中展示,但基础信息获取也很慢。原因就是查询用户基础信息也用的是按照行全量查询。

为了解决读的问题,我们做了读写分离,后来干脆多高几个Slave从库进行读,可随着业务发展,尤其有些公司扩展字段很多,读取速度就更慢了。

垂直分离,将基本信息和扩展信息拆分为两个表,ID是一致的。这样,基础信息查询用户基础基础信息表,点击更多的时候查询用户的扩展信息表。

因为是Saas多租户架构,用户表数据量也上来了,于是开始分片。这里的分片不同于数据库的那个分片,也指业务上的分片。一般方案有两个,按照某种业务规则拆分,如三个月内+历史数据(时间维度);另一种是根据ID进行Hash,平均分配到不同DB,缺点是当然你查询自己的订单时候就不得不从两个表查询了。Saas多租户,租户ID自然是比较好的拆分依据,就把不同租户的用户拆分到不同的DB中,关于是分库还是分表,建议是分库,实现简单,且两个租户不争夺IO资源,当然也不绝对,看业务。

分库后,刚开始没有进行读写分离,运维成本的考虑。但对于大公司还是比较慢的,于是就添加了从库,进行读写分离,尤其对于报表生成都迁移从库来完成。

业务发展到现在,对于一个租户来说,主库还是单点。畅想一下,一般情况,业务复杂后,数据量再上来,优先考虑纵向根据业务拆分为不同微服务,这样原来一个DB 100张表,可能就拆分为40+60的两个库,能缓解一段时间。

但如果对于一些业务表,单表都能超过kw级别,分表一定不行了,原因是:能达到kw规模存量数据,增速一定很高,写性能和IO性能是瓶颈,即使分表也会争抢IO资源,所以这里就必须进行分库了,这里的分库指的是:同一个表的分库,类似根据ID去Hash分库一样。以此来解决数据量大,单点扛不住问题。

演化到这里,已经很少有业务能到这个程度,如果到了,也只是系统中少有的几个模块,就需要特殊设计了,也不存在什么通用的方案。

数据库架构分解

说起“数据库架构”,包括:数据库表设计和数据持久层架构。下面主要将持久层架构,但也会涉及数据库表设计。

创业初期:一个服务一个库

读瓶颈:读写分离

 

架构:一主多从,主从同步,读写分离

这么一套就是一组,这个架构也成为:分组架构

技术实现:在Service层使用AOP注解标记;多数据源路由的时候根据标记路由;或者配置规则进行路由。

架构特点:

  1. 主从表结构和数据完全一致
  2. 通过binlog同步数据,会有一定的时差
  3. 解决读多写少的场景,或者读费时的问题

表中冷热数据纵向拆分

如下表单,先展示基本信息,点击“更多”后,展开其他详细信息。

刚开始数据库表设计:

前面的“基本信息”比“扩展信息”更常用,所以可以拆分为两个表:

单表总数据库大:分片架构

根据租户ID进行拆分,即:一个公司的数据独立的放在一个库里边。

路由的技术实现:Spring的动态数据源;Mycat中间件

分库还是分表:建议分库,拆分数据是为了解决单表数据量问题,数据量大的两个瓶颈是:数据库单表瓶颈和服务器IO,如果分表意味着IO瓶颈会突出出来。

水平分配规则:

  1. 按照业务key分,如:不同租户的数据;不同地点订单;不同类别等
  2. 根据ID按照Hash算法平均分配,这类只是为了解决数据量大的问题

架构特点:

  1. 每个数据库的Schema一样
  2. 数据每个库数据是不同的,区别于主从复制

解决问题:此架构解决单库成为瓶颈问题,通过拆分为多个库存储数据,一次来降低单库的压力,代价就是统计,查询我的历史等功能,需要通过合并数据才可以。

分片后读写分离

拆分为不同的库后,也有读多写少的问题,于是再对每台DB进行分组架构,添加从库进行读写分离。

如果业务读写并发量很高,数据量也很大,通常需要实施分组+分片的数据库架构:

1.通过分片来降低单库的数据量,线性提升数据库的写性能

2.通过分组来线性提升数据库的读性能,保证读库的高可用

主库单点问题扩展

此案例先进行根据租户ID分库,但如果一个租户的数据也过大,就需要对这个租户进行分库存储。图跟上面类似,路由的规则却变为根据ID去hash。这个只是扩展,实际业务需要看具体业务,必须分库会带来其他额外的工作,比如获取全部员工信息,需要从多个数据库查询查询。类似这样的功能需要全部重构。

数据库架构总结

  1. 业务初期用单库
  2. 数据量和并发量增加开始可以选择更好好一点的机器
  3. 读写比例差异,可以进行读写分离
  4. 类似报表等查询和统计类功能,又比较好性能的模块就可以迁移到从库
  5. 单库写量上来后,可以进行分片,将压力拆分到多个库中
  6. 高频的信息查询和低频信息可以拆分为两个表

题外话

其实架构就像是打架,为了解决问题手脚会并用的。

读写比例差异场景除了读写分离外,还可以将热点数据放在缓存如redis或者memcache中,只需要保证缓存数据的一致性即可。

数据如果按照冷热字段拆为两个表后,如果要统计或者查询,一般都会合并出一个中间表,在这个中间表进行操作。

如果数据分散到多个数据库中,并需要查询“简历上干过***类项目的员工”场景是,查询则需要专门的组件或者架构支持,如ES的引入,解决关键字查询为。

数据和业务到了一定量,或者一定并发。提交数据,查询,统计等功能都已经不是简简单单的数据库的事情了,需要专门为此设计解决。

补充:数据库分配优化查询速度

比如Saas多租户架构,将一个租户的数据放在一片或者相邻的片来存储,查询速度会快点。能否解决查询速度的问题?可以。

但,这属于战术层面的方法,就是在不跳转架构的情况下,可以做此优化;从战略架构层面,还是要着眼于解决扩展问题。


END

分布式.数据库架构(Mysql 就这么点东西,分库分表读写分离集群演化)相关推荐

  1. MySQL使用Mycat实现分库分表-读写分离

    MySQL使用Mycat实现分库分表-读写分离 Mycat Mycat介绍 什么是Mycat? Mycat架构 Mycat核心概念 MyCat主要解决的问题 MyCat对多数据库的支持 Mycat分片 ...

  2. 2天,我把MySQL索引、事务、分库分表、锁、性能优化撸完了!

    Java研发工程师必备技能非MySQL莫属,虽说易学好上手,但应对大厂面试,最容易遭遇滑铁卢.功败垂成的也是它. 上手简单,玩转难,才是这款开源数据库叱咤业界多年的真实写照. MySQL 8.0正式版 ...

  3. 3天,把MySQL索引、事务、分库分表撸干净了!

    前两天看到字节一个老哥写的帖子,提到高阶开发者必须掌握的技能,其中他明确提出了"精通MySQL". 为啥MySQL对开发人员如此重要? 第一,不管你去面试哪家公司,数据库是必问项, ...

  4. 太强了!这款轻量级的数据库中间件完美解决了SpringBoot中分库分表问题

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:Macky_He blog.csdn.net/Macky_H ...

  5. mysql sharding 知乎_分库分表系列(1)-shardingsphere核心概念

    欢迎关注公众号: 戏说码农职场 咱们不闲扯, 就直接入正题, 这次总结说下sharding-jdbc 分库分表的工具.整体架构 Apache ShardingSphere 是一套开源的分布式数据库中间 ...

  6. 嘘,别着急!让腾讯架构师告诉你为什么要分库分表

    在文章开头先抛几个问题: (1)什么时候才需要分库分表呢?我们的评判标准是什么? (2)一张表存储了多少数据的时候,才需要考虑分库分表? (3)数据增长速度很快,每天产生多少数据,才需要考虑做分库分表 ...

  7. MySQL(十一):分库分表方案-ShardingSphere

    Sharding-JDBC Sharding-JDBC定位为轻量级Java框架,在Java的JDBC层提供的额外服务.可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM 框架的使用 Shard ...

  8. MySQL(十):分库分表方案

    分库分表 是将数据拆分成不同的存储单元. 从分拆的角度上,可以分为垂直分片和水平分片. 垂直分片:按照业务来对数据进行分片,又称为纵向分片. 垂直分片往往需要对架构和设计进行调整.通常来讲,是来不及应 ...

  9. mysql(5):主从复制和分库分表

    主从复制集群 概念:主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点. 使用场景: 读写分离:使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读 ...

最新文章

  1. 国内第一部IT治理综合图书问世
  2. mysql中group_contact函数的使用
  3. hadoop 提高hdfs删文件效率----hadoop删除文件流程解析
  4. Vue 中多个元素、组件的过渡,及列表过渡
  5. linux安装 java jdk
  6. 前端异步请求数据未获取导致报错解决办法
  7. Spring Boot:(五)静态资源和拦截器处理
  8. Qt的Assistant制作自定义的软件帮助界面(记录)
  9. 【note】Java程序设计基础第五版(下)
  10. php get请求_JWT+PHP实现登录认证+令牌分发的修改
  11. podspec文件介绍
  12. 28.ldconfig
  13. 使用nginx反向代理获取百度MP3的真实网址
  14. 概率论——几何随机变量
  15. 网易云 计算机,网易云音乐电脑版2.7.4.198336_网易云音乐 - 系统之家
  16. 工业测试软件技术指标,工业过程难测参数软测量建模方法研究及应用
  17. 数学之美————每章小结
  18. 类对象模型实验:类数据成员大小
  19. 硬件基本概念-模拟电子电路
  20. python基础资料(Learn|Codecademy好用的工具)

热门文章

  1. hjr-MUD游戏(三):android原生游戏编写
  2. 20230119英语学习
  3. java jfinal_JFinal教程手册
  4. Jfinal项目提供接口
  5. 几款效率神器助你走上人生巅峰之园友推荐[收藏]
  6. 虚拟机内存cache使用不起来,pagecache命中率低
  7. 没有计算机网络适配器,如果win10设备管理器中没有网络适配器,该怎么办?
  8. 泛型编程之函数模板和类模板
  9. AtCoder Contest 229-C-Cheese
  10. Python3 实现 KMP 算法核心 PMT