注:(NODE1和NODE2运行于XEN虚拟化平台,硬件环境HP Z800)
分布式:主要是通过将同一个表的数据拆分成多个,放入不同的数据库实例,查询的时候也会按照同样的操作方式,来更新具体数据库实例中的对应的数据。
HA:高可用性,在设置了MYSQL心跳的情况下,如果主数据库发生了异常,Cobar会自动连接从数据库,如果主数据库恢复正常,只能手动恢复到主数据库。Cobar只负责切换数据库实例,不负责主从数据库的同步,所以需要提前将主从数据库设置双向同步。
当然,如果想努力实现这些功能,可以fork官方的源码:https://github.com/alibaba/cobar
Cobar-Server-1.2.7版本下载:http://pan.baidu.com/s/1pJudQh9
实验拓扑图如下:
#创建dbtest1脚本
dropdatabaseif exists dbtest1;
createdatabasedbtest1;
use dbtest1;
#在dbtest1上创建tb1
createtabletb1(
id intnotnull,
gmt datetime);
#创建dbtest2
dropdatabaseif exists dbtest2;
createdatabasedbtest2;
use dbtest2;
#在dbtest2上创建tb2
createtabletb2(
val varchar(256));
varchar(256));
(256));
#创建dbtest3
dropdatabaseif exists dbtest3;
createdatabasedbtest3;
use dbtest3;
#在dbtest3上创建tb2
schema.xml配置如下
<cobar:schema xmlns:cobar="http://cobar.alibaba.com/">
cobar:schema xmlns:cobar="http://cobar.alibaba.com/">
xmlns:cobar="http://cobar.alibaba.com/">
="http://cobar.alibaba.com/">
"http://cobar.alibaba.com/">
>
<schema name="dbtest" dataNode="dnTest1">
schema name="dbtest" dataNode="dnTest1">
name="dbtest" dataNode="dnTest1">
="dbtest" dataNode="dnTest1">
"dbtest" dataNode="dnTest1">
dataNode="dnTest1">
="dnTest1">
"dnTest1">
<table name="tb2" dataNode="dnTest2,dnTest3" rule="rule1" />
table name="tb2" dataNode="dnTest2,dnTest3" rule="rule1" />
name="tb2" dataNode="dnTest2,dnTest3" rule="rule1" />
="tb2" dataNode="dnTest2,dnTest3" rule="rule1" />
"tb2" dataNode="dnTest2,dnTest3" rule="rule1" />
dataNode="dnTest2,dnTest3" rule="rule1" />
="dnTest2,dnTest3" rule="rule1" />
"dnTest2,dnTest3" rule="rule1" />
rule="rule1" />
="rule1" />
"rule1" />
/>
schema>
<dataNode name="dnTest1">
dataNode name="dnTest1">
name="dnTest1">
<property name="dataSource">
property name="dataSource">
name="dataSource">
="dataSource">
"dataSource">
<dataSourceRef>dsTest[0]dataSourceRef>
dataSourceRef>dsTest[0]dataSourceRef>
>dsTest[0]dataSourceRef>
dataSourceRef>
property>
dataNode>
<dataNode name="dnTest2">
dataNode name="dnTest2">
name="dnTest2">
="dnTest2">
"dnTest2">
<dataSourceRef>dsTest[1]dataSourceRef>
dataSourceRef>dsTest[1]dataSourceRef>
>dsTest[1]dataSourceRef>
<dataNode name="dnTest3">
dataNode name="dnTest3">
name="dnTest3">
="dnTest3">
"dnTest3">
<dataSourceRef>dsTest[2]dataSourceRef>
dataSourceRef>dsTest[2]dataSourceRef>
>dsTest[2]dataSourceRef>
<dataSource name="dsTest" type="mysql">
dataSource name="dsTest" type="mysql">
name="dsTest" type="mysql">
="dsTest" type="mysql">
"dsTest" type="mysql">
type="mysql">
="mysql">
"mysql">
<property name="location">
property name="location">
name="location">
="location">
"location">
<location>192.168.137.8:3306/dbtest1location>
location>192.168.137.8:3306/dbtest1location>
>192.168.137.8:3306/dbtest1location>
location>
<location>192.168.137.31:3306/dbtest2location>
location>192.168.137.31:3306/dbtest2location>
>192.168.137.31:3306/dbtest2location>
<location>192.168.137.32:3306/dbtest3location>
location>192.168.137.32:3306/dbtest3location>
>192.168.137.32:3306/dbtest3location>
<property name="user">cobarproperty>
property name="user">cobarproperty>
name="user">cobarproperty>
="user">cobarproperty>
"user">cobarproperty>
>cobarproperty>
<property name="password">saproperty>
property name="password">saproperty>
name="password">saproperty>
="password">saproperty>
"password">saproperty>
>saproperty>
<property name="sqlMode">STRICT_TRANS_TABLESproperty>
property name="sqlMode">STRICT_TRANS_TABLESproperty>
name="sqlMode">STRICT_TRANS_TABLESproperty>
="sqlMode">STRICT_TRANS_TABLESproperty>
"sqlMode">STRICT_TRANS_TABLESproperty>
>STRICT_TRANS_TABLESproperty>
dataSource>
cobar:schema>
server.xml简单配置
<cobar:server xmlns:cobar="http://cobar.alibaba.com/">
cobar:server xmlns:cobar="http://cobar.alibaba.com/">
<user name="root">
user name="root">
name="root">
="root">
"root">
<property name="schemas">dbtestproperty>
property name="schemas">dbtestproperty>
name="schemas">dbtestproperty>
="schemas">dbtestproperty>
"schemas">dbtestproperty>
>dbtestproperty>
user>
cobar:server>
rule.xml配置
<cobar:rule xmlns:cobar="http://cobar.alibaba.com/">
cobar:rule xmlns:cobar="http://cobar.alibaba.com/">
<tableRule name="rule1">
tableRule name="rule1">
name="rule1">
="rule1">
"rule1">
<rule>
rule>
<columns>valcolumns>
columns>valcolumns>
>valcolumns>
columns>
<algorithm>algorithm>
algorithm>algorithm>
>algorithm>
algorithm>
tableRule>
<function name="func1" class="com.alibaba.cobar.route.function.PartitionByLong">
function name="func1" class="com.alibaba.cobar.route.function.PartitionByLong">
name="func1" class="com.alibaba.cobar.route.function.PartitionByLong">
="func1" class="com.alibaba.cobar.route.function.PartitionByLong">
"func1" class="com.alibaba.cobar.route.function.PartitionByLong">
class="com.alibaba.cobar.route.function.PartitionByLong">
="com.alibaba.cobar.route.function.PartitionByLong">
"com.alibaba.cobar.route.function.PartitionByLong">
<property name="partitionCount">2property>
property name="partitionCount">2property>
name="partitionCount">2property>
="partitionCount">2property>
"partitionCount">2property>
>2property>
<property name="partitionLength">512property>
property name="partitionLength">512property>
name="partitionLength">512property>
="partitionLength">512property>
"partitionLength">512property>
>512property>
function>
<function name="func2" class="com.alibaba.cobar.route.function.PartitionByString">
function name="func2" class="com.alibaba.cobar.route.function.PartitionByString">
name="func2" class="com.alibaba.cobar.route.function.PartitionByString">
="func2" class="com.alibaba.cobar.route.function.PartitionByString">
"func2" class="com.alibaba.cobar.route.function.PartitionByString">
class="com.alibaba.cobar.route.function.PartitionByString">
="com.alibaba.cobar.route.function.PartitionByString">
"com.alibaba.cobar.route.function.PartitionByString">
<property name="hashSlice">-5:property>
property name="hashSlice">-5:property>
name="hashSlice">-5:property>
="hashSlice">-5:property>
"hashSlice">-5:property>
>-5:property>
cobar:rule>
这里需要说明,INSERT语句中必须包含路由规则定义的字段,否则Cobar不会对数据进行拆分,同时存储到多个数据库实例中,比如上面的tb2表中,id字段如果设置了auto_increment,插入语句中不用指明id字段,这样就无法达到数据包拆分的目的。
准备完成之后直接运行bin目录下的./startup.sh即可。
然后查看输入的日志:
yan@yan-Z400:~/cobar-server-1.2.7/logs$ tail -f stdout.log
09:57:00,155 INFO Cobar is ready to startup ...
09:57:00,155 INFO Startup processors ...
09:57:00,198 INFO Startup connector ...
09:57:00,202 INFO Initialize dataNodes ...
09:57:00,811 INFO dnTest1:0 init success
09:57:00,816 INFO dnTest3:0 init success
09:57:00,821 INFO dnTest2:0 init success
09:57:00,835 INFO CobarManager is started and listening on 9066
09:57:00,837 INFO CobarServer is started and listening on 8066
09:57:00,837 INFO ===============================================
这样cobar服务端就已经启动。
直接使用jdbc或mysql终端连接cobar:
yan@yan-Z400:~$ mysql -uroot -psa -P8066 -h192.168.137.8
Welcome to the MySQL monitor. Commands end with ; or /g.
Your MySQL connection id is 1
Server version: 5.1.48-cobar-1.2.7 Cobar Server (ALIBABA)
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '/h' for help. Type '/c' to clear the current input statement.
#!/usr/bin/env python
#coding=utf-8
import MySQLdb
MySQLdb
#连接
cxn = MySQLdb.Connect(host='192.168.137.8',port=8066, user = 'root', passwd = 'sa')
= MySQLdb.Connect(host='192.168.137.8',port=8066, user = 'root', passwd = 'sa')
MySQLdb.Connect(host='192.168.137.8',port=8066, user = 'root', passwd = 'sa')
='192.168.137.8',port=8066, user = 'root', passwd = 'sa')
'192.168.137.8',port=8066, user = 'root', passwd = 'sa')
,port=8066, user = 'root', passwd = 'sa')
=8066, user = 'root', passwd = 'sa')
8066, user = 'root', passwd = 'sa')
, user = 'root', passwd = 'sa')
= 'root', passwd = 'sa')
'root', passwd = 'sa')
, passwd = 'sa')
= 'sa')
'sa')
)
#游标
cur = cxn.cursor()
= cxn.cursor()
cxn.cursor()
cur.execute("USE dbtest")
"USE dbtest")
for i in range(1,200):
i in range(1,200):
in range(1,200):
range(1,200):
(1,200):
1,200):
,200):
200):
):
cur.execute("INSERT INTO tb2 (val) values ('this is a test record %d')"%i)
"INSERT INTO tb2 (val) values ('this is a test record %d')"%i)
%i)
i)
print 'insert the %d record into cobar'%i
'insert the %d record into cobar'%i
%i
i
cur.close()
cxn.commit()
cxn.close()
插入后查看数据库dbtest2和数据dbtest3的情况:
可以看到有100条数据插入了dbtest2,99条数据插入了dbtest3。
后面会对Cobar进行更深入的了解。我的Fork分支
(完)