您好,登錄后才能下訂單哦!
在實現分庫分表的情況下,數據庫自增主鍵已無法保證自增主鍵的全局唯一。為此,MyCat 提供了全局 sequence,并且提供了包含本地配置和數據庫配置等多種實現方式。
1.本地文件方式
使用服務器本地磁盤文件的方式
使用專用數據庫的方式
使用時間戳算法方式
基于ZK 與本地配置的分布式ID 生成器(可以通過ZK 獲取集群(機房)唯一InstanceID,也可以通過配置文 件配置InstanceID)
另一種ZK生成方式
配置方式:
在sequence_conf.properties
文件中做如下配置:
# 這是全局表的設置 GLOBAL_SEQ.HISIDS= GLOBAL_SEQ.MINID=1001 GLOBAL_SEQ.MAXID=1000000000 GLOBAL_SEQ.CURID=1000 # 下面是自定義表的設置
HISIDS
表示使用過的歷史分段(一般無特殊需要可不配置),MINID
表示最小ID 值,MAXID
表示最大CURID
表示當前ID 值。server.xml
中配置:
<system><property name="sequnceHandlerType">0</property></system>
sequnceHandlerType
需要配置為0,表示使用本地文件方式。insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,‘test’);
[本地文件方式詳細配置和測試]
1.1 修改配置文件server.xml
,指定加密方式為本地文件方式
<system><property name="sequnceHandlerType">0</property></system>
schema.xml
文件中配置,增加表tt
,ID為主鍵,在dn$1-3上分片,分片方式mod-log
<table name="tt" primaryKey="id" autoIncrement="true" dataNode="dn$1-3" rule="mod-long"/>
sequence_conf.properties
文件中做如下配置:# 這是全局表的設置 GLOBAL.HISIDS= GLOBAL.MINID=10001 GLOBAL.MAXID=1000000000 GLOBAL.CURID=10000 # 下面是自定義表的設置 TT.HISIDS= TT.MINID=1001 TT.MAXID=2000 TT.CURID=1000
tt
CREATE TABLE tt( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `name_` INT(10) UNSIGNED NOT NULL, PRIMARY KEY (`id`) ) DEFAULT CHARSET=utf8;
mysql> desc tt; +-------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | name_ | int(10) unsigned | NO | | NULL | | +-------+------------------+------+-----+---------+----------------+ 2 rows in set (0.01 sec)
mysql> explain select * from tt; +-----------+--------------------------------+ | DATA_NODE | SQL | +-----------+--------------------------------+ | dn1 | SELECT * FROM tt LIMIT 3000000 | | dn2 | SELECT * FROM tt LIMIT 3000000 | | dn3 | SELECT * FROM tt LIMIT 3000000 | +-----------+--------------------------------+ 3 rows in set (0.07 sec)
insert into tt(id,name_) values(next value for MYCATSEQ_GLOBAL,1);
mysql> SELECT * FROM TT; +-------+-------+ | id | name_ | +-------+-------+ | 10001 | 1 | +-------+-------+ 1 row in set (0.00 sec)
insert into tt(id,name_) values(next value for MYCATSEQ_TT,2);
mysql> SELECT * FROM TT ORDER BY name_; +-------+-------+ | id | name_ | +-------+-------+ | 10001 | 1 | | 1001 | 2 | +-------+-------+ 2 rows in set (0.01 sec)
mysql> SELECT * FROM TT ORDER BY name_; +-------+-------+ | id | name_ | +-------+-------+ | 10001 | 1 | | 1001 | 2 | | 1002 | 3 | | 1003 | 4 | | 1004 | 5 | | 1005 | 6 | +-------+-------+ 6 rows in set (0.00 sec)
mysql (db1)>select * from tt; +------+-------+ | id | name_ | +------+-------+ | 1002 | 3 | | 1005 | 6 | +------+-------+ 2 rows in set (0.00 sec) mysql (db2)>select * from tt; +------+-------+ | id | name_ | +------+-------+ | 1003 | 4 | +------+-------+ 1 row in set (0.00 sec) mysql (db3)>select * from tt; +-------+-------+ | id | name_ | +-------+-------+ | 1001 | 2 | | 1004 | 5 | | 10001 | 1 | +-------+-------+
OK It works!!
優點:配置簡單,本地文件,讀寫速度快 缺點:導致MYCAT變成有狀態的中間件,不利于部署集群
數據庫方式存在比較明顯的缺點,即MYCAT集群切換和保持序列的數據庫主從切換之后,不可控內容較多 需要非常仔細的處理這些問題,維護成本較高,雖然實現MYCAT無狀態,但有單點問題
ID= 64 位二進制 (42(毫秒)+5(機器 ID)+5(業務編碼)+12(重復累加) server.xml
:
<system><property name="sequnceHandlerType">2</property></system>
sequence_time_conf.properties
:WORKID=0-31 任意整數 DATAACENTERID=0-31 任意整數
-----最想測試的還是這個
配置選項:
<property name="sequnceHandlerType">3</property>
myid.properties
的zkURL
屬性中配置。InstanceID
,也可以通過配置文件配置InstanceID
)ID 結構:long 64 位,ID 最大可占63 位current time millis (微秒時間戳38 位,可以使用17 年) |
---|
instanceId (實例ID,可以通過ZK 或者配置文件獲取,5 位,也就是十進制0-31) |
threadId (線程ID,9 位) |
increment (自增,6 位) |
一共63 位,可以承受單機房單機器單線程1000*(2^6)=640000 的并發。
無悲觀鎖,無強競爭,吞吐量更高
配置文件:sequence_distributed_conf.properties
,只要配置里面:INSTANCEID=ZK
就是從ZK 上獲取InstanceID
。
配置ZK ID生成器的主要步驟
zookeeper是hadoop的一個子項目
一般生產上需要配置zookeeper集群,奇數個節點,至少三個節點
為了測試mycat的相關特性,我們只搭建一個單節點的zookeeper
從Apache網站上(zookeeper.apache.org)下載ZooKeeper軟件包,我選擇了3.3.4版本的(zookeeper-3.3.4.tar.gz),在一臺Linux機器上安裝非常容易,只需要解壓縮后,簡單配置一下即可以啟動ZooKeeper服務器進程。
將zookeeper-3.3.4/conf目錄下面的 zoo_sample.cfg
修改為zoo.cfg
,配置文件內容如下所示:
tickTime=2000 dataDir=/home/hadoop/storage/zookeeper clientPort=2181 initLimit=5 syncLimit=2
cd zookeeper-3.3.4/ bin/zkServer.sh start
搭建生產網絡或夸機房分布式的時候再進行補充
主要涉及三個方面,修改myid.properties
,修改server.xml
,修改sequence_distributed_conf.properties
myid.properties:
loadZk=true #使用zk管理mycat和ID zkURL=127.0.0.1:2181 #zk服務器的地址和端口 clusterId=010 #本機房mycat集群的ID myid=01001 #集群內mycat的ID clusterNodes=mycat-02 #mycat節點的名稱 #server booster ; booster install on db same server,will reset all minCon to 1 #type=server #boosterDataHosts=dn2,dn3
<!DOCTYPE mycat:server SYSTEM "server.dtd"> <mycat:server xmlns:mycat="http://io.mycat/"> <system> <property name="defaultSqlParser">druidparser</property> <property name="useCompression">1</property> <property name="serverPort">3306</property> <property name="managerPort">3308</property> <property name="maxStringLiteralLength">65535</property> <!-- sequnceHandlerType 0:文件模式 1: 2:3:zookeeper分布式管理模式 --> <property name="sequnceHandlerType">3</property> </system> <user name="root"> <property name="password">password</property> <property name="schemas">dbykt</property> </user> </mycat:server>
INSTANCEID=01 CLUSTERID=01
cp *.txt *.xml *.properties zkconf/
cd ./bin/ ./init_zk_data.sh
先使用console看看啟動是否正常
./bin/mycat console
./bin/mycat start
使用工具Jmeter,此處不贅述
配置表ot1:
..... <table name="ot1" dataNode="dn$1-20,dn$21-40,dn$41-60" rule="card_no" primaryKey="id" autoIncrement="true"/> ......
./bin/mycat restart
CREATE TABLE `ot1` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, ............... ............... PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `ot1` ( `id`, ................ ................ ) VALUES ( next value for MYCATSEQ_OT, ............... ............... );
mysql> SELECT id FROM ot1 ORDER BY id; ........ | 3894484648986705980 | | 3894484648986705981 | | 3894484649020260414 | | 3894484649053814784 | | 3894484649053814847 | | 3894484649389359105 | | 3894484649926230018 | | 3894484649926230019 | | 3894484649926230020 | | 3894484649926230021 | | 3894484649959784454 | | 3894484649959784455 | | 3894484649959784456 | | 3894484649993338889 | | 3894484649993338890 | | 3894484650026893323 | | 3894484650026893324 | | 3894484650060447757 | | 3894484650060447758 | | 3894484650094002191 | ........
mysql> select count(id) id_count from ot1; +----------+ | id_count | +----------+ | 37784391 | +----------+
mysql> select max(id) id from ot1 ; +---------------------+ | id | +---------------------+ | 3897338173617897525 | +---------------------+ 1 row in set (0.03 sec)
mysql> select count(id),id from ot1 group by id having count(id)>1; Empty set (1 min 42.85 sec)
分布式ZK ID生成器,果然強大。這為數據庫跨機房雙活提供了新的方案,使得雙A機房架構下的數據最終一致性有了新的思路。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。