• mycat学习日记:全局sequence


      mycat分库分表的情况下,原生mysql的自增长主键无法满足主键全局唯一这个要求。看了MYCAT社区从零开始的一篇博客,加上自己的实践,大概总结一下。

      目前mycat对于全局sequence主要提供2种方法,本地文件方式和数据库方式。

     

      1.本地文件:

      本地文件的方式配置很简单,只需要修改2个文件即可。首先在conf下的servel.xml中添加:  

    <property name="sequnceHandlerType">0</property>
    

      然后再sequence_conf.properties中配置:

      TEST.HISIDS=
       TEST.MINID=1001
       TEST.MAXID=200000
       TEST.CURID=1000
    

      注:TEST为自定义的名称,建议根据各个表的表名进行命名,比如TEST就为tab_test表的主键seq。

      MINID为最小seq,MAXID为最大seq,CURID为目前seq的值。

      保存退出,通过 select next value for MYCAT_TEST即可测试是否成功。

      2.数据库方式:

       还是首先配置server.xml  

    <property name="sequnceHandlerType">1</property>
    

      然后选择一个数据库,我这里选择的是本机mysql中的db1,对应的dataNode是dn1。登陆mysql(非mycat),执行脚本:

      

    DROP TABLE IF EXISTS MYCAT_SEQUENCE;
    CREATE TABLE MYCAT_SEQUENCE ( name VARCHAR(50) NOT NULL, current_value INT NOT NULL, increment INT NOT NULL DEFAULT 100, PRIMARY KEY (name) ) ENGINE=InnoDB;
    -- ----------------------------
    -- Function structure for `mycat_seq_currval`
    -- ----------------------------
    DROP FUNCTION IF EXISTS `mycat_seq_currval`;
    DELIMITER ;;
    CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_currval`(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET latin1
    DETERMINISTIC
    BEGIN
    DECLARE retval VARCHAR(64);
    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 ;
    -- ----------------------------
    -- Function structure for `mycat_seq_nextval`
    -- ----------------------------
    DROP FUNCTION IF EXISTS `mycat_seq_nextval`;
    DELIMITER ;;
    CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET latin1
    DETERMINISTIC
    BEGIN
    UPDATE MYCAT_SEQUENCE
    SET current_value = current_value + increment WHERE name = seq_name;
    RETURN mycat_seq_currval(seq_name);
    END
    ;;
    DELIMITER ;
    -- ----------------------------
    -- Function structure for `mycat_seq_setval`
    -- ----------------------------
    DROP FUNCTION IF EXISTS `mycat_seq_setval`;
    DELIMITER ;;
    CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_setval`(seq_name VARCHAR(50), value INTEGER) RETURNS varchar(64) CHARSET latin1
    DETERMINISTIC
    BEGIN
    UPDATE MYCAT_SEQUENCE
    SET current_value = value
    WHERE name = seq_name;
    RETURN mycat_seq_currval(seq_name);
    END
    ;;
    DELIMITER ;
    INSERT INTO MYCAT_SEQUENCE VALUES ('GLOBAL', 0, 100);
    SELECT MYCAT_SEQ_SETVAL('GLOBAL', 1);
    SELECT MYCAT_SEQ_CURRVAL('GLOBAL');
    SELECT MYCAT_SEQ_NEXTVAL('GLOBAL'); 
    4.插入序列数据:
    INSERT INTO MYCAT_SEQUENCE VALUES ('GLOBAL', 0, 100); 
    INSERT INTO MYCAT_SEQUENCE VALUES ('GLOBAL', 0, 100); 
    

      这里我贴上博主从零开始的解释:

        

      说明:

      • 在某个分区(dataNode)数据库上创建序列号相关的表格和函数,SQL脚本在doc目录下的sequnce-sql.txt中,需要在数据库上而非Mycat上执行。
      • Mycat_home/conf/quence_db_conf.properties 中记录了sequnce所存放的db对应的配置信息。
      #sequence stored in datanode
      GLOBAL=dn1
      COMPANY=dn1
      CUSTOMER=dn1
      • 在sequnce表中,插入相应的sequnce记录,并确定其初始值,以及增长步长,步长建议一个合适的范围,比如50-500,需要在数据库上而非Mycat上执行。
      INSERT INTO MYCAT_SEQUENCE VALUES ('GLOBAL', 0, 100);
      • 修改sequnce的当前值为某个新值,需要在数据库上而非Mycat上执行。
      SELECT mycat_seq_curval('GLOBAL');

      提示:步长选择多大,取决与你数据插入的TPS,假如是每秒1000个,则步长为1000×60=6万,也不是很大,即60秒会重新从数据库读取下一批次的序列号值。

       最后,修改mycat配置文件sequence_db_conf.properties

        GLOBAL=dn1

        TEST=dn1

       通过 select next value for MYCATSEQ_GLOBAL可以进行测试。

        

  • 相关阅读:
    Jersey 2.x 运行项目
    Jersey 2.x 探索新建的工程
    Jersey 2.x 从Maven Archetype 创建一个新项目
    Jersey 2.x 服务器端应用支持的容器
    Jersey 2.x JDK 上的客户端应用
    Jersey 2.x 基于 Servlet 的服务器端应用
    =面试题:java面试基本方向 背1 有用 项目二技术学完再看
    面试题:项目开发经验总结 框架 比较难的问题 可以找一下有用
    面试题: !=!=未看
    面试题:大公司面试题 !=!=未看
  • 原文地址:https://www.cnblogs.com/toulon/p/4832611.html
Copyright © 2020-2023  润新知