-->

数据库水平切分(Mycat分片路由原理和全局序列号)

2020-02-28 15:44发布

 

分片路由原理

Select * from travelrecord where id in(5000001, 10000001);

dn1,dn2,dn3, id=5000001这条数据在dn2上,id=10000001这条数据在dn3上。

  1. 全部扫描一遍dn1  dn2  dn3,结果导致性能浪费。
  2. 扫描某个片。漏掉数据的情况。

总结:不能多扫===》性能不足,也不能少===》漏掉数据。

 

Mycat使用DruidParser作为分析器。

Visitor/Statement

    

Visitor过程,解析如下属性:

  1. 哪一张表
  2. 字段列表
  3. 条件信息
  4. 什么样的SQL

Statement过程

 

改写SQL:

   Dn2, id= 5000001

   Dn3, id= 100000001

Select * from travelrecord where id = 5000001;(dn2执行)

Select * from travelrecord where id = 10000001;(dn3执行)

 

查看mycal参数信息

9066端口连接后 show @@sysparam\G;  

可以看到 sequnceHandlerType全局序列号类型

mysql> show @@sysparam\G;
*************************** 1. row ***************************
 PARAM_NAME: processors
PARAM_VALUE: 2
PARAM_DESCR: 主要用于指定系统可用的线程数,默认值为Runtime.getRuntime().availableProcessors()方法返回的值。主要影响processorBufferPool、processorBufferLocalPercent、processorExecutor属性。NIOProcessor的个数也是由这个属性定义的,所以调优的时候可以适当的调高这个属性。
*************************** 2. row ***************************
 PARAM_NAME: processorBufferChunk
PARAM_VALUE: 4096B
PARAM_DESCR: 指定每次分配Socket Direct Buffer的大小,默认是4096个字节。这个属性也影响buffer pool的长度。
*************************** 3. row ***************************
 PARAM_NAME: processorBufferPool
PARAM_VALUE: 2097152B
PARAM_DESCR: 指定bufferPool计算 比例值。由于每次执行NIO读、写操作都需要使用到buffer,系统初始化的时候会建立一定长度的buffer池来加快读、写的效率,减少建立buffer的时间
*************************** 4. row ***************************
 PARAM_NAME: processorBufferLocalPercent
PARAM_VALUE: 100
PARAM_DESCR: 就是用来控制分配这个pool的大小用的,但其也并不是一个准确的值,也是一个比例值。这个属性默认值为100。线程缓存百分比 = bufferLocalPercent / processors属性。
*************************** 5. row ***************************
 PARAM_NAME: processorExecutor
PARAM_VALUE: 4
PARAM_DESCR: 主要用于指定NIOProcessor上共享的businessExecutor固定线程池大小。mycat在需要处理一些异步逻辑的时候会把任务提交到这个线程池中。新版本中这个连接池的使用频率不是很大了,可以设置一个较小的值。
*************************** 6. row ***************************
 PARAM_NAME: sequnceHandlerType
PARAM_VALUE: 本地文件方式
PARAM_DESCR: 指定使用Mycat全局序列的类型。
*************************** 7. row ***************************
 PARAM_NAME: Mysql_packetHeaderSize
PARAM_VALUE: 4B
PARAM_DESCR: 指定Mysql协议中的报文头长度。默认4
*************************** 8. row ***************************
 PARAM_NAME: Mysql_maxPacketSize
PARAM_VALUE: 16M
PARAM_DESCR: 指定Mysql协议可以携带的数据最大长度。默认16M
*************************** 9. row ***************************
 PARAM_NAME: Mysql_idleTimeout
PARAM_VALUE: 30分钟
PARAM_DESCR: 指定连接的空闲超时时间。某连接在发起空闲检查下,发现距离上次使用超过了空闲时间,那么这个连接会被回收,就是被直接的关闭掉。默认30分钟
*************************** 10. row ***************************
 PARAM_NAME: Mysql_charset
PARAM_VALUE: utf8
PARAM_DESCR: 连接的初始化字符集。默认为utf8
*************************** 11. row ***************************
 PARAM_NAME: Mysql_txIsolation
PARAM_VALUE: REPEATED_READ
PARAM_DESCR: 前端连接的初始化事务隔离级别,只在初始化的时候使用,后续会根据客户端传递过来的属性对后端数据库连接进行同步。默认为REPEATED_READ
*************************** 12. row ***************************
 PARAM_NAME: Mysql_sqlExecuteTimeout
PARAM_VALUE: 300秒
PARAM_DESCR: SQL执行超时的时间,Mycat会检查连接上最后一次执行SQL的时间,若超过这个时间则会直接关闭这连接。默认时间为300秒
*************************** 13. row ***************************
 PARAM_NAME: Mycat_processorCheckPeriod
PARAM_VALUE: 1秒
PARAM_DESCR: 清理NIOProcessor上前后端空闲、超时和关闭连接的间隔时间。默认是1秒
*************************** 14. row ***************************
 PARAM_NAME: Mycat_dataNodeIdleCheckPeriod
PARAM_VALUE: 300秒
PARAM_DESCR: 对后端连接进行空闲、超时检查的时间间隔,默认是300秒
*************************** 15. row ***************************
 PARAM_NAME: Mycat_dataNodeHeartbeatPeriod
PARAM_VALUE: 10秒
PARAM_DESCR: 对后端所有读、写库发起心跳的间隔时间,默认是10秒
*************************** 16. row ***************************
 PARAM_NAME: Mycat_bindIp
PARAM_VALUE: 0.0.0.0
PARAM_DESCR: mycat服务监听的IP地址,默认值为0.0.0.0
*************************** 17. row ***************************
 PARAM_NAME: Mycat_serverPort
PARAM_VALUE: 8066
PARAM_DESCR: mycat的使用端口,默认值为8066
*************************** 18. row ***************************
 PARAM_NAME: Mycat_managerPort
PARAM_VALUE: 9066
PARAM_DESCR: mycat的管理端口,默认值为9066

 

MyCat全局序列号

全局序列号策略选项设置

    0:本地文件方式

    1:数据库方式

    2:时间戳方式

    3:ZKID生成器

    4:ZK递增ID

开启全局序列号的配置在Server.xml中(2个必须步骤)

  1. sequnceHandlerType进行相应全局序列号策略选项设置
  2. autoIncrement 属性(schema.xml   table标签下的属性)

 

1.本地文件方式

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

使用到的配置文件:conf下的sequence_conf.properties

使用到的java类:io.mycat.route.sequence.handler.IncrSequenceHandler

 

缺点:当Mycat重新发布后,自增ID恢复到初始值。

例子:

mysql> insert into hotnews(id, title) values(next value for MYCATSEQ_GLOBAL, 'test');

2. 数据库方式

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

第一步:创建SEQUENCE表,用来存储序列号

mysql> create table MYCAT_SEQUENCE(
    name varchar(20) not null primary key,   /*全局SEQ名称*/
    current_value int not null,     /*当前序列ID*/
    Increment int not null,      /*初始序列ID*/
    remark varchar(50)
);
INSERT INTO MYCAT_SEQUENCE(NAME,current_value,increment) VALUES ('TABLE1', 100000, 100); 
mysql> create table TABLE (
    Id int not null primary key auto_increment,
    name varchar(20) ,
 );

第二步:创建SEQ function

-- 获取当前sequence的值(返回当前值,增量)
DROP FUNCTION IF EXISTS mycat_seq_currval; 
DELIMITER //
CREATE 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 ;

-- 设置sequence值
DROP FUNCTION IF EXISTS mycat_seq_setval; 
DELIMITER //
CREATE 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; 

-- 获取下一个sequence值
DROP FUNCTION IF EXISTS mycat_seq_nextval; 
DELIMITER //
CREATE 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;

 

第三步:在sequence_db_conf.properties

在这个文件中定义序列名称,同时可以定义到哪个分片上。

名字=分片1[,分片2][,.....][,分片N]

GLOBAL=dn1
COMPANY=dn1
CUSTOMER=dn1
ORDERS=dn1
TABLE1=dn1  #增加的

例子:

mysql> insert into hotnews(id, title) values(next value for MYCATSEQ_TABLE1, 'test11111');

  缺点:可能出现主键冲突。

 

3.本地时间戳方式

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

sequence_time_conf.properties

WORKID=01(范围01-31)

DATAACENTERID=01(范围01-31)

 

例子:

mysql> insert into hotnews(id, title) values(next value for MYCATSEQ_GLOBAL, 'test11111');

优点:不存在id重复的现象。

缺点:主键太长。

 

4.自增长主键

  1. 方式1:不同自增长初始值+步长
  2. 方式2:参考“数据库方式”

 

5.分布式ZK ID生成器

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

涉及到的配置文件:

    myid.properties

    loadZK=true|false //是否使用zk序列生成器

    zkURL=xxx.xxx.xxx.xxx:2182[,xxx.xxx.xxx.xxx:2182][,xxx.xxx.xxx.xxx:2182]

    clusterId=集群名称

 

sequence_distributed_conf.properties

    INSTANCEID=ZK  //改成“ZK”(默认是01)

    CLUSTERID=01   //编号

例子:

mysql> insert into hotnews(id, title) values(next value for MYCATSEQ_GLOBAL, 'test00000001');

 

6.ZK递增方式

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

涉及到的配置文件:

myid.properties 参考“分布式ZK ID生成器”中的介绍。

 

mysql> insert into hotnews(id, title) values(next value for MYCATSEQ_GLOBAL, 'test00000005');

标签: