人已经出不来了,还有更多的人拼命想挤进去。

仅以此文,献给哪些努力在IT界寻求未来的精英和小白们,还有更多被无视的,正准备转行的同仁,同在江湖混,不容易啊,面

试时候就装装糊涂,放人家一马,说不定,以后又是一个Made in China的乔布斯啊。

如果我有一个32核心的服务器,我就可以实现1个亿的数据分片,我有32核心的服务器么?没有,所以我至今无法实现1个亿的数

据分片。——Mycat ‘s Plan

曾经的TA

曾经的TA,长发飘飘,肤若凝脂,国色天香,长袖善舞,所以,一笑倾城。

那已成传说,一如您年少时的坚持:“书中自有黄金屋…”

Cobar曾是多少IT骚年心中的那个TA,有关Cobar的这段美好的描述(不能说是广告)俘虏了众多程序猿躁动纯真的心:

Cobar是阿里巴巴研发的关系型数据的分布式处理系统,该产品成功替代了原先基于Oracle的数据存储方案,目前已

经接管了3000+个MySQL数据库的schema,平均每天处理近50亿次的SQL执行请求。

50亿有多大?99%的普通人类看到这个数字,已经不能呼吸。当然,我指的是**RMB**。99%的程序猿除了对工资比较敏感,其

实对数字通常并不感冒。上面这个简单的数字描述,已立刻让我们程序型的大脑短路。恨不得立刻百度Cobar,立刻

Download,立刻熬夜研究。做个简单的推算,50亿次请求转换为每个schema每秒的数据访问请求即TPS,于是我们得到一个让

自己不能相信的数字:20TPS,每秒不到20个访问。

Cobar最重要的特性是分库分表。Cobar可以让你把一个MySQL的Table放到10个甚至100个位于不同物理机上的MySQL服务器

上去存储,而在用户看来是一张表(逻辑表)。这样功能很有价值。比如:我们有1亿的订单,则可以划分为10个分片,存储到

2-10个物理机上。每个MySQL服务器的压力减少,而系统的响应时间则不会增加。看上去很完美的功能,而且潜意识里,执行

这句SQL:

select count(*) from order

100%的人都会认为:会返回1条数据,但事实上,Cobar会返回N条数据,N=分片个数。

接下来我们继续执行SQL:

select count(*) from order order by order_date

你会发现奇怪的乱序现象,而且结果还随机,这是因为,Cobar只是简单的把上述SQL发给了后端N个分片对应的MySQL服务器去执

行,然后把结果集直接输出….

再继续看看,我们常用的Limit分页的结果…可以么?答案是:**不可以**

这个问题可以在客户端程序里做些工作来解决。所以随后出现了Cobar Client。据我所知,很多Cobar的使用者也都是自行开发

了类似Cobar Client的工具来解决此类问题。从实际应用效果来说,一方面,客户端编程方式解决,困难度很高,Bug率也居高

不下;另一方面,对于DBA和运维来说,增加了困难度。

当你发现这个问题的严重性,再回头看看Cobar的官方文档,你怅然若失,四顾茫然。

接下来,本文将隐藏在Cobar代码中那些不为人知的秘密逐一披漏,你洞悉了这些秘密,就会明白Mycat为什么会横空出世。

Cobar的十个秘密

第一个秘密:Cobra会假死?

是的,很多人遇到这个问题。如何来验证这点呢?可以做个简单的小实验,假如你的分片表中配置有表company,则打开mysql终

端,执行下面的SQL:

select sleep(500) from company;

此SQL会执行等待500秒,你再努力以最快的速度打开N个mysql终端,都执行相同的SQL,确保N>当前Cobra的执行线程数:

show @@threadpool

的所有Processor1-E的线程池的线程数量总和,然后你再执行任何简单的SQL,或者试图新建立连接,都会无法响应,此时

show @@threadpool

里面看到TASK_QUEUE_SIZE已经在积压中。

不可能吧,据说Cobra是NIO的非阻塞的,怎么可能阻塞!别激动,去看看代码,Cobra前端是NIO的,而后端跟Mysql的交互,

是阻塞模式,其NIO代码只给出了框架,还未来得及实现。真相永远在代码里,所以,为了发现真相,还是转行去做码农吧!貌

似码农也像之前的技术工人,越来越稀罕了。

第二个秘密:高可用的陷阱?

每一个秘密的背后,总是隐藏着更大的秘密。Cobra假死的的秘密背后,还隐藏着一个更为“强大”的秘密,那就是假死以

后,Cobra的频繁主从切换问题。我们看看Cobra的一个很好的优点——“高可用性”的实现机制,下图解释了Cobra如何实现

高可用性:

分片节点dn2_M1配置了两个dataSource,并且配置了心跳检测(heartbeat)语句,在这种配置下,每个dataNode会定期对当前

正在使用的dataSource执行心跳检测,

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

默认是第一个,频率是10秒钟一次,当心跳检测失败以后,会自动切换到第二个

dataSource上进行读写,假如Cobra发生了假死,则在假死的1分钟内,Cobra会自动切换到第二个节点上,因为假死的缘故,

第二个节点的心跳检测也超时。于是,1分钟内Cobra频繁来回切换,懂得MySQL主从复制机制的人都知道,在两个节点上都执

行写操作意味着什么?——可能数据一致性被破坏,谁也不知道那个机器上的数据是最新的。

还有什么情况下,会导致心跳检测失败呢?这是一个不得不说的秘密:当后端数据库达到最大连接后,会对新建连接全部拒绝,

此时,Cobar的心跳检测所建立的新连接也会被拒绝,于是,心跳检测失败,于是,一切都悄悄的发生了。

幸好,大多数同学都没有配置高可用性,或者还不了解此特性,因此,这个秘密,一直在安全的沉睡。

第三个秘密:看上去很美的自动切换

Cobar很诱人的一个特性是高可用性,高可用性的原理是数据节点DataNode配置引用两个DataSource,并做心跳检测,当第一

个DataSource心跳检测失败后,Cobar自动切换到第二个节点,当第二个节点失败以后,又自动切换回第一个节点,一切看起来

很美,无人值守,几乎没有宕机时间。

在真实的生产环境中,我们通常会用至少两个Cobar实例组成负载均衡,前端用硬件或者HAProxy这样的负载均衡组件,防止单

点故障,这样一来,即使某个Cobar实例死了,还有另外一台接手,某个Mysql节点死了,切换到备节点继续,至此,一切看起

来依然很美,喝着咖啡,听着音乐,领导视察,你微笑着点头——No problem,Everything is OK!直到有一天,某个Cobar实

例果然如你所愿的死了,不管是假死还是真死,你按照早已做好的应急方案,优雅的做了一个不是很艰难的决定——重启那个故

障节点,然后继续喝着咖啡,听着音乐,轻松写好故障处理报告发给领导,然后又度过了美好的一天。

你忽然被深夜一个电话给惊醒,你来不及发火,因为你的直觉告诉你,这个问题很严重,大量的订单数据发生错误很可能是昨

天重启cobar导致的数据库发生奇怪的问题。你努力排查了几个小时,终于发现,主备两个库都在同时写数据,主备同步失败,

你根本不知道那个库是最新数据,紧急情况下,你做了一个很英明的决定,停止昨天故障的那个cobar实例,然后你花了3个通

宵,解决了数据问题。

这个陷阱的代价太高,不知道有多少同学中枪过,反正我也是躺着中枪过了。若你还不清楚为何会产生这个陷阱,现在我来告

诉你:

1. Cobar启动的时候,会用默认第一个Datasource进行数据读写操作;

2. 当第一个Datasource心跳检测失败,会切换到第二个Datasource;

3. 若有两个以上的Cobar实例做集群,当发生节点切换以后,你若重启其中任何一台Cobar,就完美调入陷阱;

那么,怎么避免这个陷阱?目前只有一个办法,节点切换以后,尽快找个合适的时间,全部集群都同时重启,避免隐患。为何是

重启而不是用节点切换的命令去切换?想象一下32个分片的数据库,要多少次切换?

MyCAT怎么解决这个问题的?很简单,节点切换以后,记录一个properties文件( conf目录下),重启的时候,读取里面的节

点index,真正实现了无故障无隐患的高可用性。

第四个秘密:只实现了一半的NIO

NIO技术用作JAVA服务器编程的技术标准,已经是不容置疑的业界常规做法,若一个Java程序员,没听说过NIO,都不好意思

说自己是Java人。所以Cobar采用NIO技术并不意外,但意外的是,只用了一半。

Cobar本质上是一个“数据库路由器”,客户端连接到Cobar,发生SQL语句,Cobar再将SQL语句通过后端与MySQL的通讯接

口Socket发出去,然后将结果返回给客户端的Socket中。下面给出了SQL执行过程简要逻辑:

SQL->FrontConnection->Cobar->MySQLChanel->MySQL

FrontConnection 实现了NIO通讯,但MySQLChanel则是同步的IO通讯,原因很简单,指令比较复杂,NIO实现有难度,容易

有BUG。后来最新版本Cobar尝试了将后端也NIO化,大概实现了80%的样子,但没有完成,也存在缺陷。

由于前端NIO,后端BIO,于是另一个有趣的设计产生了——两个线程池,前端NIO部分一个线程池,后端BIO部分一个线程

池。各自相互不干扰,但这个设计的结果,导致了线程的浪费,也对性能调优带来很大的困难。

由于后端是BIO,所以,也是Cobar吞吐量无法太高、另外也是其假死的根源。

MyCAT在Cobar的基础上,完成了彻底的NIO通讯,并且合并了两个线程池,这是很大一个提升。从1.1版本开始,MyCAT则

彻底用了JDK7的AIO,有一个重要提升。

第五个秘密:阻塞、又见阻塞

Cobar本质上类似一个交换机,将后端Mysql 的返回结果数据经过加工后再写入前端连接并返回,于是前后端连接都存在一个

“写队列”用作缓冲,后端返回的数据发到前端连接FrontConnection的写队列中排队等待被发送,而通常情况下,后端写入的

的速度要大于前端消费的速度,在跨分片查询的情况下,这个现象更为明显,于是写线程就在这里又一次被阻塞。

解决办法有两个,增大每个前端连接的“写队列”长度,减少阻塞出现的情况,但此办法只是将问题抛给了使用者,要是使用

者能够知道这个写队列的默认值小了,然后根据情况进行手动尝试调整也行,但Cobar的代码中并没有把这个问题暴露出来,比

如写一个告警日志,队列满了,建议增大队列数。于是绝大多数情况下,大家就默默的排队阻塞,无人知晓。

MyCAT解决此问题的方式则更加人性化,首先将原先数组模式的固定长度的队列改为链表模式,无限制,并且并发性更好,此

外,为了让用户知道是否队列过长了(一般是因为SQL结果集返回太多,比如1万条记录),当超过指定阀值(可配)后,会产生

一个告警日志。

1024

第六个秘密:又爱又恨的SQL 批处理模式

正如一枚硬币的正反面无法分离,一块磁石怎样切割都有南北极,爱情中也一样,爱与恨总是纠缠着,无法理顺,而Cobar的

SQL 批处理模式,也恰好是这样一个令人又爱又恨的个性。

通常的SQL 批处理,是将一批SQL作为一个处理单元,一次性提交给数据库,数据库顺序处理完以后,再返回处理结果,这个

特性对于数据批量插入来说,性能提升很大,因此也被普遍应用。JDBC的代码通常如下:

String sql = “insert into travelrecord (id,user_id,traveldate,fee,days) values(?,?,?,?,?)”;

ps = con.prepareStatement(sql);

for (Map<String, String> map : list) {

ps.setLong(1, Long.parseLong(map.get(“id”)));

ps.setString(2, (String) map.get(“user_id”));

ps.setString(3, (String) map.get(“traveldate”));

ps.setString(4, (String) map.get(“fee”));

ps.setString(5, (String) map.get(“days”));

ps.addBatch();

}

ps.executeBatch();

con.commit();

ps.clearBatch();

但Cobar的批处理模式的实现,则有几个地方是与传统不同的:

提交到cobar的批处理中的每一条SQL都是单独的数据库连接来执行的

批处理中的SQL并发执行

并发多连接同时执行,则意味着Batch执行速度的提升,这是让人惊喜的一个特性,但单独的数据库连接并发执行,则又带来一

个意外的副作用,即事务跨连接了,若一部分事务提交成功,而另一部分失败,则导致脏数据问题。看到这里,你是该“爱”呢

还是该“恨”?

先不用急着下结论,我们继续看看Cobar的逻辑,SQL并发执行,其实也是依次获取独立连接并执行,因此还是有稍微的时间

差,若某一条失败了,则cobar会在会话中标记”事务失败,需要回滚“,下一个没执行的SQL就抛出异常并跳过执行,客户端

就捕获到异常,并执行rollback,回滚事务。绝大多数情况下,数据库正常运行,此刻没有宕机,因此事务还是完整保证了,但

万一恰好在某个SQL commit指令的时候宕机,于是杯具了,部分事务没有完成,数据没写入。但这个概率有多大呢?一条insert

MyCat:第二章:Mycat前世今生,java运行原理图相关推荐

  1. 《深入理解JAVA虚拟机》详细解读(第二章 ):JAVA内存区域与内存溢出异常

    目录 一.JAVA内存区域与内存溢出异常 1. 概述 2. 运行时数据区域 2.1 程序计数器 2.2 Java虚拟机栈 2.3本地方法栈 2.4 堆 2.5 方法区 2.6 运行时常量池 2.7直接 ...

  2. Educoder- 《JAVA从小白到大牛》(第二章)2-3 Java面向对象 - 封装、继承和多态的综合练习

    提示:本文章为个人学习记录,仅供参考学习,禁止转载,支持交流与讨论. 文章目录 第1关:通关任务一 任务描述 相关知识 面向对象思想 封装 继承 `super()`和`this()` 编程要求 测试说 ...

  3. linux运行 的模块,第二章:构造和运行模块

    1.用户空间和内核空间 用户空间:应用程序运行在用户空间,运行在处理器的最低级别,处理器控制着对硬件的直接访问以及内存的非授权访问. 内核空间:驱动模块运行于内核空间,运行在处理器的最高级别,可以进行 ...

  4. 数据库中间件:Mycat 权威指南+Mycat 实战笔记,双管齐下

    前阵子复习了一下消息中间件MQ系列的知识点,忽然想起还有个数据库中间件--MyCat! Mycat 是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户可以把它看作是一个数据库代 ...

  5. 《计算机网络》第二章作业

    <计算机网络>第二章作业 复习题 R5 运行在一台主机上的一个进程,使用什么信息来标识运行在另一台主机上的进程? 在两个不同端系统上的进程,通过跨域计算机网络交换报文(message)而相 ...

  6. MyCat:第二章:Mycat前世今生(1),java技术分享主题

    高可用性: 分片节点dn2_M1配置了两个dataSource,并且配置了心跳检测(heartbeat)语句,在这种配置下,每个dataNode会定期对当前 正在使用的dataSource执行心跳检测 ...

  7. MyCat:第二章:Mycat前世今生,java同步锁原理

    是阻塞模式,其NIO代码只给出了框架,还未来得及实现.真相永远在代码里,所以,为了发现真相,还是转行去做码农吧!貌 似码农也像之前的技术工人,越来越稀罕了. 第二个秘密:高可用的陷阱? 每一个秘密的背 ...

  8. MyCat:第二章:Mycat前世今生

    Mycat前世今生 如果我有一个32核心的服务器,我就可以实现1个亿的数据分片,我有32核心的服务器么?没有,所以我至今无法实现1个亿 的数据分片.--Mycat 's Plan 上面这句话是Myca ...

  9. 《Effective Java》学习笔记 第二章 创建和销毁对象

    第二章 创建和销毁对象 何时以及如何创建对象,何时以及如何避免创建对象,如何确保他们能够适时地销毁,以及如何管理对象销毁之前必须进行的各种清理动作. 1 考虑用静态工厂方法代替构造器 一般在某处获取一 ...

最新文章

  1. 每日一皮:用户永远不知道怎么用我们的产品...
  2. MyBatis3: There is no getter for property named 'code' in 'class java.lang.String'
  3. Spring-data-jpa和mybatis的比较及两者的优缺点?
  4. SpringBoot入门实战项目各阶段目录
  5. VTK:Filtering之ConnectivityFilterDemo
  6. 常见的社会潜规则有哪些?
  7. 干货 | 大白话彻底搞懂 HBase RowKey 详细设计
  8. linux 扩展挂载盘大小_Linux 添加挂载硬盘(包含挂载大于2T以上硬盘)
  9. html5 页面加载缓慢,html5体验优化页面加载的14条建议
  10. linux mysql 5.7密码忘记_Mysql5.7.14 linux版密码忘记的找回方法
  11. 二十一天学通之cookie的路径和域
  12. Unity学习日志_NGUI简介
  13. 【p6spy】程序员开发利器P6spy——打印执行sql语句,mybatis、ibatis、Hibernate均可使用
  14. 全志V3s 荔枝派WiFi RTL8723BS 连接
  15. Kettle 全量抽取数据
  16. 【CSS】CSS盒子模型
  17. 模拟量输入输出模块的用途是什么?
  18. pageX,clientX,screenX,offsetX区别
  19. 【韩顺平Linux】学习笔记1
  20. idead 1099端口被占用 解决

热门文章

  1. NLP入门学习1——分词和词性标注
  2. SLURM 系统入门使用指南
  3. Unity 游戏设计模式 — 中介者模式(Mediator)
  4. 我看看你今天上班骑车
  5. js jq 删除列表元素
  6. 视频截帧大概率避免连续重复图片
  7. 十分详细的HashMap 源码
  8. 语言模型(一)—— 统计语言模型n-gram语言模型
  9. PR —— 轨道操作(锁定、解锁、可见、不可见、恢复误删除音视频)
  10. html时间选择控件 简书,flatpickr好看的日期选择器插件