ECM
ECM
总版主
总版主
  • 社区居民
  • 忠实会员
  • 原创写手
阅读:957亚博国际平台老虎机官网:0

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

楼主#
更多 发布于:2015-12-31 16:14


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客户端运行,结果如下图所示:
根据业务场景和数据特点,可以选用以下的分片规则:
l 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数据库。

l 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的定义可以用简化的方式来写,如:
?。对于此种方式,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%以上的企业应用所面临的问题。
多对多的表格如何处理?多对多的表格通常情况下,有以下几种:
l 主表+关系表+字典表
l 主表A+关系表+主表B
对于第一种,字典表可以被定义为“全局表”,字典表的记录规模可以在几千到几十万之间,基本是变动比较少的表,由MyCAT自动实时同步到所有分片,这样就可以三个表都做JOIN操作了。
对于第二种,需要从业务角度来看,关系表更偏向哪个表,即“A的关系”还是“B的关系”,来决定关系表跟从那个方向存储。目前还暂时无法很好支持这种模式下的3个表之间的关联。未来版本中将考虑将中间表进行双向复制,以实现从A-关系表 以及B-关系表的双向关联查询。
关于全局表的实现方式,全局表在数据插入或更新的时候,会自动在全局表定义的所有数据节点上执行相同的操作,以保证所有数据节点都一致,由于这个特性,全局表可以跟任何分片或不分片的表格进行JOIN操作。对数据更新不频繁的,规模不是很大的(100万之内)的表都可以定义为MyCAT的全局表,以实现用存储换性能的目标。


1.1.3 主键分片 VS 非主键分片

主键分片还是非主键分片,这个问题并不是很难,当你没人任何字段可以作为分片字段的时候,主键分片就是唯一选择,其优点是按照主键的查询最快,当采用自动增长的序列号作为主键时,还能比较均匀的将数据分片在不同的节点上。
若有某个合适的业务字段比较合适作为分片字段,则建议采用此业务字段分片,选择分片字段的条件如下:
[list=disc]
  • 尽可能的比较均匀分布数据到各个节点上;
  • 该业务字段是最频繁的或者最重要的查询条件。
  • 常见的除了主键之外的其他可能分片字段有“订单创建时间”、“店铺类别”或“所在省”等。当你找到某个合适的业务字段作为分片字段以后,不必纠结于“牺牲了按主键查询记录的性能”,因为在这种情况下,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支持高可用性的企业级特性,根据应用特性,可以配置如下几种策略:
    l 后端数据库配置为一主多从,并开启读写分离机制。
    l 后端数据库配置为双主双从(多从),并开启读写分离机制。
    l 后端数据库配置为多主多从,并开启读写分离机制
    后面两种配置,具有更高的系统可用性,当其中一个写节点(主节点)失败后,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

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    异常中心网是一家专门收集整理程序员编程过程中遇到的常见异常(exception)以及各种异常问答中心的网站。异常中心网旨在,减少程序员在编码遇到异常,处理各种异常时间和痛苦,让程序员能更愉快的、快速的定位异常并查找对应的异常解决方案。异常中心网诚心打造最完美的编程社区为程序员用户服务,努力成为最好的程序员乐园程序员社区程序异常中心程序bug中心异常问答中心

    ?

    喜欢0 评分0
    游客

    返回顶部