关系型数据的分布式处理系统MyCAT(2)——高级功能和管理监控

关系型数据的分布式处理系统MyCAT(2)

——高级功能和管理监控

日期:2014/12/24

文:阿蜜果

1、   高级功能

1.1 分片策略

MyCAT通过定义表的分片规则来实现分片,每个表格可以捆绑一个分片规则,每个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法。

1.1.1 分片规则

以常用的基于整数映射的分片函数org.MyCAT.route.function.PartitionByFileMap为例,此函数通过一个配置文件来确定映射关系,以下面的sharding-by-intfile这个分片规则为例:

< tableRule  name ="sharding-by-intfile" >
    
< rule >
      
< columns > sharding_id </ columns >
      
< algorithm > hash-int </ algorithm >
    
</ rule >
</ tableRule >

< function  name ="hash-int"  class ="org.opencloudb.route.function.PartitionByFileMap" >
    
< property  name ="mapFile" > partition-hash-int.txt </ property >
</ function >

conf目录下的partition-hash-int.txt文件的默认内容如下所示:

10000=0
10010=1

表明当字段user_id取值为10000的时候,返回分片节点ID0,以此类推。

Schema.xml中定义customer表的分片规则为此规则:

< table  name ="t_user"   dataNode =" user0,user1,user2,user3"  rule ="sharding-by-intfile"   />

于是t_user按照字段user_id进行水平分片,分片存储在四个数据节点user1user2user3user4上。

使用MySQL客户端连接mycattest_mycat数据库,分别运行如下插入语句:

INSERT   INTO  t_user ( user_id , receive_address, create_time, province_code)  VALUES  ( ' 10000 ' ' 广州市越秀区广州大道中599号 ' ' 2014-12-25 16:00:00 ' ' GD ' );
INSERT   INTO  t_user ( user_id , receive_address, create_time, province_code)  VALUES  ( ' 10010 ' ' 广州市越秀区广州大道中599号 ' ' 2014-12-25 16:00:00 ' ' GD ' );
INSERT   INTO  t_user ( user_id , receive_address, create_time, province_code)  VALUES  ( ' 10011 ' ' 广州市越秀区广州大道中599号 ' ' 2014-12-25 16:00:00 ' ' GD ' );

连接localhostuser0 user3四个数据库,查看t_user表的数据后可得知user_id1000010010的记录分别进入user0user1数据库,最后一条运行记录因为根据partition-hash-int.txt的配置无法确定写入那个数据库节点,因为报错:

[ Err ]   1003   -  can ' t find datanode for sharding column:USER_ID val:10011

如何知道某个SQL在哪个分片上执行? explain sql语句:

explain  select   *   from  t_user  where   user_id = 10000   or   user_id = 10010 ;

MySQL客户端运行,结果如下图所示:

         运行如下explain sql语句:

explain  select   *   from  t_user;

         MySQL客户端运行,结果如下图所示:

根据业务场景和数据特点,可以选用以下的分片规则:

auto-sharding-long 主键自动增长的数字,按照范围进行自动分片,比如0-200万的数据在分片节点0,200-400万的数据在分片节点2,依次类推,根据数据库服务器的性能,可以每个分片存储100-500条记录之间,此种方式,每个分片表一个独立的自增长ID机制,确保记录的连续性。conf/ autopartition-long.txt中定义了分段范围与分片ID的关系。

rule.xml的参考配置为:

< tableRule  name ="auto-sharding-long" >
    
< rule >
      
< columns > user_id </ columns >
      
< algorithm > rang-long </ algorithm >
    
</ rule >
</ tableRule >

< function  name ="rang-long"  class ="org.opencloudb.route.function.AutoPartitionByLong" >
    
< property  name ="mapFile" > autopartition-long.txt </ property >
</ function >

对应的范围设置在conf/autopartition-long.txt文件,参考内容如下:

# range start-end ,data node index
# K=1000,M=10000.
0-10000=0
10001-20000=1
20001-30000=2
30000-40000=3

schema.xml更改t_user表的ruleauto-sharding-long,重启MyCAT后,使用MySQL连接后运行如下SQL语句:

INSERT INTO t_user(user_id, receive_address, create_time, province_code) VALUES ('9999', '广州市越秀区广州大道中599号', '2014-12-25 17:00:00', 'GD');
INSERT INTO t_user(user_id, receive_address, create_time, province_code) VALUES ('10001', '广州市越秀区广州大道中599号', '2014-12-25 17:00:00', 'GD');
INSERT INTO t_user(user_id, receive_address, create_time, province_code) VALUES ('20001', '广州市越秀区广州大道中599号', '2014-12-25 17:00:00', 'GD');
INSERT INTO t_user(user_id, receive_address, create_time, province_code) VALUES ('30001', '广州市越秀区广州大道中599号', '2014-12-25 17:00:00', 'GD');


分别查询user0~user3数据库,可看到user_id分别为9999100012000130001的记录分别被插入到user0user1user2user3数据库。

mod-long,对某些表,我们基本上很少会涉及到范围查询的,只根据某个字段(最常见是主键)进行查找定位,则可以用求余的方式,随机分配到其中一个节点上。

rule.xml的参考配置为:

< tableRule  name ="mod-long" >
    
< rule >
      
< columns > user_id </ columns >
      
< algorithm > mod-long </ algorithm >
    
</ rule >
 
</ tableRule >

< function  name ="rang-long"  class ="org.opencloudb.route.function.AutoPartitionByLong" >
    
< property  name ="mapFile" > autopartition-long.txt </ property >
</ function >

schema.xml更改t_user表的rulemod-long,重启MyCAT后,使用MySQL连接后运行如下SQL语句:

INSERT INTO t_user (user_id, receive_address, create_time, province_code) VALUES (10004, '广州市越秀区广州大道中599号', '2014-12-25 17:30:00', 'GD');
INSERT INTO t_user (user_id, receive_address, create_time, province_code) VALUES (10005, '广州市越秀区广州大道中599号', '2014-12-25 17:30:00', 'GD');
INSERT INTO t_user (user_id, receive_address, create_time, province_code) VALUES (10006, '广州市越秀区广州大道中599号', '2014-12-25 17:30:00', 'GD');
INSERT INTO t_user (user_id, receive_address, create_time, province_code) VALUES (10007, '广州市越秀区广州大道中599号', '2014-12-25 17:30:00', 'GD');

分别查询user0~user3数据库,可看到user_id分别为1000410007的记录分别被插入到user0user1user2user3数据库。

所有的分片规则都在rule.xml中定义,不同的表根据需求,定义不同的分片规则。

对于某些不分片的表格,或者分片规则一样的表格,table的定义可以用简化的方式来写,如:<table name="t_user,t_user_class_rel" rule="auto-sharding-long" />  。对于此种方式,name中定义的这些表格具有相同的属性,并且都不能有childTable 元素。

1.1.2 基于E-R关系分片策略

传统的数据库分片方式都是基于单个表格,对于表关联这种操作,则很难处理。为了能够执行t_usert_user_class_rel的联合查询, MyCAT借鉴了NewSQL领域的新秀Foundation DB的设计思路,Foundation DB创新性的提出了Table Group的概念,其将子表的存储位置依赖于主表,并且物理上紧邻存放,因此彻底解决了JOIN的效率和性能问题,根据这一思路,提出了基于E-R关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上。

t_usert_user_class_rel例子为例,schema.xml中定义如下的分片配置:

< table  name ="t_user"  dataNode ="user0,user1,user2,user3"  rule ="mod-long" >
    
< childTable  name ="t_user_class_rel"  primaryKey ="id"  joinKey ="user_id"  parentKey ="user_id"   />
</ table >

t_user采用mod-long这个分片策略,分片在user0~user3上,t_user_class_rel依赖父表进行分片,两个表的关联关系为t_user_class_rel.user_id=t_user.id。于是数据分片和存储的示意图如下:

这样一来,分片user0上的t_useruser0上的t_user_class_rel就可以进行局部的JOIN联合,user1~user3上也如此,再合并两个节点的数据即可完成整体的JOIN,试想一下,每个分片上t_user_class_rel表有1000万条,则10个分片就有1个亿,基于E-R映射的数据分片模式,基本上解决了80%以上的企业应用所面临的问题。

多对多的表格如何处理?多对多的表格通常情况下,有以下几种:

主表+关系表+字典表

主表A+关系表+主表B

对于第一种,字典表可以被定义为“全局表”,字典表的记录规模可以在几千到几十万之间,基本是变动比较少的表,由MyCAT自动实时同步到所有分片,这样就可以三个表都做JOIN操作了。

对于第二种,需要从业务角度来看,关系表更偏向哪个表,即“A的关系”还是“B的关系”,来决定关系表跟从那个方向存储。目前还暂时无法很好支持这种模式下的3个表之间的关联。未来版本中将考虑将中间表进行双向复制,以实现从A-关系表 以及B-关系表的双向关联查询。

关于全局表的实现方式,全局表在数据插入或更新的时候,会自动在全局表定义的所有数据节点上执行相同的操作,以保证所有数据节点都一致,由于这个特性,全局表可以跟任何分片或不分片的表格进行JOIN操作。对数据更新不频繁的,规模不是很大的(100万之内)的表都可以定义为MyCAT的全局表,以实现用存储换性能的目标。

1.1.3 主键分片 VS 非主键分片

主键分片还是非主键分片,这个问题并不是很难,当你没人任何字段可以作为分片字段的时候,主键分片就是唯一选择,其优点是按照主键的查询最快,当采用自动增长的序列号作为主键时,还能比较均匀的将数据分片在不同的节点上。

若有某个合适的业务字段比较合适作为分片字段,则建议采用此业务字段分片,选择分片字段的条件如下:

  • 尽可能的比较均匀分布数据到各个节点上;
  • 该业务字段是最频繁的或者最重要的查询条件。

常见的除了主键之外的其他可能分片字段有“订单创建时间”、“店铺类别”或“所在省”等。当你找到某个合适的业务字段作为分片字段以后,不必纠结于“牺牲了按主键查询记录的性能”,因为在这种情况下,MyCAT提供了“主键到分片”的内存缓存机制,热点数据按照主键查询,丝毫不损失性能。做法如下:

< table  name ="t_user"  primaryKey ="user_id"  dataNode ="user0,user1,user2,user3"  rule ="mod-long" >
< childTable  name ="t_user_class_rel"  primaryKey ="id"  joinKey ="user_id"  parentKey ="user_id"   />
</ table >

对于非主键分片的table,填写属性primaryKey,此时MyCAT会将你根据主键查询的SQL语句的第一次执行结果进行分析,确定该Table 的某个主键在什么分片上,并进行主键到分片ID的缓存,以下面SQL为例,由于id 不是orders的分片字段,因此这个SQL第一次会发送给所有分片去执行:

select   *   from  orders  where  id = 1 ;

对于多个主键的查询,一样可以自动优化,如:

select   *   from  orders  where  id  in  ( 1 , 2 , 3 )

则会分别存储123这三个主键到分片的缓存关系。

设想下,每个表有5000万数据,10%的热点数据经常按照主键查询,5000*10%=500万,缓存上述信息大概需要1.5G内存,通过分析缓存使用信息,就可以最精确的调优这笔缓存的内存。通过连接MyCAT9066管理端口,执行show @@cache,可以显示当前缓存的使用情况。

1.2 高可用性配置

MyCAT支持高可用性的企业级特性,根据应用特性,可以配置如下几种策略:

后端数据库配置为一主多从,并开启读写分离机制。

后端数据库配置为双主双从(多从),并开启读写分离机制。

后端数据库配置为多主多从,并开启读写分离机制

后面两种配置,具有更高的系统可用性,当其中一个写节点(主节点)失败后,Mycat会侦测出来(心跳机制)并自动切换到下一个写节点,MyCAT在任何时候,只会往一个写节点写数据。

下面是典型的双主双从的MySQL集群配置:

MyCATschema.xml配置文件中的双主双从参考配置:

< dataHost  name ="testhost"  maxCon ="1000"  minCon ="10"  balance ="1"
        writeType
="0"  dbType ="mysql"  dbDriver ="native" >
    
< heartbeat > select user() </ heartbeat >
    
<!--  can have multi write hosts  -->
    
< writeHost  host ="hostM1"  url ="localhost:3306"  user ="root"  password ="" >
        
< readHost  host ="hostM2"  url ="10.18.96.144:3306"  user ="axx"  password ="axx"   />
    
</ writeHost >
    
< writeHost  host ="hostM3"  url ="……:3306"  user ="root"  password ="" >
        
< readHost  host ="hostM4"  url ="……:3306"  user ="axx"  password ="axx"   />
    
</ writeHost >
</ dataHost >



2、   管理监控命令

MyCAT自身有类似其他数据库的管理监控方式,通过Mysql命令行,登录管理端口(9066)执行相应的SQL,进行管理

mysql  - utest  - ptest  - P9066
show 
@@help

此命令会显示所有的管理监控命令,另外请参照《Mycat命令行监控指南.docx》这个文档来深入了解。

2.1 监控命令汇总

show @@help;”命令的运行结果如下所示:

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  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  @@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  @@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                  |
+ -- ------------------------------------+-----------------------------------+
37  rows  in   set  ( 0.02  secs)




2.2 常用监控命令

常用的监控命令如下所示:

2.2.1 reload @@config

MyCAT的命令行监控窗口运行:

reload  @@config ;

该命令用于更新配置文件,例如更新schema.xml文件后在命令行窗口输入该命令,可不用重启即进行配置文件更新。运行结果参考如下:

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


 

2.2.2 show @@database

MyCAT的命令行监控窗口运行:

show  @@database ;

该命令用于显示MyCAT的数据库的列表,对应schema.xml配置文件的schema子节点,参考运行结果如下:

mysql >  show  @@database ;
+ -- ----------+
|   DATABASE     |
+ -- ----------+
|  photo       |
|  test_mycat  |
|  weixin      |
|  yixin       |
+ -- ----------+
4  rows  in   set  ( 0.00  sec)

 

2.2.3 show @@datanode

MyCAT的命令行监控窗口运行:

show  @@datanode ;

该命令用于显示MyCAT的数据节点的列表,对应schema.xml配置文件的dataNode节点,参考运行结果如下:

mysql >  show  @@datanode ;
+ -- ------+--------------------+-------+-------+--------+------+------+---------+------------+----------+---------+--------------+
| NAME | DATHOST | INDEX | TYPE | ACTIVE | IDLE | SIZE | EXECUTE | TOTAL_TIME | MAX_TIME | MAX_SQL | RECOVERY_TIME |
+ -- ------+--------------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
| photo | testhost / photo | 0 | mysql | 0 | 7 | 1000 | 0 | 0 | 0 | 0 |- 1 |
| user0 | testhost / eip_user0 | 0 | mysql | 0 | 7 | 1000 | 5 | 0 | 0 | 0 |- 1 |
| user1 | testhost / eip_user1 | 0 | mysql | 0 | 7 | 1000 | 1 | 0 | 0 | 0 |- 1 |
| user2 | testhost / eip_user2 | 0 | mysql | 0 | 7 | 1000 | 1 | 0 | 0 | 0 |- 1 |
| user3 | testhost / eip_user3 | 0 | mysql | 0 | 7 | 1000 | 1 | 0 | 0 | 0 |- 1 |
| weixin | testhost / weixin | 0 | mysql | 0 | 7 | 1000 | 0 | 0 | 0 | 0 |- 1 |
| yixin | testhost / yixin | 0 | mysql | 0 | 7 | 1000 | 0 | 0 | 0 | 0 |- 1 |
+ -- ------+--------------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
7  rows  in   set  ( 0.05  sec)

其中,“NAME”表示dataNode的名称;“dataHost”表示对应dataHost属性的值,即数据主机;“ACTIVE”表示活跃连接数;“IDLE”表示闲置连接数;“SIZE”对应总连接数量。

运行如下命令,可查找对应的schema下面的dataNode列表:

show  @@datanode   where   schema   =  ?

该命令的执行结果参考如下:

mysql >  show  @@datanode   where   schema   =  test_mycat;
+ -- -----+--------------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
| NAME | DATHOST | INDEX | TYPE | ACTIVE | IDLE | SIZE | EXECUTE | TOTAL_TIME | MAX_TIM |  MAX_SQL | RECOVERY_TIME |
+ -- -----+--------------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
| user0 | testhost / eip_user0 | 0 | mysql | 0 | 6 | 1000 | 5 | 0 | 0 | 0 |- 1 |
| user1 | testhost / eip_user1 | 0 | mysql | 0 | 6 | 1000 | 1 | 0 | 0 | 0 |- 1 |
| user2 | testhost / eip_user2 | 0 | mysql | 0 | 6 | 1000 | 1 | 0 | 0 | 0 |- 1 |
| user3 | testhost / eip_user3 | 0 | mysql | 0 | 6 | 1000 | 1 | 0 | 0 | 0 |- 1 |
+ -- -----+--------------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
4  rows  in   set  ( 0.00  sec)


 

2.2.4 show @@heartbeat

         该命令用于报告心跳状态,参考运行结果如下所示:

mysql >  show  @@heartbeat ;
+ -- ------+-------+--------------+------+---------+-------+--------+---------+----------------+---------------------+-------+
| NAME | TYPE | HOST | PORT | RS_CODE | RETRY | STATUS | TIMEOUT | EXECUTE_TIME | LAST_ACTIVE_TIME | STOP |
+ -- ------+-------+--------------+------+---------+-------+--------+---------+----------------+---------------------+-------+
| hostM1 | mysql | localhost | 3306 | 1 | 0 | idle | 30000 | 0 , 2001 , 1445 | 2014 - 12 - 26   12 : 11 : 05 | false |
| hostM3 | mysql | localhost | 3306 | 1 | 0 | idle | 30000 | 5003 , 5168 , 4278 | 2014 - 12 - 26   12 : 11 : 05 | false |
| hostM2 | mysql | 10.18 . 96.144 | 3306 | 1 | 0 | idle | 30000 | 5 , 3 , 2 | 2014 - 12 - 26   12 : 11 : 05 | false |
| hostM4 | mysql | 10.18 . 96.144 | 3306 | 1 | 0 | idle | 30000 | 2 , 2 , 2 | 2014 - 12 - 26   12 : 11 : 05 | false |
+ -- ------+-------+--------------+------+---------+-------+--------+---------+----------------+---------------------+-------+
4  rows  in   set  ( 0.01  sec)



2.2.5 show @@version

         该命令用于获取MyCAT的版本,参考运行结果如下所示:

mysql >  show  @@version ;
+ -- ----------------+
|  VERSION           |
+ -- ----------------+
|   5.1 . 48 - mycat - 1.2   |
+ -- --------------+
1  row  in   set  ( 0.00  sec)

 

2.2.6 show @@sql.slow

         该命令用于查询运行缓慢的SQL语句,参考运行结果如下所示:

mysql >  show  @@sql .slow;
Empty 
set  ( 0.00  sec)



2.2.7 show @@connection

         该命令用于获取连接状态,参考运行结果如下所示:

 

mysql >  show  @@connection ;
+ -- ----------+------+-----------+------+------------+------------+---------+----
--
--+---------+---------------+-------------+------------+
| PROCESSOR | ID | HOST | PORT | LOCAL_PORT | SCHEMA | CHARSET | NET_IN | NET_OUT | ALIVE_TIME(S) | RECV_BUFFER | SEND_QUEUE |
+ -- ----------+------+-----------+------+------------+------------+---------+----
--
--+---------+---------------+-------------+------------+
| Processor0 | 5 | 127.0 . 0.1 | 8066 | 54448 | test_mycat | utf8 | 320 | 44674 | 225 | 4096 | 0 |
| Processor3 | 6 | 127.0 . 0.1 | 9066 | 54432 | NULL | utf8 | 162 | 741 | 459 | 4096 | 0 |
+ -- ----------+------+-----------+------+------------+------------+---------+----
--
--+---------+---------------+-------------+------------+
2  rows  in   set  ( 0.04  sec)

 

3、   参考文档

1)《MyCAT inAction中文版》

2)《Mycat命令行监控指南.docx

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值