分布式mysql中间件(mycat)html
Mycat-download@github : https://github.com/MyCATApache/Mycat-download.git java
官网 : mycat.ionode
qq官方群:106088787mysql
Mycat权威指南官方下载:http://songwie.com/attached/file/mycat_1.5.2.pdfgit
视频资料下载:http://pan.baidu.com/s/1i4mgga5程序员
随着传统的数据库技术日趋成熟、计算机网络技术的飞速发展和应用范围的扩充,数据库应用已经广泛创建于计算机网络之上。这时集中式数据库系统表现出它的不足:github
(1)集中式处理,势必形成性能瓶颈;web
(2)应用程序集中在一台计算机上运行,一旦该计算机发生故障,则整个系统受到影响,可靠性不高;sql
(3)集中式处理引发系统的规模和配置都不够灵活,系统的可扩充性差。
在这种形势下,集中式数据库将向分布式数据库发展。
MyCAT的诞生,要从其前身Amoeba和Cobar提及。
Amoeba(变形虫)项目,该开源框架于2008年开始发布一款 Amoeba for Mysql软件。这个软件致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的时候充当SQL路由功能,专一于分布式数据库代理层(Database Proxy)开发。座落与 Client、DB Server(s)之间,对客户端透明。具备负载均衡、高可用性、SQL过滤、读写分离、可路由相关的到目标数据库、可并发请求多台数据库合并结果。 经过Amoeba你可以完成多数据源的高可用、负载均衡、数据切片的功能,目前Amoeba已在不少企业的生产线上面使用。
阿里巴巴于2012年6月19日,正式对外开源的数据库中间件Cobar,前身是早已经开源的Amoeba,不过其做者陈思儒离职去盛大以后,阿里巴巴内部考虑到Amoeba的稳定性、性能和功能支持,以及其余因素,从新设立了一个项目组而且更换名称为Cobar。Cobar 是由 Alibaba 开源的 MySQL 分布式处理中间件,它能够在分布式的环境下看上去像传统数据库同样提供海量数据服务。
Cobar自诞生之日起, 就受到广大程序员的追捧,可是自2013年后,几乎没有后续更新。在此状况下,MyCAT应运而生,它基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能,以及众多成熟的使用案例使得MyCAT一开始就拥有一个很好的起点,站在巨人的肩膀上,MyCAT能看到更远。目前MyCAT的最新发布版本为1.3.0.2版本。
能够经过git或官网下载,地址见首页。
简单的说,MyCAT就是:
MyCAT的目标是:低成本的将现有的单机数据库和应用平滑迁移到“云”端,解决数据存储和业务规模迅速增加状况下的数据瓶颈问题。
1
MyCAT的架构以下图所示:
MyCAT使用MySQL的通信协议模拟成一个MySQL服务器,并创建了完整的Schema(数据库)、Table (数据表)、User(用户)的逻辑模型,并将这套逻辑模型映射到后端的存储节点DataNode(MySQL Instance)上的真实物理库中,这样一来,全部能使用MySQL的客户端以及编程语言都能将MyCAT当成是MySQLServer来使用,没必要开发新的客户端协议。
当MyCAT收到一个客户端发送的SQL请求时,会先对SQL进行语法分析和检查,分析的结果用于SQL路由,SQL路由策略支持传统的基于表格的分片字段方式进行分片,也支持独有的基于数据库E-R关系的分片策略,对于路由到多个数据节点(DataNode)的SQL,则会对收到的数据集进行“归并”而后输出到客户端。
SQL执行的过程,简单的说,就是把SQL经过网络协议发送给后端的真正的数据库上进行执行,对于MySQL Server来讲,是经过MySQL网络协议发送报文,并解析返回的结果,若SQL不涉及到多个分片节点,则直接返回结果,写入客户端的SOCKET流中,这个过程是非阻塞模式(NIO)。
DataNode是MyCAT的逻辑数据节点,映射到后端的某一个物理数据库的一个Database,为了作到系统高可用,每一个DataNode能够配置多个引用地址(DataSource),当主DataSource被检测为不可用时,系统会自动切换到下一个可用的DataSource上,这里的DataSource便可认为是Mysql的主从服务器的地址。
与任何一个传统的关系型数据库同样,MyCAT也提供了“数据库”的定义,并有用户受权的功能,下面是MyCAT逻辑库相关的一些概念:
MyCAT目前经过配置文件的方式来定义逻辑库和相关配置:
MyCAT使用Java开发,由于用到了JDK 7的部分功能,因此在使用前请确保安装了JDK 7.0,并设置了正确的Java环境变量(可在命令行窗口输入:“java –version”获知是否安装成功,以及获取JDK的版本)。
安装完成后,须要添加MYCAT_HOME环境变量,值对应MyCAT安装的根目录。
目录说明见下表所示:
--bin 启动目录 --conf 配置文件存放配置文件: --server.xml:是Mycat服务器参数调整和用户受权的配置文件。 --schema.xml:是逻辑库定义和表以及分片定义的配置文件。 --rule.xml: 是分片规则的配置文件,分片规则的具体一些参数信息单独存放为文件,也在这个目录下,配置文件修改须要重启MyCAT。 --log4j.xml: 日志存放在logs/log中,天天一个文件,日志的配置是在conf/log4j.xml中,根据本身的须要能够调整输出级别为debug debug级别下,会输出更多的信息,方便排查问题。 --autopartition-long.txt,partition-hash-int.txt,sequence_conf.properties, sequence_db_conf.properties 分片相关的id分片规则配置文件 --lib MyCAT自身的jar包或依赖的jar包的存放目录。 --logs MyCAT日志的存放目录。日志存放在logs/log中,天天一个文件
下面图简单描述了最重要的3大配置文件的关系:
启动前,通常须要修改JVM配置参数,打开conf/wrapper.conf文件,以下行的内容为2G和2048,可根据本机配置状况修改成512M或其它值。
在命令行窗口中进入MyCAT安装解压文件下的bin目录,输入以下命令可安装(可选)、启动和中止MyCAT,参考结果以下所示:
./mycat start 启动 ./mycat stop 中止 ./mycat console 前台运行 ./mycat install 添加到系统自动启动(暂未实现) ./mycat remove 取消随系统自动启动(暂未实现) ./mycat restart 重启服务 ./mycat pause 暂停 ./mycat status 查看启动状态
win下:直接运行startup_nowrap.bat,若是出现闪退,在cmd 命令行运行,查看出错缘由。
安装MySQL服务器和MySQL客户端,笔者使用的MySQL服务器是免安装版本:mysql-noinstall-5.1.73-winx64,MySQL客户端是:Navicat for MySQL,免安装版本安装方法请参考:http://blog.csdn.net/q98842674/article/details/12094777,再也不赘述。
建立user、和pay 两个个数据库,并分别创建表结构。
数据的垂直切分,也能够称为纵向切分。将数据库想象成由不少个一大块一大块的“数据块”(表)组成,垂直地将这些“数据块”切开,而后把它们分散到多台数据库主机上面。这样的切分方法就是垂直(纵向)的数据切分。
一个架构设计较好的应用系统,其整体功能确定是由不少个功能模块所组成的,而每个功能模块所须要的数据对应到数据库中就是一个或多个表。而在架构设计中,各个功能模块相互之间的交互点越统1、越少,系统的耦合度就越低,系统各个模块的维护性及扩展性也就越好。这样的系统,实现数据的垂直切分也就越容易。
垂直切分优势:
(1)数据库的拆分简单明了,拆分规则明确;
(2)应用程序模块清晰明确,整合容易;
(3)数据维护方便易行,容易定位。
垂直切分缺点:
(1)部分表关联没法在数据库级别完成,要在程序中完成;
(2)对于访问极其频繁且数据量超大的表仍然存在性能瓶颈,不必定能知足要求;
(3)事务处理相对复杂;
(4)切分达到必定程度以后,扩展性会受到限制;
(5)过分切分可能会带来系统过于复杂而难以维护。
在以下的实例中,须要将
编辑MYCAT_HOME/conf/schema.xml文件,修改dataHost和schema对应的链接信息,user,pay 垂直切分后的配置以下所示:
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://org.opencloudb/"> <schema name="user" checkSQLschema="false" sqlMaxLimit="100" dataNode="user" /> <schema name="pay" checkSQLschema="false" sqlMaxLimit="100" dataNode="pay" /> <dataNode name="user" dataHost="host" database="user" /> <dataNode name="pay" dataHost="host" database="pay" /> <dataHost name="host" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> <heartbeat>select 1</heartbeat> <!-- can have multi write hosts --> <writeHost host="hostM1" url="192.168.0.2:3306" user="root" password="root" /> <writeHost host="hostM2" url="192.168.0.3:3306" user="root" password="root" /> </dataHost> </mycat:schema>
注意:writeHost/readHost中的location,user,password的值须要根据实际的MySQL的链接信息进行修改。
查看conf/server.xml文件,该文件是Mycat服务器参数调整和用户受权的配置文件,默认的MyCat的数据库链接的用户名/密码为mycat/mycat,文件内容参考以下:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd"> <mycat:server xmlns:mycat="http://org.opencloudb/"> <system> <property name="defaultSqlParser">druidparser</property> </system> <user name="mycat"> <property name="password">mycat</property> <property name="schemas">user,pay</property> </user> </mycat:server>
上述文件中的schemas属性须要配置对应的schema(在schema.xml)中进行配置。
重启MyCAT,使用MySQL客户端链接MyCAT,须要注意的是,默认数据端口为8066,管理端口为9066,在MySQL客户端链接MyCAT时,注意填写端口为8066,用户名/密码根据server.xml中的配置进行填写。
链接后可查看后端链接的三个数据库,以下图所示:
水平切分所指的是经过一系列的切分规则将数据水平分布到不一样的DB或table中,在经过相应的DB路由 或者table路由规则找到须要查询的具体的DB或者table以进行Query操做,好比根据用户ID将用户表切分到多台数据库上。
将某个访问极其频繁的表再按照某个字段的某种规则来分散到多个表之中,每一个表中包含一部分数据。
例如,全部数据都是和用户关联的,那么咱们就能够根据用户来进行水平拆分,将不一样用户的数据切分到不一样的数据库中。
如今互联网很是火爆的web 2.0类型的网站,基本上大部分数据都可以经过会员用户信息关联上,可能不少核心表都很是适合经过会员ID来进行数据的水平切分。而像论坛社区讨论系统,就更容易切分了,很是容易按照论坛编号来进行数据的水平切分。切分以后基本上不会出现各个库之间的交互。
水平切分的优势:
表关联基本可以在数据库端所有完成;
不会存在某些超大型数据量和高负载的表遇到瓶颈的问题;
应用程序端总体架构改动相对较少;
事务处理相对简单;
只要切分规则可以定义好,基本上较难遇到扩展性限制。
水平切分的缺点:
切分规则相对更为复杂,很难抽象出一个可以知足整个数据库的切分规则;
后期数据的维护难度有所增长,人为手工定位数据更困难;
应用系统各模块耦合度较高,可能会对后面数据的迁移拆分形成必定的困难。
在通常的应用系统中,用户表及其密切相关的关联表,可根据“用户表”(eg:t_user)中的“用户ID”(user_id)进行水平切分,并基于MyCAT的E-R关系分片策略将其密切相关的表(eg:t_user_class_rel)也分到对应的库中。
在建表语句参考以下:
CREATE DATABASE IF NOT EXISTS `mycat_node1` ;
/**
user 用户表
*/
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`user_id` int(11) NOT NULL COMMENT '用户ID',
`receive_address` varchar(256) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '收货地址',
`create_time` datetime NOT NULL,
`province_code` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用户信息表';
/**
`t_area` 全局表
*/
CREATE TABLE `t_area` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`caller` varchar(16) CHARACTER SET utf8 DEFAULT NULL COMMENT '调用方系统表示',
`province_code` varchar(10) CHARACTER SET utf8 NOT NULL COMMENT '省份编码',
`area_code` varchar(10) CHARACTER SET utf8 NOT NULL COMMENT '区域编码',
`area_name` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '区域名称',
`parent_area_code` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '父区域编码',
`create_time` datetime NOT NULL COMMENT '建立时间',
`modify_time` datetime DEFAULT NULL COMMENT '修改时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3792 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/**
user 节点测试表
*/
DROP TABLE IF EXISTS `t_node`;
CREATE TABLE `t_node` (
`vid` int(11) NOT NULL COMMENT 'ID',
`user_id` int(11) NOT NULL COMMENT '用户ID',
`note` varchar(256) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'note',
`create_time` datetime NOT NULL,
PRIMARY KEY (`vid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='note表';
首先配置schema.xml文件,添加mycat_node1数据库的dataNode设置,并添加t_user和t_area表的schema设置,本次配置了双主,读写分离配置,
同一个表多个分片的配置能够用dataNode="dn$1-100" 通配方式。
修改后的schema.xml文件内容以下所示:
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://org.opencloudb/"> <schema name="mycat" checkSQLschema="true" sqlMaxLimit="100"> <table name="t_user" primaryKey="user_id" dataNode="dn1,dn2" rule="rule1" /> <table name="t_node" primaryKey="vid" autoIncrement="true" dataNode="dn1,dn2" rule="rule1" /> <table name="t_area" type="global" primaryKey="ID" dataNode="dn1,dn2" /> </schema> <dataNode name="dn1" dataHost="jdbchost" database="mycat_node1" /> <dataNode name="dn2" dataHost="jdbchost2" database="mycat_node1" /> <dataHost name="jdbchost" maxCon="500" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> <heartbeat>select 1</heartbeat> <writeHost host="maste1" url="192.168.0.1:3306" user="root" password="root"> <!-- <readHost host="readshard" url="192.168.0.2:3306" user="root" password="root"/> --> </writeHost> <writeHost host="maste2" url="192.168.0.3:3306" user="root" password="root"> <!-- <readHost host="readshard" url="192.168.0.4:3306" user="root" password="root"/> --> </writeHost> </dataHost> <!-- --> <dataHost name="jdbchost2" maxCon="500" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> <heartbeat>select 1</heartbeat> <writeHost host="maste1" url="192.168.0.5:3306" user="root" password="root"> <!-- <readHost host="readshard" url="192.168.0.6:3306" user="root" password="root"/> --> </writeHost> <writeHost host="maste2" url="192.168.0.6:3307" user="root" password="root"> <!-- <readHost host="readshard" url="192.168.0.8:3306" user="root" password="root"/> --> </writeHost> </writeHost> </dataHost> </mycat:schema>
在schema.xml的文件内容中可看到t_user表指定的分片规则是rule1,须要在conf/rule.xml文件中设置rule1的规则为根据user_id进行分片,并按照类“org.opencloudb.route.function.PartitionByLong”的规则进行分片。
该文件的参考内容以下所示:
在server.xml文件中的schemas属性中添加test_mycat的schema。修改后的文件以下所示:
重启MyCAT,使用MySQL客户端链接后,链接后可在mycat数据库下看到t_user和t_area,t_node表,以下图所示:
在MySQL客户端链接的MyCat的test_mycat数据库的t_user表运行以下插入语句,插入2000条数据:
为了确保数据库产品的稳定性,不少数据库拥有双机热备功能。也就是,第一台数据库服务器,是对外提供增删改查业务的生产服务器;第二台数据库服务器,仅仅接收来自第一台服务器的备份数据。通常来讲,为了配置方便,以及稳定性,这两台数据库服务器,都用的是相同的配置。
在实际运行中,第一台数据库服务器的压力,远远大于第二台数据库服务器。所以,不少人但愿合理利用第二台数据库服务器的空闲资源。
从数据库的基本业务来看,数据库的操做无非就是增删改查这4个操做。但对于“增删改”这三个操做,若是是双机热备的环境中作,一台机器作了这三个操做的某一个以后,须要当即将这个操做,同步到另外一台服务器上。出于这个缘由,第二台备用的服务器,就只作了查询操做。进一步,为了下降第一台服务器的压力,干脆就把查询操做所有丢给第二台数据库服务器去作,第一台数据库服务器就只作增删改了。
优势:合理利用从数据库服务器的空闲资源。
缺点:原本第二台数据库服务器,是用来作热备的,它就应该在一个压力很是小的环境下,保证运行的稳定性。而读写分离,却增长了它的压力,也就增长了不稳定性。所以,读写分离,实质上是一个在资金比较缺少,但又须要保证数据安全的需求下,在双机热备方案上,作出的一种折中的扩展方案。
MyCAT的读写分离机制以下:
例如将本机做为写库,10.18.96.133做为读库,MyCAT的读写分离的配置以下:
dataHost的balance属性设置为:
一个dataHost元素,代表进行了数据同步的一组数据库,DBA须要保证这一组数据库服务器是进行了数据同步复制的。writeHost至关于Master DB Server,而其下的readHost则是与从数据库同步的Slave DB Server。当dataHost配置了多个writeHost的时候,任何一个writeHost宕机,Mycat 都会自动检测出来,并尝试切换到下一个可用的writeHost。
在没有配置数据同步复制的状况下,重启后进行测试,可以使用MySQL客户端直接链接读库,插入几条数据后,使用MySQL客户端链接MyCat,运行select语句验证是否在读库上执行。
多主,多读写分离参考:
其中分为dn1,dn2两个分片,每一个分片有两个写入,写入之间开启mysql开启2进制复制,mycat会从当前可用的写入host随机获取一个写入,mycat在任什么时候候 只会单点写入。若是要开启读写分离在放开注释read配置,balance=1或2。
writeType=1 表明全部节点都是写入写入,慎重开启,多节点写入顺序为默认写入根据配置顺序,第一个挂掉切换另外一个。
一个真实的业务系统中,每每存在大量的相似字典表的表格,它们与业务表之间可能有关系,这种关系,能够理解为“标签”,而不该理解为一般的“主从关系”,这些表基本上不多变更,能够根据主键ID进行缓存,下面这张图说明了一个典型的“标签关系”图:
在分片的状况下,当业务表由于规模而进行分片之后,业务表与这些附属的字典表之间的关联,就成了比较棘手的问题,考虑到字典表具备如下几个特性:
鉴于此,MyCAT定义了一种特殊的表,称之为“全局表”,全局表具备如下特性:
将字典表或者符合字典表特性的一些表定义为全局表,则从另一个方面,很好的解决了数据JOIN的难题。经过全局表+基于E-R关系的分片策略,MyCAT能够知足80%以上的企业应用开发。
在各个库分别建立全局表(例如:t_area)的表结构,表结构保持一致,例如:
全局表配置比较简单,不用写Rule规则,在schema.xml中修改test_schema,添加t_area的table子元素,参考以下配置便可:
运行以下insert语句,往test_mycat的t_area表插入10条数据,以下所示:
插入后去dn1,dn2分片中查找,可看到这2个分片中的t_area表都被插入10条数据。执行select语句能返回t_area表的对应记录,执行update和delete语句能对应对全局表相关的分片中的记录进行更新和删除操做。
《MyCat inAction中文版》
主站:Mycat-server@github : https://github.com/MyCATApache/Mycat-Server.git
Mycat-web@github : https://github.com/MyCATApache/Mycat-Web.git
Mycat-doc@github : https://github.com/MyCATApache/Mycat-doc.git
Mycat-download@github : https://github.com/MyCATApache/Mycat-download.git
qq官方群:106088787