`
vanadiumlin
  • 浏览: 505389 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

关于mysql分表

 
阅读更多
开源产品一览
diamond:http://code.taobao.org/svn/diamond/trunk/
Dubbo:https://github.com/alibaba/dubbo
metaq:https://github.com/alibaba/metaq
sqlautoreview:https://github.com/taobao/sqlautoreview
taokeeper:https://github.com/alibaba/taokeeper
tb-tddl:https://github.com/alibaba/tb_tddl
tdh_socket:https://github.com/alibaba/TDH_Socket
TProfiler:https://github.com/alibaba/TProfiler

///////以下关于cobar////////
   这几天研究了下Cobar, Cobar是阿里巴巴研发的关系型数据的分布式处理系统(Amoeba的升级版,该产品成功替代了原先基于Oracle的数据存储方案,目前已经接管了3000+个MySQL数据库的schema,平均每天处理近50亿次的SQL执行请求。)(github上面的是源码,大家下来需要自己用maven2编译后运行、者放Eclipse里面运行,一开始我用maven3没有执行成功。)

首先,使用Cobar的核心功能如下:

分布式:
Cobar的分布式主要是通过将表放入不同的库来实现:
1. Cobar支持将一张表水平拆分成多份分别放入不同的库来实现表的水平拆分
2. Cobar也支持将不同的表放入不同的库
3. 多数情况下,用户会将以上两种方式混合使用
这里需要强调的是,Cobar不支持将一张表,例如test表拆分成test_1, test_2, test_3.....放在同一个库中,必须将拆分后的表分别放入不同的库来实现分布式。

HA:
在用户配置了MySQL心跳的情况下,Cobar可以自动向后端连接的MySQL发送心跳,判断MySQL运行状况,一旦运行出现异常,Cobar可以自动切换到备机工作。但需要强调的是:
1. Cobar的主备切换有两种触发方式,一种是用户手动触发,一种是Cobar的心跳语句检测到异常后自动触发。那么,当心跳检测到主机异常,切换到备机,如果主机恢复了,需要用户手动切回主机工作,Cobar不会在主机恢复时自动切换回主机,除非备机的心跳也返回异常。
2. Cobar只检查MySQL主备异常,不关心主备之间的数据同步,因此用户需要在使用Cobar之前在MySQL主备上配置双向同步,详情可以参阅MySQL参考手册。

其次,我们也需要注意Cobar的功能约束:

1) 不支持跨库情况下的join、分页、排序、子查询操作。
2) SET语句执行会被忽略,事务和字符集设置除外。
3) 分库情况下,insert语句必须包含拆分字段列名。
4) 分库情况下,update语句不能更新拆分字段的值。
5) 不支持SAVEPOINT操作。
6) 暂时只支持MySQL数据节点。
7) 使用JDBC时,不支持rewriteBatchedStatements=true参数设置(默认为false)。
8) 使用JDBC时,不支持useServerPrepStmts=true参数设置(默认为false)。
9) 使用JDBC时,BLOB, BINARY, VARBINARY字段不能使用setBlob()或setBinaryStream()方法设置参数。

然后,我们来分析一下Cobar逻辑层次图:



* dataSource:数据源,表示一个具体的数据库连接,与物理存在的数据库schema一一对应。
* dataNode:数据节点,由主、备数据源,数据源的HA以及连接池共同组成,可以将一个dataNode理解为一个分库。
* table:表,包括拆分表(如tb1,tb2)和非拆分表。
* tableRule:路由规则,用于判断SQL语句被路由到具体哪些datanode执行。
* schema:cobar可以定义包含拆分表的schema(如schema1),也可以定义无拆分表的schema(如schema2)。

Cobar支持的数据库结构(schema)的层次关系具有较强的灵活性,用户可以将表自由放置不同的datanode,也可将不同的datasource放置在同一MySQL实例上。在实际应用中,我们需要通过配置文件(schema.xml)来定义我们需要的数据库服务器和表的分布策略,这点我们将在后面的安装和配置部分中介绍到。

接着,我们来介绍Cobar的安装和配置步骤:

下面我们将使用一个最简单的分库分表的例子来说明Cobar的基本用法,数据库schema如下图(该实例也可参考:Cobar产品首页)。



1) 系统对外提供的数据库名是dbtest,并且其中有两张表tb1和tb2。
2) tb1表的数据被映射到物理数据库dbtest1的tb1上。
3) tb2表的一部分数据被映射到物理数据库dbtest2的tb2上,另外一部分数据被映射到物理数据库dbtest3的tb2上。

1、环境准备

操作系统:Linux或者Windows (推荐在Linux环境下运行Cobar)
MySQL:http://www.mysql.com/downloads/ (推荐使用5.1以上版本)
JDK:http://www.oracle.com/technetwork/java/javase/downloads/ (推荐使用1.6以上版本)
Cobar:https://github.com/alibaba/cobar (下载tar.gz或者zip文件,特意说明下,阿里的开源全部移到github上去了,里面有很多阿里人的作品,当然包含著名的dubbo,地址是:https://github.com/alibaba/)

2、数据准备

假设本文MySQL所在服务器IP为192.168.0.1,端口为3306,用户名为test,密码为空,我们需要创建schema:dbtest1、dbtest2、dbtest3,table:tb1、tb2,SQL如下:
[sql] view plaincopy
1.  #创建dbtest1 
2.  drop database if exists dbtest1; 
3.  create database dbtest1; 
4.  use dbtest1; 
5.  #在dbtest1上创建tb1 
6.  create table tb1( 
7.  id    int not null, 
8.  gmt   datetime); 
9.    
10.#创建dbtest2 
11.drop database if exists dbtest2; 
12.create database dbtest2; 
13.use dbtest2; 
14.#在dbtest2上创建tb2 
15.create table tb2( 
16.id    int not null, 
17.val   varchar(256)); 
18.  
19.#创建dbtest3 
20.drop database if exists dbtest3; 
21.create database dbtest3; 
22.use dbtest3; 
23.#在dbtest3上创建tb2 
24.create table tb2( 
25.id    int not null, 
26.val   varchar(256)); 

3、配置Cobar

Cobar解压之后有四个目录:
bin/:可执行文件目录,包含启动(start)、关闭(shutdown)和重启(restart)脚本
lib/:逻辑类库目录,包含了Cobar所需的jar包
conf/:配置文件目录,下面会详细介绍
logs/:运行日志目录,最主要的log有两个:程序日志(stdout.log)和控制台输出(console.log)

配置文件的用法如下:
log4j.xml:日志配置,一般来说保持默认即可
schema.xml:定义了schema逻辑层次图中的所有元素,并利用这些元素以及rule.xml中定义的规则组建分布式数据库系统
rule.xml:定义了分库分表的规则
server.xml:系统配置文件

我们在schema.xml中配置数据库结构(schema)、数据节点(dataNode)、以及数据源(dataSource)。
[html] view plaincopy
1.  <?xml version="1.0" encoding="UTF-8"?> 
2.  <!DOCTYPE cobar:schema SYSTEM "schema.dtd"> 
3.  <cobar:schema xmlns:cobar="http://cobar.alibaba.com/"> 
4.    
5.    <!-- schema定义 --> 
6.    <schema name="dbtest" dataNode="dnTest1"> 
7.      <table name="tb2" dataNode="dnTest2,dnTest3" rule="rule1" /> 
8.    </schema> 
9.    
10.  <!-- 数据节点定义,数据节点由数据源和其他一些参数组织而成。--> 
11.  <dataNode name="dnTest1"> 
12.    <property name="dataSource"> 
13.      <dataSourceRef>dsTest[0]</dataSourceRef> 
14.    </property> 
15.  </dataNode> 
16.  <dataNode name="dnTest2"> 
17.    <property name="dataSource"> 
18.      <dataSourceRef>dsTest[1]</dataSourceRef> 
19.    </property> 
20.  </dataNode> 
21.  <dataNode name="dnTest3"> 
22.    <property name="dataSource"> 
23.      <dataSourceRef>dsTest[2]</dataSourceRef> 
24.    </property> 
25.  </dataNode> 
26.  
27.  <!-- 数据源定义,数据源是一个具体的后端数据连接的表示。--> 
28.  <dataSource name="dsTest" type="mysql"> 
29.    <property name="location"> 
30.      <location>192.168.0.1:3306/dbtest1</location> <!--注意:替换为您的MySQL IP和Port--> 
31.      <location>192.168.0.1:3306/dbtest2</location> <!--注意:替换为您的MySQL IP和Port--> 
32.      <location>192.168.0.1:3306/dbtest3</location> <!--注意:替换为您的MySQL IP和Port--> 
33.    </property> 
34.    <property name="user">test</property> <!--注意:替换为您的MySQL用户名--> 
35.    <property name="password">test</property> <!--注意:替换为您的MySQL密码--> 
36.    <property name="sqlMode">STRICT_TRANS_TABLES</property> 
37.  </dataSource> 
38.</cobar:schema> 
我们注意到,上述配置实际上已经把图2中的数据库结构配置好了。dbtest主要映射的是dnTest1库(即192.168.0.1:3306/dbtest1库),而其中的tb2表则是按照规则rule1,被分配到dnTest2库(即192.168.0.1:3306/dbtest2库)和dnTest3库(即192.168.0.1:3306/dbtest3库)中。此外,规则rule1的定义可以在rule.xml中找到,代码如下:
[html] view plaincopy
1.  <?xml version="1.0" encoding="UTF-8"?> 
2.  <!DOCTYPE cobar:rule SYSTEM "rule.dtd"> 
3.  <cobar:rule xmlns:cobar="http://cobar.alibaba.com/"> 
4.   
5.    <!-- 路由规则定义,定义什么表,什么字段,采用什么路由算法。--> 
6.    <tableRule name="rule1"> 
7.      <rule> 
8.        <columns>id</columns> 
9.        <algorithm><![CDATA[ func1(${id})]]></algorithm> 
10.    </rule> 
11.  </tableRule> 
12. 
13.  <!-- 路由函数定义,应用在路由规则的算法定义中,路由函数可以自定义扩展。--> 
14.  <function name="func1" class="com.alibaba.cobar.route.function.PartitionByLong"> 
15.    <property name="partitionCount">2</property> 
16.    <property name="partitionLength">512</property> 
17.  </function> 
18.</cobar:rule> 
结合schema.xml中的内容,我们可以看出分表的规则是,按照id字段把tb2表中的数据分配到dnTest2和dnTest3两个分区中,其中id小于512的数据会被放到dnTest2库的分区中,而其余的会被放到dnTest3库的分区中,更多路由算法可以参考《路由文档》。最后,我们来看一下server.xml的配置,代码如下。
[html] view plaincopy
1.  <?xml version="1.0" encoding="UTF-8"?> 
2.  <!DOCTYPE cobar:server SYSTEM "server.dtd"> 
3.  <cobar:server xmlns:cobar="http://cobar.alibaba.com/"> 
4.    
5.    <!--定义Cobar用户名,密码--> 
6.    <user name="root"> 
7.      <property name="password">passwd</property> 
8.      <property name="schemas">dbtest</property> 
9.    </user> 
10.</cobar:server> 
这里的server.xml配置比较简单,只配置了本地Cobar服务的数据库结构、用户名和密码。在启动Cobar服务之后,使用用户名root和密码passwd就可以登录Cobar服务。

4、运行Cobar

启动Cobar服务很简单,运用bin目录下的start.sh即可(停止使用shutdown.sh)。启动成功之后,可以在logs目录下的stdout.log中看到如下日志:
[html] view plaincopy
1.  10:54:19,264 INFO  =============================================== 
2.  10:54:19,265 INFO  Cobar is ready to startup ... 
3.  10:54:19,265 INFO  Startup processors ... 
4.  10:54:19,443 INFO  Startup connector ... 
5.  10:54:19,446 INFO  Initialize dataNodes ... 
6.  10:54:19,470 INFO  dnTest1:0 init success 
7.  10:54:19,472 INFO  dnTest3:0 init success 
8.  10:54:19,473 INFO  dnTest2:0 init success 
9.  10:54:19,481 INFO  CobarManager is started and listening on 9066 
10.10:54:19,483 INFO  CobarServer is started and listening on 8066 
11.10:54:19,484 INFO  =============================================== 

接着,我们就可以使用“mysql -h127.0.0.1 -uroot -ppasswd -P8066 -Ddbtest”命令来登录Cobar服务了,再接下来的操作就和在其他MySQL Client中一样了。比如,我们可以使用“show databases”命令查看数据库,使用“show tables”命令查看数据表,如下图:


接着,我们按照下图中的SQL指定向数据表插入测试记录。


可以看到,这里的tb2中包含了id为1、2、513的3条记录。而实际上,这3条记录存储在不同的物理数据库上的,大家可以到物理库上验证一下。

至于Cobar的连接和使用方法和MySQL一样,Java程序中可以使用JDBC(建议5.1以上的版本),PHP中可以使用PDO。当然,Cobar还提供HA、集群等高级的功能,更多信息请参考其《产品文档》。此外,产品文档中还为我们提供了详细的PPT文档《Cobar原理及应用.ppt》来介绍Cobar在实际生产环境中的使用方法。

此外,特别解释一下大家可能比较关心的心跳检测问题,Cobar的心跳检测主要用在以下两个地方。

1、在配置数据节点的时候,我们需要使用心跳检测来探测数据节点的运行状况。Cobar中使用执行SQL的方式来进行探测,简单且实用。例如,我们可以把前面实例中的schema.xml中的dataNode配置成下面的样子。
[html] view plaincopy
1.  ... ... 
2.    <!-- 数据节点定义,数据节点由数据源和其他一些参数组织而成。--> 
3.    <dataNode name="dnTest1"> 
4.      <property name="dataSource"> 
5.        <dataSourceRef>dsTest[0]</dataSourceRef> 
6.      </property> 
7.      <!--Cobar与后端数据源连接池大小设置--> 
8.      <property name="poolSize">256</property> 
9.      <!--Cobar通过心跳来实现后端数据源HA,一旦主数据源心跳失败,便切换到备数据源上工作--> 
10.    <!--Cobar心跳是通过向后端数据源执行一条SQL语句,根据该语句的返回结果判断数据源的运行情况--> 
11.    <property name="heartbeat">select user()<property> 
12.  </dataNode> 
13.... ... 
2、当我们需要对Cobar作集群(cluster),进行负载均衡的时候,我们也需要用到心跳机制。不过此处的配置则是在server.xml中,代码如下:
[html] view plaincopy
1.  ... ... 
2.    <!--组建一个Cobar集群,只需在cluster配置中把所有Cobar节点(注意:包括当前Cobar自身)都配置上便可--> 
3.    <cluster> 
4.      <!--node名称,一个node表示一个Cobar节点,一旦配置了node,当前Cobar便会向此节点定期发起心跳,探测节点的运行情况--> 
5.      <node name="cobar1"> 
6.        <!--Cobar节点IP, 表示当前Cobar将会向192.168.0.1上部署的Cobar发送心跳--> 
7.        <property name="host">192.168.0.1</property> 
8.        <!--节点的权重,用于客户端的负载均衡,用户可以通过命令查询某个节点的运行情况以及权重--> 
9.        <property name="weight">1</property> 
10.    </node> 
11.    <!--当前Cobar将会向192.168.0.2上部署的Cobar发送心跳--> 
12.    <node name="cobar2"> 
13.      <property name="host">192.168.0.2</property> 
14.      <property name="weight">2</property> 
15.    </node> 
16.    <!--当前Cobar将会向192.168.0.3上部署的Cobar发送心跳--> 
17.    <node name="cobar3"> 
18.      <property name="host">192.168.0.3</property> 
19.      <property name="weight">3</property> 
20.    </node> 
21.    <!--用户还可以将Cobar节点分组,以便实现schema级别的细粒度负载均衡--> 
22.    <group name="group12"> 
23.      <property name="nodeList">cobar1,cobar2</property> 
24.    </group> 
25.     <group name="group23"> 
26.      <property name="nodeList">cobar2,cobar3</property> 
27.    </group> 
28.  </cluster> 
29.... ... 

最后,简单看一下Cobar的实现原理。

首先是系统模块架构。


从上图中可以看到,Cobar的前、后端模块都实现了MySQL协议;当接受到SQL请求时,会依次进行解释(SQL Parser)和路由(SQL Router)工作,然后使用SQL Executor去后端模块获取数据集(后端模块还负责心跳检测功能);如果数据集来自多个数据源,Cobar则需要把数据集进行组合(Result Merge),最后返回响应。整个过程应该比较容易理解,

下面是Cobar的网络通讯模块架构。


从上图中可以看出,Cobar采用了主流的Reactor设计模式来处理请求,并使用NIO进行底层的数据交换,这大大提升系统的负载能力。其中,NIOAcceptor用于处理前端请求,NIOConnector则用于管理后端的连接,NIOProcessor用于管理多线程事件处理,NIOReactor则用于完成底层的事件驱动机制,就是看起来和Mina和Netty的网络模型比较相似。如果有兴趣,大家还可以到Cobar站点的下载页面(https://github.com/alibaba/cobar)获取该项目的源码,感谢阿里人的付出!

最后说点题外话,目前国内关于mysql分布式中间有
360公司的Atlas:http://www.guokr.com/blog/475765/
淘宝的tddl:http://www.guokr.com/blog/475765/
京东的蓝海豚:http://cio.zdnet.com.cn/cio/2014/0731/3028990.shtml?fromrss=rss
网易的DDB:http://wenku.baidu.com/link?url=TiILF6KxWQBUu1bj2n8mA1E-_-RUESzjI7ALpo-mDWXW9uQv-0PCjmJrl9QH6ijP1ycFTXyz3plcrWgXOV80snuIVcMkLYNNKJA3EujCPTG
但是还是阿里的cobar好些,因为他开源了,除了中间件本身,还开源提供驱动、管理器。

分享到:
评论

相关推荐

    MySQL分表及分表后插入sql

    MySQL分表及分表后插入sql语句,表为订单表,可以参考一下

    Node.js 实现的 MySQL 分表分库中间件,用于海量数据的分布式集群储存管理和高并发访问。.zip

    本文将深入探讨基于Node.js实现的MySQL分表分库中间件,它在分布式集群环境中起到至关重要的作用。 首先,Node.js是一种流行的JavaScript运行环境,它允许开发人员使用JavaScript进行服务器端编程。Node.js的异步非...

    mysql分表分库demo

    MySQL 分表分库 Demo MySQL 分表分库是指将大型数据库表分割成多个小表,以提高数据库的性能和可扩展性。随着业务数据的增长,数据库表中的数据不断增加,如果不加以控制,数据库的性能将会下降,影响业务的发展。 ...

    MySQL分表和分区最佳攻略word

    MySQL分表和分区最佳攻略 word版本,

    Python+MySQL分表分库实战

    MySQL分库分表是数据库架构设计中用于处理大规模数据量以及高并发请求的一种技术手段。通过将数据拆分到不同的数据库服务器中,能够有效降低单个数据库的负载,提高系统的扩展性和性能。Python作为一种流行的编程...

    mysql 分表

    关于mysql的分表技术实现方法。以及分表设计, 及简单的代码实例。

    mysql分表创建

    文件`mysql分表创建.sql`很可能包含了创建分表的SQL脚本,如创建新表、插入数据、设置分区等操作。具体操作时,应确保理解分表策略,合理选择分片键,避免数据热点,并测试分表后的查询性能。 总之,MySQL分表是...

    Python与MySQL分表分库实战

    本篇文章将深入探讨"Python与MySQL分表分库实战"这一主题,帮助你理解如何有效地利用这两种技术来优化数据库性能和处理大数据。 首先,我们需要理解“分表分库”这一概念。随着数据量的增长,单一数据库可能会面临...

    MySQL分表和分区最佳攻略

    常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表。这样的表过于庞大,导致...分表和表分区的目的就是减少数据库的负担,提高数据库的效率,通常点来讲就是提高表的增删改查效率。

    Python+MySQL分表分库实战 - v1.0 - 运维生存时间 -(2016).mobi

    Python后端运维工程师的可靠参考书,重点介绍如何优化mysql数据库性能。

    Mysql分表查询,哈希,范围,列表

    【MySQL分表查询】在大型数据库系统中,随着数据量的不断增长,单表的数据规模可能会变得非常庞大,导致查询效率下降,系统性能受到影响。此时,分表技术就显得尤为重要。MySQL提供了多种分表策略,如哈希分表、范围...

    mysql 分库分表查询工具-shard.zip

    以下是一些关于 MySQL 分库分表查询工具 Shard 的关键知识点: 1. **数据路由**:Shard 工具的关键组件之一是数据路由算法,它根据预先定义的分片策略(如哈希、范围或基于用户 ID)来确定数据应存储在哪个分片上,...

    PHP操作mysql数据库分表的方法_.docx

    本文主要讨论如何使用PHP操作MySQL数据库进行分表。 分表是一种常见的数据库扩展策略,它通过将一个大表拆分成多个小表来提高查询效率和系统性能。在PHP中,我们可以编写SQL语句或者使用ORM(对象关系映射)框架来...

    zabbix 5.0 mysql 数据库分表操作详细流程

    其中有每个命令的使用说明与注释。并增加了清理数据的方式。以及导入输入的注意事项

    MySQL数据库之分库分表方案_ITPUB博客.mhtml

    MySQL数据库之分库分表方案_ITPUB博客.mhtml MySQL数据库之分库分表方案_ITPUB博客.mhtml MySQL数据库之分库分表方案_ITPUB博客.mhtml

    TP5+MySQL通用分表代码

    - 很简单,网上很多关于分表的都是含糊其辞,没有任何详细的,通用的,既然没有,那么我写一个出来吧。 - 主要目的 - 产品上线以后,数据量越来越大,当一个表有几十万上百万条记录的时候,是时候考虑分表了。...

    基于hibernate的mysql分表分库实例-mysql-cluster-hibernate.zip

    "基于hibernate的mysql分表分库实例-mysql-cluster-hibernate.zip"这个压缩包文件提供了一个具体的解决方案,它涉及到Hibernate ORM框架与MySQL数据库集群的整合,旨在处理高并发、大数据量的业务场景。 **...

    mysql 用存储过程 备份分表

    1、修改表名 2、创建新表 3、按时间条件插入数据 由于数据太大、用的改表名的方式备份分表,通过传入表名和条件字段名备份相应的表

    MySQL分库分表技术

    **MySQL分库分表技术** 随着互联网业务的快速发展,数据量呈现爆炸性增长,单个数据库的性能瓶颈问题日益突出。在这种背景下,MySQL的分库分表技术应运而生,旨在解决高并发、大数据量场景下的性能挑战。本篇将深入...

Global site tag (gtag.js) - Google Analytics