收藏 分享(赏)

Mycat权威指南.docx

上传人:wo7103235 文档编号:5859169 上传时间:2019-03-19 格式:DOCX 页数:292 大小:7.85MB
下载 相关 举报
Mycat权威指南.docx_第1页
第1页 / 共292页
Mycat权威指南.docx_第2页
第2页 / 共292页
Mycat权威指南.docx_第3页
第3页 / 共292页
Mycat权威指南.docx_第4页
第4页 / 共292页
Mycat权威指南.docx_第5页
第5页 / 共292页
点击查看更多>>
资源描述

1、入门篇 1MYCAT 开源宣言 1概述 3数据库切分概述 3垂直切分 5水平切分 6Mycat 前世今生 9序章 9Cobar 的十个秘密 10Mycat 闪耀登场 14Mycat 概述 18Mycat 中的概念 21数据库中间件 21逻辑库(schema) 21逻辑表(table) 22分片节点(dataNode) 23节点主机(dataHost) 23分片规则(rule) 23全局序列号(sequence) 23多租户 23快速入门 2510 分钟入门 25快速镜像方式体验 MyCAT 26服务安装与配置 26服务启动与启动设置 28demo 使用 29日志分析 30warpper 日志:

2、 30mycat 日志 31debug 模式下分析 sql 执行。 33异常日志 35Mycat 的配置 37搞定 schema.xml 37schema 标签 37table 标签 39childTable 标签 41dataNode 标签 42dataHost 标签 42heartbeat 标签 44server.xml 45优化配置 45user 标签 45system 标签 46rule.xml 48tableRule 标签 48function 标签 49Mycat 的 join 50分片 join 50全局序列号 57全局序列号介绍 57本地文件方式 57数据库方式 57本地时间戳

3、方式 59其他方式 60自增长主键 60Mycat 分片规则 63分片规则概述 63Mycat 常用的分片规则 64权限控制 74多租户支持 74常见问题与解决方案 76常见问题与解答 76高级进阶篇 83读写分离 83MySQL 主从复制的几种方案 83MySQL 主从复制的几个问题 85Mycat 支持的读写分离 87高可用与集群 89MySQL 高可用的几种方案 89Mycat 高可用方案 93事务支持 95Mycat 里的数据库事务 95XA 事务原理 96XA 事务的问题和 MySQL 的局限 98SQL 拦截 100Mycat SQL 拦截机制 100Mycat 注解 102注解原

4、理 102注解使用示例 103Mycat Catlet 104MyCAT 支持的 Catlet 实现 105jdbc 多数据库支持 105JDBC 概述 105JDBC 体系结构 106JDBC API 106JDBC 4.0 107Mycat 对 JDBC 的支持 108NoSQL 支持(MongoDB) 108MongoDB 109Oracle 116SQL Server 117DB2 118Spark SQL/Hive 118PostgreSQL 121管理命令与监控 122压缩协议支持 130压缩协议支持 130配置说明 130压缩性能测试 130mysql 压缩协议 130Mycat

5、-Web 132Mycat-Web 简介 132Mycat-web 架构及原理 132Mycat-Web 使用篇 132Mycat-Web 安装 132Mycat-Web 功能介绍 134生产实践篇 138生产实践案例 138Mycat 读写分离案例 138分表分库案例 139SAAS 多租户案例 140每天 2 亿数据的实时查询案例 141物联网 26 亿数据的案例 142大型分布式零售系统案例 142生产环境部署 144单节点 mycat 部署 144mycat 的高可用与负载均衡 144Mycat 最佳实践 154Mycat 如图所述通过后端接入不同的后端解决业务的完整需求。 154My

6、cat 实施指南 155Mycat 项目实施步骤 155数据迁移与扩容实践 161案例一:使用一致性 Hash 进行分片 161案例二:使用范围分片 166数据迁移的注意点 167load data 批量导入 168使用 mysqldump 进行数据迁移 169迁移一个表中的部分数据 170版本选择与升级指南 171版本选择 171mycat1.2 中的功能: 171mycat1.3 中的功能: 171mycat1.4 中的功能: 172小结 172性能调优 174主机调优 174JVM 调优 174MyCAT 调优 178MySQL 通用调优 179开发篇 181加入 Mycat 181My

7、cat 开发基础 181Mycat 架构分析 183MyCAT 和 TDDL、Amoeba、Cobar 的架构比较 183框架比较 183点评 185其它资料 186MyCAT 线程模型分析 187MyCAT 线程模型 187Mycat 线程介绍 187Cobar 线程介绍 189Cobar 为什么那么多个线程池? 191MyCAT 与 Cobar 的比较 193mycat 的连接池 195Mycat 连接池模型 195Mycat 的网络通信框架 199先从一个测试说起 199测试环境 199MyCAT 网络框架 201与 Cobar 原有 NIO 细节比较 215MyCAT 的 AIO 实现

8、 217Mycat 的路由与分发流程 224路由的作用 224路由解析器 224druid 路由解析的两种方式 226路由计算 228路由计算的核心要素 232单个表的路由计算 232多个表的路由计算 233全局表的路由计算 234or 语句的路由计算 234系统语句的路由计算 237相关类图和序列图 238路由解析过程中的一些控制变量 241Mycat 的 JDBC 后端框架 242JDBC 方式访问后端数据库 242JDBC 相关类图 242JDBCDatasource 242JDBCConnection 244JDBCHeartbeat 247Mycat 的事务管理机制 249Mycat

9、 事务源码分析 249Mycat 的分页和跨库 Join 251多数据库支持的分页机制 251ShareJoin 代码分析 258Mycat 缓存 265缓存介绍及代码分析 265SQLRouteCache 266TableID2DataNodeCache 268ER_SQL2PARENTID 271Mycat 的分片规则设计 275分片规则设计架构 275分片规则自定义实现 277Mycat Load Data 源码 280load data 代码分析 280mysql 压缩协议代码分析 2831入门篇MYCAT 开源宣言随着技术的不断进步,是否应该有一种比公司形态更有效的组织来支撑经济的进

10、一步发展?这种新型组织在以有形资产为核心的,以农业经济和工业经济为主导的社会是不可能取得成功的,而在以无形资产逐渐成为核心的,以知识经济为主导的信息社会将会成为可能。如国内崛起的分布式数据库中间件产品 Mycat 并不是由任何一家公司主导开发的,而是由民间自发组织的由那些喜爱它的不知名的程序员共同开发,如今该产品的发展速度极快其影响力也逐渐扩大。国内外类似的开源组织和产品还有很多,这些开源产品潜力无限,无论开发效率和质量都逐渐超越任何一家公司的产品。这也导致了一些公司试图通过收购等手段遏制开源产品的发展。那么这些开源产品爱好者和贡献者获得了什么呢?在无私奉献的过程中他们获得了知识 信息社会最有

11、价值的资产,他们可以用这些知识以任何形式换来不可估量的财富,信息社会的开源组织使按劳分配达到了前所未有的公平与公正。企业所采取的期权激励、扁平化管理、自由工作时间等模式,正是对公司这种生产关系自顶向下的改良,以适应持久技术进步带来的生产力的高速发展。但公司的本质:追求股东利益最大化,使其不可能实现真正意义的去中心化。信息社会的开源组织形态是对原有公司模式自底向上的一次颠覆式创新,他们将带来生产力的极速发展。这种组织先天具有开放、共享、敏捷、去中心化等等这些可以带来高效率的特性,可以想像拥有杰出技术与高效团队的开源组织可以创造出超越一切公司的更优秀的产品。每一个人为改变他的状况而自然做出的努力,

12、当其具有施展的自由和安全时,就是一个十分强有力的原则,不需要借助其他,这种个人的努力,就能给社会带来财富和繁荣亚当斯密的这段话是工业革命中的小公司向拥有国家特许经营权的垄断企业发出的呐喊。没有工业革命就没有现代公司存在的必要性;没有现代公司的存在和发展,工业革命的快速进程也无法出现。历史总在重演,信息社会的开源组织将亚当斯密这段话原封不动的回赠给了现代公司制度。它让知识经济不再只是少数资本家的游戏,而成为普通人登台表演的机会。技术不再高高在上,而是落地生根。开源组织将成为引领信息社会进步的发动机,接下来的竞争,就看谁能在无限的数字世界里更好的发挥开源组织的能量了,一个新的时代即将到来!2随着信

13、息技术的持续快速发展和中国经济实力的不断加强,以 Mycat 为代表的中国开源组织和产品的价值和发展前景不可限量!3概述数据库切分概述OLTP 和 OLAP在互联网时代,海量数据的存储与访问成为系统设计与使用的瓶颈问题,对于海量数据处理,按照使用场景,主要分为两种类型:联机事务处理(OLTP)和联机分析处理(OLAP)。联机事务处理(OLTP)也称为面向交易的处理系统,其基本特征是原始数据可以立即传送到计算中心进行处理,并在很短的时间内给出处理结果。联机分析处理(OLAP)是指通过多维的方式对数据进行分析、查询和报表,可以同数据挖掘工具、统计分析工具配合使用,增强决策分析功能。对于两者的主要区

14、别可以用下表来说明:OLTP OLAP系统功能 日常交易处理 统计、分析、报表DB 设计 面向实时交易类应用 面向统计分析类应用数据处理 当前的, 最新的细节的 , 二维的分立的 历史的, 聚集的 , 多维的集成的 , 统一的实时性 实时读写要求高 实时读写要求低事务 强一致性 弱事务分析要求 低、简单 高、复杂关系型数据库和 NoSQL 数据库针对上面两类系统有多种技术实现方案,存储部分的数据库主要分为两大类:关系型数据库与 NoSQL数据库。关系型数据库,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库中的数据。主流的 oracle、DB2、MS SQL Ser

15、ver 和 mysql 都属于这类传统数据库。NoSQL 数据库,全称为 Not Only SQL,意思就是适用关系型数据库的时候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可,可以考虑使用更加合适的数据存储。主要分为临时性键值存储(memcached、Redis)、永久性键值存储(ROMA、Redis )、面向文档的数据库(MongoDB、 CouchDB)、面向列的数据库(Cassandra、HBase),每种 NoSQL 都有其特有的使用场景及优点。Oracle,mysql 等传统的关系数据库非常成熟并且已大规模商用,为什么还要用 NoSQL 数据库呢?主要是由于随着互

16、联网发展,数据量越来越大,对性能要求越来越高,传统数据库存在着先天性的缺陷,即单机(单库)性能瓶颈,并且扩展困难。这样既有单机单库瓶颈,却又扩展困难,自然无法满足日益增长的海4量数据存储及其性能要求,所以才会出现了各种不同的 NoSQL 产品,NoSQL 根本性的优势在于在云计算时代,简单、易于大规模分布式扩展,并且读写性能非常高。下面分析下两者的特点,及优缺点:关系型数据库1) 关系数据库的特点是:- 数据关系模型基于关系模型,结构化存储,完整性约束。- 基于二维表及其之间的联系,需要连接、并、交、差、除等数据操作。- 采用结构化的查询语言(SQL)做数据读写。- 操作需要数据的一致性,需要

17、事务甚至是强一致性。2) 优点:- 保持数据的一致性(事务处理)- 可以进行 join 等复杂查询。- 通用化,技术成熟。3) 缺点:- 数据读写必须经过 sql 解析,大量数据、高并发下读写性能不足。- 对数据做读写,或修改数据结构时需要加锁,影响并发操作。- 无法适应非结构化存储。- 扩展困难。- 昂贵、复杂。NoSQL 数据库1) NoSQL 数据库的特点是:- 非结构化的存储。- 基于多维关系模型。- 具有特有的使用场景。2) 优点:- 高并发,大数据下读写能力较强。- 基本支持分布式,易于扩展,可伸缩。- 简单,弱结构化存储。3) 缺点:- join 等复杂操作能力较弱。- 事务支持

18、较弱。- 通用性差。- 无完整约束复杂业务场景支持较差。虽然在云计算时代,传统数据库存在着先天性的弊端,但是 NoSQL 数据库又无法将其替代,NoSQL只能作为传统数据的补充而不能将其替代,所以规避传统数据库的缺点是目前大数据时代必须要解决的问题。如果传统数据易于扩展,可切分,就可以避免单机(单库)的性能缺陷,但是由于目前开源或者商用的传统数据库基本不支持大规模自动扩展,所以就需要借助第三方来做处理,那就是本书要讲的数据切分,下面就来分析一下如何进行数据切分。5何为数据切分?简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设

19、备负载的效果。数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式。一种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种切可以称之为数据的垂直(纵向)切分;另外一种则是根据表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分。垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很小,业务逻辑非常清晰的系统。在这种系统中,可以很容易做到将不同业务模块所使用的表分拆到不同的数据库中。根据不同的表来进行拆分,对应用程序的影响也更小,拆分规则也会比较简单清

20、晰。水平切分于垂直切分相比,相对来说稍微复杂一些。因为要将同一个表中的不同数据拆分到不同的数据库中,对于应用程序来说,拆分规则本身就较根据表名来拆分更为复杂,后期的数据维护也会更为复杂一些。垂直切分一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面,如下图:系统被切分成了,用户,订单交易,支付几个模块。一个架构设计较好的应用系统,其总体功能肯定是由很多个功能模块所组成的,而每一个功能模块所需要的数据对应到数据库中就是一个或者多个表。而在架构设计中,各个功能模块相互之间的交互点越统一越少,系统的耦

21、合度就越低,系统各个模块的维护性以及扩展性也就越好。这样的系统,实现数据的垂直切分也就越容易。但是往往系统之有些表难以做到完全的独立,存在这扩库 join 的情况,对于这类的表,就需要去做平衡,是数据库让步业务,共用一个数据源,还是分成多个库,业务之间通过接口来做调用。在系统初期,数据量比较少,或者资源有限的情况下,会选择共用数据源,但是当数据发展到了一定的规模,负载很大的情况,就需要必须去做分割。6一般来讲业务存在着复杂 join 的场景是难以切分的,往往业务独立的易于切分。如何切分,切分到何种程度是考验技术架构的一个难题。下面来分析下垂直切分的优缺点:优点: 拆分后业务清晰,拆分规则明确。

22、 系统之间整合或扩展容易。 数据维护简单。缺点: 部分业务表无法 join,只能通过接口方式解决,提高了系统复杂度。 受每种业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高。 事务处理复杂。由于垂直切分是按照业务的分类将表分散到不同的库,所以有些业务表会过于庞大,存在单库读写与存储瓶颈,所以就需要水平拆分来做解决。水平切分相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中,如图:7拆分数据就需要定义

23、分片规则。关系型数据库是行列的二维模型,拆分的第一原则是找到拆分维度。比如:从会员的角度来分析,商户订单交易类系统中查询会员某天某月某个订单,那么就需要按照会员结合日期来拆分,不同的数据按照会员 ID 做分组,这样所有的数据查询 join 都会在单库内解决;如果从商户的角度来讲,要查询某个商家某天所有的订单数,就需要按照商户 ID 做拆分;但是如果系统既想按会员拆分,又想按商家数据,则会有一定的困难。如何找到合适的分片规则需要综合考虑衡量。几种典型的分片规则包括: 按照用户 ID 求模,将数据分散到不同的数据库,具有相同数据用户的数据都被分散到一个库中。 按照日期,将不同月甚至日的数据分散到不

24、同的库中。 按照某个特定的字段求摸,或者根据特定范围段分散到不同的库中。如图,切分原则都是根据业务找到适合的切分规则分散到不同的库,下面用用户 ID 求模举例:既然数据做了拆分有优点也就优缺点。优点: 拆分规则抽象好,join 操作基本可以数据库做。 不存在单库大数据,高并发的性能瓶颈。 应用端改造较少。 提高了系统的稳定性跟负载能力。缺点: 拆分规则难以抽象。 分片事务一致性难以解决。 数据多次扩展难度跟维护量极大。8 跨库 join 性能较差。前面讲了垂直切分跟水平切分的不同跟优缺点,会发现每种切分方式都有缺点,但共同的特点缺点有: 引入分布式事务的问题。 跨节点 Join 的问题。 跨节

25、点合并排序分页问题。 多数据源管理问题。针对数据源管理,目前主要有两种思路:A. 客户端模式,在每个应用程序模块中配置管理自己需要的一个(或者多个)数据源,直接访问各个数据库,在模块内完成数据的整合;B. 通过中间代理层来统一管理所有的数据源,后端数据库集群对前端应用程序透明;可能 90%以上的人在面对上面这两种解决思路的时候都会倾向于选择第二种,尤其是系统不断变得庞大复杂的时候。确实,这是一个非常正确的选择,虽然短期内需要付出的成本可能会相对更大一些,但是对整个系统的扩展性来说,是非常有帮助的。Mycat 通过数据切分解决传统数据库的缺陷,又有了 NoSQL 易于扩展的优点。通过中间代理层规

26、避了多数据源的处理问题,对应用完全透明,同时对数据切分后存在的问题,也做了解决方案。下面章节就分析,mycat 的由来及如何进行数据切分问题。由于数据切分后数据 Join 的难度在此也分享一下数据切分的经验:第一原则:能不切分尽量不要切分。第二原则:如果要切分一定要选择合适的切分规则,提前规划好。第三原则:数据切分尽量通过数据冗余或表分组(Table Group)来降低跨库 Join 的可能。第四原则:由于数据库中间件对数据 Join 实现的优劣难以把握,而且实现高性能难度极大,业务读取尽量少使用多表 Join。什么是 mycat,maycat 从哪里来,又是如何解决这些问题的,下一章让我们来

27、作分析。9Mycat 前世今生序章如果我有一个 32 核心的服务器,我就可以实现 1 个亿的数据分片,我有 32 核心的服务器么?没有,所以我至今无法实现 1 个亿的数据分片。 Mycats Plan上面这句话是 Mycat 1.0 快要完成时候的一段感言,而当发展到 Mycat 1.3 的时候,我们又有了一个新的 Plan:如果我们有 10 台物理机,我们就可以实现 1000 亿的数据分片,我们有 10 台物理机么?没有,所以,Mycat 至今没有机会验证 1000 亿大数据的支撑能力 Mycats Plan 2.0“每一个成功的男人背后都有一个女人”。自然 Mycat 也逃脱不了这个法则。

28、Mycat 背后是阿里曾经开源的知名产品 Cobar。 Cobar 的核心功能和优势是 MySQL 数据库分片,此产品曾经广为流传,据说最早的发起者对 Mysql 很精通,后来从阿里跳槽了,阿里随后开源的 Cobar,并维持到 2013 年年初,然后,就没有然后了。Cobar 的思路和实现路径的确不错。基于 Java 开发的,实现了 MySQL 公开的二进制传输协议,巧妙地将自己伪装成一个 MySQL Server,目前市面上绝大多数 MySQL 客户端工具和应用都能兼容。比自己实现一个新的数据库协议要明智的多,因为生态环境在哪里摆着。Cobar 使用起来也非常方便。由于是基于 Java 语言

29、开发的,下载下来解压,安装 JDK,然后配置几个不是很复杂的配置文件,猛击鼠标,就能启动 Cobar。因此这个开源产品赢得了很多 Java 粉丝以及 PHP 用户的追捧。当然,笨人(Leader us)也跟着进入,并且在某个大型云项目中 “苦海无边”的煎着熬,良久。爱情就像是见鬼。只有撞见了,你才会明白爱情是怎么回事。TA 是如此神秘,欲语还羞。情窦初开的你又玩命将 TA 的优点放大,使自己成为一只迷途的羔羊。每个用过 Cobar 的人就像谈过一段一波三折、荡气回肠的爱情,令你肝肠寸断。就像围城:里面的人已经出不来了,还有更多的人拼命想挤进去。 仅以此文,献给哪些努力在 IT 界寻求未来的精英

30、和小白们,还有更多被无视的,正准备转行的同仁,同在江湖混,不容易啊,面试时候就装装糊涂,放人家一马,说不定,以后又是一个 Made in China 的乔布斯啊。如果我有一个 32 核心的服务器,我就可以实现 1 个亿的数据分片,我有 32 核心的服务器么?没有,所以我至今无法实现 1 个亿的数据分片。 Mycat s Plan曾经的 TA曾经的 TA,长发飘飘,肤若凝脂,国色天香,长袖善舞,所以,一笑倾城。那已成传说,一如您年少时的坚持:“书中自有黄金屋”Cobar 曾是多少 IT 骚年心中的那个 TA,有关 Cobar 的这段美好的描述(不能说是广告) 俘虏了众多程序猿躁动纯真的心:Cob

31、ar 是阿里巴巴研发的关系型数据的分布式处理系统,该产品成功替代了原先基于 Oracle 的数据存储方案,目前已经接管了 3000+个 MySQL 数据库的 schema,平均每天处理近 50 亿次的 SQL 执行请求。1050 亿有多大?99%的普通人类看到这个数字,已经不能呼吸。当然,我指的是*RMB*。99% 的程序猿除了对工资比较敏感,其实对数字通常并不感冒。上面这个简单的数字描述,已立刻让我们程序型的大脑短路。恨不得立刻百度 Cobar,立刻 Download,立刻熬夜研究。做个简单的推算,50 亿次请求转换为每个 schema 每秒的数据访问请求即 TPS,于是我们得到一个让自己不

32、能相信的数字:20TPS,每秒不到 20个访问。Cobar 最重要的特性是分库分表。Cobar 可以让你把一个 MySQL 的 Table 放到 10 个甚至 100 个位于不同物理机上的 MySQL 服务器上去存储,而在用户看来是一张表(逻辑表)。这样功能很有价值。比如:我们有 1 亿的订单,则可以划分为 10 个分片,存储到 2-10 个物理机上。每个 MySQL 服务器的压力减少,而系统的响应时间则不会增加。看上去很完美的功能,而且潜意识里,执行这句 SQL:select count(*) from order 100%的人都会认为:会返回 1 条数据,但事实上,Cobar 会返回 N

33、条数据,N=分片个数。接下来我们继续执行 SQL:select count(*) from order order by order_date你会发现奇怪的乱序现象,而且结果还随机,这是因为,Cobar 只是简单的把上述 SQL 发给了后端 N 个分片对应的 MySQL 服务器去执行,然后把结果集直接输出. 再继续看看,我们常用的 Limit 分页的结果 可以么?答案是: 不可以。这个问题可以在客户端程序里做些工作来解决。所以随后出现了 Cobar Client。据我所知,很多Cobar 的使用者也都是自行开发了类似 Cobar Client 的工具来解决此类问题。从实际应用效果来说,一方面,

34、客户端编程方式解决,困难度很高,Bug 率也居高不下;另一方面,对于 DBA 和运维来说,增加了困难度。当你发现这个问题的严重性,再回头看看 Cobar 的官方文档,你怅然若失,四顾茫然。接下来,本文将隐藏在 Cobar 代码中那些不为人知的秘密逐一披漏,你洞悉了这些秘密,就会明白Mycat 为什么会横空出世。Cobar 的十个秘密第一个秘密:Cobra 会假死?是的,很多人遇到这个问题。如何来验证这点呢?可以做个简单的小实验,假如你的分片表中配置有表company,则打开 mysql 终端,执行下面的 SQL:select sleep(500) from company;此 SQL 会执行等

35、待 500 秒,你再努力以最快的速度打开 N 个 mysql 终端,都执行相同的 SQL,确保 N当前 Cobra 的执行线程数: show threadpool11的所有 Processor1-E 的线程池的线程数量总和,然后你再执行任何简单的 SQL,或者试图新建立连接,都会无法响应,此时 show threadpool里面看到 TASK_QUEUE_SIZE 已经在积压中。 不可能吧,据说 Cobra 是 NIO 的非阻塞的,怎么可能阻塞!别激动,去看看代码,Cobra 前端是 NIO的,而后端跟 Mysql 的交互,是阻塞模式,其 NIO 代码只给出了框架,还未来得及实现。真相永远在代

36、码里,所以,为了发现真相,还是转行去做码农吧!貌似码农也像之前的技术工人,越来越稀罕了。第二个秘密:高可用的陷阱?每一个秘密的背后,总是隐藏着更大的秘密。Cobra 假死的的秘密背后,还隐藏着一个更为 “强大”的秘密,那就是假死以后,Cobra 的频繁主从切换问题。我们看看 Cobra 的一个很好的优点 “高可用性”的实现机制,下图解释了 Cobra 如何实现高可用性:分片节点 dn2_M1 配置了两个 dataSource,并且配置了心跳检测(heartbeat) 语句,在这种配置下,每个 dataNode 会定期对当前正在使用的 dataSource 执行心跳检测,默认是第一个,频率是 1

37、0 秒钟一次,当心跳检测失败以后,会自动切换到第二个 dataSource 上进行读写,假如 Cobra 发生了假死,则在假死的 1 分钟内, Cobra 会自动切换到第二个节点上,因为假死的缘故,第二个节点的心跳检测也超时。于是,1 分钟内 Cobra 频繁来回切换,懂得 MySQL 主从复制机制的人都知道,在两个节点上都执行写操作意味着什么? 可能数据一致性被破坏,谁也不知道那个机器上的数据是最新的。还有什么情况下,会导致心跳检测失败呢?这是一个不得不说的秘密:当后端数据库达到最大连接后,会对新建连接全部拒绝,此时,Cobar 的心跳检测所建立的新连接也会被拒绝,于是,心跳检测失败,于是,

38、一切都悄悄的发生了。幸好,大多数同学都没有配置高可用性,或者还不了解此特性,因此,这个秘密,一直在安全的沉睡。第三个秘密:看上去很美的自动切换Cobar 很诱人的一个特性是高可用性,高可用性的原理是数据节点 DataNode 配置引用两个DataSource,并做心跳检测,当第一个 DataSource 心跳检测失败后,Cobar 自动切换到第二个节点,当第二个节点失败以后,又自动切换回第一个节点,一切看起来很美,无人值守,几乎没有宕机时间。在真实的生产环境中,我们通常会用至少两个 Cobar 实例组成负载均衡,前端用硬件或者 HAProxy 这样的负载均衡组件,防止单点故障,这样一来,即使某

39、个 Cobar 实例死了,还有另外一台接手,某个Mysql 节点死了,切换到备节点继续,至此,一切看起来依然很美,喝着咖啡,听着音乐,领导视察,你微笑着点头 No problem,Everything is OK!直到有一天,某个 Cobar 实例果然如你所愿的死了,不管是假死还是真死,你按照早已做好的应急方案,优雅的做了一个不是很艰难的决定 重启那个故障节点,然后继续喝着咖啡,听着音乐,轻松写好故障处理报告发给领导,然后又度过了美好的一天。你忽然被深夜一个电话给惊醒,你来不及发火,因为你的直觉告诉你,这个问题很严重,大量的订单数据发生错误很可能是昨天重启 cobar 导致的数据库发生奇怪的问

40、题。你努力排查了几个小时,终于发现,主备两个库都在同时写数据,主备同步失败,你根本不知道那个库是最新数据,紧急情况下,你做了一个很英明的决定,停止昨天故障的那个 cobar 实例,然后你花了 3 个通宵,解决了数据问题。12这个陷阱的代价太高,不知道有多少同学中枪过,反正我也是躺着中枪过了。若你还不清楚为何会产生这个陷阱,现在我来告诉你:1. Cobar 启动的时候,会用默认第一个 Datasource 进行数据读写操作;2. 当第一个 Datasource 心跳检测失败,会切换到第二个 Datasource;3. 若有两个以上的 Cobar 实例做集群,当发生节点切换以后,你若重启其中任何一

41、台 Cobar,就完美调入陷阱;那么,怎么避免这个陷阱?目前只有一个办法,节点切换以后,尽快找个合适的时间,全部集群都同时重启,避免隐患。为何是重启而不是用节点切换的命令去切换?想象一下 32 个分片的数据库,要多少次切换?MyCAT 怎么解决这个问题的?很简单,节点切换以后,记录一个 properties 文件( conf 目录下),重启的时候,读取里面的节点 index,真正实现了无故障无隐患的高可用性。第四个秘密:只实现了一半的 NIONIO 技术用作 JAVA 服务器编程的技术标准,已经是不容置疑的业界常规做法,若一个 Java 程序员,没听说过 NIO,都不好意思说自己是 Java

42、人。所以 Cobar 采用 NIO 技术并不意外,但意外的是,只用了一半。Cobar 本质上是一个“数据库路由器”,客户端连接到 Cobar,发生 SQL 语句,Cobar 再将 SQL 语句通过后端与 MySQL 的通讯接口 Socket 发出去,然后将结果返回给客户端的 Socket 中。下面给出了SQL 执行过程简要逻辑:SQL-FrontConnection-Cobar-MySQLChanel-MySQLFrontConnection 实现了 NIO 通讯,但 MySQLChanel 则是同步的 IO 通讯,原因很简单,指令比较复杂,NIO 实现有难度,容易有 BUG。后来最新版本 C

43、obar 尝试了将后端也 NIO 化,大概实现了 80%的样子,但没有完成,也存在缺陷。由于前端 NIO,后端 BIO,于是另一个有趣的设计产生了 两个线程池,前端 NIO 部分一个线程池,后端 BIO 部分一个线程池。各自相互不干扰,但这个设计的结果,导致了线程的浪费,也对性能调优带来很大的困难。由于后端是 BIO,所以,也是 Cobar 吞吐量无法太高、另外也是其假死的根源。MyCAT 在 Cobar 的基础上,完成了彻底的 NIO 通讯,并且合并了两个线程池,这是很大一个提升。从 1.1 版本开始,MyCAT 则彻底用了 JDK7 的 AIO,有一个重要提升。第五个秘密:阻塞、又见阻塞C

44、obar 本质上类似一个交换机,将后端 Mysql 的返回结果数据经过加工后再写入前端连接并返回,于是前后端连接都存在一个“写队列”用作缓冲,后端返回的数据发到前端连接 FrontConnection 的写队列中排队等待被发送,而通常情况下,后端写入的的速度要大于前端消费的速度,在跨分片查询的情况下,这个现象更为明显,于是写线程就在这里又一次被阻塞。解决办法有两个,增大每个前端连接的“写队列”长度,减少阻塞出现的情况,但此办法只是将问题抛给了使用者,要是使用者能够知道这个写队列的默认值小了,然后根据情况进行手动尝试调整也行,但13Cobar 的代码中并没有把这个问题暴露出来,比如写一个告警日志

45、,队列满了,建议增大队列数。于是绝大多数情况下,大家就默默的排队阻塞,无人知晓。MyCAT 解决此问题的方式则更加人性化,首先将原先数组模式的固定长度的队列改为链表模式,无限制,并且并发性更好,此外,为了让用户知道是否队列过长了(一般是因为 SQL 结果集返回太多,比如1 万条记录),当超过指定阀值(可配)后,会产生一个告警日志。1024第六个秘密:又爱又恨的 SQL 批处理模式正如一枚硬币的正反面无法分离,一块磁石怎样切割都有南北极,爱情中也一样,爱与恨总是纠缠着,无法理顺,而 Cobar 的 SQL 批处理模式,也恰好是这样一个令人又爱又恨的个性。通常的 SQL 批处理,是将一批 SQL

46、作为一个处理单元,一次性提交给数据库,数据库顺序处理完以后,再返回处理结果,这个特性对于数据批量插入来说,性能提升很大,因此也被普遍应用。JDBC 的代码通常如下:String sql = “insert into travelrecord (id,user_id,traveldate,fee,days) values(?,?,?,?,?)“;ps = con.prepareStatement(sql);for (Map map : list) ps.setLong(1, Long.parseLong(map.get(“id“);ps.setString(2, (String) map.get

47、(“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();mit();ps.clearBatch();但 Cobar 的批处理模式的实现,则有几个地方是与传统不同的: 提交到 cobar 的批处理中的每一条 SQL 都是单独的数据库连接来执行的 批处理中的 SQL 并发执行并发多连接同时执行,则意味着 Batch

48、 执行速度的提升,这是让人惊喜的一个特性,但单独的数据库连接并发执行,则又带来一个意外的副作用,即事务跨连接了,若一部分事务提交成功,而另一部分失败,则导致脏数据问题。看到这里,你是该“爱”呢还是该“恨”?先不用急着下结论,我们继续看看 Cobar 的逻辑,SQL 并发执行,其实也是依次获取独立连接并执行,因此还是有稍微的时间差,若某一条失败了,则 cobar 会在会话中标记 ”事务失败,需要回滚“,下一个没执行的 SQL 就抛出异常并跳过执行,客户端就捕获到异常,并执行 rollback,回滚事务。绝大多数情况下,数据库正常运行,此刻没有宕机,因此事务还是完整保证了,但万一恰好在某个 SQL

49、 commit 指令的时候宕机,于是杯具了,部分事务没有完成,数据没写入。但这个概率有多大呢?一条 insert insert 语句执行commit 指令的时间假如是 50 毫秒,100 条同时提交,最长跨越时间是 5000 毫秒,即 5 秒中,而这个 C指令的时间占据程序整个插入逻辑的时间的最多 20%,假如程序批量插入的执行时间占整个时间的20%(已经很大比例了),那就是 20%20%=4%的概率,假如机器的可靠性是 99.9%,则遇到失败的概率是 0.1%4%=十万分之四。十万分之四,意味着 99.996%的可靠性,亲,可以放心了么?另外一个问题,即批量执行的 SQL,通常都是 insert 的,插入成功就 OK,失败的怎么办?通常会记录日志,重新找机会再插入,因此建议主键是能日志记录的,用于判断数据是否已经插入。14最后,假如真要多个 SQL 使用同一个后端 MYSQL 连接并保持事务怎么办?就采用通常的事务模式,单条执行 SQL,这个过程中, Cobar 会采用 Session 中上次用过的物理连接执行下一个 SQL 语句,因此,整个过程是与通常的事务模式完全一致。第六个秘密:庭院深深锁清秋说起死锁,貌似我

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 实用文档 > 说明文书

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报