資料庫路由中介軟體MyCat - 使用篇(3)上篇
此文已由作者張鎬薪授權網易雲社群釋出。
歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。
全域性序列號
資料切分後,原有的關係資料庫中的主鍵約束在分散式條件下將無法使用,因此需要引入外部機制保證資料唯一性標識,這種保證全域性性的資料唯一標識的機制就是全域性序列號(sequence)。
1. 本地檔案方式
classpath下有一個sequence_conf.properties檔案:
GLOBAL_SEQ.HISIDS= GLOBAL_SEQ.MINID=1001 GLOBAL_SEQ.MAXID=1000000000 GLOBAL_SEQ.CURID=1000
HISIDS表示歷史使用過的值,MINID為ID最小值,MAXID為ID最大值,CURID為當前值。 需要在server.xml加入如下配置:
<system><property name="sequnceHandlerType">0</property></system>
sequnceHandlerType 需要配置為 0,表示使用本地檔案配置。 使用示例:
insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,‘test’);
但是這麼做,MyCat就不是無狀態中介軟體,很難去做MyCat叢集。而且,這樣的id只是純數字。最後,每次MyCat重新發布,id恢復初始值。所以,不推薦這種用法。
2.資料庫方式
在資料庫中建立一張表,存放 sequence 名稱(name),sequence 當前值(current_value),步長(increment)每次讀取多少個 sequence,假設為 K)等資訊; server.xml:
<system><property name="sequnceHandlerType">1</property></system>
建表語句:
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;INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES (‘GLOBAL’, 100000, 100);
建立相關function:
DROP FUNCTION IF EXISTS mycat_seq_currval;DELIMITERCREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf-8DETERMINISTICBEGINDECLARE 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;ENDDELIMITER;– 謳置 sequence 值DROP FUNCTION IF EXISTS mycat_seq_setval;DELIMITERCREATE FUNCTION mycat_seq_setval(seq_name VARCHAR(50),value INTEGER) RETURNS varchar(64) CHARSET utf-8DETERMINISTICBEGINUPDATE MYCAT_SEQUENCESET current_value = valueWHERE name = seq_name;RETURN mycat_seq_currval(seq_name);ENDDELIMITER;– 獲叏下一個 sequence 值DROP FUNCTION IF EXISTS mycat_seq_nextval;DELIMITERCREATE FUNCTION mycat_seq_nextval(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf-8DETERMINISTICBEGINUPDATE MYCAT_SEQUENCESET current_value = current_value + increment WHERE name = seq_name;RETURN mycat_seq_currval(seq_name);ENDDELIMITER;
sequence_db_conf.properties指定 sequence 相關配置在哪個節點上
USER_SEQ=test_dn1
使用示例:
insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,‘test’);
這樣做雖然MyCat為無狀態而且id有持久化,並且一次可以取出多個id,通過配置可以有主從切換。但是,id還是純數字,沒有有意義的資訊,而且,MyCat主從切換並不可靠,id生成有故障,則整個服務都無法正常進行,這在架構上有單點問題,是不推薦的。
3.本地時間戳方式
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 任意整數
4.通過繼承或者重構相關類實現
修改原始碼,主要是和MyCATSequnceProcessor相關的類,定製自己的id。之後原始碼篇會講
但是全域性序列號還是推薦用獨立的id生成器服務(獨立於MyCat的服務)去實現最佳!
安裝準備
環境
Red Hat Enterprise Linux Server release 6.6 (Santiago) java version "1.7.0_79"
軟體
zookeeper 3.4.6 (MyCat監控依賴於zookeeper,同時,MyCat1.5之後引入了zk的配置方式)
MyCat 1.5GA(1.5版本已經比較穩定):https://github.com/MyCATApache/Mycat-Server/
MyCat-eye 1.0: https://github.com/MyCATApache/Mycat-Web 用來監控MyCat
配置並部署zookeeper
只要部署好即可,預設配置,將conf/zoo_sample.cfg 重新命名為conf/zoo.cfg。啟動後驗證下即可(因為目前只為了為監控服務)
配置MyCat
下載MyCat的原始碼,並使用maven打包安裝:mvn install -Dmaven.test.skip=true. 使用生成的linux下的tar.gz檔案,解壓。
1. 業務分析
接下來是我們的重點,MyCat的配置,還是拿之前的例子,我們只需要一個邏輯庫(schema1),運單庫則需要分成3片,客戶庫需要分成2片,統一由MyCat管理。業務上,客戶和快遞員查詢和自己相關的運單比客戶和快遞員還有倉管員通過運單號查詢相關資訊的業務量少的,所以以運單為中心進行分片。 運單表根據運單號雜湊取模分片; 運單子母件表作為運單表的子表; 快遞員運單關係表作為運單表的子表; 客戶運單關係表作為運單表的子表; 快遞員資訊變動不頻繁,而且量不大,但是業務上基本沒有需要和快遞員join的場景,作為非分片表; 客戶表根據客戶id做雜湊取模; 運單狀態資訊表,運單狀態資訊表記錄狀態的解釋資訊,做為公共表。
運單根據量放在3個分片節點上,客戶根據量也放在兩個分片節點上。(這裡假設都撐得住未來10年的量,主要要考慮儲存量級和tps/qps兩個維度,採用涉及到雜湊取模的分片規則,最好一開始就估計足量,避免未來的擴容麻煩)
更多網易技術、產品、運營經驗分享請點選。
相關文章:
【推薦】 selenium下拉框踩坑埋坑
【推薦】 後臺服務專案的白盒測試之旅