背景

cobar 是一个数据库中间件。

虽然已经不再维护好多年,但是做为一个学习的模型还是不错的。

在了解完 cobar 的基本原理后,再去学其它的中间件就很容易了。

我自己不是 DBA,因此下文中的语言或者内容很可能有错,欢迎指正。

第一个程序

效果

系统对外提供数据库dbtest, 包含tb1tb2两张表。

其与物理数据库的对应关系为:

  • tb1: 映射到物理数据库dbtest1tb1
  • tb2: 一部分数据映射到物理数据库dbtest2tb2上,另一部分数据映射到物理数据库dbtest3tb2

即不但实现了最基础的代理功能,还实现了分库分表的功能。

准备环境

数据库环境

搭建 MySQL 数据库,过程略。

在数据库上,创建 schema:dbtest1、dbtest2、dbtest3,table:tb1、tb2

# 创建dbtest1 
DROP DATABASE IF EXISTS dbtest1;

CREATE DATABASE dbtest1;

USE dbtest1;

# 在dbtest1上创建tb1 
CREATE TABLE tb1 (
    id int NOT NULL,
    gmt datetime
);

# 创建dbtest2 
DROP DATABASE IF EXISTS dbtest2;

CREATE DATABASE dbtest2;

USE dbtest2;

# 在dbtest2上创建tb2 
CREATE TABLE tb2 (
    id int NOT NULL,
    val varchar(256)
);

# 创建dbtest3 
DROP DATABASE IF EXISTS dbtest3;

CREATE DATABASE dbtest3;

USE dbtest3;

# 在dbtest3上创建tb2 
CREATE TABLE tb2 (
    id int NOT NULL,
    val varchar(256)
);

部署 cobar

wget https://github.com/alibaba/cobar/releases/download/v1.2.7/cobar-server-1.2.7.tar.gz
tar xvf cobar-server-1.2.7.tar.gz
cd cobar-server-1.2.7

目录树如下:

cobar-server-1.2.7
├── bin
│   ├── restart.sh
│   ├── shutdown.sh
│   ├── startup.bat
│   └── startup.sh
├── conf
│   ├── log4j.xml
│   ├── rule.xml
│   ├── schema.xml
│   └── server.xml
└── lib
    ├── cobar-server-1.2.7.jar
    └── log4j-1.2.17.jar

配置 schema.xml

定义了 schema, 数据节点,数据源相关配置。

确认一下其中的 "注意" 部分即可。

<?xml version="1.0" encoding="UTF-8"?> 
<!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>192.168.0.1:3306/dbtest1</location><!-- 注意: 替换为您的 MySQLIP 和 Port--> 
       <location>192.168.0.1:3306/dbtest2</location><!-- 注意: 替换为您的 MySQLIP 和 Port--> 
       <location>192.168.0.1:3306/dbtest3</location><!-- 注意: 替换为您的 MySQLIP 和 Port--> 
     </property>

     <property name="user">test</property><!-- 注意: 替换为您的 MySQL 用户名 -->
     <property name="password"></property><!-- 注意: 替换为您的 MySQL 密码 -->
     <property name="sqlMode">STRICT_TRANS_TABLES</property>
   </dataSource> 
</cobar:schema>

配置 rule.xml

配置路由相关信息

  • 路由规则定义,定义什么表,什么字段,采用什么路由算法
  • 路由函数定义
<?xml version="1.0" encoding="UTF-8"?> 
<!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>
    <property name="partitionLength">512</property> 
  </function>
</cobar:rule>     

配置 server.xml

  • 定义 Cobar 用户名,密码

启动 cobar

建立目录 logs

启动 cobar

$ bin/startup.sh

日志见 logs 目录下

logs/
├── alarm.log
├── console.log
├── heartbeat.log
└── stdout.log

使用 cobar

连接 mysql

命令行方式

$ mysql -h192.168.0.1 -utest -ptest -P8066 -Ddbtest
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

JDBC 方式

#JDBC(建议 5.1 以上的 mysqldriver 版本) 
Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection("jdbc:mysql://192.168.0.1:8066/dbtest","test", "test");

查看数据库

mysql> show databases;
+----------+
| DATABASE |
+----------+
| dbtest   |
+----------+
1 row in set (0.00 sec)

查看数据表

mysql> show tables;
+------------------+
| Tables_in_dbtest |
+------------------+
| tb1              |
| tb2              |
+------------------+
2 rows in set (0.00 sec)

查看表结构

mysql> desc tb1;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(11)  | NO   |     | NULL    |       |
| gmt   | datetime | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> desc tb2;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int(11)      | NO   |     | NULL    |       |
| val   | varchar(256) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

插入数据

# 向表 tb1 插入一条数据
mysql>insert into tb1(id,gmt) values (1,now()); 

# 向表 tb2 插入一条数据 
mysql>insert into tb2(id,val) values (1,"part1"); 

# 向表 tb2 同时插入多条数据
mysql>insert into tb2(id,val) values (2,"part1"),(513,"part2");

查询数据

mysql> select * from tb1;
+----+---------------------+
| id | gmt                 |
+----+---------------------+
|  1 | 2018-06-10 18:16:47 |
+----+---------------------+
1 row in set (0.01 sec)
mysql> select * from tb2;
+-----+-------+
| id  | val   |
+-----+-------+
|   1 | part1 |
|   2 | part1 |
| 513 | part2 |
+-----+-------+
3 rows in set (0.00 sec)

查看物理表中数据

mysql> select * from dbtest1.tb1;
+----+---------------------+
| id | gmt                 |
+----+---------------------+
|  1 | 2018-06-10 18:16:47 |
+----+---------------------+
1 row in set (0.00 sec)

确认逻辑表tb1映射到了物理表dbtest1.tb1

mysql> select * from dbtest2.tb2;
+----+-------+
| id | val   |
+----+-------+
|  1 | part1 |
|  2 | part1 |
+----+-------+
2 rows in set (0.00 sec)
mysql> select * from dbtest3.tb2;
+-----+-------+
| id  | val   |
+-----+-------+
| 513 | part2 |
+-----+-------+
1 row in set (0.00 sec)

确认逻辑表tb1映射到了物理表dbtest2.tb2dbtest3.tb2

CobarManager

前面提到了管理端口为 9066。这个管理端口有什么用处呢?

CobarManager 通过连接 9066,可以查看 Cobar 的状态。

CobarManager 示例

下载安装 tomcat

wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.8/bin/apache-tomcat-9.0.8.tar.gz
tar xvf apache-tomcat-9.0.8.tar.gz
cd apache-tomcat-9.0.8
sh bin/startup.sh

安装

cd webapps
wget https://github.com/alibaba/cobar/releases/download/v1.2.7/cobar-manager-1.0.5.war

修改配置

  1. 修改WEB-INF/classes/log4j.xml中的日志输出路径, 日志级别调整为 INFO 及以上
  2. 查看WEB-INF/classes/下的各 xml 配置文件,不是必须更改
  3. 修改WEB-INF/xmlpath.properties文件,将xmlpath指向上面的各 xml 配置文件的路径,如/home/admin/xml/

使用

重启 tomcat

打开浏览器: http://127.0.0.1:8080/cobar-manager-1.0.5/

初始用户名和密码为 root/123456,在WEB-INF/classes/user.xml中指定的。

可以在页面上修改。

参考

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品: PipeSoloSymWide 等,欢迎大家加入,贡献开源。

    3033 引用 • 3699 回帖 • 660 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    222 引用 • 442 回帖
感谢    赞同    分享    收藏    关注    反对    举报    ...