MyCat介绍与配置

MyCat介绍与配置

 

Mycat 前生今世

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

Mycat 简介

Mycat是什么?

  从定义和分类来看,它是一个开源的分布式数据库系统,是一个实现了MySQL协议的Server,前端用户可以把它看做是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生(Native)协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分库分表,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。
 
  Mycat发展到目前版本,已经不在是一个单纯的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NOSQL方式的存储,未来还会支持更多类型的存储。而在最终用户看来,无论是那种存储方式,在Mycat里,都是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅度降低开发难度,提升开发速度,在测试阶段,可以将一表定义为任何一种Mycat支持的存储方式,比如MySQL的MyASM表、内存表、或者MongoDB、LeveIDB以及号称是世界上最快的内存数据库MemSQL上。
 
    试想一下,用户表存放在MemSQL上,大量读频率远超过写频率的数据如订单的快照数据存放于InnoDB中,一些日志数据存放于MongoDB中,而且还能把Oracle的表跟MySQL的表做关联查询,你是否有一种不能呼吸的感觉?而未来,还能通过Mycat自动将一些计算分析后的数据灌入到Hadoop中,并能用Mycat+Storm/Spark Stream引擎做大规模数据分析,看到这里。

对于DBA来说,可以这么理解Mycat:

  Mycat就是MySQL Server,而Mycat后面连接的MySQL Server,就好象是MySQL的存储引擎,如InnoDB,MyISAM等,因此,Mycat本身并不存储数据,数据是在后端的MySQL上存储的,因此数据可靠性以及事务等都是MySQL保证的,简单的说,Mycat就是MySQL最佳伴侣,它在一定程度上让MySQL拥有了能跟Oracle PK的能力。

对于软件工程师来说,可以这么理解Mycat:

   Mycat就是一个近似等于MySQL的数据库服务器,你可以用连接MySQL的方式去连接Mycat(除了端口不同,默认的Mycat端口是8066而非MySQL的3306,因此需要在连接字符串上增加端口信息),大多数情况下,可以用你熟悉的对象映射框架使用Mycat,但建议对于分片表,尽量使用基础的SQL语句,因为这样能达到最佳性能,特别是几千万甚至几百亿条记录的情况下。

对于架构师来说,可以这么理解Mycat:

Mycat是一个强大的数据库中间件,不仅仅可以用作读写分离、以及分表分库、容灾备份,而且可以用于多租户应用开发、云平台基础设施、让你的架构具备很强的适应性和灵活性,借助于即将发布的Mycat智能优化模块,系统的数据访问瓶颈和热点一目了然,根据这些统计分析数据,你可以自动或手工调整后端存储,将不同的表映射到不同存储引擎上,而整个应用的代码一行也不用改变。  
 
    当前是个大数据的时代,但究竟怎样规模的数据是和数据库系统呢?对此,国外有一个数据库领域的权威人士说了一个结论:干亿以下的数据规模仍然是数据库领域的专长,而Hadoop等这种系统,更适合的是干亿以上的规模,所以,Mycat适合1000亿条以下的单表规模,如果你的数据超过了这个规模,请投靠Mycat Plus吧!

Mycat原理

Mycat的原理并不复杂,复杂的是代码,如果代码也不复杂,那么早就成为一个传说了。
    Mycat的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
    上述图片里,Orders表被分为三个分片datanode(简称dn),这三个分片是分布在两台MySQL Server上(DataHost),即datanode=database@datahost方式,因此你可以用一台到N台服务器来分片,分片规则为(sharding rule)典型的字符串枚举分片规则,一个规则的定义是分片字段(sharding column)+分片函数(rule function),这里的分片字段为rov而分片函数为字符串枚举方式。
    当Mycat收到一个SQL时,会先解析这个SQL,查找涉及到的表,然后看此表的定义,如果有分片规则,则获取到SQL里分片字段的值,并匹配分片函数,得到该QL对应的分片列表,然后将SQL发往这些分片去执行,最后收集和处理所有分片返回的结果数据,并输出到客户端。以select * from Orders where prov=?语句为例,查到prov=wuhan,按照分片函数,wuhan返回
dn1,于是SQL就发给了MySQL1,去取DB1上的查询结果,并返回给用户。
    如果上述SQL改为elect * from Orders where prov in (‘wuhan’,‘beijing’),那么,SQL就会发给ySQL1与MySQL2去执行,然后结果集合并后输出给用户。但通常业务中我们的SQL会有Order By 以及Limit翻页语法,此时就涉及到结果集在Mycat端的二次处理,这部分的代码也比较复杂,而最复杂的则属两个表的Jion问题,为此,Mycat提出了创新性的ER分片、全局表、HBT(Human Brain Tech)人工智能的Catlet、以及结合Storm/Spark引擎等十八般武艺的解决办法,从而成为目前业界最强大的方案,这就是开源的力量!

应用场景

Mycat发展到现在,适用的场景已经很丰富,而且不断有新用户给出新的创新性的方案,以下是几个典型的应用场景:
  a.单纯的读写分离,此时配置最为简单,支持读写分离,主从切换
  b.分表分库,对于超过1〇〇〇万的表进行分片,最大支持1 〇〇〇亿的单表分片
  c.多租户应用,每个应用一个库,但应用程序只连接Mycat,从而不改造程序本身,实现多租户化
  d.报表系统,借助于Mycat的分表能力,处理大规模报表的统计
  e.代替Hbase,分析大数据
  f.作为海量数据实时查询的一种简单有效方案,比如 1〇〇亿条频繁查询的记录需要在3秒内查询出来结果, 除了基于主键的查询,还可能存在范围查询或其他属性查询,此时Mycat可能是最简单有效的选择
---单纯的读写分离,此时配置最为简单,支持读写分离,主从切换分表分库,对于超过000万的表进行分片,最大支持1000亿的单表分片
---多租户应用,每个应用一个库,但应用程序只连接Mycat,从而不改造程序本身,实现多租户化
---报表系统,借助于Mycat的分表能力,处理大规模报表的统计替代Hbase,分析大数据,作为海量数据实时查询的一种简单有效方案,比如100亿条频繁查询的记录需要在3秒内查询出来结果,除了基于主键的查询,还可能存在范围查询或其他属性查询,此时ycat可能是最简单有效的选择  

Mycat长期路线图

    强化分布式数据库中间件的方面的功能,使之具备丰富的插件、强大的数据库智能优化功能、全面的系统监控能力、以及方便的数据运维工具,实现在线数据扩容、迁移等高级功能进一步挺进大数据计算领域,深度结合Spark Stream和Storm等分布式实时流引擎,能够完成快速的巨表关联、排序、分组聚合等 OLAP方向的能力,并集成一些热门常用的实时分析算法,让工程师以及DBA们更容易用Mycat实现一些高级数据分析处理功能。
   不断强化Mycat开源社区的技术水平,吸引更多的IT技术专家,使得Mycat社区成为中国的Apache,并将Mycat推到Apache基金会,成为国内顶尖开源项目,最终能够让一部分志愿者成为专职的Mycat开发者,荣耀跟实力一起提升。
依托Mycat社区,聚集100个CXO级别的精英,众筹建设亲亲山庄,Mycat社区+亲亲山庄=中国最大IT O2O社区

Mycat中的概念

数据库中间件

前面讲了Mycat是一个开源的分布式数据库系统,但是由于真正的数据库需要存储引擎,而Mycat并没有存储引擎,所以并不是完全意义的分布式数据库系统。
那么Mycat是什么?Mycat是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服务。由于前面讲的对数据进行分片处理之后,从原有的一个库,被切分为多个分片数据库,所有的分片数据库集群构成了整个完整的数据库存储。
 
  如上图所表示,数据被分到多个分片数据库后,应用如果需要读取数据,就要需要处理多个数据源的数据。如果没有数据库中间件,那么应用将直接面对分片集群,数据源切换、事务处理、数据聚合都需要应用直接处理,原本该是专注于业务的应用,将会花大量的工作来处理分片后的问题,最重要的是每个应用处理将是完全的重复造轮子。
  所以有了数据库中间件,应用只需要集中与业务处理,大量的通用的数据聚合,事务,数据源切换都由中间件来处理,中间件的性能与处理能力将直接决定应用的读写性能,所以一款好的数据库中间件至关重要。  

逻辑库(schema)

    通常对实际应用来说,并不需要知道中间件的存在,开发人员只需要知道数据库的概念,所以数据库中间件可以被看做是一个或多个数据库集群构成的逻辑库。
    在云计算时代,数据库中间件可以以多租户的形式给一个或多个应用提供服务,每个应用访问的可能是一个独立或者是共享的物理库,常见的如阿里云数据库服务器RDS。

 

逻辑表(table)

    既然有逻辑库,那么就会有逻辑表,分布式数据库中,对应用来说,读写数据的表就是逻辑表。逻辑表,可 以是数据切分后,分布在一个或多个分片库中,也可以不做数据切分,不分片,只有一个表构成。

分片表

  分片表,是指那些原有的很大数据的表,需要切分到多个数据库的表,这样,每个分片都有一部分数据,所 有分片构成了完整的数据
  例如在mycat配置中的t_node就属于分片表,数据按照规则被分到dn1,dn2两个分片节点(dataNode) 上。
<table name=nt_noden primaryKey=nvidn autoincrement=ntruen dataNode=ndn1,dn2n rule=nrule1n />

非分片表

  一个数据库中并不是所有的表都很大,某些表是可以不用进行切分的,非分片是相对分片表来说的,就是那 些不需要进行数据切分的表。
  如下配置中t_node ,只存在于分片节点(dataNode ) dn1上。
<table name=nt_noden primaryKey=nvidn autoincrement=ntruen dataNode=ndn1" />

ER 表

    关系型数据库是基于实体关系模型(Entity-Relationship Model)之上,通过其描述了真实世界中事物与关 系,Mycat中的ER表即是来源于此。根据这一思路,提出了基于E-R关系的数捤分片策略,子表的记录与所关 联的父表记录存放在同一个数据分片上,即子表依赖于父表,通过表分组(Table Group )保证数据Join不会跨库操作。
    表分组(Table Group )是解决跨分片数据join的一种很好的思路,也是数据切分规划的重要一条规则。

全局表

  一个真实的业务系统中,往往存在大量的类似字典表的表,这些表基本上很少变动,字典表具有以下几个特性:
1.变动不频繁
2.数据量总体变化不大
3.数据规模不大,很少有超过数十万条记录。

分片节点(dataNode)

  数据切分后,一个大表被分到不同的分片数据库上面,每个表分片所在的数据库就是分片节点 (dataNode )。
节点主机(dataHost)
  数据切分后,每个分片节点(dataNode )不一定都会独占一台机器,同一机器上面可以有多个分片数据库, 这样一个或多个分片节点(dataNode )所在的机器就是节点主机(dataHost),为了规避单节点主机并发数限 制,尽量将读写压力高的分片节点(dataNode )均衡的放在不同的节点主机(dataHost )。

分片规则(rule)

  前面讲了数据切分,1个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到 某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难度。

多租户

多租户技术或称多重租赁技术,是一种软件架构技术,它是在探讨与实现如何于多用户的环境下共用相同的系统或程序组件,并且仍可确保各用户间数据的隔离性。在云计算时代,多租户技术在共用的数据中心以单一系统架构与服务提供多数客户端相同甚至可定制化的服务,并且仍然可以保障客户的数据隔离。目前各种各样的云计算服务就是这类技术范畴,例如阿里云数据库服务(RDS )、阿里云服务器(ECS)等等。
多租户在数据存储上存在三种主要的方案,分别是:

1.1 独立数据库

这是第一种方案,即一个租户一个数据库,这种方案的用户数据隔离级别最高,安全性最好,但成本也高。 
优点:
1、为不同的租户提供独立的数据库,有助于简化数据模型的扩展设计,满足不同租户的独特需求;
2、如果出现故障,恢复数据比较简单。
缺点:
1、增大了数据库的安装数量,随之带来维护成本和购置成本的增加。
    这种方案与传统的一个客户、一套数据、一套部署类似,差别只在于软件统一部署在运营商那里。如果面对的是银行、医院等需要非常高数据隔离级别的租户,可以选择这种模式,提高租用的定价。如果定价较低,产品 走低价路线,这种方案一般对运营商来说是无法承受的。

1.2共享数据库,隔离数据架构

这是第二种方案,即多个或所有租户共享Database,但是每个租户一个Schema。
优点:
1、为安全性要求较高的租户提供了一定程度的逻辑数据隔离,并不是完全隔离;每个数据库可以支持更多的租户数量。
缺点:
1、如果出现故障,数据恢复比较困难,因为恢复数据库将牵扯到其它租户的数据
2、如果需要跨租户统计数据,存在一定困难。

共享数据库,共享数据架构

这是第三种方案,即租户共享同一个Database、同一个Schema,但在表中通过TenantID区分租户的数据。这是共享程度最高、隔离级别最低的模式。
优点:
1、三种方案比较,第三种方案的维护和购置成本最低,允许每个数据库支持的租户数量最多。
缺点:
1、隔离级别最低,安全性最低,需要在设计开发时加大对安全的开发量;
2、数据备份和恢复最困难,需要逐表逐条备份和还原。
3、如果希望以最少的服务器为最多的租户提供服务,并且租户接受以牺牲隔离级别换取降低成本,这种方案最适合
 
官方网站:http://www.mycat.org.cn/

何为数据切分?

简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主 机)上面,以达到分散单台设备负载的效果。

数据的切分(Sharding )根据其切分规则的类型,可以分为两种切分模式。一种是按照不同的表(或者 Schema )来切分到不同的数据库(主机)之上,这种切可以称之为数据的垂直(纵向)切分;另外一种则是根据表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分。

垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很小,业务逻辑非常清晰的系统。在这种系统中,可以很容易做到将不同业务模块所使用的表分拆到不同的数据库中。根据不同的表来进行拆分,对应用程序的影响也更小,拆分规则也会比较简单清晰。

水平切分于垂直切分相比,相对来说稍微复杂一些。因为要将同一个表中的不同数据拆分到不同的据库中,对于应用程序来说,拆分规则本身就较根据表名来拆分更为复杂,后期的数据维护也会更为复杂一些。

垂直切分

一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同 的数据库上面,这样也就将数据或者说压力分担到不同的库上面,如下图:
 

 

    一个架构设计较好的应用系统,其总体功能肯定是由很多个功能模块所组成的,而每一个功能模块所需要的 数据对应到数据库中就是一个或者多个表。而在架构设计中,各个功能模块相互之间的交互点越统一越少,系统 的耦合度就越低,系统各个模块的维护性以及扩展性也就越好。这样的系统,实现数据的垂直切分也就越容易。
      但是往往系统之有些表难以做到完全的独立,存在这扩库join的情况,对于这类的表,就需要去做平衡,是数据库让步业务,共用一个数据源,还是分成多个库,业务之间通过接口来做调用。在系统初期,数据量比较少,或者资源有限的情况下,会选择共用数据源,但是当数据发展到了一定的规模,负载很大的情况,就需要必须去做分割。
  一般来讲业务存在着复杂join的场景是难以切分的,往往业务独立的易于切分。如何切分,切分到何种 程度是考验技术架构的一个难题。

下面来分析下垂直切分的优缺点:

优点:
  1. 拆分后业务清晰,拆分规则明确。
  2. 系统之间整合或扩展容易。
  3. 数据维护简单。
缺点:
  1. 部分业务表无法join ,只能通过接口方式解决,提高了系统复杂度。
  2. 受每种业务不同的限制存在单库性能瓶颈,不易扩展跟性能提高。
  3. 事务处理复杂。由于垂直切分是按照业务的分类将表分散到不同的库,所以有些业务表会过于庞大,存在单库读写与存储瓶颈,所以就需要水平拆分来做解决。

水平切分

    相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分 到一个数据库,而另外的某些行又切分到其他的数据库中,如图:
 
    拆分数据就需要定义分片规则。关系型数据库是行列的二维模型,拆分的第一原则是找到拆分维度。比如: 从会员的角度来分析,商户订单交易类系统中查询会员某天期某个订单,那么就需要按照会员结合日期来拆分,不同的数据按照会员ID做分组,这样所有的数据查询join都会在单库内解决;如果从商户的角度来讲,要查询某个商家某天所有的订单数,就需要按照商户ID做拆分;但是如果系统既想按会员拆分,又想按商家数据,则会有一定的困难。如何找到合适的分片规则需要综合考虑衡量。

几种典型的分片规则包括:

  a.按照用户ID求模,将数据分散到不同的数据库,具有相同数据用户的数据都被分散一个库中。
  b.按照日期,将不同月甚至日的数据分散到不同的库中。
  c.按照某个特定的字段求模,或者根据特定范围段分散到不同的库中。
 
如图,切分原则都是根据业务找到适合的切分规则分散到不同的库,下面用用户 ID 求模举例:
 

 

 
既然数据做了拆分有优点也就优缺点。
优点:
A.拆分规则抽象好,join 操作基本可以数据库做
B.不存在单库大数据,高并发的性能瓶颈。
C.应用端改造较少。
D.提高了系统的稳定性跟负载能力。
缺点:
a.拆分规则难以抽象。
b.分片亊务一致性难以解决。
c.数捤多次扩展难度跟维护量极大。
d.跨库 join 性能较差。

前面讲了垂直切分跟水平切分的不同跟优缺点,会发现每种切分都有缺点,但共同的特点缺点有:

1.引入分布式亊务的问题。
2.跨节点 Join 的问题。
3.跨节点合并排序分页问题。
4.多数据源管理问题。

针对数据源管理,目前主要有两种思路:

  A. 客户端模式,在每个应用程序模块中配置管理自己需要的一个(或者多个)数据源,直接访问各个数据库,在模块内完成数据的整合;
  B. 通过中间代理层来统一管理所有的数据源,后端数据库集群对前端应用程序透明;
 

可能 90%以上的人在面对上面这两种解决思路的时候都会倾向于选择第二种,尤其是系统不断变得庞大复杂的时候。确实,这是一个非常正确的选择,虽然短期内需要付出的成本可能会相对更大一些,但是对整个系统的扩展性来讲,是非常有帮助的数据切分的原则:

数据切分的原则:

第一原则:能不切分尽量不要切分。
第二原则:如果要切分一定要选择合适的切分规则,提前规划好。
第三原则:数据切分尽量通过数据冗余或者表分组(Table Group)来降低跨库 Join 的可能。
第四原则:由于数据库中间件对数据 Join 实现的优劣难以把握,而且实现高性能难度极大,业务读取尽量少使用多表 Join。

安装Mycat

安装Mycat

wget http://dl.mycat.io/1.6.5/Mycat-server-1.6.5-release-20180122220033-linux.tar.gz
tar zxf Mycat-server-1.6.5-release-20180122220033-linux.tar.gz 
mkdir /application/
mv mycat /application/
echo "export PATH=/application/mycat/bin:$PATH" >> /etc/profile
source /etc/profile
echo $PATH

下载安装JDK

因为jdk和Tomcat的版本对运维来说没什么区别,提供本文使用的软件下载地址:

链接:https://pan.baidu.com/s/1OToeWr-1jD-hmKYc8UivUA 密码:ze3h

[root@tomcat ~]# cd /application/tools/
[root@tomcat tools]# rz
rz waiting to receive.
Starting zmodem transfer.  Press Ctrl+C to cancel.
Transferring apache-tomcat-8.0.27.tar.gz...
  100%    8914 KB    8914 KB/sec    00:00:01       0 Errors  
Transferring jdk-8u60-linux-x64.tar.gz...
  100%  176990 KB    14749 KB/sec    00:00:12       0 Errors  
tar xf jdk-8u60-linux-x64.tar.gz -C /application/
ln -s /application/jdk1.8.0_60 /application/jdk
sed -i.ori '$a export JAVA_HOME=/application/jdk\nexport PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH\nexport CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar' /etc/profile
source /etc/profile
#→出现下面结果证明部署成功
[root@tomcat ~]# java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

创建管理用户

主库上对rep和rep_r用户授权如下:
用户:rep  密码:oldboy 端口:3306
权限:all
命令:
grant replication slave on test.* to 'rep'@'10.0.0.%' identified by 'oldboy';
grant replication slave on test.* to 'rep_r'@'10.0.0.%' identified by 'oldboy';
flush privileges;
注:为了方便下面的主从切换,两个用户都授予了所有的权限,生产环境尽量不要这样子授权!
修改mycat配置文件
[root@Linuxdemo3 mycat]# pwd
/application/mycat
[root@Linuxdemo3 mycat]# ll
total 24
drwxr-xr-x 2 root root 4096 Jul  4 03:13 bin
drwxrwxrwx 2 root root 4096 Dec 13  2015 catlet
drwxrwxrwx 2 root root 4096 Jul  4 03:13 conf
drwxr-xr-x 2 root root 4096 Jul  4 03:13 lib
drwxrwxrwx 2 root root 4096 Dec 13  2015 logs
-rwxrwxrwx 1 root root  219 Jun 22 15:33 version.txt
目录解释如下:
1.bin程序目录,存放了 window版本和linux版本,除了提供封装服务的版本之外,也提供了 nowrap的 shell脚本命令,方便大家选择和修改,进入到bin目录:
2.Linux 下运行:./mycat console,首先要 chmod +x *
注:mycat 支持的命令{ console | start | stop | restart | status | dump }
3.conf目录下存放配置文件,其中:
4.server.xm丨是Mycat服务器参数调整和用户授权的配置文件,
5.schema.xm丨是逻 辑库定义和表仌及分片定义的配置文件,
6.rule.xml是分片规则的配置文件,分片规则的具体一些参数信息单独存 放为文件,也在这个目录下,配置文件修改,需要重启Mycat或者通过9066端口 reload. 
7.lib目录下主要存放mycat依赖的一些jar文件.
9.日志存放在logs/mycat.log中,每天一个文件,日志的配置是在conf/log4j.xml中,根据自己的需要,可 以调整输出级别为debug , debug级别下,会输出更多的信息,方便排查问题
注意:Linux下部署安装MySQL ,默认不忽略表名大小写,需要手动到/etc/my.cnf下配置 lower_case_table_names=1使Linux环境下MySQL忽略表名大小写,否则使用MyCAT的时候会提示找不到 表的

修改server.xml文件

[root@Linuxdemo3 conf]#  vim server.xml
        </system>
        <user name="rep">
                <property name="password">oldboy</property>
                <property name="schemas">test</property>
        </user>
        <user name="rep_r">
                <property name="password">oldboy</property>
                <property name="schemas"> test</property>
                <property name="readOnly">true</property>
        </user>
注意:
1、这里配置的是可以连接主库的两个用户
用户:rep   密码:oldboy 给予此用户test数据库增删改查的权限。   
用户:rep_r 密码:oldboy 给予此用户test数据库读的权限。  
2、这里的test,不一定是你数据库上的真实库名,可以任意指定,只要接下来和schema.xml的配置文件的库名统一即可。

修改schema.xml文件

[root@Linuxdemo3 conf]#  vim schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/" >
        <schema name="test" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="test" />
        <dataNode name="dn2" dataHost="localhost1" database=" test " />
        <dataNode name="dn3" dataHost="localhost1" database=" test " />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
                writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM1" url="10.0.0.202:3306" user="rep"
                        password="oldboy">
                </writeHost>
                 <readHost host="hostS1" url="10.0.0.202:3307" user="rep_r"
                        password="oldboy" />
                 </readHost>
                 </dataHost>             
</mycat:schema>
(1)<schema name="test" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
这里的oldboy就是我们所宣称的数据库名称,必须和server.xml中的用户指定的数据库名称一致。添加一个dataNode=”dn1”,是指定了我们这个库只有在dn1上,没有分库。
(2) <dataNode name="dn1" dataHost="localhost1" database="test" />
这里只需要改database的名字,db1就是你真是的数据库上的数据库名,可根据自己的数据库名称修改。
(3) 
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
                writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">

需要配置的位置:

balance="1"   writeType="0"   switchType="1"

balance

1、balance=0  不开启读写分离机制,所有读操作都发送到当前可用的writehost了 .
2、balance=1  全部的readhost与stand by writeHost 参与select语句的负载均衡。简单的说,双主双从模式(M1àS1,M2àS2,并且M1和M2互为主备),正常情况下,M1,S1,S2都参与select语句的复杂均衡。
3、balance=2  所有读操作都随机的在readhost和writehost上分发

writeType 

负载均衡类型,目前的取值有3种:
1、writeType="0", 所有写操作发送到配置的第一个writeHost。
2、writeType="1",所有写操作都随机的发送到配置的writeHost。
3、writeType="2",不执行写操作。

switchType 

1、switchType=-1 表示不自动切换
2、switchType=1 默认值,自动切换
3、switchType=2 基于MySQL 主从同步的状态决定是否切换
<writeHost host="hostM1" url="10.0.0.202:3306" user="rep"
                        password="oldboy">
                        <!-- can have multi read hosts -->
                <readHost host="hostS1" url="10.0.0.202:3306" user="rep_r"
                        password="oldboy"/>
注意:
这里配置的是读写服务器的IP地址和端口访问,访问的用户名和密码;而且一定要先在客户端测试OK了以后在进行配置。

启动Mycat

[root@Linuxdemo3 conf]# /application/mycat/bin/mycat start
Starting Mycat-server...
[root@Linuxdemo3 logs]#
出现这个界面表示mycat已经成功启动了,如果出现错误的话请查看日志wrapper.log
 读写分离测试1、在客户端连接mysql主库服务器:
mysql -urep -poldboy -h10.0.0.202 -P8066
mysql> explain create table company(id int not null primary key,name varchar(100));
+-----------+---------------------------------------------------------------------+
| DATA_NODE | SQL                                                                 |
+-----------+---------------------------------------------------------------------+
| dn1       | create table company(id int not null primary key,name varchar(100)) |
| dn2       | create table company(id int not null primary key,name varchar(100)) |
| dn3       | create table company(id int not null primary key,name varchar(100)) |
+-----------+---------------------------------------------------------------------+
3 rows in set (0.06 sec)
 
mysql> create table company(id int not null primary key,name varchar(100));
Query OK, 0 rows affected (1.82 sec)
 
mysql> explain insert into company(id, name) values (100, 'abc');
+-----------+---------------------------------------------------+
| DATA_NODE | SQL                                               |
+-----------+---------------------------------------------------+
| dn1       | insert into company(id, name) values (100, 'abc') |
| dn2       | insert into company(id, name) values (100, 'abc') |
| dn3       | insert into company(id, name) values (100, 'abc') |
+-----------+---------------------------------------------------+
3 rows in set (0.00 sec)
 
mysql> insert into company(id, name) values (100, 'abc');
Query OK, 1 row affected (0.24 sec)

查看日志

日志中有如下信息
 

分别在主从库中执行以下命令:

mysql> select * from company where id = 100;
+-----+------+
| id  | name |
+-----+------+
| 100 | abc  |
+-----+------+
1 row in set (0.00 sec)

 日志中有如下

在从库中执行insert命令会得到以下错误:
mysql> insert into company(id, name) values (4, 'abcwq');        
ERROR 1495 (HY000): User readonly
#从库只读
从上面的测试中可以看出来,向数据库中读写数据,走的是不同的数据库,证明,读写分离测试成功!

主从切换测试

将schema.xml文件做如下修改:

[root@Linuxdemo3 conf]#  vim schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/" >
        <schema name="test" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="test" />
        <dataNode name="dn2" dataHost="localhost1" database=" test " />
        <dataNode name="dn3" dataHost="localhost1" database=" test " />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
                writeType="0" dbType="mysql" dbDriver="native" switchType="2"  slaveThreshold="100">
                <heartbeat>show slave status</heartbeat>
                <writeHost host="hostM1" url="10.0.0.202:3306" user="rep"
                        password="oldboy">
                </writeHost>
                 <readHost host="hostS1" url="10.0.0.202:3307" user="rep_r"
                        password="oldboy" />
                 </readHost>
<writeHost host="hostM2" url="10.0.0.202:3307" user="rep"
                        password="oldboy">
                </writeHost>
                 </dataHost>             
</mycat:schema>

重启mycat服务

[root@Linuxdemo2 conf]# /application/mycat/bin/mycat restart
Stopping Mycat-server...
Stopped Mycat-server.
Starting Mycat-server...
此时,停止主库,再进行测试,会发现mycat服务依然可以正常读写数据库。mysql已切换到从库。
[root@Linuxdemo2 conf]# /data/3306/mysql stop

Mycat-Web

    MyCAT-WEB就是基于mycat的一个性能监控工具,方便大家更有效的使用mycat管理mycat监控mycat,让大家的mycat工作更加高效。mycat-web的运行依赖 zookpeer 所以事先要安装好。 
    Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题, 它能提供基于类似于文件系统的目录节点树方式的数据存储,但是 Zookeeper 并不是用来专门存储数据的,它的作用主要是用来维护和监控你存储的数据的状态变化,通过监控这些数据状态的变化,从而可以达到基于数据的集群管理。 
    ZooKeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目。ZooKeeper提供一个简单的原语集合,以便于分布式应用可以在它之上构建更高层次的同步服务。ZooKeeper的设计非常易于编程,它使用的是类似于文件系统那样的树形数据结构。 

安装zookpeer 

wget  http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz
tar -xzvf  zookeeper-3.4.6.tar.gz 
cd zookeeper-3.4.6/conf
cp zoo_sample.cfg zoo.cfg 
cd zookeeper-3.4.6/bin
./zkServer.sh start 
出现一下信息 说明启动成功 
JMX enabled by default 
Using config: /usr1/zookeeper/bin/../conf/zoo.cfg 
Starting zookeeper ... STARTED 

安装mycat-web

wget https://github.com/MyCATApache/Mycat-download/raw/master/mycat-web-1.0/Mycat-web-1.0-SNAPSHOT-20160617163048-linux.tar.gz
tar zxf Mycat-web-1.0-SNAPSHOT-20160617163048-linux.tar.gz
cd mycat-web/mycat-web/WEB-INF/classes
vim mycat.properties
zookeeper=127.0.0.1:2181
sqlonline.server=10.0.0.202
cd mycat-web
#将start.sh文件中的JVM调整到合适的大小
./start.sh &
#8082端口是web端口
访问10.0.0.202:8082/mycat即可进入web页面
配置Mycat(此步骤可省略)
cd /application/mycat/bin
另外有四个相对重要的文件
            文件                                                                           用处
/application/mycat/bin/xml_to_yaml.sh 根据mycat配置生成 zookeeper yaml 配置工具
/application/mycat/bin/init_zk_data.sh 将生成的yaml配置文件导入远程zookeeper
/application/mycat/conf/myid.properties zookeeper 路径配置参数信息
/application/mycat/conf/zk-create.yaml 自动生成的zk配置

1)确认安装好zookeeper 环境
2)启动mycat服务,确认本地服务一切正常。
3)执行xml_to_yaml.sh脚本(确认本地配置过 JAVA_HOME 和 MYCAT_HOME环境变量,)

[root@Linuxdemo3 bin]# ./xml_to_yaml.sh

4) 执行 init_zk_data.sh 脚本 , 注意下默认情况下脚本会将zookeeper定位在同一台服务器上面,如有需要可以调整下 ZK 的 IP : PORT

[root@Linuxdemo3 bin]# ./init_zk_data.sh

 

 

管理命令与监控

mycat自身有类似其他数据库的管理监控方式,可通过mysql命令行,登陆端口9066执行相应的SQL操作,也可通过jdbc的方式进行远程连接管理。
  登录: mycat有两个端口,8066数据端口,9066管理端口。命令行登录时通过9066管理端口来执行:
mysql -urep -poldboy  -h10.0.0.202 -P9066 -Dtest   
选项:
-h 后面接主机
-u mycat server.xml配置的逻辑库用户
-p mycat server.xml配置的逻辑库密码
-P 后面接的端口9066,注意P大写
-D Mycat server.xml中配置的逻辑库

1、查看所有的命令,如下:

mysql> show @@help;
+--------------------------------------+-----------------------------------+
| STATEMENT                            | DESCRIPTION                       |
+--------------------------------------+-----------------------------------+
| clear @@slow where datanode = ?      | Clear slow sql by datanode        |
| clear @@slow where schema = ?        | Clear slow sql by schema          |
| kill @@connection id1,id2,...        | Kill the specified connections    |
| offline                              | Change MyCat status to OFF        |
| online                               | Change MyCat status to ON         |
| reload @@config                      | Reload basic config from file     |
| reload @@config_all                  | Reload all config from file       |
| reload @@route                       | Reload route config from file     |
| reload @@user                        | Reload user config from file      |
| rollback @@config                    | Rollback all config from memory   |
| rollback @@route                     | Rollback route config from memory |
| rollback @@user                      | Rollback user config from memory  |
| show @@backend                       | Report backend connection status  |
| show @@cache                         | Report system cache usage         |
| show @@command                       | Report commands status            |
| show @@connection                    | Report connection status          |
| show @@connection.sql                | Report connection sql             |
| show @@database                      | Report databases                  |
| show @@datanode                      | Report dataNodes                  |
| show @@datanode where schema = ?     | Report dataNodes                  |
| show @@datasource                    | Report dataSources                |
| show @@datasource where dataNode = ? | Report dataSources                |
| show @@heartbeat                     | Report heartbeat status           |
| show @@parser                        | Report parser status              |
| show @@processor                     | Report processor status           |
| show @@router                        | Report router status              |
| show @@server                        | Report server status              |
| show @@session                       | Report front session details      |
| show @@slow where datanode = ?       | Report datanode slow sql          |
| show @@slow where schema = ?         | Report schema slow sql            |
| show @@sql where id = ?              | Report specify SQL                |
| show @@sql.detail where id = ?       | Report execute detail status      |
| show @@sql.execute                   | Report execute status             |
| show @@sql.slow                      | Report slow SQL                   |
| show @@threadpool                    | Report threadPool status          |
| show @@time.current                  | Report current timestamp          |
| show @@time.startup                  | Report startup timestamp          |
| show @@version                       | Report Mycat Server version       |
| stop @@heartbeat name:time           | Pause dataNode heartbeat          |
| switch @@datasource name:index       | Switch dataSource    

2、更新配置文件

mysql> reload @@config;
Query OK, 1 row affected (0.13 sec)
Reload config success

3、显示mycat数据库的列表,对应的在scehma.xml配置的逻辑库

mysql> show @@database;
+----------+
| DATABASE |
+----------+
| oldboy   |
+----------+
1 row in set (0.00 sec)

4、显示mycat数据节点的列表,对应的是scehma.xml配置文件的dataNode节点

mysql> show @@datanode;
+------+-------------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
| NAME | DATHOST           | INDEX | TYPE  | ACTIVE | IDLE | SIZE | EXECUTE | TOTAL_TIME | MAX_TIME | MAX_SQL | RECOVERY_TIME |
+------+-------------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
| dn1  | localhost1/oldboy |     0 | mysql |      0 |   10 | 1000 |     457 |          0 |        0 |       0 |            -1 |
| dn2  | localhost1/oldboy |     0 | mysql |      0 |   10 | 1000 |     457 |          0 |        0 |       0 |            -1 |
| dn3  | localhost1/oldboy |     0 | mysql |      0 |   10 | 1000 |     457 |          0 |        0 |       0 |            -1 |
+------+-------------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
3 rows in set (0.00 sec)
其中,NAME表示datanode的名称;dataHost 对应的是dataHost属性的值,数据主机的名称,ACTIVE表示活跃的连接数,IDIE表示闲置的连接数,SIZE对应的是总连接的数量。

5、报告心跳状态

mysql> show @@heartbeat;
+--------+-------+-------------+------+---------+-------+--------+---------+--------------+---------------------+-------+
| NAME   | TYPE  | HOST        | PORT | RS_CODE | RETRY | STATUS | TIMEOUT | EXECUTE_TIME | LAST_ACTIVE_TIME    | STOP  |
+--------+-------+-------------+------+---------+-------+--------+---------+--------------+---------------------+-------+
| hostM1 | mysql | 10.0.0.202 | 3306 |       1 |     0 | idle   |       0 | 1,1,1        | 2015-12-29 21:39:40 | false |
| hostS1 | mysql | 10.0.0.202 | 3307 |       1 |     0 | idle   |       0 | 3,3,3        | 2015-12-29 21:39:40 | false |
+--------+-------+-------------+------+---------+-------+--------+---------+--------------+---------------------+-------+
2 rows in set (0.01 sec) 
RS_STATUS状态为1,正常状态

6、获取当前mycat的版本

mysql> show @@version;
+--------------------------------------+
| VERSION                              |
+--------------------------------------+
| 5.5.8-mycat-1.4-alpha-20150520235658 |
+--------------------------------------+
1 row in set (0.00 sec)

7、显示mycat前端连接状态

mysql> show @@connection;
+------------+------+-----------+------+------------+--------+---------+--------+---------+---------------+-------------+------------+---------+------------+
| PROCESSOR  | ID   | HOST      | PORT | LOCAL_PORT | SCHEMA | CHARSET | NET_IN | NET_OUT | ALIVE_TIME(S) | RECV_BUFFER | SEND_QUEUE | txlevel | autocommit |
+------------+------+-----------+------+------------+--------+---------+--------+---------+---------------+-------------+------------+---------+------------+
| Processor0 |    6 | 127.0.0.1 | 9066 |      46490 | oldboy | utf8:33 |    281 |    6164 |          1008 |        4096 |          0 |         |            |
+------------+------+-----------+------+------------+--------+---------+--------+---------+---------------+-------------+------------+---------+------------+
1 row in set (0.00 sec)

8、显示mycat后端连接状态

mysql> show @@backend;
+------------+------+---------+-------------+------+--------+--------+---------+------+--------+----------+------------+--------+---------+---------+------------+
| processor  | id   | mysqlId | host        | port | l_port | net_in | net_out | life | closed | borrowed | SEND_QUEUE | schema | charset | txlevel | autocommit |
+------------+------+---------+-------------+------+--------+--------+---------+------+--------+----------+------------+--------+---------+---------+------------+
| Processor0 |    1 |      30 | 10.0.0.202 | 3306 |  14881 |   3554 |    1068 | 5041 | false  | false    |          0 | oldboy | utf8:33 | 3       | true       |
| Processor0 |    2 |      32 | 10.0.0.202 | 3306 |  14883 |   3554 |    1068 | 5041 | false  | false    |          0 | oldboy | utf8:33 | 3       | true       |
| Processor0 |    3 |      24 | 10.0.0.202 | 3306 |  14875 |   3515 |    1068 | 5041 | false  | false    |          0 | oldboy | utf8:33 | 3       | true       |
| Processor0 |    4 |      28 | 10.0.0.202 | 3306 |  14879 |   3561 |     986 | 5041 | false  | false    |          0 | oldboy | utf8:33 | 0       | true       |

9、显示数据源

mysql> show @@datasource;
+----------+--------+-------+-------------+------+------+--------+------+------+---------+
| DATANODE | NAME   | TYPE  | HOST        | PORT | W/R  | ACTIVE | IDLE | SIZE | EXECUTE |
+----------+--------+-------+-------------+------+------+--------+------+------+---------+
| dn1      | hostM1 | mysql | 10.0.0.202 | 3306 | W    |      0 |   10 | 1000 |     525 |
| dn1      | hostS1 | mysql | 10.0.0.202 | 3306 | R    |      0 |    8 | 1000 |     522 |
| dn3      | hostM1 | mysql | 10.0.0.202 | 3306 | W    |      0 |   10 | 1000 |     525 |
| dn3      | hostS1 | mysql | 10.0.0.202 | 3306 | R    |      0 |    8 | 1000 |     522 |
| dn2      | hostM1 | mysql | 10.0.0.202 | 3306 | W    |      0 |   10 | 1000 |     525 |
| dn2      | hostS1 | mysql | 10.0.0.202 | 3306 | R    |      0 |    8 | 1000 |     522 |
+----------+--------+-------+-------------+------+------+--------+------+------+---------+
6 rows in set (0.01 sec)
特别说明:
reload @@config,这个命令在执行的时候,mycat服务不可用,防止提交的事物出错。
posted @ 2018-04-23 09:40  活的潇洒80  阅读(977)  评论(0编辑  收藏  举报