zoukankan      html  css  js  c++  java
  • Mycat概述

    mycat 概述

     

    从开始接触mycat,到现在为止也有三个多月的时间了,目前在测试环境中已经初步应用!大概可以总结一下了

    mycat是一个数据库中间件,也可以理解为是数据库代理。在架构体系中是位于数据库和应用层之间的一个组件,并且对于应用层是透明的,即数据库感受不到mycat的存在,认为是直接连接的mysql数据库(实际上是连接的mycat,mycat实现了mysql的原生协议)

    mycat的三大功能:分表、读写分离、主从切换;mycat的主要功能也就是这三个了吧!??

    1、分表

      对于数据量很大的表(千万级以上),mysql性能会有很大下降,因此尽量控制在每张表的大小在百万级别。对于数据量很大的一张表,可以考虑将这些记录按照一定的规则放到不同的数据库里面。这样每个数据库的数据量不是太大,性能也不会有太大损失。

      mycat自动会帮助我们实现分表功能,而对于应用层来说是透明的,即跟一张表没有什么区别!

      mycat分表的实现:首先在mycat的scheme.xml中配置逻辑表,并且在配置中说明此表在哪几个物理库上。此逻辑表的名字与真实数据库中的名字一致!然后需要配置分片规则,即按照什么逻辑分库!分片规则有很多,选取以下几个简单说明:

      1、根据数据库某字段的hash值片

      2、截取某字段的几位数字,匹配分区号

      3、按照时间(年份分表)

      4、……

      分表的原则是尽量避免跨库操作操作,跨库操作会损失很多性能,mycat会对各个库的结果集进行合并,另外就是要考虑扩展之后,尽量使最少量的数据迁移。

      分表规则很多,很灵活,并且在源码基础上修改分片规则也很容易!

      分表之后有什么弊端呢?

      使用存储过程/函数就不太方便了,mycat本身不支持存储过程,是通过注解的方式实现存储过程的调用。并且在所有库上都执行,将执行结果合并,并返回(mysql存储过程返回结果最好使用select方式返回)。

      分表之后还有一个问题,就是自增ID的问题,在分库场景下,如果使用mysql的自增主键,会导致各个库中主键之间有重复。mycat使用内部的全局序列号解决这个问题;即插入数据的时候,mycat会自动的显示的插入自增主键,使用的是全局序列号;

      需要在配置逻辑表的时候,配置上自增字段,自增属性=true 这两个属性;

     <table name="fh_fullnote" primaryKey="FH_FULLNOTE_ID" autoIncrement="true" dataNode="dn1,dn2,dn3" rule="sharding-by-substring" />

      那么全局序列号存储在什么地方呢?mycat是怎么去取的呢?

      全局序列号有两种存储方式:基于本地文件和基于数据库的存储;

      我们是采用基于数据库的存储方式,需要在数据库中建立 mycat_sequence表

    复制代码
    Create Table: CREATE TABLE `mycat_sequence` (
      `name` varchar(50) NOT NULL,
      `current_value` int(11) NOT NULL,
      `increment` int(11) NOT NULL DEFAULT '100',
      PRIMARY KEY (`name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    复制代码

      全局序列号就是存储在这个表中;第一个是全局序列号的名,第二个是当前值,第三个是增量;即每次mycat会取出一批序列号(增量就是作用与此),用完之后再取;如果每次都取,在效率上会有损失。

      mycat取全局序列号是通过函数来取的,因此需要在数据库上增加如下三个函数:

    复制代码
    ⑤    /******************************获取函数当前值***********************************/
    
    DELIMITER $$
    
    USE `mycat1`$$
    
    DROP FUNCTION IF EXISTS `mycat_seq_currval`$$
    
    CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_currval`(seq_name VARCHAR(50)) RETURNS VARCHAR(64) CHARSET utf8
        DETERMINISTIC
    BEGIN
        DECLARE retval VARCHAR(64);
        SET retval="-999999999,null";
            SET retval="-999999999,null";
            SELECT CONCAT(CAST(current_value AS CHAR),",",CAST(increment AS CHAR)) INTO retval FROM MYCAT_SEQUENCE
            WHERE NAME = seq_name;
        RETURN retval;
        END$$
    
    DELIMITER ;
    /*******************************获取下一批值***************************************/
    DELIMITER $$
    
    USE `mycat1`$$
    
    DROP FUNCTION IF EXISTS `mycat_seq_nextval`$$
    
    CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(50)) RETURNS VARCHAR(64) CHARSET utf8
    BEGIN
        UPDATE MYCAT_SEQUENCE
        SET current_value = current_value + increment WHERE NAME = seq_name;
        RETURN mycat_seq_currval(seq_name);
        END$$
    
    DELIMITER ;
    
    /*******************************设定值***************************************/
    DELIMITER $$
    
    USE `mycat1`$$
    
    DROP FUNCTION IF EXISTS `mycat_seq_setval`$$
    
    CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_setval`(seq_name VARCHAR(50),VALUE INTEGER) RETURNS VARCHAR(64) CHARSET utf8
    BEGIN
        UPDATE MYCAT_SEQUENCE
        SET current_value = VALUE
        WHERE NAME = seq_name;
        RETURN mycat_seq_currval(seq_name);
        END$$
    
    DELIMITER ;
    复制代码

      一般来说,每一个表应该对应一个全局序列号;

      此对应关系在sequence_db_conf.properties配置;

      表名 = 全局序列号数据库(dn1)

      2、读写分离

      经过统计发现,对数据库的大量操作是读操作,一般占到所有操作70%以上。所以做读写分离还是很有必要的,如果不做读写分离,那么从库也是一种很大的浪费。

      mycat的读写分离也是在scheme.xml里面配置的。配置方式如下:

    <writeHost host="hostM1" url="192.168.91.231:3306" user="root" password="123456">
          <!-- can have multi read hosts -->
          <readHost host="hostS2" url="192.168.91.232:3306" user="root" password="123456" />
    </writeHost>

      值得注意的是,读库是附属于写库的,如果写库挂掉之后,读库也就不能使用了。

      读写分离一般涉及到两个问题:一个是读操作的均衡,是全部走读库?还是部分走读库,部分读写库?    另一个问题,如果同步不及时或者同步出错,或者实时性要求较高,这种场景下,如何强制走写库?

      首先来看第一个问题,读写均衡问题:

      scheme.xml配置文件  dataHost标签中有一个balance属性,该属性的不同值表示不同的含义:

  • 相关阅读:
    CentOS7 FTP安装与配置
    EF CodeFirst 数据库的操作
    CentOS7 防火墙(firewall)的操作命令
    小程序学习(四)小程序逻辑层之注册页面
    小程序学习(三)小程序逻辑层的注册程序和场景值
    小程序学习(二)基本结构与文件的类型
    VS2015 无法启动IIS Express Web服务器(已解决)
    django 2.接口之工作原理
    django 1.开发接口环境搭建
    pytest 15 fixture之autouse=True
  • 原文地址:https://www.cnblogs.com/A121/p/9126253.html
Copyright © 2011-2022 走看看