面试关系型DB(MySQL,MyBatis )

MyCat学习笔记

2019-08-18  本文已影响0人  青年心路
一、MyCat简介
1.什么是MyCat

MyCat是目前最流行的基于Java语言编写数据库中间件,是一个实现了MySql协议的服务器,其核心功能是分库分表。配合数据库的主从模式还可以实现读写分离
MyCat官网:http://www.mycat.io/

2.使用MyCat后的架构图
image.png
3.使用MyCat的优势
3.1数据量级

单一的MySql数据存储量和操作量级有限,
MyCat可以管理若干MySql数据库,可以实现数据库的存储和操作。

3.2 开源性质

Mycat 是 java 编写的中间件,开源,免费
有非常多的人和组织对 Mycat 实行开发、维护、管理、更新
Mycat 是阿里原应用 corba 转型而来的

二、MyCat中的概念
1.切分

逻辑上的切分,在物理层面使用多库(database)、多表(table)实现切分。

1.1 纵向切分/垂直切分

就是把原来存储在一个库的数据存储在多个库上
由于数据库的读写都是对同一个库进行操作,所以单库并不能解决大规模并发写入的问题。
例如:我们会建立定义数据库 workDB、商品数据库 payDB、用户数据库 userDB、日志数据库 logDB 等。

优点:
缺点:
1.2 横向切分/水平切分

把原本存储于一个表的数据分块存储到多个表上
当一个表中的数据量过大时,我们可以把该表的数据按照某种规则,进行划分,然后存储到多个结构相同的表上。
例如:我们 userDB 中的 userTable 中数据量很大,那么可以把 userDB 切分为结构相同的多个 userDB:part0DB、part1DB 等,再将 userDB 上的 userTable,切分为很多 userTable:userTable0、userTable1 等,然后将这些表按照一定的规则存储到多个 userDB 上。

优点:
缺点:
2.逻辑库-Schema

MyCat中定义的database是逻辑上存在的,但物理上是不存在的。
主要是针对纵向切分提供的概念

3.逻辑表-Table

MyCat中定义的table,是逻辑上存在,物理上不存在的
主要是针对横向切分提供的概念

4.默认端口

MySql:3306
MyCat:8066
Tomcat:8080
Oracle:1521
nginx:80
http:协议默认端口80
redis:6379

5.数据主机-DataHost

物理MySql存放的主机地址,可以使用主机名,IP,域名定义。

6.数据节点-DataNode

配置物理的database。数据保存的物理节点就是database

7.分片规则

当控制数据的时候,如何访问物理database和table?
就是访问dataHost和dataNode的算法
在Mysql处理CRUD时,如何访问datahost和datanode的算法?如:哈希算法,crc32算法等。

三、MyCat的使用
1.读写分离

原理:需要搭建主从模式,让主数据库(master)处理增(insert)、删(delete)、改(update),而从数据库(slave)处理查(select)操作。
MyCat配合数据库本身的复制功能,可以解决读写分离的问题。

2.主从备份概念

主从备份:就是一种主备模式的数据库应用
主库(master)数据与备库(slave)数据完全一致
实现数据的多重备份,保证数据的安全。
可以在Master[InnoDB]和Slave[MyISAM]中使用不同的数据库引擎,实现读写分离。

2.1 MySql5.5、5.6版本后本身支持主从备份

在旧版本的MySql数据库系统中,不支持主从备份,需要安装额外的RPM包,如果需要安装RPM,只能在一个位置节点安装。

2.2 主从备份目的
2.3 主从备份效果
2.4 主从模式下的逻辑图
image.png
3.MySql的主从模式搭建
3.1 安装MySql

主库:192.168.254.128
从库:192.168.254.140

3.2 主从备份配置
3.3 Master[主库]配置
service mysqld restart
mysql -uusername -ppassword
grant all privileges on *.* to 'username'@'ip' identified by 'password' with grant option;
flush privileges;
grant all privileges on *.* to 'myslave'@'192.168.254.140' identified by 'myslave' with grant option;
flush privileges;
use mysql
select host,name from user
image.png
show master status;
image.png
3.4 Slave[从库]配置
vim /etc/my.cnf
service mysqld restart
mysql -uusername -ppassword
stop slave
change master to master_host='ip', master_user='username', master_password='password',
master_log_file='log_file_name';
change master to
master_host='192.168.254.128',master_user='myslave',master_password='myslave',master_log_fil
e='master_log.000002';
start slave;
show slave status \G;
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.254.128
                  Master_User: myslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master_log.000002
          Read_Master_Log_Pos: 635
               Relay_Log_File: mysqld-relay-bin.000002
                Relay_Log_Pos: 799
        Relay_Master_Log_File: master_log.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 635
              Relay_Log_Space: 973
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 36cebd9f-7c98-11e9-8f51-000c29a9c235
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
1 row in set (0.00 sec)

新建库:

create database demo1 default character set utf8;

新建表:

CREATE TABLE `user` (
 `id` int(11) NOT NULL,
 `name` varchar(30) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

添加数据:

insert into user values(1,‘admin’)
4.安装MyCat
4.1 安装环境

192.168.254.141

4.2 配置jdk
4.3 在主数据库和从数据库都需要完成

在 Mycat 中通过 Master 数据库的 root 用户访问 Master 数据库

grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;

flush privileges;
4.4 解压上传的MyCat压缩包
4.5 将解压的文件夹复制到/usr/local/mycat
4.6 MyCat目录介绍
5.MyCat配置文件

MyCat是代理,MyCat后面是物理数据库。和Web服务器的Nginx类似。对于使用者来说,访问的都是MyCat,不会接触到后面的数据库

Mycat 的配置文件都在 conf 目录里面,这里介绍几个常用的文件


image.png
5.1 server.xml
<property name="serverPort">8066</property> <!-- Mycat 服务端口号 -->
<property name="managerPort">9066</property><!-- Mycat 管理端口号 -->
<user name="root"><!-- mycat 用户名 -->
  <property name="password">密码</property>
  <property name="schemas">用户可访问逻辑库名</property>
  <!-- 表级 DML 权限设置 -->
  <!-- 不检查 SQL 语法结果
  <privileges check="false">
  <schema name="逻辑库名" dml="0110" >
  <table name="逻辑表名" dml="0000"></table>
  <table name="tb02" dml="1111"></table>
   </schema>
   </privileges>
   -->
 </user>
 <user name="user"><!-- 其他用户名 -->
 <property name="password">密码</property>
 <property name="schemas">可访问逻辑库名</property>
 <property name="readOnly">是否只读</property>
 </user>
5.2 schema.xml

schema.xml 是最主要的配置文件,首先看默认的配置文件

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
    <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
        <table name="t_user" dataNode="dn1,dn2,dn3" rule="crc32slot" />
    </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="localhost:3306" user="root"
                   password="root">
            <readHost host="hostS2" url="192.168.1.200:3306" user="root"
                      password="root" />
        </writeHost>
    </dataHost>
</mycat:schema>
5.3 rule.xml

用于定义分片规则的配置文件
mycat 默认的分片规则: 以 500 万为单位,实现分片规则

逻辑库 A 对应 dataNode - db1 和 db2. 1-500 万保存在 db1 中, 500 万零 1 到 1000 万保存在 db2 中,1000 万零 1 到 1500 万保存在 db1 中.依次类推.

<tableRule name="rule1">
  <rule>
  <columns>id</columns>
  <algorithm>func1</algorithm>
  </rule>
</tableRule>

function

<function name="func1" class="io.mycat.route.function.PartitionByLong">
  <property name="partitionCount">8</property>
  <property name="partitionLength">128</property>
</function>
image.png
6.实现读写分离
6.1 配置读写分离
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

    <schema name="suibian" checkSQLschema="false" sqlMaxLimit="100">
                <!--name为表名,dataNode与dataNode的name关联-->
        <table name="user" dataNode="dn1" />
    </schema>
        <!--dataHost与dataHost的name对应-->
    <dataNode name="dn1" dataHost="localhost1" database="demo1" />
    <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.254.128:3306" user="root"
                   password="root">
            <!-- 从库地址及密码 -->
            <readHost host="hostS2" url="192.168.254.140:3306" user="root" password="root" />
        </writeHost>
    </dataHost>
</mycat:schema>
    <user name="root">
        <property name="password">123456</property>
        <property name="schemas">suibian</property>
        
        <!-- 表级 DML 权限设置 -->
        <!--        
        <privileges check="false">
            <schema name="TESTDB" dml="0110" >
                <table name="tb01" dml="0000"></table>
                <table name="tb02" dml="1111"></table>
            </schema>
        </privileges>       
         -->
    </user>

    <user name="user">
        <property name="password">user</property>
        <property name="schemas">suibian</property>
        <property name="readOnly">true</property>
    </user>
bin/mycat start
bin/mycat stop
bin/mycat restart
bin/mycat status
mysql -u 用户名 -p 密码 -hmycat 主机 IP -P8066

连接成功后,可以当做 MySQL 数据库使用,访问约束

logs/wrapper.log

日志中记录的是所有的 mycat 操作. 查看的时候主要看异常信息 caused by 信息

7.MyCat分库
7.1 分片规则
7.2 配置分片规则需要注意的地方

1)<columns>id</columns>中推荐配置主键列
2)所有的 tableRule 只能使用一次。如果需要为多个表配置相同的分片规则,那么需要在此重新定义该规则。
3)在 crc32Slot 算法中的分片数量一旦给定,MyCat 会将该分片数量和 slor 的取值范围保存到文件中。再次修改分片数量时是不会生效的,需要将该文件删除。文件位置位于 conf目录中的 ruledata 目录中。

7.3 配置分库
需求
创建数据库
create database demo1 default character set utf8;
create database demo2 default character set utf8;
create database demo3 default character set utf8;
创建t_user表
CREATE TABLE `users` (
 `id` int(11) NOT NULL,
 `name` varchar(30) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
修改 Schema.xml

注意dataNode与table

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

    <schema name="suibian" checkSQLschema="false" sqlMaxLimit="100">
        <table name="users" dataNode="dn1,dn2,dn3" rule="crc32slot" />
    </schema>

    <dataNode name="dn1" dataHost="localhost1" database="demo1" />
    <dataNode name="dn2" dataHost="localhost1" database="demo2" />
    <dataNode name="dn3" dataHost="localhost1" database="demo3" />
    <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
              writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <!-- can have multi write hosts -->
        <writeHost host="hostM1" url="192.168.254.128:3306" user="root"
                   password="root">
            <!-- can have multi read hosts -->
            <readHost host="hostS2" url="192.168.254.140:3306" user="root" password="root" />
        </writeHost>
    </dataHost>
</mycat:schema>
7.4 注意

1)使用 MyCat 实现分库时,先在 MyCat 中定义逻辑库与逻辑表,然后在 MyCat 的链接中执行创建表的命令必须要在 MyCat 中运行。因为 MyCat 在创建表时,会在表中添加一个新的列,列名为_slot。
2)使用 MyCat 插入数据时,语句中必须要指定所有的列。即便是一个完全项插入也不允许省略列名。

上一篇下一篇

猜你喜欢

热点阅读