MyCat搭建

安装步骤

什么是MyCat

为什么使用MyCat

如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB。对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求。这个时候NoSQL的出现暂时解决了这一危机。它通过降低数据的安全性,减少对事务的支持,减少对复杂查询的支持,来获取性能上的提升。但是,在有些场合NoSQL一些折衷是无法满足使用场景的,就比如有些使用场景是绝对要有事务与安全指标的。这个时候NoSQL肯定是无法满足的,所以还是需要使用关系性数据库。如何使用关系型数据库解决海量存储的问题呢?此时就需要做数据库集群,为了提高查询性能将一个数据库的数据分散到不同的数据库中存储,为应对此问题就出现了——MyCat
  综上所述:Mycat作用为:能满足数据库数据大量存储;提高了查询性能

支持的数据库

mysql,sqlserver,mongoDB

架构

前端用户可以把mycat看作是一个数据库代理,用mysql客户端工具(如Navicat)和命令访问,而后端支持mysql,sqlserver,oracle等主流数据库,用mysql native 协议和多个mysql服务器通信,也可用JDBC协议与大多数主流数据库服务器通信,其核心功能就是分库分表,即将一个大表水平分割为N个小表,真正的存储在后端Mysql服务器中或其它数据库中

mycat原理

mycat原理:可以用“拦截”一词形容,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析,如分片分析,路由分析,读写分离分析,缓存分析等,然后将此sql发往后端的真实数据库,并将返回的结果做适当处理,最终返回给用户

分片

  • 数据库分片指:通过某种特定的条件,将我们存放在一个数据库中的数据分散存放在不同的多个数据库(主机)中,这样来达到分散单台设备的负载,根据切片规则,可分为以下两种切片模式:
  • 垂直切片
    将不同的表切分到不同的数据库中
  • 水平切片
    将同一种表按照某种条件切分到不同的数据库中(这种方式最常用)

水平分片

MyCAT通过定义表的分片规则来实现分片,每个表格可以捆绑一个分片规则,每个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法
  1.Schema:逻辑库,与MySQL中的Database(数据库)对应,一个逻辑库中定义了所包括的Table。
  2.Table:逻辑表,即物理数据库中存储的某一张表,与传统数据库不同,这里的表格需要声明其所存储的逻辑数据节点DataNode。在此可以指定表的分片规则。
  3.DataNode:MyCAT的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,通过DataSource来关联到后端某个具体数据库上
  4.DataSource:定义某个物理库的访问地址,用于捆绑到Datanode上

配置文件详解

mycat主要有3个配置文件,rule.xml,schema.xml和server.xml,这主要对这3个文件作讲解

rule.xml

该文件主要定义了分片的规则,这个文件里面主要有tableRule和function这两个标签。在具体使用过程中可以按照需求添加tableRule和function

tableRule标签

1
2
3
4
5
6
<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns>
<algorithm>rang-long</algorithm>
</rule>
</tableRule>

tableRule标签

  • name:用户标识不同的分表规则
  • columns:指定按哪一列进行拆分
  • algorithm:该属性值为下面function标签中name的属性值,定义了连接表规则的具体的路由算法,多个表规则可以连接到同一个路由算法上

function标签

1
2
3
4
<function name="rang-long"
class="org.opencloudb.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>

function标签

  • name:标识算法的名字
  • class:指定路由算法具体的类名字
  • property:具体算法用到的一些属性

schema.xml

该文件是MyCat中重要的配置文件之一,管理着MyCat的逻辑库、表、分片规则、DataNode以及DataSource

schema.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">
<schema name="e3mall" checkSQLschema="false" sqlMaxLimit="100">
<table name="tb_item" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
</schema>
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<dataNode name="dn3" dataHost="localhost1" database="db3" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.20.216:3306" user="root"
password="root">
</writeHost>
</dataHost>
</mycat:schema>

schema.xml

  • schema标签:定义mycat实例中的逻辑库
  • table标签:定义mycat实例中的逻辑表
  • dataNode标签:定义mycat中的数据节点,也是通常说的数据分片
  • dataHost标签:作为最底层标签存在,定义了具体的真正存放数据的数据库实例,读写分离配置和心跳语句,我这只用来一台主键,所以只配了一个dataHost,如果你配了N个主机,就要配N个dataHost节点

server.xml

1
2
3
4
5
6
7
8
9
10
11
!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://org.opencloudb/">
<system>
<property name="defaultSqlParser">druidparser</property>
</system>
<user name="user">
<property name="password">user</property>
<property name="schemas">e3mall</property>
<property name="readOnly">false</property>
</user>
</mycat:server>
  • system标签:内嵌的所有property标签都与系统配置有关
    • defaultSqlParser:指定默认的解析器(如解析sql),目前的可用的取值有:druidparser和 fdbparser。使用的时候可以选择其中的一种,目前一般都使用druidparser
  • user标签
    • name:逻辑用户名,即登录mycat的用户名
    • password:逻辑密码,即登录mycat的用户名对应的密码
    • schemas:逻辑数据库,可配置多个,用英文逗号隔开,对应于schema.xml文件中配置的逻辑数据库,两者对应
    • readOnly:该数据库是否为只读,如果true就是只读

安装MySQL

  • 查看安装

    1
    rpm -qa |grep -i mysql
  • 源码安装

    1
    2
    ./configure -prefix=install path
    make && make install
  • rpm安装
    在Centos 7上使用

    1
    rpm -ivh https://repo.mysql.com//mysql57-community-release-el7-11.noarch.rpm

    Centos 6上安装mysql rpm包

    1
    rpm -ivh https://repo.mysql.com//mysql57-community-release-el6-11.noarch.rpm
  • yum安装

    1
    2
    3
    4
    5
    yum -y install mysql
    yum -y install mysql-server
    yum -y install mysql-devel

    yum -y remove mysql
  • 启动

    • Centos 7系统启动mysql命令
      1
      2
      3
      4
      systemctl start mysql
      systemctl start mysqld.service
      systemctl enable mysqld.service
      systemctl status mysqld.service
    • Centos 6启动mysql命令
      1
      2
      3
      4
      service mysqld start
      service mysqld status
      chkconfig --add mysqld
      chkconfig mysqld on
  • 验证mysql是否启动成功命令,使用netstat命令

    1
    netstat -nap |grep 3306
  • 关闭防火墙

    1
    systemctl stop firewalld.service
  • 最后需要查看mysql5.7的初始化密码(如果是mysql5.6的话默认密码应该为空,不需要此命令查询)
    grep 'temporary password' /var/log/mysqld.log

  • 然后输入mysql -uroot -p命令登录mysql服务器,并修改mysql初始化密码。输入初始化密码登录之后,重新设置mysql密码

    1
    mysql -u root -p
    1
    mysqladmin -u root password 12345678
    1
    mysql> set password for root@localhost = password('12345678');
  • validate_password_policy有以下取值

    1
    2
    3
    4
    5
    6
    7
     mysql> set global validate_password_policy=0;
    mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '12345678';
    ```
    - 也可以 直接再添加新用户     
    ```bash
      mysql>  CREATE USER ‘root‘@‘%‘ IDENTIFIED BY ‘您的密码‘;
      mysql>  grant all privileges on *.* to 'root'@'%' identified by '12345678'  with grant option;

    增加root用户指定可以任意IP登录,如果想限制只能让指定IP登录请把%替换成IP地址

添加mysql用户及权限并配置数据库

1
2
vim /etc/my.cnf
default-character-set=utf8

安装

  • 默认配置文件路径:
    • 配置文件:/etc/my.cnf
    • 日志文件:/var/log/var/log/mysqld.log
    • 服务启动脚本:/usr/lib/systemd/system/mysqld.service
    • socket文件:/var/run/mysqld/mysqld.pid
  • 在[mysqld]后面任意一行添加“skip-grant-tables”用来跳过密码验证的过程
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    mysql> use mysql;
    mysql> update user set password=password("你的新密码") where user="root";
    mysql> flush privileges;
    mysql> quit
    mysql> select user,password from user where user="root";
    mysql> select user,host from user;
    mysql> delete from user where user="";
    mysql> update user set host='%' where user='root' and host='localhost';
    mysql> insert into mysql.user(Host,User,Password) values("%","mycat",password("12345678"));
    mysql> GRANT USAGE ON *.* TO 'mycat'@'%' IDENTIFIED BY '12345678' WITH GRANT OPTION;
    mysql> grant all privileges on *.* to 'mycat'@'%' identified by '12345678' WITH GRANT OPTION;
    mysql> flush privileges;
    mysql> show grants for 'root'@'%';
  • 三台机器
    1
    2
    3
    4
    mysql> mysql -u mycat -p
    mysql> create database db1;
    mysql> create database db2;
    mysql> create database db3;
    mysql 5.7的数据库没有了password字段 用的是authentication_string字段
    1
    2
    mysql> update mysql.user set authentication_string=password('12345678') where user='root' ;
    flush privileges;

Mycat数据库分库分表中间件

  1. 安装mycat
    1
    2
    3
    4
    tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
    vim /etc/profile
    export MYCAT_HOME=/opt/sxt/soft/mycat
    PATH=$PATH:$MYCAT_HOME/bin
  • 开机启动
    1
    sh /opt/sxt/soft/mycat/bin/mycat start
1
2
3
4
tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
vim /etc/profile
export MYCAT_HOME=/usr/local/mycat
PATH=$PATH:$MYCAT_HOME/bin
  • 开机启动

    1
    sh /usr/local/mycat/bin/mycat start
  • 创建一个新的group
    groupadd mycat

  • 创建一个新的用户,并加入group
    useradd -g mycat mycat

  • 给新用户设置密码12345678
    passwd mycat

  1. 配置mycat配置文件
    三台服务上的mysql都修改,添加配置忽略大小写
    1
    2
    3
    vim /etc/my.cnf
    default-character-set=utf8
    lower_case_table_names=1
1
2
3
4
5
6
7
8
9
10
mv mycat /usr/local/
cd /usr/local/mycat/conf
more rule.xml
cp schema.xml schema.xml.bak
vim schema.xml
vim server.xml
vim partition-hash-int.txt
10000=0
10010=1
10020=2
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
<schema name="mydb" checkSQLschema="true" sqlMaxLimit="100">
<table name="employee" primaryKey="ID" dataNode="dn1,dn2,dn3" rule="sharding-by-intfile" />
</schema>
<dataNode name="dn1" dataHost="master" database="db1" />
<dataNode name="dn2" dataHost="salve1" database="db2" />
<dataNode name="dn3" dataHost="salve2" database="db3" />

<dataHost name="master" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="master:3306" user="mycat" password="12345678">
<!-- can have multi read hosts -->
<!--<readHost host="hostS2" url="192.168.1.200:3306" user="root" password="xxx" />-->
</writeHost>
<!-- <writeHost host="hostS1" url="localhost:3316" user="root" password="12345678"/>-->
<!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
</dataHost>
<dataHost name="salve1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM2" url="salve1:3306" user="mycat" password="12345678">
</writeHost>
</dataHost>
<dataHost name="salve2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM3" url="salve2:3306" user="mycat" password="12345678">
</writeHost>
</dataHost>
  1. 测试mycat
  • 启动maycat
    1
    2
    ./bin/mycat start
    ./bin/mycat stop
    mycat默认端口是8066
1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE employee  (
`id` int(11) NOT NULL COMMENT 'ID',
`name` varchar(100) NULL DEFAULT NULL COMMENT '姓名',
`sharding_id` int(11) NOT NULL COMMENT '共享ID',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB COMMENT = '员工表' ROW_FORMAT = Dynamic;

INSERT into employee(id,name,sharding_id) values (1,'i am db1',10000);
INSERT into employee(id,name,sharding_id) values (2,'i am db2',10010);
INSERT into employee(id,name,sharding_id) values (3,'i am db3',10020);
INSERT into employee(id,name,sharding_id) values (4,'i am db1',10000);
INSERT into employee(id,name,sharding_id) values (5,'i am db2',10010);
INSERT into employee(id,name,sharding_id) values (6,'i am db3',10020);
1
2
3
4
vim /etc/hosts
10.211.55.10 master
10.211.55.11 salve1
10.211.55.12 salve2

chmod 777 patition-pattern.txt
next value for MYCATSEQ_USER
autoIncrement=true

-------------本文结束感谢您的阅读-------------
undefined