MyCat - 背景篇(1)

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

SQL与NoSQL

目前,对于互联网海量数据的存储以及处理,按使用场景,分为OLTP(联机事务处理,比如即时交易,强调快速响应与处理)与OLAP(联机分析处理,比如BI,强调多维数据分析)。对于这些数据的存储,主要有两种解决方案,即基于SQL的关系型数据库,和NoSQL的非关系型数据库。
非关系型数据库在某些特定场景下有奇效,比如键值存储(redis,ROMA,Memcached)数据库应用在排行更新,会话保存,面向文档的数据库(mongoDB、couchDB)应用在日志记录,面向列的数据库(Cassandra、HBase)在博客中的应用。关系型数据库最大的问题在于速度与可扩展性上,而这些NoSQL数据库一般部署简单,支持扩展,而且速度极高。
但是,NoSQL目前还是只能做为关系型数据库在某些特定应用场景的补充,不能完全替代严谨规范的关系型数据库。

关系型数据库瓶颈

目前商用的数据库以及开源的数据库一般都不支持大规模自动扩展,单库上面存在着性能瓶颈。一般的,MySQL数据库单表超过1000W~2000W条记录时,性能就会有比较明显的下降。为了提升性能以及可以存储数据的量,我们需要分库分表。

分库分表

举个例子,假设我们原来的应用是为了客户完成下单,快递员接受并更新运单状态,客户可以随时查看运单状态的任务。一开始我们的数据库层架构设计(忽略其他部分,比如缓存、CDN等)可能是这样:


但是很快地,我们发现,把所有的数据放在同一个库里面,随着业务的增长,数据量太大,响应时间变得越来越慢。业务需求已经承受不住了。我们首先做了垂直分片,按照业务模块,将数据库拆分成了快递员库,运单库和客户库来管理。


再之后,我们发现运单单表有效数据量量级已经超过了2000W条,为了不影响TPS与QPS。我们需要把运单表做进一步的水平拆分。但是,水平分片后,像分片表关联这种操作,比如order by,group by还有join就不能通过数据库自己本身去完成了,因为每个分片库的数据都不是完整的。而且,跨分片事务(即分布式事务,分布式XA),比较难以实现。
拆分规则有很多种,需要根据具体业务决定。比如如果我们整体业务TPS小于单库可承受TPS,只是我们每天要产生2000W记录,而且这些记录要保存一周。我们可以按照日期分片,比如周一的数据保存到库1,之后以此类推。


但是这样做的缺点很明显,同一天的写压力全都打到一个分片上,其他分片处于写空闲状态。即使整体业务TPS小于单库可承受TPS,这样的架构也不利于以后业务增长进行扩展。
我们还可以按照运单号对某一数字(分片个数)取模,让这些运单平均分布到每个后台分片库上。


这样,我们可以保证同一时间所有的分片都是工作状态,没有资源浪费。但是,未来如果分片不够用了,扩容难还是个问题。
还有很多其它分片的规则(比如wang-jeekins哈希取模范围,扩容哈希范围,id字段范围等),在之后的MyCat中间件具体使用篇我会详细介绍,并给出一些原创的可行的分片方案。

谁来分库分表

实现这种分库分表可以有多种思路,看上面的架构图,我们可以:

  • 在数据库层做手脚

  • 在应用层做手脚

  • 在应用层与数据库层添加数据库路由中间件(相当于代理)

    首先,在数据库层做手脚 ,需要数据库产品为开源的,而且修改MySQL和MariaDB之类的数据库需要相当专业的团队以及较高的成本,所以,一般项目初期不会考虑这种方式。

然后是在应用层做手脚 ,像Ibatis sharding, shark,TDDL等。他们实现分库分表的思路是很相似的:


一般这些框架很轻量级,在应用端放一个jar。他们本身不一定都实现了动态配置,但是他们都可以和Disconf之类的动态配置中心结合,实现动态数据源与动态分片规则。首先,应用会访问附近的配置中心,配置中心会告诉这个应用应该去访问哪个数据库以及分片规则是什么。之后,应用会自己去访问数据库,并作分片和合并结果。
这样做的好处是:
- 实现分片和结果聚合的压力分摊给了每一个应用
- 根据应用业务场景开发对应的功能
- 轻量级,代码少
- 能最大发挥后台数据库的能力
但是同时,也有它的局限性:
- 依赖于额外的配置中心实现动态配置
- 对应用代码有侵入性
- 使应用处理变重
- 应用出问题难以定位是哪里出了问题
- 将业务开发与后台数据库分库分表管理耦合,难于开发管理

最后,是代理的方式:


实现思路大概是,实现mysql协议栈,将自己伪装成一个mysql数据库,自己后台管理所有mysql实例。应用无感知,只当后台只是一个mysql实例。这个代理mysql实例,实现分库分表,结果合并等功能。
这种代理实现的好处在于:
- 对应用没有侵入性
- 压力打在中间件上
- 统一管理后台数据库,能及时定位问题
但是,他也有自己的缺陷,首先就是压力打在中间件上的话,可能不能发挥后台数据库最大的能力。由此,中间件需要做负载均衡集群,这要求中间件必须是无状态的。但是,这无疑增加了架构的复杂程度。目前,淘宝的高吞吐量业务还是在用TDDL类似的产品也是这个原因。
这两种实现方式还都有共同的难以解决的问题,比如分布式事务这个问题,目前也没有非常完美的方案。还有,他们对于SQL都有限制(比如有的不支持DDL,大部分都不推荐使用大事务等)
整体说来,项目初期使用代理这种实现方式还是利大于弊的,网上有很多开源产品,他们基本和淘宝的Amoeba和Cobar一脉相承。实际应用场景众多,较为可靠。本文即将介绍的MyCat也不例外。
下一篇我们将更详细地介绍MyCat的背景 :-D

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值