一般在现实中,用cobar是多台集群的,mysql用的是多实例,并且是主主同步来达到数据的高可用。下面是我画的一个简单草图,很形像地说明了之间的关系。
Cobar是taobao公司用java开发的分布式MySQL中间件,可以支持数据的分片,且接口与mysql相同,因此可以无缝切换。并且不仅支持Mysql,而且还支持MariaDB哦,对版本的要求也很低,只要5.1以上就可以了。如果公司有较多的java项目,推荐使用。我们就来试试Cobar的集群搭建吧。
第一步:下载Cobar
现在可以从两个官方地址下载,一个是github上:https://github.com/alibaba/cobar 可以下载源码,也可以直接下载编译好的包https://github.com/alibaba/cobar/releases
淘宝现在的开源网站也有:http://code.taobao.org/p/cloud-cobar/src/
两个地方下载的目录结构稍有不同,但目前内容基本一样,且都可以运行,您可以自行选择。本例子所用版本为1.2.7。
第二步:安装多个MySQL数据库
请参考文章http://bangbangba.blog.51cto.com/3180873/1703972 的第二步,不过Cobar不需要gtid支持,因此gtid相关的配置可选,如果是MariaDB,这几行是不需要配的,此处我们使用的是MariaDB-10.1。
我们配置9个数据库用于测试
作用 地址 端口 数据文件路径 配置文件路径
分片1 192.168.1.8 14011 /dev/shm/data/co11 cobra/co11.cnf
分片2 192.168.1.8 14021 /dev/shm/data/co21 cobra/co21.cnf
分片3 192.168.1.8 14031 /dev/shm/data/co31 cobra/co31.cnf
分片4 192.168.1.8 14041 /dev/shm/data/co41 cobra/co41.cnf
备份1 192.168.1.8 14051 /dev/shm/data/co51 cobra/co51.cnf
备份2 192.168.1.8 14061 /dev/shm/data/co61 cobra/co61.cnf
备份3 192.168.1.8 14071 /dev/shm/data/co71 cobra/co71.cnf
备份4 192.168.1.8 14081 /dev/shm/data/co81 cobra/co81.cnf
不分片 192.168.1.8 14091 /dev/shm/data/co91 cobra/co91.cnf
编辑好co11.cnf ~ co91.cnf 这9个配置文件,执行init_start.sh即可全部初始化好并启动。这里之所以配置为ip而不是localhost或127.0.0.1是为了后面集群做准备。
第三步:部署Cobar
Cobar只有配置文件,没有其他的元数据,因此关键就在于配置文件的修改,下载的包里面有一个例子配置文件,我们在此基础上做修改。我们第一次先只使用分片1~4,后面的4个等下再使用。
首先我们修改schema.xml,我的内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<!-- Copyright 1999-2012 Alibaba Group. 。。。。-->
<!DOCTYPE cobar:schema SYSTEM "schema.dtd">
<
cobar:schema
xmlns:cobar
=
"http://cobar.alibaba.com/"
>
<!-- schema定义 name="lyw" 意思是对外显示的数据库名是lyw,dataNode="dnG"表示默认的数据节点是dnG -->
<
schema
name
=
"lyw"
dataNode
=
"dnG"
>
<
table
name
=
"h1"
dataNode
=
"dn0,dn1,dn2,dn3"
rule
=
"ruleLong"
/>
</
schema
>
<!-- 数据节点定义,数据节点由数据源和其他一些参数组织而成。ds[0]这样的下标是dataSource中数据数组的序号 -->
<
dataNode
name
=
"dn0"
>
<
property
name
=
"dataSource"
>
<
dataSourceRef
>ds[0]</
dataSourceRef
>
</
property
>
</
dataNode
>
<
dataNode
name
=
"dn1"
>
<
property
name
=
"dataSource"
>
<
dataSourceRef
>ds[1]</
dataSourceRef
>
</
property
>
</
dataNode
>
<
dataNode
name
=
"dn2"
>
<
property
name
=
"dataSource"
>
<
dataSourceRef
>ds[2]</
dataSourceRef
>
</
property
>
</
dataNode
>
<
dataNode
name
=
"dn3"
>
<
property
name
=
"dataSource"
>
<
dataSourceRef
>ds[3]</
dataSourceRef
>
</
property
>
</
dataNode
>
<!-- 不分片的数据源,跟schema第一个dataNode对应 -->
<
dataNode
name
=
"dnG"
>
<
property
name
=
"dataSource"
>
<
dataSourceRef
>ds[8]</
dataSourceRef
>
</
property
>
</
dataNode
>
<!-- 数据源定义,数据源是一个具体的后端数据连接的表示。 -->
<
dataSource
name
=
"ds"
type
=
"mysql"
>
<
property
name
=
"location"
>
<
location
>192.168.1.8:14011/lyw</
location
>
<
location
>192.168.1.8:14021/lyw</
location
>
<
location
>192.168.1.8:14031/lyw</
location
>
<
location
>192.168.1.8:14041/lyw</
location
>
<
location
>192.168.1.8:14051/lyw</
location
>
<
location
>192.168.1.8:14061/lyw</
location
>
<
location
>192.168.1.8:14071/lyw</
location
>
<
location
>192.168.1.8:14081/lyw</
location
>
<
location
>192.168.1.8:14091/lyw</
location
>
</
property
>
<
property
name
=
"user"
>lyw</
property
>
<
property
name
=
"password"
>123456</
property
>
<
property
name
=
"sqlMode"
>STRICT_TRANS_TABLES</
property
>
</
dataSource
>
</
cobar:schema
>
|
配置好schema.xml后,我们可以看到里面有个字段rule="ruleLong",这个ruleLong的具体内容是配置在rule.xml文件中,我们这里的配置如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<!-- Copyright 1999-2012 Alibaba Group. 。。。。-->
<!DOCTYPE cobar:rule SYSTEM "rule.dtd">
<
cobar:rule
xmlns:cobar
=
"http://cobar.alibaba.com/"
>
<!-- 路由规则定义,定义什么表,什么字段,采用什么路由算法 -->
<!-- 所有路由规则tableRule都必须在所有函数function前面 -->
<
tableRule
name
=
"ruleLong"
>
<
rule
>
<
columns
>id</
columns
>
<
algorithm
>
<![CDATA[ funcLong(${id}) ]]>
</
algorithm
>
</
rule
>
</
tableRule
>
<!-- 路由函数定义,所有函数定义都需要在规则下面 -->
<!--- partitionCount * partitionLength必须等于1024 -->
<
function
name
=
"funcLong"
class
=
"com.alibaba.cobar.route.function.PartitionByLong"
>
<
property
name
=
"partitionCount"
>4</
property
>
<
property
name
=
"partitionLength"
>256</
property
>
</
function
>
</
cobar:rule
>
|
可以看到ruleLong规则中用到funcLong函数,funcLong函数在下面定义,注意所有函数定义都需要在规则下面,partitionCount * partitionLength必须等于1024,否则无法启动。
然后是server.xml,这个文件修改下用户名密码就可以了,其他用默认参数。
1
2
3
4
5
6
7
8
9
10
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<!-- Copyright 1999-2012 Alibaba Group. -->
<!DOCTYPE cobar:server SYSTEM "server.dtd">
<
cobar:server
xmlns:cobar
=
"http://cobar.alibaba.com/"
>
<!-- 用户访问定义,用户名、密码、schema等信息。 -->
<
user
name
=
"lyw"
>
<
property
name
=
"password"
>123456</
property
>
<
property
name
=
"schemas"
>lyw</
property
>
</
user
>
</
cobar:server
>
|
另外还有个配置文件log4j.xml,无需修改。
我们的配置文件都已准备好,然后就启动吧
1
2
3
4
5
6
7
|
$ bin
/startup
.sh
$ jps
15894 CobarStartup
15946 Jps
$
netstat
-nlp|
grep
java
tcp6 0 0 :::8066 :::* LISTEN 15894
/java
tcp6 0 0 :::9066 :::* LISTEN 15894
/java
|
java7下可以直接启动,如果时java8需要注释掉startup.sh中的一行。
1
|
# JAVA_OPTS="$JAVA_OPTS -XX:+UseCMSCompactAtFullCollection"
|
请检查下进程是否启动,如果配置有误是无法启动的。启动后,我们可以看到已经开启了两个端口,8066和9066,其中8066是用于数据读写等操作的,9066是用于cobar自身管理的。我们迫不及待的要去试下了。
第四步:使用Cobar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
lyw@lywd:~/db/mariadb-10.1$ bin/mysql -ulyw -p123456 -h127.0.0.1 -P8066
MySQL [(none)]> show databases;
+
----------+
|
DATABASE
|
+
----------+
| lyw |
+
----------+
1 row
in
set
(0.04 sec)
MySQL [(none)]> use lyw;
Database
changed
MySQL [lyw]> show tables;
Empty
set
(0.00 sec)
MySQL [lyw]>
create
table
h1 (id
int
primary
key
, v
varchar
(32));
Query OK, 0
rows
affected (0.01 sec)
MySQL [lyw]>
insert
into
h1 (id, v)
values
(1,
'aa'
), (2,
'2'
), (256,
'cc'
), (600,
'dd'
),(900,
'ee'
), (1000,
'ff'
);
Query OK, 6
rows
affected (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0
MySQL [lyw]>
select
*
from
h1;
+
------+------+
| id | v |
+
------+------+
| 256 | cc |
| 900 | ee |
| 1000 | ff |
| 600 | dd |
| 1 | aa |
| 2 | 2 |
+
------+------+
6
rows
in
set
(0.00 sec)
MySQL [lyw]>
select
*
from
h1
where
id = 256;
+
-----+------+
| id | v |
+
-----+------+
| 256 | cc |
+
-----+------+
1 row
in
set
(0.00 sec)
MySQL [lyw]>
select
*
from
h1
where
id
in
(256, 900, 901);
+
-----+------+
| id | v |
+
-----+------+
| 256 | cc |
| 900 | ee |
+
-----+------+
2
rows
in
set
(0.00 sec)
|
最后返回的结果看起来有点乱,并且每次执行这样的select语句,顺序都会不同,这是因为我们插入的这6条数据已经根据ruleLong的规则分散在了4个数据库中,返回的时候cobar只是简单的合并,并没有排序。我们这时候可以到4个库中分别查询,每个库都只包含其中的一部分数据。
注意:前面的insert语句中指定了列名(id, v),这是必须的,否则会将数据插入到所有数据库中去,即插入1条等于插入4条。
select * from h1 where id = 256; 这行查询语句指定了id = 256,因此cobar会计算256这个值是在哪个数据库(第二个)因此这条语句只会在第二个数据库中查找
select * from h1 where id in (256, 900, 901); 这行查询语句指定了两个id,cobar会计算这些id都属于哪个库,然后去对应的库查询,实际上会变成两个语句,
在第二个库执行select * from h1 where id in (256),
在第四个库执行select * from h1 where id in (900, 901),
然后合并数据返回。
我们可以用explain命令查看cobar的拆分情况。这个命令只是语法分析,不会到mysql中执行。
1
2
3
4
5
6
7
8
|
MySQL [lyw]> explain
select
*
from
h1
where
id
in
(256, 900, 901);
+
-----------+-----------------------------------------+
| DATA_NODE | SQL |
+
-----------+-----------------------------------------+
| dn1 |
SELECT
*
FROM
h1
WHERE
id
IN
(256) |
| dn3 |
SELECT
*
FROM
h1
WHERE
id
IN
(900, 901) |
+
-----------+-----------------------------------------+
2
rows
in
set
(0.00 sec)
|
Cobar是不支持事务的,begin命令就不可以运行,很多操作尽量使用语句内原子操作。比如
update h1 set a=a+1 where id = 2;
而不是先读出数据,再修改。拆成两条就需要事务支持才安全了。
Cobar支持多库同时操作,但只是在多个库分别执行后,一起返回数据而已,我们试下下面的几个语句
1
2
3
4
5
6
7
8
9
|
MySQL [lyw]>
select
*
from
h1 limit 1;
+
-----+------+
| id | v |
+
-----+------+
| 600 | dd |
| 256 | cc |
| 1 | aa |
| 900 | ee |
+
-----+------+
|
我们是想要得到一条数据,而实际上是得到4条,并且是每个库中一条,因此这样的结果并不符合我们的初衷,所以对于分页这样的操作用cobar并不合适。大家还可以去试下sort, group,join等操作,以及他们的组合操作,都是如此。
那Cobar合适的是什么呢?cobar最合适的就是单行的操作,另外还有in这样的多行操作。或者其他只需要一个库就能搞定的操作。这也是需要我们在设计表结构的时候多下工夫才行。
第五步:多种分片方式配置
前面讲了一个按照数字进行hash分片的例子。cobar自身提供了4种分片方法,分别是PartitionByLong,PartitionByString,PartitionByFileMap,Dimension2PartitionFunction。每种方法需要配置的参数都不同
PartitionByString 按字符串hash分片
我们需要修改rule.xml文件,如下部分,记得所有的tableRule 在所有的function前面
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<tableRule
name
=
"ruleString"
>
<
rule
>
<columns>id</columns>
<algorithm><![CDATA[ funcString(${id}) ]]></algorithm>
</
rule
>
</tableRule>
<
function
name
=
"funcString"
class=
"com.alibaba.cobar.route.function.PartitionByString"
>
<property
name
=
"partitionCount"
>4</property>
<property
name
=
"partitionLength"
>256</property>
<property
name
=
"hashSlice"
>:12</property>
</
function
>
|
其中hashSlice的含义是字符串的哪几个字符进行hash运算,例子中:12表示前面的12个字符进行运算,另外还有负数表示法,表示从后面开始数。
在schema.xml增加一个表格
1
|
<
table
name
=
"h3"
dataNode
=
"dn0,dn1,dn2,dn3"
rule
=
"ruleString"
/>
|
配置好后,我们可以用集群管理的reload方法热更新配置文件。(注意端口是9066)
1
2
3
4
|
bin/mysql -ulyw -p123456 -h127.0.0.1 -P 9066
MySQL [(none)]> reload @@config;
Query OK, 1 row affected (0.02 sec)
Reload config success
|
PartitionByFileMap 按文件内容分片
我们需要修改rule.xml文件,如下部分,
1
2
3
4
5
6
7
8
9
10
11
|
<
tableRule
name
=
"ruleFileMap"
>
<
rule
>
<
columns
>district </
columns
>
<
algorithm
>
<![CDATA[ funcFileMap(${id}) ]]>
</
algorithm
>
</
rule
>
</
tableRule
>
<
function
name
=
"funcFileMap"
class
=
"com.alibaba.cobar.route.function.PartitionByFileMap"
>
<
property
name
=
"fileMapPath"
>/home/lyw/file_map.txt</
property
>
<
property
name
=
"defaultNode"
>0</
property
>
</
function
>
|
rule.xml中fileMapPath字段我们指定了一个配置文件/home/lyw/file_map.txt,这个文件内容的格式是k=v结构,k是分片的字符串,v是节点序号(不是hash值)。内容如下,您可自己多写一些。
1
2
3
4
5
|
a=0
b=1
c=2
d=3
。。。。。。
|
defaultNode 字段表示如果key值不在这个配置文件中,那么将数据存储在这个节点中。
然后我们还要在schema.xml增加一个表格
1
|
<
table
name
=
"h5"
dataNode
=
"dn0,dn1,dn2,dn3"
rule
=
"ruleFileMap"
/>
|
只有字符串完整地属于配置文件中,才算匹配到,不是前缀,如例子中只有a,b,c,d可以找到对应的节点,其他任何值都将放入默认节点。因此这种方式一般不是用于id等主键字段,而是其他种类有限的字段,如国家、省份等。
Dimension2PartitionFunction 二维分片
二维分片有两个维度,都需要配置,因此配置内容较多
rule.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<
tableRule
name
=
"rule2D"
>
<
rule
>
<
columns
>id, id2</
columns
>
<
algorithm
>
<![CDATA[ func2D(${id}, ${id2}) ]]>
</
algorithm
>
</
rule
>
<
rule
>
<
columns
>id</
columns
>
<
algorithm
>
<![CDATA[ func2D(${id}, null) ]]>
</
algorithm
>
</
rule
>
<
rule
>
<
columns
>id2</
columns
>
<
algorithm
>
<![CDATA[ func2D(null, ${id2}) ]]>
</
algorithm
>
</
rule
>
</
tableRule
>
<
function
name
=
"func2D"
class
=
"com.alibaba.cobar.route.function.Dimension2PartitionFunction"
>
<
property
name
=
"keyTypeX"
>string</
property
>
<
property
name
=
"partitionCountX"
>2</
property
>
<
property
name
=
"partitionLengthX"
>512</
property
>
<
property
name
=
"hashSliceX"
>:12</
property
>
<
property
name
=
"keyTypeY"
>long</
property
>
<
property
name
=
"partitionCountY"
>2</
property
>
<
property
name
=
"partitionLengthY"
>512</
property
>
</
function
>
|
从rule.xml文件中我们看到tableRule配置了三个rule,其中第一个规则是有两个参数的,后两个规则只有一个参数,这3个rule不是必须全配置,但是要实现只匹配一个维度的话,就需要配置,否则当查询语句中只有一个维度的key时会进行所有库的执行,效率不高。
函数需要指定两个维度,字符串和数字都可以,其他类型目前不支持。
同样schema.xml增加一个表格
1
|
<
table
name
=
"d1"
dataNode
=
"dn0,dn1,dn2,dn3"
rule
=
"rule2D"
/>
|
如果需要二维分片,集群规模一般要相当大了,比如8*8=64,否则采用二维分片的意义不大。
第六步:Cobar自身集群配置
前面配置的cobar只是在一台机器上运行,而运行时cobar需要的资源是比较多的,一台cobar可以拖3台左右mysql服务器,而实际上只要用到cobar,mysql数量都在8台以上,所以需要多个cobar支撑,集群相关的内容在server.xml中配置,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<
cluster
>
<
node
name
=
"cobar1"
>
<
property
name
=
"host"
>192.168.1.8</
property
>
<
property
name
=
"weight"
>1</
property
>
</
node
>
<
node
name
=
"cobar2"
>
<
property
name
=
"host"
>192.168.1.9</
property
>
<
property
name
=
"weight"
>1</
property
>
</
node
>
<
node
name
=
"cobar3"
>
<
property
name
=
"host"
>192.168.1.10</
property
>
<
property
name
=
"weight"
>1</
property
>
</
node
>
</
cluster
>
|
每增加一台机器就多配置一个node,然后将这个配置文件复制到每台cobar电脑上,并启动。这时我们在任意一台电脑上用下面的命令查看活着的集群(宕机的节点不会显示)
1
2
3
4
5
6
7
8
9
|
MySQL [lyw]> show cobar_cluster;
+
--------------+--------+
| HOST | WEIGHT |
+
--------------+--------+
| 192.168.1.8 | 1 |
| 192.168.1.9 | 1 |
| 192.168.1.10 | 1 |
+
--------------+--------+
3
rows
in
set
(0.00 sec)
|
此处虽然有host和weight两个值,但是cobar并没有做负载均衡相关的具体事情,只是告诉客户端,cobar集群的运行情况,让客户端自己制定负载均衡策略。
第七步:Cobar自身管理
前面讲的是数据操作,用的是8066端口,cobar提供集群管理功能默认用的是9066端口
1
2
|
bin/mysql -ulyw -p123456 -h127.0.0.1 -P9066
MySQL [(none)]> show @@help;
|
reload命令会是一个常用命令,当修改了配置文件,就执行下这个命令让配置生效。
1
2
3
|
MySQL [(none)]> reload @@config;
Query OK, 1 row affected (0.01 sec)
Reload config success
|
注意server.xml中的system部分不可以热加载,需要重启生效。
如果加载后发现有误,可以用rollback命令回滚配置,注意只能回滚一次。
假如我们要看下所有服务器的活动情况,我们可以用下面的命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
MySQL [(none)]> show @@heartbeat;
+
--------+-------+-------------+-------+---------+-------+----------+---------+--------------+---------------------+-------+
|
NAME
| TYPE | HOST | PORT | RS_CODE | RETRY | STATUS | TIMEOUT | EXECUTE_TIME | LAST_ACTIVE_TIME | STOP |
+
--------+-------+-------------+-------+---------+-------+----------+---------+--------------+---------------------+-------+
| cobar1 | COBAR | 192.168.1.8 | 8066 | 1 | 0 | idle | 10000 | 0,0,0 | 2015-10-22 10:33:28 |
false
|
| cobar2 | COBAR | 192.168.1.9 | 8066 | -1 | 3 | checking | 10000 | 0,0,0 | 2015-10-22 10:33:27 |
false
|
| cobar3 | COBAR | 192.168.1.10| 8066 | -1 | 1 | checking | 10000 | 0,0,0 | 2015-10-22 10:33:26 |
false
|
| dn0 | MYSQL | 192.168.1.8 | 14011 | 0 | 0 | idle | -1 | 0,0,0 |
NULL
|
false
|
| dn1 | MYSQL | 192.168.1.8 | 14021 | 0 | 0 | idle | -1 | 0,0,0 |
NULL
|
false
|
| dn2 | MYSQL | 192.168.1.8 | 14031 | 0 | 0 | idle | -1 | 0,0,0 |
NULL
|
false
|
| dn3 | MYSQL | 192.168.1.8 | 14041 | 0 | 0 | idle | -1 | 0,0,0 |
NULL
|
false
|
| dnG | MYSQL | 192.168.1.8 | 14091 | 0 | 0 | idle | -1 | 0,0,0 |
NULL
|
false
|
+
--------+-------+-------------+-------+---------+-------+----------+---------+--------------+---------------------+-------+
8
rows
in
set
(0.00 sec)
|
前面3行是cobar自身集群,我这里只启动了一台,所以只有一台的状态是正常的,其他两台都不可用,一直在尝试检查是否活动起来。
下面5台并没有开启心跳,所以timeout是-1,不会进行检查,直接认为是正常的。
其他命令您可以自己尝试,都很好理解。
第八步:dataNode的高可用配置
细心的您一定发现了我们开始的时候部署了9个mysql,但是我们只有用到了5台,另外4台还没有用起来,现在我们要将另外4台也用起来。
我们计划将另外4台和前面4台两两配置为双主(也可以是其他方案,如galera等)
然后修改我们的配置文件schema.xml中dataNode的内容,每个dataNode都增加一台对应的服务器,并且配置上心跳,(实际上心跳最好是写操作的语句)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<!-- 数据节点定义,数据节点由数据源和其他一些参数组织而成。 -->
<
dataNode
name
=
"dn0"
>
<
property
name
=
"dataSource"
>
<
dataSourceRef
>ds[0]</
dataSourceRef
>
<
dataSourceRef
>ds[4]</
dataSourceRef
>
</
property
>
<
property
name
=
"heartbeatSQL"
>select user()</
property
>
</
dataNode
>
<
dataNode
name
=
"dn1"
>
<
property
name
=
"dataSource"
>
<
dataSourceRef
>ds[1]</
dataSourceRef
>
<
dataSourceRef
>ds[5]</
dataSourceRef
>
</
property
>
<
property
name
=
"heartbeatSQL"
>select user()</
property
>
</
dataNode
>
<
dataNode
name
=
"dn2"
>
<
property
name
=
"dataSource"
>
<
dataSourceRef
>ds[2]</
dataSourceRef
>
<
dataSourceRef
>ds[6]</
dataSourceRef
>
</
property
>
<
property
name
=
"heartbeatSQL"
>select user()</
property
>
</
dataNode
>
<
dataNode
name
=
"dn3"
>
<
property
name
=
"dataSource"
>
<
dataSourceRef
>ds[3]</
dataSourceRef
>
<
dataSourceRef
>ds[7]</
dataSourceRef
>
</
property
>
<
property
name
=
"heartbeatSQL"
>select user()</
property
>
</
dataNode
>
|
然后reload配置,在用show @@datanode;命令检查下运行情况
1
2
3
4
5
6
7
8
9
10
11
|
MySQL [(none)]> show @@datanode;
+
------+-------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
|
NAME
| DATASOURCES |
INDEX
| TYPE | ACTIVE | IDLE |
SIZE
|
EXECUTE
| TOTAL_TIME | MAX_TIME | MAX_SQL | RECOVERY_TIME |
+
------+-------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
| dn0 | ds[0],ds[4] | 0 | mysql | 0 | 0 | 128 | 0 | 0 | 0 | 0 | -1 |
| dn1 | ds[1],ds[5] | 0 | mysql | 0 | 0 | 128 | 0 | 0 | 0 | 0 | -1 |
| dn2 | ds[2],ds[6] | 0 | mysql | 0 | 0 | 128 | 0 | 0 | 0 | 0 | -1 |
| dn3 | ds[3],ds[7] | 0 | mysql | 0 | 0 | 128 | 0 | 0 | 0 | 0 | -1 |
| dnG | ds[8] | 0 | mysql | 0 | 0 | 128 | 0 | 0 | 0 | 0 | -1 |
+
------+-------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
5
rows
in
set
(0.01 sec)
|
我们发现DATASOURCES中前面4个都有两个节点,INDEX目前都是0,表示连接的是前面这个节点。
这时我们模拟宕机,将ds[0]这个节点kill掉,过几秒钟再用上面这个命令查看时,就会发现第一个INDEX变成了1,也就是说用到的是ds[4]节点。之后的读写都会在ds[4]中操作。
然后我们重新启动ds[0],再查状态,发现还是INDEX还是维持1,cobar不会主动切换回去。假如我们想切换回去,可以用命令switch @@datasource name:index,(序号参数可选)
1
2
|
MySQL [(none)]> switch @@datasource dn0:0;
Query OK, 1 row affected (0.03 sec)
|
注意该功能只会修改当前cobar的配置,其他节点并不会一同修改,因此有一定风险。配置文件的加载也是一样,多个节点间不会同步,因此也有一点风险。
至此Cobar的基本特性就是这样了,更多的高级功能就在逐步的使用中去发现吧。
如果觉得Cobar的操作限制有点多,那么也许可以考虑使用MySQL Cluster。
在多种集群之间选择犹豫时,可以参考下《MySQL Cluster, Fabric, Cobar 三大集群特性对比》这篇文章,一定会对你有所帮助的。
本文出自 “棒棒吧” 博客,请务必保留此出处http://bangbangba.blog.51cto.com/3180873/1705245