zoukankan      html  css  js  c++  java
  • Mycat(水平拆分--分表 全局序列)

    在实现分库分表的情况下,数据库自增主键已经无法保证自增主键的全局唯一。为此Mycat提供了全局sequence,并且提供了包含本地配置和数据库配置等多种实现方式。

    1、本地文件

    此方式 mycat 将sequence 配置到文件中,当使用到 sequence 中的配置后, Mycat 会更下 classpath 中的 sequence_conf.properties 文件中的sequence当前的值。

    • 优点:本地加载,读取速度较快

    • 缺点:抗风险能力差, Mycat所在宿主机宕机后,无法读取本地文件。

    2.数据库方式

    原理:在数据库中建立一张表(表名MYCAT_SEQUENCE),存放 sequence 名称(name),sequence 当前值(current_value),步长(increment,每次读取多少个 sequence)等信息;

    Sequence 获取步骤:

    • 当初次使用该 sequence 时,根据传入的 sequence 名称,从数据库这张表中读取 current_value,和increment (得到一个sequence号段)到 MyCat 中,并将数据库中的这张表的 current_value 设置为原 current_value 值+increment 值;

    • Mycat 将读取到 current_value+1 作为每次插入数据要使用的 sequence 值,当使用 increment 次后,执行上面步骤相同的操作;

    • 若Mycat某次读取的sequence号段还有一串值没有用完,系统就停掉了,则这次读取的 sequence 号段的剩余值不会再使用,没了就没了,只需保证每次插入数据的sequence值是唯一的;

    切换到dn1数据库

    创建表:

    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;

    为MYCAT_SEQUENCE表插入数据(序列名 起始值 步长):

    INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES (‘GLOBAL’, 100000,100); 

    创建相应的函数一:传入序列名,获取当前sequence的值

    DELIMITER $$
    CREATE FUNCTION mycat_seq_currval(SEQ_NAME VARCHAR(50)) RETURNS VARCHAR(64) CHARSET utf8
    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 ;

    创建相应的函数二:给指定sequence设定当前值(指定具体value)

    DELIMITER $$
    CREATE FUNCTION mycat_seq_setval(SEQ_NAME VARCHAR(50),VALUE INTEGER) RETURNS        VARCHAR(64) CHARSET UTF8
    DETERMINISTIC
    BEGIN
    UPDATE MYCAT_SEQUENCE
    SET CURRENT_VALUE = VALUE
    WHERE NAME = SEQ_NAME;
    RETURN MYCAT_SEQ_CURRVAL(SEQ_NAME);
    END$$
    DELIMITER ;

    创建相应的函数三:给指定sequence设定当前值(当前值=原当前值+步长)

    DELIMITER $$
    CREATE FUNCTION mycat_seq_nextval(SEQ_NAME VARCHAR(50)) RETURNS VARCHAR(64)  CHARSET UTF8
    DETERMINISTIC
    BEGIN
    UPDATE MYCAT_SEQUENCE
    SET CURRENT_VALUE = CURRENT_VALUE + INCREMENT WHERE NAME = SEQ_NAME;
    RETURN MYCAT_SEQ_CURRVAL(SEQ_NAME);
    END$$
    DELIMITER ;

    配置Mycat的/conf/sequence_db_conf.properties(指明所用的序列名,以及MYCAT_SEQUENCE表在哪个分片节点上)

    GLOBAL=dn1

    配置Mycat的/conf/server.xml,表示所用的全局序列方式为数据库方式

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

    重启Mycat

    INSERT INTO orders(id,amount,customer_id,order_type) VALUES(next value for MYCATSEQ_GLOBAL,1000,101,102);

    此时在Mycat里select一下数据,可以看到插入的数据记录已经自动获取主键值

    3.时间戳方式

    全局序列 ID = 64 位 二进制 42(毫秒 )+ 5(机器 ID)+5(业务编码) + 12(重复累加)换算成十进制为 18 位数的 long 类型,每毫秒可以并发 12 位二进制的累加。

    • 优点:配置简单

    • 缺点:18位ID过长

       注:后续补上

    4.自主生成全局序列

    可以在java项目里自己生成全局序列,

    • 根据业务逻辑组合

    • 可以利用redis的单线程原子性 incr 来生成序列

      但,自主生成需要单独在工程中用java代码实现,还是推荐使用Mycat 自带全局序列

  • 相关阅读:
    HDU 1160 FatMouse's Speed ——(DP)
    HDU 1114 Piggy-Bank ——(完全背包)
    poj 1458 Common Subsequence ——(LCS)
    HDU 1087 Super Jumping! Jumping! Jumping! ——(LIS变形)
    HDU 1257 最少拦截系统 ——(LIS)
    strrchr函数
    常用位操作
    Map中放置类指针并实现调用
    log4net 一分钟上手
    简单易懂的冒泡排序
  • 原文地址:https://www.cnblogs.com/chenjiahao9527/p/14210565.html
Copyright © 2011-2022 走看看