cobar的读写分离及高可用

一、cobar的功能原理介绍及执行过程

1.cobar的介绍
Cobar是阿里巴巴开源(官方github)的一个对应用保持透明的MySQL数据库分布式处理中间件.
cobar是关系型数据的分布式处理系统,它可以在分布式的环境下看上去像传统数据库一样提供海量数据服务。

官方说明:
● 产品在阿里巴巴稳定运行3年以上。
● 接管了3000+个MySQL数据库的schema。
● 集群日处理在线SQL请求50亿次以上。
● 集群日处理在线数据流量TB级别以上。


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

2.2 高可用(HA)
在用户配置了Mysql心跳的情况下,Cobar可以自动向后端连接的Mysql发送心跳,判断Mysql运行状况,一旦运行了出现异常,cobar可以自动切换到备机工作,但是需要强调时:
1.cobar只检查mysql主备异常,不关心主备之间的数据同步,因此用户需要在使用cobar之前mysql上配置双向同步。


(1)sql转发

(2)SQL语句拆分作为两部分执行

(3)返回结果

(4)系统实现

(5)实施应用

数据平滑迁移
  场景:Mysql数据库节点扩容
  拆分规则更改
目标:迁移过程中应用保持可用
  数据不能丢失、多余或者不一致
  全量:dump


增量dump:
数据持续更新,将binlog同步到新库中。

清理老数据:

二、cobar部署安装

下载详见:
https://github.com/alibaba/cobar/wiki

1.cobar的脚本及配置文件说明
解压cobar安装包后,可以看到以下目录:

bin  #包含Cobar的启动、重启、停止等脚本文件
conf  #包含Cobar所有配置文件
lib  #包含Cobar及其依赖的jar文件
logs  #包含Cobar所有日志文件

1)启动脚本说明:
Cobar的所有启动停止脚本全部放在bin目录中,进入bin目录,可以看到:

startup.sh  #Linux环境启动脚本
startup.bat  #Windows环境启动脚本
restart.sh  #Linux环境重启脚本
shutdown.sh  #Linux环境停止脚本

2)配置文件说明
Cobar的所有配置文件全部放在conf目录中,进入conf目录,可以看到:

server.xml #Cobar系统、用户、集群等相关配置
rule.xml #分布式规则定义
log4j.xml #日志相关配置
schema.xml #schema,dataNode,dataSource相关配置,其中:
dataSource:数据源,表示一个具体的数据库连接,与一个物理存在的schema一一对应。
dataNode:数据节点,由主、备数据源,数据源的HA以及连接池共同组成,可以将一个dataNode理解为一个分库。
schema:cobar可以定义包含拆分表的schema(如schema1),也可以定义无拆分表的schema(如schema2)。

详见官方文档
2.cobar配置及安装
(1)下面我们将使用一个最简单的分库分表的例子来说明Cobar的基本用法,数据库schema如下图(该实例也可参考:Cobar产品首页)

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

(2)分布式环境部署

  操作系统:Linux Centos6.7
  MySQL:5.5.49版本
  JDL:jdk-8u60-linux-x64.tar
  Cobar:cobar-server-1.2.7.tar

(3)分布式环境部署
#初始化准备环境
提前安装mysql,并提前在mysql/data/3306实例创建dbtest1库与tb1表,dbtest2库与tb2表,dbtest3库与tb2表,并且授权

mysql -uroot -poldboy123 -S /data/3306/mysql.sock
mysql> grant all privileges on *.* to 'cobar'@'172.16.1.%' identified by 'oldboy123';
mysql> flush privileges;
create database dbtest1;
create database dbtest2;
create database dbtest3;
use dbtest1;
create table tb1(
id int(4) not null,
name char(20) not null,
age tinyint(2) NOT NULL default '0',
dept varchar(16) default NULL,
primary key(id),
KEY index_name(name)
);
use dbtest2;
create table tb2 (
id int(4) NOT NULL,
name char(20) NOT NULL,
PRIMARY KEY (id)
);
use dbtest3;
create table tb2 (
id int(4) NOT NULL,
name char(20) NOT NULL,
PRIMARY KEY (id)
);

上传jdk和cobar的gz包到/home/oldboy/tools
#配置java环境

cd /application/tools/
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

#配置cobar环境

d /home/oldboy/tools
tar xf cobar-server-1.2.7.tar.gz
cp -a cobar-server-1.2.7 /application/
mv /application/cobar-server-1.2.7 /application/cobar
cd /application/cobar/
cd conf

#配置cobar配置文件
1.配置schema.xml文件

[root@db02 conf]# cat schema.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright 1999-2012 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<!DOCTYPE cobar:schema SYSTEM "schema.dtd">
<cobar:schema xmlns:cobar="http://cobar.alibaba.com/">
<!-- schema定义 -->
<schema name="dbtest" dataNode="dnTest1"> #这条规则意思是dbtest主要映射的是dnTest1库,也就是下面172.16.1.52:3306/dbtest1库
<table name="tb2" dataNode="dnTest2,dnTest3" rule="rule1" /> #tb2表则是按照规则rule1,被分配到dnTest2库(即172.16.1.52:3306/dbtest2库)和dnTest3库(即172.16.1.52:3306/dbtest3库)中
</schema>
<!-- 数据节点定义,数据节点由数据源和其他一些参数组织而成。-->
<dataNode name="dnTest1">
<property name="dataSource">
<dataSourceRef>dsTest[0]</dataSourceRef>
</property>
</dataNode>
<dataNode name="dnTest2">
<property name="dataSource">
<dataSourceRef>dsTest[1]</dataSourceRef>
</property>
</dataNode>
<dataNode name="dnTest3">
<property name="dataSource">
<dataSourceRef>dsTest[2]</dataSourceRef>
</property>
</dataNode>
<!-- 数据源定义,数据源是一个具体的后端数据连接的表示。-->
<dataSource name="dsTest" type="mysql">
<property name="location">
<location>172.16.1.52:3306/dbtest1</location> #数据库的IP和端口号
<location>172.16.1.52:3306/dbtest2</location>
<location>172.16.1.52:3306/dbtest3</location>
</property>
<property name="user">cobar</property> #数据库给cobar的用户名
<property name="password">oldboy123</property> #数据库给cobar的密码
<property name="sqlMode">STRICT_TRANS_TABLES</property>
</dataSource>
</cobar:schema>

2.配置rule.xml文件

[root@db02 conf]# cat rule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright 1999-2012 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<!DOCTYPE cobar:rule SYSTEM "rule.dtd">
<cobar:rule xmlns:cobar="http://cobar.alibaba.com/">
<!-- 路由规则定义,定义什么表,什么字段,采用什么路由算法 -->
<tableRule name="rule1">
<rule>
<columns>id</columns>
<algorithm><![CDATA[ func1(${id}) ]]></algorithm>
</rule>
</tableRule>
<!-- 路由函数定义 -->
<function name="func1" class="com.alibaba.cobar.route.function.PartitionByLong">
<property name="partitionCount">2</property> #需要注意的就是这两行,对数据库插入大于512的会存储至dnTest3对应的库表中
<property name="partitionLength">512</property>
</function>
</cobar:rule>

3.配置server.xml文件

[root@db02 conf]# cat server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright 1999-2012 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<!DOCTYPE cobar:server SYSTEM "server.dtd">
<cobar:server xmlns:cobar="http://cobar.alibaba.com/">
<!-- 系统参数定义,服务端口、管理端口,处理器个数、线程池等。 -->
<!--
<system>
<property name="serverPort">8066</property>
<property name="managerPort">9066</property>
<property name="initExecutor">16</property>
<property name="timerExecutor">4</property>
<property name="managerExecutor">4</property>
<property name="processors">4</property>
<property name="processorHandler">8</property>
<property name="processorExecutor">8</property>
<property name="clusterHeartbeatUser">_HEARTBEAT_USER_</property>
<property name="clusterHeartbeatPass">_HEARTBEAT_PASS_</property>
</system>
-->
<!-- 用户访问定义,用户名、密码、schema等信息。 -->
<user name="cobar">
<property name="password">oldboy123</property>
<property name="schemas">dbtest</property>
</user>
<!--
<user name="root">
<property name="password">oldboy123</property>
</user>
-->
<!-- 集群列表定义,指定集群节点的主机和权重,用于集群间的心跳和客户端负载均衡。 -->
<!--
<cluster>
<node name="cobar1">
<property name="host">127.0.0.1</property>
<property name="weight">1</property>
</node>
</cluster>
-->
<!-- 隔离区定义,可以限定某个主机上只允许某个用户登录。 -->
<!--
<quarantine>
<host name="1.2.3.4">
<property name="user">test</property>
</host>
</quarantine>
-->
</cobar:server>

#这里定义的帐号密码就是命令行登录数据库的帐号密码
#登录mysql命令:
mysql -ucobar -poldboy123 -h172.16.1.52 -P8066
上面的说明:用户就是server.xml定义的用户cobar,密码也是配置文件里面的密码,cobar是用8066端口登录的,这个也是启用的java进程的端口号。
#分库分表测试阶段
启动cobar:
/application/cobar/bin/startup.sh
查看启动结果:

[root@db02 conf]# ps -ef|grep cobar
root 10219 1 0 18:17 ? 00:00:16 /application/jdk/bin/java -Dcobar.home=/application/cobar -classpath /application/cobar/conf:/application/cobar/lib/classes:/application/cobar/lib/cobar-server-1.2.7.jar:/application/cobar/lib/log4j-1.2.16.jar -server -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:+UseFastAccessorMethods -XX:+DisableExplicitGC -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 com.alibaba.cobar.CobarStartup
root 10251 1 0 18:47 ? 00:00:00 grep --color=auto cobar
[root@db02 conf]# netstat -tulnap |grep 8066
tcp6 0 0 :::8066 :::* LISTEN 10219/java

使用cobar登录,简单测试一下:
[root@db02 conf]# mysql -ucobar -poldboy123 -h172.16.1.52 -P8066
进入数据库执行测试操作:

mysql> show databases;
+----------+
| DATABASE |
+----------+
| dbtest |
+----------+
mysql> use dbtest;
Database changed
mysql> show tables;
+------------------+
| Tables_in_dbtest |
+------------------+
| tb2 |
| tb1 |
+------------------+
mysql> insert into tb2(id,name) values(55,'oldgirl');
mysql> insert into tb2(id,name) values(520,'oldboy'); #520大于512,因此会被存储到3306实例的dbtest3库的tb2表下
mysql> quit

然后进入3306实例里面查看:

[root@db02 conf]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| dbtest |
| dbtest1 |
| dbtest2 |
| dbtest3 |
| mysql |
| oldboy |
| performance_schema |
+--------------------+
mysql> use dbtest3
Database changed
mysql> show tables;
+-------------------+
| Tables_in_dbtest3 |
+-------------------+
| tb2 |
+-------------------+
mysql> select * from tb2;
+-----+--------+
| id | name |
+-----+--------+
| 520 | oldboy |
+-----+--------+

果然只有520存储到3306实例的dbtest3库的tb2表下
#添加一个实例测试:
启动新实例:
[root@db02 conf]# data/3308/mysql start
登录数据库:

[root@db02 conf]# mysql -uroot -poldboy123 -S /data/3308/mysql.sock
mysql> grant all privileges on *.* to 'cobar'@'172.16.1.%' identified by 'oldboy123';
mysql> flush privileges;
create database dbtest1;
create database dbtest2;
create database dbtest3;
use dbtest1;
create table tb1(
id int(4) not null,
name char(20) not null,
age tinyint(2) NOT NULL default '0',
dept varchar(16) default NULL,
primary key(id),
KEY index_name(name)
);
use dbtest2;
create table tb2 (
id int(4) NOT NULL,
name char(20) NOT NULL,
PRIMARY KEY (id)
);
use dbtest3;
create table tb2 (
id int(4) NOT NULL,
name char(20) NOT NULL,
PRIMARY KEY (id)
);

修改cobar的schema.xml配置文件:

[root@db02 conf]# cat schema.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright 1999-2012 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<!DOCTYPE cobar:schema SYSTEM "schema.dtd">
<cobar:schema xmlns:cobar="http://cobar.alibaba.com/">
<!-- schema定义 -->
<schema name="dbtest" dataNode="dnTest1">
<table name="tb2" dataNode="dnTest2,dnTest3" rule="rule1" />
</schema>
<!-- 数据节点定义,数据节点由数据源和其他一些参数组织而成。-->
<dataNode name="dnTest1">
<property name="dataSource">
<dataSourceRef>dsTest[0]</dataSourceRef>
</property>
</dataNode>
<dataNode name="dnTest2">
<property name="dataSource">
<dataSourceRef>dsTest[1]</dataSourceRef>
</property>
</dataNode>
<dataNode name="dnTest3">
<property name="dataSource">
<dataSourceRef>dsTest[2]</dataSourceRef>
</property>
</dataNode>
<!-- 数据源定义,数据源是一个具体的后端数据连接的表示。-->
<dataSource name="dsTest" type="mysql">
<property name="location">
<location>172.16.1.52:3306/dbtest1</location>
<location>172.16.1.52:3306/dbtest2</location>
<location>172.16.1.52:3308/dbtest3</location>
</property>
<property name="user">cobar</property>
<property name="password">oldboy123</property>
<property name="sqlMode">STRICT_TRANS_TABLES</property>
</dataSource>
</cobar:schema>

#在登录cobar用户:

[root@db02 conf]# mysql -ucobar -poldboy123 -h172.16.1.52 -P8066
mysql> insert into tb2(id,name) values(555,’qiangge’);

!!!!!#在插入信息的时候一定要在表名后面加(id,name),不然不能实现分布式储存的,只会同时写入两个表中,以至于成为双写。
再登录3308实例查看是否555,’qiangge’插入到dbtest3的tb2中:

[root@db02 conf]# mysql -uroot -poldboy123 -S /data/3308/mysql.sock
mysql> use dbtest3;
mysql> select * from tb2;
+-----+----------+
| id| name |
+-----+----------+
| 555 | qiangge2 |
+-----+----------+

发表评论

发表评论

*

沙发空缺中,还不快抢~