• 【Mycat2实战】三、Mycat实现读写分离


    1. 无聊的理论知识

    image-20231114093853568

    什么是读写分离

    读写分离,基本的原理是让主数据库处理事务性增、改、删操作, 而从数据库处理查询操作。

    为什么使用读写分离

    从集中到分布,最基本的一个需求不是数据存储的瓶颈,而是在于计算的瓶颈,即 SQL 查询的瓶颈,我们知道,正常情况下,Insert SQL 就是几十个毫秒的时间内写入完成,而系 统中的大多数 Select SQL 则要几秒到几分钟才能有结果,很多复杂的 SQL,其消耗服器 CPU 的能力超强,不亚于死循环的威力。

    读写分离方案

    MyCat的读写分离是建立在MySQL主从复制基础之上实现的,所以必须先搭建MySQL的主从复制。数据库读写分离对于⼤型系统或者 访问量很⾼的互联网应用来说,是必不可少的⼀个重要功能。

    image-20231114094002230

    注意: Mycat实现的读写分离和自动切换机制,需要MySQL的主从复制机制配合。

    读写分离存在的问题

    主从数据延迟,导致业务数据无法保证强一致性

    Mysql 主从复制的常用拓扑结构

    一主一从 最基础的复制结构,用来分担之前单台数据库服务器的压力, 可以进行读写分离。

    一主多从 一台 Slave 承受不住读请求压力时,可以添加多台,进行负载均衡,分散读压力。

    双主复制 双主结构就是用来解决这个问题的,互相将对方作为自己的 Master,自己作为对方的 Slave 来进行复制,但对外来讲,还是一个主和一个从。

    级联复制 级联结构就是通过减少直接从属于 Master 的 Slave 数量,减轻 Master 的压力,分散复制请求,从而提高整体的复制效率。

    双主级联 Mysql 的复制结构有很多种方式,复制的最大问题是数据延时,选择复制结构时需要根据自己的具体情况,并评估好目标结构的延时对系统的影响。

    2. Mycat搭建读写分离

    本文以一主一从的读写分离方案搭建进行演示。

    mycat是直接接管我们的请求,然后分发到不同的数据库中,我们程序也是直接连接mycat,而不是数据库了。

    2.1 准备工作

    在配置之前,我们需要准备两个数据库,一主一从,并且已经完成了主从同步的配置,测试用的数据库、表确保都已经存在,同时创建好mycat要用的账户(主库、从库都需要配置)。

    Mysql主从同步同步搭建过程参考文章包教包会:Mysql主从复制搭建,这里就不再赘述了。

    因为已经主从同步,创建语句只需要在master库执行即可

    创建测试数据库语句:

    CREATE DATABASE IF NOT EXISTS `test-xxf`;
    
    • 1

    创建测试表语句,当然这里也可以不创建,利用Mycat也可以进行创建表的操作。

    CREATE TABLE `xxf_user` (
    	`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
    	`user_name` VARCHAR(30) NULL DEFAULT NULL COMMENT '用户姓名',
    	`email` VARCHAR(50) NULL DEFAULT NULL COMMENT '用户邮箱',
    	`phone` VARCHAR(11) NULL DEFAULT NULL COMMENT '手机号码',
    	`sex` CHAR(1) NULL DEFAULT NULL COMMENT '用户性别',
    	PRIMARY KEY (`id`) USING BTREE
    ) COMMENT='笑小枫-用户信息表' COLLATE='utf8_general_ci' ENGINE=InnoDB;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20231114100624317

    创建Mycat的账号,如果开启了全部操作的主从库同步,在主库创建则自动会同步到从库。

    CREATE USER 'mycat'@'%' IDENTIFIED BY '123456'; 
    -- 必须要有的权限 mysql8才有的
    GRANT XA_RECOVER_ADMIN ON *.* TO 'mycat'@'%';
    -- 权限根据需求来给,这里直接给的全部权限
    GRANT ALL PRIVILEGES ON *.* TO 'mycat'@'%' ;
    flush PRIVILEGES;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.2 Mycat配置

    Mycat安装部署一文中已经配置了prototypeDs.datasource.json的数据库连接。这里无需改动。

    {
            "dbType":"mysql",
            "idleTimeout":60000,
            "initSqls":[],
            "initSqlsGetConnection":true,
            "instanceType":"READ_WRITE",
            "maxCon":1000,
            "maxConnectTimeout":3000,
            "maxRetryCount":5,
            "minCon":1,
            "name":"prototypeDs",
            "password":"123456",
            "type":"JDBC",
            "url":"jdbc:mysql://localhost:3306/mysql?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
            "user":"mycat",
            "weight":0
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3.3 添加主数据源

    进入mycat目录下的conf/datasources目录,复制 prototypeDs.datasource.json 并将名称设为master.datasource.json

    cp prototypeDs.datasource.json master.datasource.json
    
    • 1

    操作完后,如下图所示:

    image-20231114103840720

    修改master.datasource.json

    vim master.datasource.json
    
    • 1

    主要修改数据源成jdbc:mysql://localhost:3306/test-xxf、name属性为master,如果用户名密码发生变化,则需要一并修改,然后保存退出。

    {
            "dbType":"mysql",
            "idleTimeout":60000,
            "initSqls":[],
            "initSqlsGetConnection":true,
            "instanceType":"READ_WRITE",
            "maxCon":1000,
            "maxConnectTimeout":3000,
            "maxRetryCount":5,
            "minCon":1,
            "name":"master",
            "password":"123456",
            "type":"JDBC",
            "url":"jdbc:mysql://localhost:3306/test-xxf?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
            "user":"mycat",
            "weight":0
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    如果有多个主节点就再配置一份叫mater02.datasource.json

    3.4 添加从数据源

    同主数据源配置一样,复制master.datasource.json设置为slave.datasource.json,然后进行编辑

    cp master.datasource.json slave.datasource.json
    
    vim slave.datasource.json
    
    • 1
    • 2
    • 3

    主要修改数据源成从库连接jdbc:mysql://localhost:3307/test-xxf、name属性为slave读写模式instanceType改成只读模式READ,如果用户名密码发生变化,则需要一并修改,然后保存退出。

    {
            "dbType":"mysql",
            "idleTimeout":60000,
            "initSqls":[],
            "initSqlsGetConnection":true,
            "instanceType":"READ",
            "maxCon":1000,
            "maxConnectTimeout":3000,
            "maxRetryCount":5,
            "minCon":1,
            "name":"slave",
            "password":"123456",
            "type":"JDBC",
            "url":"jdbc:mysql://localhost:3307/test-xxf?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
            "user":"mycat",
            "weight":0
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    如果有多个从节点就再配置一份叫slave02.datasource.json

    3.5 配置数据源集群

    由于配置读写分离涉及到多个数据库,所以就要配置数据源集群。
    cd conf/clusters

    cp prototype.cluster.json master-slave.cluster.json
    
    vim master-slave.cluster.json
    
    • 1
    • 2
    • 3

    主要配置主从数据源的名称,值就对应前边配置数据源(*.datasource.json)中所定义的值

    修改name为(*.cluster.json)中所定义的值

    {
        // 集群类型:SINGLE_NODE(单节点)、MASTER_SLAVE(普通主从)、GARELA_CLUSTER(garela cluster/PXC集群)等
        "clusterType":"MASTER_SLAVE",
        "heartbeat":{
            "heartbeatTimeout":1000,
            "maxRetry":3,
            "minSwitchTimeInterval":300,
            "slaveThreshold":0
        },
        "masters":[
            // 主节点数据源名称
            "master"
           // "master02"
        ],
        "replicas":[
            // 从节点数据源名称
            "slave"
           // "slave02"
        ],
        "maxCon":200,
        // 集群名称。在后面配置物理库(schema)时会用到
        "name":"master-slave",
        "readBalanceType":"BALANCE_ALL",
        // NOT_SWITCH(不进行主从切换)、SWITCH(进行主从切换)
        "switchType":"NOT_SWITCH"
    }
    
    • 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

    3.6 配置物理库 schemas和mycat数据源/集群的关联关系

    上边的集群和数据源都配置好了,那么就差跟mycat关联起来了,让mycat知道我们配置好的目标库应该指向哪个物理库,创建一个新的master_slave.schema.json文件。

    cd conf/schemas
    
    vim master_slave.schema.json
    
    • 1
    • 2
    • 3
    {
        // 物理库
        "schemaName": "test-xxf",
        // 指向集群,或者数据源
        "targetName": "master-slave",
        // 这里可以配置数据表相关的信息,在物理表已存在或需要启动时自动创建物理表时配置此项
        "normalTables": {}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    至此读写分离配置完成,下边开始测试。

    3. 测试Mycat读写分离

    在mycat上执行命令,可以查看到Mycat的数据源

    /*+ mycat:showDataSources{} */
    
    • 1

    image-20231114150717407

    连接mycat,在mycat里面执行sql。准备下面的sql语句,插入一条数据。

    INSERT INTO `xxf_user` VALUES (1, '张三', 'zhangsan@xiaoxiaofeng.com', '18300000000', '1');
    
    • 1

    然后可以在master和slave里面都看到了插入的数据。

    因为我们数据设置的是,主数据库向从数据库同步,所以写操作发生在master数据源,然后同步到slave数据库。

    image-20231114141050107

    执行查询语句,可以看到刚刚插入的数据。

    SELECT * FROM xxf_user;
    
    • 1

    image-20231114142355747

    为了更好的判断数据库读的是主库还是从库,我们手动修改从库的user_name为张三slave,修改从库数据,不会往主库同步,日常使用中不要修改从库数据,不然会导致数据不一致。

    image-20231114142740576

    可以看到,一会查询的是张三,一会是张三slave,证明两个库都会查询,权重的话,可以在datasources下的master和slave数据源文件下修改weight属性。

    image-20231114145745559

    4. 总结一下吧

    本文主要讲解了如何使用Mycat实现一主一从的读写分离。一主多从、双主复制、多主多从,文章也是简单的提了一下,小伙伴门感兴趣可以自己去尝试,就是配置多个主从的数据源。

    如果在搭建的过程中有任何疑问,可以评论区留言或者关注微信公众号留言,博主看到会及时的给予解答。

    5. 本系列文章

    本系列文章持续更新中,包括Mycat搭建,读写分离,分库分表等,敬请期待。

    后续更新完成统一维护链接,占个坑先…

  • 相关阅读:
    C++ Reference: Standard C++ Library reference: C Library: cwchar: putwchar
    Java的根类Object
    手动实现function isInstanceOf(child,Parent)
    uniapp 集成蓝牙打印功能(个人测试佳博打印机)
    爱编程 why not AI编程
    [MySQL]视图
    房产销售数据分析与可视化的设计与实现
    java--并发
    Python编程必备:掌握列表遍历的6种神级技巧!
    输入一个正整数并计算它在二进制下的1的个数
  • 原文地址:https://blog.csdn.net/qq_34988304/article/details/134425977