海量数据存储解决方案之分库分表原理解析及mycat安装及使用_踩踩踩从踩的博客-CSDN博客
前言
上篇文章主要对海量数据的分片进行介绍,并且包括mycat的安装和简单使用,做了一个简单的配置,也对分片中会出现的问题做分析;这篇文章会接着继续进行分析数据库中间件中重要的mycat,在使用上有一些高级特性及核心概念、分片解决的办法做了哪些优化和处理大的介绍
核心概念理解和工作原理
mycat的版本迭代
- Mycat-mini-monitor项目开源了,又一款Mycat监控!
- Mycat-mini-monitor-1.0.0 版本发布
- Mycat-server-1.6.6-release 版本发布
- Mycat-server-1.6.6-test 版本发布
- Mycat-server-1.6-release 版本发布
- Mycat-server-1.5-release 版本发布
- Mycat-server-1.4-release 版本发布
- Mycat-server-1.3-release 版本发布
- Mycat-web(eye) 版本发布
Mycat工作原理
- 将订单表 orders 数据按省份分片;
- 应用连接mycat,提交SQL;
- Mycat ‚拦截‛
Mycat 的原理
: ‚拦截‛,它拦截了用户发送过来的SQL 语句,首先解析SQL 语句,做一
些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL 发往
后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户;
架构
连接mycat 利用mysql的连接包,基于mysql协议包,sql执行组件。 对于mysql 不适用jdbc进行连接,如果其他的数据库,使用的jdbc的数据库,并发能力也好,还是其他的特殊的支持等都不是很好。
核心概念
数据库中间件
:对应用,mycat就是数据库服务,mycat是后端数据库集群的代理
应用层访问数据库,依次会找到下面的 对应的配置
- 逻辑库:mycat数据库服务中定义、管理的数据库
- 逻辑表:逻辑库中包含的需分库分表存储的表
- dataNode:数据节点(分片节点),逻辑表分片的存放节点。这里的datanode 对应的数据节点。
- dataHost: 数据主机(节点主机),数据节点所在的主机。
- writeHost:写主机,真实的数据库服务主机描述
- readHost:读主机,真实的数据库服务主机描述
schema配置-schema
逻辑库 schema
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
</schema>
</mycat:schema>
MyCat 可以有多个逻辑库,每个逻辑库都有自己的相关配置。
如果不配置schema 标签,所有的表配置,会属于同一个默认的逻辑库。
schema元素属性说明
checkSQLschema 需要设置为true ,当库名与逻辑库名相同时,会去掉语句中的库名前缀。
这个在实际应用中一般都加上的。
schema配置-table
逻辑表 table
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
<table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2" />
<table name="customer" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile">
<childTable name="orders" primaryKey="ID" joinKey="customer_id" parentKey="id">
<childTable name="order_items" joinKey="order_id" parentKey="id" />
</childTable>
</table>
</schema>
Table标签定义了MyCat中的逻辑表,所有需要拆分的表都需要通过这个标签定义。、
table元素属性说明
这其中,
- name :表名,同个schema 标签中定义的名字必须唯一,存放表数据的数据节点名。
- dataNode
很多难以罗列时,可以这样配置:dataNode=‚multipleDn$0-99,multipleDn2$100-
199‛,$0-99表示0-99
<dataNode name="multipleDn$0-99" dataHost="localhost1" database="db$0-99"
></dataNode>
- primaryKey 用来做缓存的。
schema配置-childTable标签
<table name="customer" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile">
<childTable name="orders" primaryKey="ID" joinKey="customer_id" parentKey="id">
<childTable name="order_items" joinKey="order_id" parentKey="id" />
</childTable>
</table>
childTable 标签用于定义E-R 分片的子表,通过标签上的属性与父表进行关联。
两张表有关联关系,定义出父子关系。防止分片过后,join的问题。
schema配置-dataHost
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="localhost:3306" user="root" password="123456">
<!-- can have multi read hosts -->
<readHost host="hostS2" url="192.168.1.200:3306" user="root" password="xxx" />
</writeHost>
</dataHost>
dataHost定义Mycat中的数据主机,数据主机定义中定义了具体的数据库服务、读写分离配置
和心跳语句。这是与物理数据库服务关联的地方。
真正关联的地方
这些对应不配置都有默认的。
schema配置-heartbeat
<heartbeat>select user()</heartbeat>
- 这个标签内指明用于和后端数据库进行心跳检查的语句 如:MYSQL 可以使用select user(),Oracle 可以使用select 1 from dual 等。
- 这个标签还有一个connectionInitSql 属性,主要是当使用Oracle数据库时,需要执行的初始化SQL 语句就放到这里。 如:alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'
- 主从切换的语句必须是:show slave status
schema配置-writeHost readHost
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="localhost:3306" user="root" password="123456">
<!-- can have multi read hosts -->
<readHost host="hostS2" url="192.168.1.200:3306" user="root" password="xxx" />
</writeHost>
这两个标签都指定后端数据库的相关配置给mycat,用于实例化后端连接池。writeHost 指定写实例、readHost 指定读实例。
在一个dataHost 内可以定义多个writeHost 和readHost。但是,如果writeHost 指定的后端数据库宕机,那么这个writeHost 绑定的所有readHost 都将不可用。另一方面,由于这个writeHost 宕机系统会自动的检测到,并切换到备用的writeHost 上去。
加密密码,执行mycat jar 程序(1.4.1 以后)
java -cp Mycat-server-1.4.1-dev.jar io.mycat.util.DecryptUtil 1:host:user:passwordMycat-server-1.4.1-dev.jar 为mycat download 下载目录的jar1:host:user:password 中1 为db 端加密标志,host 为dataHost 的host 名称
Mycat如何解决分库分表带来的挑战
解决原则
第一原则:能不切分尽量不要切分
第二原则:如果要切分一定要选择合适的切分规则,提前规划好。
第三原则:数据切分尽量通过数据冗余或表分组(Table Group)来降低跨库Join 的可能。
第四原则:由于数据库中间件对数据Join实现的优劣难以把握,而且实现高性能难度极大,
业务读取尽量少使用多表Join。
Mycat中表分类
分片表
分片表,是指那些有很大数据,需要切分到多个数据库的表,这样每个分片都有一部分
数据,所有分片构成了完整的数据。
<table name="t_goods" primaryKey="vid" autoIncrement="true" dataNode="dn1,dn2" rule="rule1" />
非分片表
一个数据库中并不是所有的表都很大,某些表是可以不用进行切分的,非分片是相对分
片表来说的,就是那些不需要进行数据切分的表。
<table name="t_node" primaryKey="vid" autoIncrement="true" dataNode="dn1" />
ER表
Mycat 中的ER 表是基于E-R 关系的数据分片策略,子表的记录与所关联的父表记录存放
在同一个数据分片上,保证数据Join 不会跨库操作。
ER分片是解决跨分片数据join 的一种很好的思路,也是数据切分规划的一条重要规则。
做一个关联起来, 规则是一样的就可以,将数据进行分割开
<table name="customer" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile">
<childTable name="orders" primaryKey="ID" joinKey="customer_id" parentKey="id">
<childTable name="order_items" joinKey="order_id" parentKey="id" />
</childTable>
</table>
全局表
一个真实的业务系统中,往往存在大量的类似字典表的表,数据量不大,这些表基本上很少变动。
问题:
业务表往往需要和字典表Join查询,当业务表因为规模而进行分片以后,业务表与字典表之
间的关联跨库了。
解决
:Mycat中通过表冗余来解决这类表的join,即它的定义中指定的dataNode上都有一份该表的
拷贝。(将字典表或者符合字典表特性的表定义为全局表。 )
<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
也是解决效率慢,一定要数据量小,不然会导致占用空间大。
分片规则
在conf/rule.xml中定义分片规则
tableRule
标签说明:
- name 属性指定唯一的名字,用于标识不同的表规则。
- 内嵌的rule 标签则指定对物理表中的哪一列进行拆分和使用什么路由算法。
function
标签说明:
- name 指定算法的名字。
- class 制定路由算法具体的类名字。
- property 为具体算法需要用到的一些属性。
Mycat内置的常用分片规则
分片枚举(列表分片)
通过在配置文件中配置可能的枚举
id
,自己配置分片,本规则适用于特定的场景,比如有些业务需要按照省份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则,配置如下:
function
分片函数中配置说明:
- 算法实现类为:io.mycat.route.function.PartitionByFileMap
- mapFile 标识配置文件名称;
- type 默认值为0,0 表示Integer,非零表示String;
- defaultNode defaultNode 默认节点:小于0 表示不设置默认节点,大于等于0 表示设置默认节点为第几个数 据节点。
- 默认节点的作用:枚举分片时,如果碰到不识别的枚举值,就让它路由到默认节点 如果不配置默认节点 (defaultNode 值小于0 表示不配置默认节点),碰到不识别的枚举值就会报错。
like this:can’t find datanode for sharding column:column_name val:ffffffff
- sharding-by-enum.txt 放置在conf/下,配置内容示例:
10000=0 # 字段值为 10000 的放到 0 号数据节点10010=1
范围分片
此分片适用于,提前规划好分片字段某个范围属于哪个分片
配置说明:
- mapFile 代表配置文件路径
- defaultNode 超过范围后的默认节点。
所有的节点配置都是从
0
开始,及
0
代表节点
1
。
mapFile
中的定义规则:
非
start <= range <= end.
range start-end=data node index
K=1000,M=10000.
配置示例:
0-500M=0
500M-1000M=1
1000M-1500M=2
按日期范围分片
此规则为按日期段进行分片。
配置说明:
- columns :标识将要分片的表字段
- algorithm :分片函数
- dateFormat :日期格式
- sBeginDate :开始日期
- sEndDate:结束日期
- sPartionDay :分区天数,即默认从开始日期算起,分隔10 天一个分区
sBeginDate,sEndDate
配置情况说明:
- sBeginDate,sEndDate 都有指定 此时表的dataNode 数量的>=这个时间段算出的分片数,否则启动时会异常:
如果配置了
sEndDate
则代表数据达到了这个日期的分片后循环从开始分片插入。
- 没有指定 sEndDate 的情况 数据分片将依次存储到dataNode上,数据分片随时间增长,所需的dataNode数也随之增长,当超出了为该表配置的dataNode数时,将得到如下异常信息:
自然月分片
按月份列分区,每个自然月一个分片。
<tableRule name="sharding-by-month">
<rule>
<columns>create_time</columns>
<algorithm>sharding-by-month</algorithm>
</rule>
</tableRule>
<function name="sharding-by-month" class="io.mycat.route.function.PartitionByMonth">
<property name="dateFormat">yyyy-MM-dd</property>
<property name="sBeginDate">2014-01-01</property>
</function>
配置说明:
- columns: 分片字段,字符串类型
- dateFormat : 日期字符串格式,默认为yyyy-MM-dd
- sBeginDate : 开始日期,无默认值
- sEndDate:结束日期,无默认值
- 节点从0 开始分片
使用场景:
场景
1
:默认设置(不指定
sBeginDate
、
sEndDate
)
节点数量必须是12 个,对应1 月~12 月
- "2017-01-01" = 节点0
- "2018-01-01" = 节点0
- "2018-05-01" = 节点4
- "2019-12-01" = 节点11
场景
2
:仅指定
sBeginDate
- sBeginDate = "2017-01-01" 该配置表示"2017-01 月"是第0 个节点,从该时间按月递增,无最大节点
- "2014-01-01" = 未找到节点
- "2017-01-01" = 节点0
- "2017-12-01" = 节点11
- "2018-01-01" = 节点12
- "2018-12-01" = 节点23
场景
3
:
指定
sBeginDate=1
月、
sEndDate=12
月
- sBeginDate = "2015-01-01" sEndDate = "2015-12-01" 该配置可看成与场景1 一致。
- "2014-01-01" = 节点0
- "2014-02-01" = 节点1
- "2015-02-01" = 节点1
- "2017-01-01" = 节点0
- "2017-12-01" = 节点11
- "2018-12-01" = 节点11
场景
4
:
sBeginDate = "2015-01-01"sEndDate = "2015-03-01"
该配置表示只有
3
个节点;很难与月份对应上;平均分散到3 个节点上
取模
此规则为对分片字段进行十进制运算,来分片数据。
<tableRule name="mod-sharding">
<rule>
<columns>user_id</columns>
<algorithm>mod-fun</algorithm>
</rule>
</tableRule>
<function name="mod-fun" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">3</property>
</function>
配置说明:
count
指明
dataNode
的数量,是求模的基数
此种在批量插入时可能存在批量插入单事务插入多数据分片,增大事务一致性难度。
取模范围分片
此种规则是取模运算与范围约束的结合,主要为了后续数据迁移做准备,即可以自主决定取模后数据的节点 分布。
<tableRule name="sharding-by-pattern">
<rule>
<columns>user_id</columns>
<algorithm>sharding-by-pattern</algorithm>
</rule>
</tableRule>
<function name="sharding-by-pattern" class="io.mycat.route.function.PartitionByPattern">
<property name="patternValue">256</property>
<property name="defaultNode">2</property>
<property name="mapFile">partition-pattern.txt</property>
</function>
partition-pattern.txt
1-32=0 #余数为1-32的放到数据节点0上
33-64=1
65-96=2
97-128=3
129-160=4
161-192=5
193-224=6
225-256=7
0-0=7
配置说明:
- patternValue 即求模基数
- defaoultNode 默认节点,如果配置了默认节点,如果id 非数据,则会分配在defaoultNode 默认节点
- mapFile 指定余数范围分片配置文件
二进制取模范围分片
本条规则类似于十进制的求模范围分片,区别在于是二进制的操作
,
是分片列值的二进制低
10
位
&1111111111
。 此算法的优点在于如果按照10
进制取模运算,在连续插入
1-10
时候
1-10
会被分到
1-10
个分片,增大了插入的事务控制难度,而此算法根据二进制则可能会分到连续的分片,减少插入事务控制难度。
二进制低
10&1111111111
的结果是
0-1023
一共是
1024
个值,按范围分成多个连续的片(最大
1024
个片)
<tableRule name="rule1">
<rule>
<columns>user_id</columns>
<algorithm>func1</algorithm>
</rule>
</tableRule>
<function name="func1" class="io.mycat.route.function.PartitionByLong">
<property name="partitionCount">2,1</property>
<property name="partitionLength">256,512</property>
</function>
配置说明:
- partitionCount 分片个数列表。
- partitionLength 分片范围列表
分区长度
:
默认为最大
2^n=1024 ,
即最大支持
1024
分区
约束
:
- count,length 两个数组的长度必须是一致的。
- 1024 = sum((count[i] * length[i])),count 和length 两个向量的点积恒等于1024
范围取模分片
先进行范围分片计算出分片组,组内再求模。 优点可以避免扩容时的数据迁移,又可以一定程度上避免范围分片的热点问题。综合了范围分片和求模分片的优点,分片组内使用求模可以保证组内数据比较均匀,分片组之间是范围分片可以兼顾范围查询。
最好事先规划好分片的数量,数据扩容时按分片组扩容,则原有分片组的数据不需要迁移。由于分片组内数据比 较均匀,所以分片组内可以避免热点数据问题
配置说明:
- mapFile 配置文件路径
- defaultNode 超过范围后的默认节点顺序号,节点从0 开始。
- partition-range-mod.txt 以下配置一个范围代表一个分片组,=号后面的数字代表该分片组所拥有的分片的数量。
一致性hash
一致性
hash
算法有效解决了分布式数据的扩容问题。
<tableRule name="sharding-by-murmur">
<rule>
<columns>user_id</columns>
<algorithm>murmur</algorithm>
</rule>
</tableRule>
<function name="murmur" class="io.mycat.route.function.PartitionByMurmurHash">
<!-- 默认是0-->
<property name="seed">0</property>
<!-- 要分片的数据库节点数量,必须指定,否则没法分片-->
<property name="count">2</property>
<!-- 一个实际的数据库节点被映射为多少个虚拟节点,默认是160 -->
<property name="virtualBucketTimes">160</property>
<!-- <property name="weightMapFile">weightMapFile</property>
节点的权重,没有指定权重的节点默认是1。以properties 文件的格式填写,以从0 开始到count-1 的整数值也 就是节点索引为key,以节点权重值为值。所有权重值必须是正整数,否则以1 代替-->
<!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property> 用于测试时观察各物理节点与虚拟节点的分布情况,如果指定了这个属性,会把虚拟节点的murmur hash 值与物理 节点的映射按行输出到这个文件,没有默认值,如果不指定,就不会输出任何东西-->
</function>
应用指定
此规则是在运行阶段有应用自主决定路由到那个分片。
配置说明:
此方法为直接根据字符子串(必须是数字)计算分区号(由应用传递参数,显式指定分区号)。 例如
id=05- 100000002 在此配置中代表根据
id
中从
startIndex=0
,开始,截取
siz=2
位数字即
05
,
05
就是获取的分区,如果没传 默认分配到defaultPartition
截取字符ASCII求和求模范围分片
此种规则类似于取模范围约束,只是计算的数值是取前几个字符的
ASCII
值和,再取模,再对余数范围分片。
partition-pattern.tx
range start-end =data node index
配置说明:
- patternValue 即求模基数,
- prefifixLength ASCII 截取的位数,求这几位字符的ASCII码值的和,再求余patternValue
- mapFile 配置文件路径,配置文件中配置余数范围分片规则。
主键值生成
在实现分库分表的情况下,数据库自增主键已无法保证自增主键的全局唯一。
为此,MyCat 提供了全局sequence,并且提供了包含本地配置和数据库配置等多种实现方式。
本地文件方式
原理:此方式
MyCAT
将
sequence
配置到文件中,当使用到
sequence
中的配置后,
MyCAT
会更新
conf
中的sequence_conf.properties 文件中
sequence
当前的值。
配置方式:
1
、在
sequence_conf.properties
文件中做如下配置:
GLOBAL.HISIDS=
GLOBAL.MINID=1001
GLOBAL.MAXID=1000000000
GLOBAL.CURID=1000
其中
HISIDS
表示使用过的历史分段
(
一般无特殊需要可不配置
)
,
MINID
表示最小
ID
值,
MAXID
表示最大
ID
值,
CURID
表示当前
ID
值。
2
、
server.xml
中配置:
<system><property name="sequnceHandlerType">0</property></system>
注:
sequnceHandlerType
需要配置为
0
,表示使用本地文件方式。
使用示例:
insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,‘test’);
缺点:当
MyCAT
重新发布后,配置文件中的
sequence
会恢复到初始值。 优点:本地加载,读取速度较快。
为表配置主键自增值的序列:
规则:在
sequence_conf.properties
中配置以表名为名的序列
T_COMPANY.CURID=501
T_COMPANY.MINID=1
T_COMPANY.MAXID=1000000000
就可以使用了。
<table name="t_company" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2,dn3" rule="range-sharding-by-members-count" />
数据库方式
在数据库中建立一张表,存放
sequence
名称
(name)
,
sequence
当前值
(current_value)
,步长
(increment int
类型,每次读取多少个sequence)
等信息;
Sequence
获取步骤:
- 1. 当初次使用该sequence 时,根据传入的sequence 名称,从数据库这张表中读取current_value,和 increment 到MyCat 中,并将数据库中的current_value 设置为原current_value 值+increment 值。
- 2. MyCat 将读取到current_value+increment 作为本次要使用的sequence 值,下次使用时,自动加1,当使用increment 次后,执行步骤1)相同的操作。
MyCat
负责维护这张表,用到哪些
sequence
,只需要在这张表中插入一条记录即可。若某次读取的
sequence
没有用完,系统就停掉了,则这次读取的sequence
剩余值不会再使用。
配置方式:
server.xml
配置:
<system><property name="sequnceHandlerType">1</property></system>
注:
sequnceHandlerType
需要配置为
1
,表示使用数据库方式生成
sequence
。
- 创建MYCAT_SEQUENCE 表
- 创建相关function
注意:
MYCAT_SEQUENCE
表和以上的
3
个
function
,需要放在同一个节点上。
function
请直接在具体节点的数据库上执行,如果执行的时候报:
you might want to use the less safe log_bin_trust_function_creators variable
需要对数据库做如下设置:
windows
下
my.ini[mysqld]
加上
log_bin_trust_function_creators=1 linux 下/etc/my.cnf
下
my.ini[mysqld]
加上
log_bin_trust_function_creators=1
修改完后,即可在
mysql
数据库中执行
上面的函数。
- sequence_db_conf.properties 相关配置,指定sequence 相关配置在哪个节点上:
例如:
USER_SEQ=test_dn1
使用示例:
insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,'test');
配置表的主键自增使用序列:
在序列定义表中增加名字为表名的序列:
INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('T_COMPANY', 1,100);
在
sequence_db_conf.properties
中增加表的序列配置
T_COMPANY=dn1
主键自增就可以使用了
<table name="t_company" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2,dn3" rule="range-sharding-by-members-count" />
本地时间戳方式
原理:
ID= 64
位二进制:
42(
毫秒
)+5(
机器
ID)+5(
业务编码
)+12(
重复累加
)
换算成十进制为
18
位数的
long
类型,每毫秒可以并发
12
位二进制的累加。
使用方式:
- 配置server.xml
<property name="sequnceHandlerType">2</property>
- 在mycat 下配置:sequence_time_conf.properties
WORKID=0-31 任意整数 表示机器id(或mycat实例id)
DATAACENTERID=0-31 任意整数 业务编码
多个
mycat
节点下每个
mycat
配置的
WORKID
,
DATAACENTERID
不同,组成唯一标识,总共支持
32*32=1024
种组合。
ID
示例:
56763083475511
。
主键自增配置
<table name="t_company" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2,dn3" rule="range-sharding-by-members-count" />
分布式ZK ID 生成器
<property name="sequnceHandlerType">3</property>
配置
1 Zk
的连接信息统一在
myid.properties
的
zkURL
属性中配置。
此只需关注
zkURL
。
基于
ZK
与本地配置的分布式
ID
生成器,
ID
结构:
long 64
位,
ID
最大可占
63
位:
- |current time millis(微秒时间戳38 位,可以使用17 年)|clusterId(机房或者ZKid,通过配置文件配置5位)|instanceId(实例ID,可以通过ZK 或者配置文件获取,5 位)|threadId(线程ID,9 位) |increment(自增,6 位)
- 一共63 位,可以承受单机房单机器单线程1000*(2^6)=640000 的并发。
- 无悲观锁,无强竞争,吞吐量更高
2
配置文件:
sequence_distributed_conf.properties
,只要配置里面:
INSTANCEID=ZK
就是从
ZK
上获取 InstanceID。
(
可以通过
ZK
获取集群(机房)唯一
InstanceID
,也可以通过配置文件配置
InstanceID)
Zk 递增方式
<property name="sequnceHandlerType">4</property>
Zk
的连接信息统一在
myid.properties
的
zkURL
属性中配置。
配置:
配置文件:
sequence_conf.properties
只要配置好
ZK
地址和表名的如下属性
- TABLE.MINID 某线程当前区间内最小值
- TABLE.MAXID 某线程当前区间内最大值
- TABLE.CURID 某线程当前区间内当前值
文件配置的
MAXID
以及
MINID
决定每次取得区间,这个对于每个线程或者进程都有效。文件中的这三个属性配置 只对第一个进程的第一个线程有效,其他线程和进程会动态读取ZK
。