zoukankan      html  css  js  c++  java
  • MyCat学习笔记

    一、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 等。

    优点:
    • 减少增量数据写入时的锁对查询的影响。
    • 由于单表数量下降,常见的查询操作由于减少了需要扫描的记录,使得单表单次查询所需检索的行数变少,减少了磁盘IO、时延变短。
    缺点:
    • 无法解决单表数据量太大的问题。
    1.2 横向切分/水平切分

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

    优点:
    • 单表的并发能力提高了,磁盘的I/O性能也提高了
    • 如果出现高并发的话,总表可以根据不同的查询,将并发压力发到不同的小表里。
    缺点:
    • 无法实现表连接查询
    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 主从备份目的
    • 实现主备模式
      保证数据安全,尽量避免数据丢失
    • 实现读写分离
      使用不同的数据库引擎,实现读写分离,提高所有的操作效率。
      InnoDB使用DML语法操作、MyISAM使用DQL语法操作。
    2.3 主从备份效果
    • 主库操作同步到备库
      所有对Master的操作,都会同步到Slave中
      注意:如果 Master 和 Salve 天生上环境不同,那么对 Master 的操作,可能会在 Slave 中出现错误
      如:在创建主从模式之前,Master 有 database : db1、db2、db3。Slave 有 database: db1、db2
      创建主从模式.现在的情况 Master 和 Slave 天生不同
      主从模式创建成功后,在 Master 中 drop database db3. Slave 中抛出数据库 SQL 异常,后续所有的命令不能同步.
      一旦出现错误,只能重新实现主从模式
    2.4 主从模式下的逻辑图
     
    image.png
    3.MySql的主从模式搭建
    3.1 安装MySql

    主库:192.168.254.128
    从库:192.168.254.140

    3.2 主从备份配置
    3.3 Master[主库]配置
    • 修改Master配置文件
      路径:/etc/my.cnf
      命令:vim /etc/my.cnf
    • server_id
      本环境中server_id是1
      MySql服务唯一标识
      配置要求
      server_id 任意配置,只要是数字即可
      server_id Master唯一标识数字必须小于Slave唯一标识数字
    • log_bin
      本环境中log_bin的值:master_log
      开启日志功能以及日志文件命名,log_bin=master_log
      变量的值就是日志文件名称,是日志文件名称的主体
      MySql数据库自动增加文件后缀和文件类型
    • 重启MySql
    service mysqld restart
    
    • 配置Master
      • 访问MySql
    mysql -uusername -ppassword
    
    • 创建用户
      在MySql数据库中,为不存在的用户授权,就是同步创建用户并授权。
      此用户是从库访问主库使用的用户
      ip地址不能写%,因为主从备份中,当前创建的用户,是给从库(Slave)访问主库(Master)使用的。用户必须有指定的访问地址,不能是通用地址。
    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
    • 查看Master的信息
    show master status;
    
     
    image.png
    • 关闭防火墙或在防火墙中开放3306端口
    3.4 Slave[从库]配置
    • 修改Slave配置文件
    vim /etc/my.cnf
    
    • server_id
      唯一标识,本环境中配置为2
    • 重启MySql服务
    service mysqld restart
    
    • 配置Slave
      • 访问MySql
    mysql -uusername -ppassword
    
    • 停止Slave功能
    stop slave
    
    • 配置主从信息
      需要修改的数据是依据Master信息修改的,ip是Master所在物理机IP,用户名和密码是Master提供的Slave访问用户名和密码,日志文件是在Master中查看的主库信息提供的,在Master中使用命令show master status查看日志文件名称。
    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';
    
    • 启动Slave功能
    start slave;
    
    • 查看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)
    
    • 3.5 测试从库

    新建库:

    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 在主数据库和从数据库都需要完成
    • 放开 3306 端口
    • 保证 root 用户可以被 mycat 访问

    在 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目录介绍
    • bin 目录里是启动脚本
    • conf 目录里是配置文件
    • catlet 为 Mycat 的一个扩展功能
    • lib 目录里是 Mycat 和它的依赖 jar
    • logs 目录里是 console.log 用来保存控制台日志,和 mycat.log 用来保存 mycat 的 log4j日志
    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>
    
    • 配置MyCat服务信息
      如:MyCat中的用户,用户可以访问的逻辑库,可以访问的逻辑表,服务的端口号

       
      image.png

      注意:默认配置了一个账号root 密码是123456,针对数据库TESTDB,读写权限都有,没有针对表做任何特殊的权限
    • 配置权限


       
      image.png

      dml 权限顺序为:insert(新增),update(修改),select(查询),delete(删除),0000--> 1111,0 为禁止权限,1 为开启权限。

    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>
    
    • 用于定义逻辑库和逻辑表的配置文件
      在配置文件中可以定义读写分离,逻辑库,逻辑表,dataHost,dataNode 等信息


       
      image.png
    • 节点与属性介绍

      • 标签schema
        配置逻辑库标签

        • 属性name
          逻辑库名称
        • 属性checkSQLschema
          是否检查sql语法中的schema信息
          如: Mycat 逻辑库名称 A, dataNode 名称 B
          SQL :select * from A.table;
          checkSQLschema 值是 true, Mycat 发送到数据库的 SQL 是 select * from table;
          checkSQLschema 值是 false,Mycat 发送的数据库的 SQL 是 select * from A.table;
        • sqlMaxLimit
          Mycat 在执行 SQL 的时候,如果 SQL 语句中没有 limit 子句.自动增加 limit 子句. 避免一次性得到过多的数据,影响效率. limit子句的限制数量默认配置为100.如果 SQL中有具体的 limit子句,当前属性失效.
          SQL : select * from table; mycat 解析后: select * from table limit 100;
          SQL : select * from table limit 10;mycat 不做任何操作修改.
      • 标签table
        定义逻辑表的标签

        • 属性name
          逻辑表名
        • 属性 dataNode
          数据节点名称. 即物理数据库中的 database 名称.多个名称使用逗号分隔
        • 属性 rule
          分片规则名称.具体的规则名称参考 rule.xml 配置文件.
      • 标签 dataNode
        定义数据节点的标签

        • 属性 name
          数据节点名称, 是定义的逻辑名称,对应具体的物理数据库 database
        • 属性 dataHost
          引用 dataHost 标签的 name 值,代表使用的物理数据库所在位置和配置信息.
        • 属性 database
          在 dataHost 物理机中,具体的物理数据库 database 名称
      • dataHost 标签
        定义数据主机的标签

        • 属性 name
          定义逻辑上的数据主机名称
        • 属性 maxCon/minCon
          最大连接数, max connections
          最小连接数, min connections
        • 属性 dbType
          数据库类型 : mysql 数据库
        • 属性 dbDriver
          数据库驱动类型, native,使用 mycat 提供的本地驱动
      • dataHost 子标签 writeHost
        写数据的数据库定义标签. 实现读写分离操作.

        • 属性 host
          数据库命名
        • 属性 url
          数据库访问路径
        • 属性 user
          数据库访问用户名
        • 属性 password
          访问用户密码
      • writeHost 子标签 readHost

        • 属性 host
          数据库命名
        • 属性 url
          数据库访问用户名
        • 属性 password
    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>
    
    • tableRule


       
      image.png

    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 配置读写分离
    • Schema.xml
    <?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>
    
    • Server.xml
        <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>
    
    • 测试读写分离

      • 启动mycat命令
    bin/mycat start
    
    • 停止命令
    bin/mycat stop
    
    • 重启命令
    bin/mycat restart
    
    • 查看 MyCat 状态
    bin/mycat status
    
    • 访问方式
      可以使用命令行访问或客户端软件访问
    • 命令行访问方式
    mysql -u 用户名 -p 密码 -hmycat 主机 IP -P8066
    

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

    • 查看 Mycat 日志
    logs/wrapper.log
    

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

    • balance
      balance=”0”, 不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上
      balance=”1”,全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡
      balance=”2”,所有读操作都随机的在 writeHost、 readhost 上分发。
      balance=”3”, 所有读请求随机的分发到 writeHost 对应的 readhost 执行,writerHost不负担读压力
    7.MyCat分库
    7.1 分片规则
    • auto-sharding-long 范围约定
      以 500 万为单位,实现分片规则.
      逻辑库 A 对应 dataNode - db1 和 db2. 1-500 万保存在 db1 中, 500 万零 1 到 1000 万保存在 db2 中,1000 万零 1 到 1500 万保存在 db1 中.依次类推.
    • crc32slot 规则
      在 CRUD 操作时,根据具体数据的 crc32 算法计算,数据应该保存在哪一个dataNode 中
    7.2 配置分片规则需要注意的地方

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

    7.3 配置分库
    需求
    • 在 master 中创建 3 个数据库
    • 在 MyCat 中配置分库
    创建数据库
    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 插入数据时,语句中必须要指定所有的列。即便是一个完全项插入也不允许省略列名。



    作者:鲁毅_
    链接:https://www.jianshu.com/p/c8973edc550a
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    Java中遍历Set集合的方法
    分布式RPC框架Apache Dubbo
    CSS:页面美化和布局控制
    JavaScript实例
    Codeforces Round #604 题解
    洛谷P1533 可怜的狗狗题解
    Educational Codeforces Round 81 题解
    P1494 [国家集训队]小Z的袜子 题解
    洛谷P1283 平板涂色题解
    洛谷P1220 关路灯题解
  • 原文地址:https://www.cnblogs.com/1124li/p/13153370.html
Copyright © 2011-2022 走看看