Zdal使用指南_第1頁(yè)
Zdal使用指南_第2頁(yè)
Zdal使用指南_第3頁(yè)
Zdal使用指南_第4頁(yè)
Zdal使用指南_第5頁(yè)
已閱讀5頁(yè),還剩18頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Zdal使用指南1.   分庫(kù)分表概述1.1分庫(kù)分表的目的       分庫(kù)分表的主要目的是將數(shù)據(jù)進(jìn)行垂直和水平切分,使同一張表的記錄可以分散到不同的物理表乃至數(shù)據(jù)庫(kù)上,減少單張表的大小,從而提高增刪改查的效率。一般來(lái)說(shuō)都會(huì)先分庫(kù)再分表,數(shù)據(jù)記錄先定位到數(shù)據(jù)庫(kù)上,再定位到具體的表上。1.2傳統(tǒng)的分庫(kù)分表方式傳統(tǒng)的分庫(kù)分表方式有兩種· 第一種是通過(guò)先對(duì)分庫(kù)分表鍵進(jìn)行哈希,然后再取模的方式計(jì)算出記錄所處的庫(kù)與表的位置,通常應(yīng)用于無(wú)統(tǒng)一順序號(hào)的表,具有良好的負(fù)載均衡能力。但當(dāng)新增設(shè)備做水平擴(kuò)展時(shí),往往需要對(duì)數(shù)據(jù)進(jìn)行遷移,帶來(lái)額外的

2、工作量· 第二種是通過(guò)順序號(hào)分段的方式計(jì)算出記錄所處的庫(kù)與表的位置,通常應(yīng)用于有統(tǒng)一順序號(hào)的流水信息,具有比較好的擴(kuò)展能力。但負(fù)載均衡能力較差,多張表時(shí),只能一張表寫(xiě)滿(mǎn)之后再寫(xiě)另一張表.2.   ZDAL系統(tǒng)整體架構(gòu) zdal組件主要有5部分組成:1)        Zdal-client:開(kāi)發(fā)編程接口,實(shí)現(xiàn)jdbc的Datasource,Connection,Statement,PreparedStatement,ResultSet等接口,實(shí)現(xiàn)通用的jdbc-sql訪(fǎng)問(wèn),內(nèi)部還實(shí)現(xiàn)讀

3、庫(kù)重試,group數(shù)據(jù)源的選擇器,表名替換,sql執(zhí)行器等功能;2)        Zdal-parser:支持oracle/mysql/db2等數(shù)據(jù)庫(kù)的sql語(yǔ)句解析,并且緩存;根據(jù)規(guī)則引擎提供的參數(shù)列表,在指定的sql中查找到需要的參數(shù),然后返回拆分字段;3)        Zdal-rule:根據(jù)zdal-parser解析后的拆分字段值來(lái)確定邏輯庫(kù)和物理表名;4)        Z

4、dal-datasource:數(shù)據(jù)庫(kù)連接的管理,支持mysql,oracle,db2數(shù)據(jù)庫(kù)的連接管理;5)        Zdal-common:zdal組件所使用的一些公共組件類(lèi)。 3.   ZDAL配置說(shuō)明 ZDAL需要三個(gè)配置:ZdalDataSource配置,<appName>-<dbMode>-ds.xml用于配置各個(gè)數(shù)據(jù)庫(kù)的數(shù)據(jù)源,<appName>-<dbMode>-rule.xml用于配置分庫(kù)分表規(guī)則。3.1 Z

5、dalDataSource配置ZdalDataSource是ZDAL的對(duì)外接口,它對(duì)分庫(kù)分表進(jìn)行了封裝,從上層看,ZdalDataSource就是一個(gè)普通的數(shù)據(jù)源。在程序中,通過(guò)使用ZdalDataSource完成對(duì)數(shù)據(jù)庫(kù)的操作。·  zdal數(shù)據(jù)源配置說(shuō)明(com.alipay.zdal.client.jdbc.ZdalDataSource)屬性名可用值說(shuō)明屬性名可用值說(shuō)明appName必須與ZdalAppBean的appName屬性值一致應(yīng)用名appDsName必須與AppDataSourceBean的appDataSourceName屬性值一致指定使用的應(yīng)用數(shù)據(jù)源名稱(chēng)

6、dbmode必須與ZdalAppBean的dbmode屬性值一致數(shù)據(jù)庫(kù)環(huán)境configPath指定兩個(gè)配置文件所在目錄的路徑,兩個(gè)配置文件必須位于同一目錄下配置文件路徑3.2 <appName>-<dbMode>-ds.xml數(shù)據(jù)源bean配置文件,例如:shard-dev-ds.xml·  zdal應(yīng)用Bean配置說(shuō)明(com.alipay.zdal.client.config.bean.ZdalAppBean)屬性名可用值說(shuō)明屬性名可用值說(shuō)明appName無(wú)約束應(yīng)用名dbmode無(wú)約束數(shù)據(jù)庫(kù)環(huán)境appDataSourceList內(nèi)容必須是存在的A

7、ppDataSourceBean的id應(yīng)用數(shù)據(jù)源列表·  zdal應(yīng)用數(shù)據(jù)源Bean配置說(shuō)明(com.alipay.zdal.client.config.bean.AppDataSourceBean)屬性名可用值說(shuō)明屬性名可用值說(shuō)明appDataSourceName無(wú)約束應(yīng)用名dataBaseTypeDB2/ORACLE/MYSQL數(shù)據(jù)庫(kù)類(lèi)型,對(duì)應(yīng)枚舉DBType中的值configTypeGROUP/SHARD/SHARD_GROUP/SHARD_FAILOVER讀寫(xiě)分離與分庫(kù)分表類(lèi)型配置,對(duì)應(yīng)枚舉DataSourceConfigType中的值appRule必須與AppRu

8、le的id一致分庫(kù)分表規(guī)則physicalDataSourceSet內(nèi)容必須是存在的PhysicalDataSourceBean的id物理數(shù)據(jù)源列表·  物理數(shù)據(jù)源配置說(shuō)明(com.alipay.zdal.client.config.bean.PhysicalDatasourceBean)屬性名可用值說(shuō)明屬性名可用值說(shuō)明Name無(wú)約束將被用在rule中用來(lái)指定數(shù)據(jù)源名jdbcUrl例如: jdbc:db2:/192.168.1.102:6000/hcore數(shù)據(jù)庫(kù)URLuserName無(wú)約束數(shù)據(jù)庫(kù)用戶(hù)名Password無(wú)約束數(shù)據(jù)庫(kù)密碼minConn數(shù)字最小連接數(shù)maxConn

9、數(shù)字最大連接數(shù)blockingTimeoutMillis數(shù)字,毫秒拋出異常前等待連接的最大時(shí)間,此時(shí)間不適用于創(chuàng)建新連接。適用于JBOSS,待驗(yàn)證是否適用于其它idleTimeoutMinutes數(shù)字,分鐘如果連接在指定時(shí)間內(nèi)未使用,將會(huì)被回收,zdal每隔idleTimeoutMinutes/2分鐘檢測(cè)一次preparedStatementCacheSize 緩存的preparedStatement大小,使用LRU算法,保存的最小preparedStatement個(gè)數(shù)是2(zdal內(nèi)部寫(xiě)死),緩存的內(nèi)容主要是PreparedStatement對(duì)象,以及數(shù)據(jù)庫(kù)返回的該對(duì)象的部分屬性,

10、緩存該對(duì)象可以減少與數(shù)據(jù)庫(kù)服務(wù)器通訊的次數(shù),從而加快速度,需要driver支持,oracle-driver支持,mysql-driver不支持queryTimeout數(shù)字,秒查詢(xún),更新等操作超時(shí)時(shí)間prefilltrue/false是否預(yù)熱數(shù)據(jù)庫(kù)連接,可以防止連接風(fēng)暴connectionProperties.connectTimeout 不同數(shù)據(jù)庫(kù)支持不同屬性,這些屬性非必要connectionProperties.autoReconnect 不同數(shù)據(jù)庫(kù)支持不同屬性,這些屬性非必要connectionProperties.initialTimeout 不同數(shù)據(jù)庫(kù)支

11、持不同屬性,這些屬性非必要connectionProperties.maxReconnects 不同數(shù)據(jù)庫(kù)支持不同屬性,這些屬性非必要connectionProperties.socketTimeout 不同數(shù)據(jù)庫(kù)支持不同屬性,這些屬性非必要connectionProperties.failOverReadOnly 不同數(shù)據(jù)庫(kù)支持不同屬性,這些屬性非必要3.3 <appName>-<dbMode>-rule.xml分庫(kù)分表規(guī)則配置文件,例如shard-dev-rule.xml·   應(yīng)用規(guī)則配置(com.ali

12、pay.zdal.rule.config.beans.AppRule)屬性名可用值說(shuō)明屬性名可用值說(shuō)明masterRule必須與ShardRule的id相同configType=shard/shard_failover時(shí)指定訪(fǎng)問(wèn)主庫(kù)的各張表的拆分規(guī)則slaveRule必須與ShardRule的id相同類(lèi)似masterRule, 但是用來(lái)指定備庫(kù)的·  分表總規(guī)則(com.alipay.zdal.rule.config.beans.ShardRule)屬性名可用值說(shuō)明屬性名可用值說(shuō)明tableRules必須與TableRule的logicTableName屬性和id值相同每個(gè)

13、表都必須配規(guī)則,key表達(dá)邏輯表名,value-ref對(duì)應(yīng)TableRule對(duì)應(yīng)的id·  分表明細(xì)規(guī)則(com.alipay.zdal.rule.config.beans.TableRule)屬性名可用值說(shuō)明屬性名可用值說(shuō)明dbIndexes例如: 0,false,master_0:slave_0,0:10000;1,true,master_1:slave_1,10001:20000配置數(shù)據(jù)庫(kù)分組分段信息,每個(gè)分組用分號(hào)(;)分隔。配置的具體格式為:分組順序號(hào)(數(shù)字), 可新增標(biāo)識(shí)(true/false), 物理數(shù)據(jù)源1:物理數(shù)據(jù)源2:., 本組數(shù)據(jù)開(kāi)始序號(hào):本組數(shù)據(jù)結(jié)束

14、序號(hào)(結(jié)束序號(hào)為-1時(shí)表示不限制);.tbSuffixresetForEachDB/throughAllDB/dbIndexForEachDB/groovyTableListresetForEachDB:例如:resetForEachDB:_00-_01,每個(gè)數(shù)據(jù)庫(kù)都有相同的兩個(gè)表,表后綴分另是_00, _01throughAllDB:例如:throughtAllDB:_00-_49,每個(gè)庫(kù)中表的個(gè)數(shù)為表總數(shù)除以庫(kù)個(gè)數(shù),每個(gè)庫(kù)中表的后綴依次遞增,對(duì)于上例,表總數(shù)為50個(gè),假如有兩個(gè)庫(kù),則每個(gè)庫(kù)中有25個(gè)表,第一個(gè)庫(kù)中表的后綴為_(kāi)00-_24,第二個(gè)庫(kù)中表的后綴為_(kāi)25-_49。dbIndexF

15、orEachDB:例如:dbIndexForEachDB:_00-_01,每個(gè)庫(kù)一張表,表后綴和數(shù)據(jù)庫(kù)后綴相同groovyTableList例如<property name ="tbSuffix"><value>groovyTableList:def list = ;for (int i=0; i<10; i+) list.add(#dbSeq#*10+i);return list;def list = ;(0.99).eachi -> list.add("$i".padLeft(2,"0");(0

16、.500).eachi -> list.add("$i".padLeft(3,"0");   return list;</value></property>logicTableName必須是存在的無(wú)后綴的數(shù)據(jù)庫(kù)表名邏輯數(shù)據(jù)庫(kù)表名(未發(fā)現(xiàn)該參數(shù)起作用)disableFullTableScantrue/false默認(rèn)值為true,不進(jìn)行全表掃描;如果置為false,則where條件中不包含分庫(kù)分表鍵時(shí),遍歷所有的庫(kù),如果where條件中含有鍵,就根據(jù)鍵值計(jì)算具體庫(kù)表dbRuleArray以return開(kāi)頭的表

17、達(dá)式例如1. return 0;2. return com.cmbc.test.TestClass. parserDbIndex (#分庫(kù)分表鍵#)具體寫(xiě)法參見(jiàn)第8.5節(jié)tbRuleArray以return開(kāi)頭的表達(dá)式類(lèi)似dbRuleArray,根據(jù)該參數(shù)值選擇庫(kù)中對(duì)應(yīng)索引值的一個(gè)表 4.   SQL語(yǔ)句4.1 查詢(xún)語(yǔ)句       ZDAL對(duì)大部分的SQL查詢(xún)提供了很好的支持,對(duì)于其支持的SQL語(yǔ)法詳見(jiàn)10.1節(jié)。但是ZDAL仍然不是一個(gè)完全遵循SQL規(guī)范的SQL語(yǔ)法解析器。并不能夠保證所有的SQL都可以通過(guò),當(dāng)SQL語(yǔ)句無(wú)法被正確

18、解析時(shí),可以通過(guò)ThreadLocalString、ThreadLocalMap和RouteCondition的結(jié)合使用解決。4.1.1 ZDAL查詢(xún)使用示例  /首先根據(jù)上一章的配置說(shuō)明,在程序中創(chuàng)建ZdalDataSource類(lèi)。ZdalDataSource dataSource = new ZdalDataSource();dataSource.setAppName(.);dataSource.setAppDsName(.);dataSource.setDbmode(.);dataSource.setConfigPath(.);dataSource.init(); /數(shù)據(jù)源初始

19、化,ZdalDataSource對(duì)象創(chuàng)建完畢。/上述配置也可以在Spring配置文件中完成Connection conn = dataSource.getConnection();Statement st = conn.createStatement();ResultSet rs= st.executeQuery("select * from iloan_cr_ln_hdr where cust_no='1111' ");/ 接下來(lái)可以對(duì)rs進(jìn)行遍歷,獲取查詢(xún)結(jié)果。.上面程序說(shuō)明的是ZDAL支持的SQL語(yǔ)句的使用方法。下面說(shuō)明對(duì)ZDAL不支持的SQL語(yǔ)法的解

20、決辦法。4.1.2 RouteCondition類(lèi)使用說(shuō)明當(dāng)執(zhí)行ZDAL不支持的SQL語(yǔ)句時(shí),可以在executeQuery前添加下面語(yǔ)句:ThreadLocalMap.put(ThreadLocalString.ROUTE_CONDITION,RouteCondition對(duì)象);ZDAL框架在執(zhí)行時(shí),會(huì)檢查T(mén)hreadLocalMap中ThreadLocalString.ROUTE_CONDITION對(duì)應(yīng)的值,如果不為null,則取出該值,并且跳過(guò)ZDAL自身的語(yǔ)法解析器。下面詳細(xì)說(shuō)明ThreadLocalString和RouteCondition。· ThreadLocalStr

21、ingThreadLocalString中定義了四個(gè)靜態(tài)屬性,下表詳細(xì)說(shuō)明了各屬性的含義:變量名說(shuō)明變量名說(shuō)明ThreadLocalString.ROUTE_CONDITION用來(lái)繞過(guò)SQL解析執(zhí)行復(fù)雜SQL語(yǔ)句ThreadLocalString.DATABASE_INDEX適用于讀寫(xiě)分離情況:選擇某個(gè)讀庫(kù)來(lái)執(zhí)行某條SQLThreadLocalString.SELECT_DATABASE適用于讀寫(xiě)分離:在同時(shí)分庫(kù)分表的情況下,選擇寫(xiě)庫(kù)來(lái)執(zhí)行某條SQLThreadLocalString.GET_ID_AND_DATABASE最后的SQL是在哪個(gè)庫(kù)執(zhí)行的,SQL執(zhí)行完畢之后調(diào)用ThreadLoca

22、lMap.get(ThreadLocalString.GET_ID_AND_DATABASE)來(lái)獲取SQL最終執(zhí)行的數(shù)據(jù)庫(kù)· RouteConditionRouteCondition作用相當(dāng)于一個(gè)SQL語(yǔ)句解析輔助工具,在RouteCondition對(duì)象中填入要執(zhí)行的SQL語(yǔ)句的解析信息,ZDAL獲得該對(duì)象后,就直接使用對(duì)象執(zhí)行分庫(kù)分表規(guī)則,而不再解析SQL語(yǔ)句。它是一個(gè)接口,其繼承關(guān)系如下圖,圖中每個(gè)類(lèi)都有不同的用途:            使用RouteCondition, ZDAL就不在對(duì)SQL語(yǔ)句進(jìn)行語(yǔ)法解

23、析,所以對(duì)于ZDAL不支持的語(yǔ)法可以使用RouteCondition解決。             ZDAL從ThreadLocalMap中獲取到RouteCondition對(duì)象之后,就直接把對(duì)象從ThreadLocalMap中刪除掉,所以下次使用相同的RouteCondition對(duì)象時(shí),必須重新調(diào)用ThreadLocalMap.put方法。 下面對(duì)RouteCondition的各個(gè)對(duì)象使用方法進(jìn)行說(shuō)明。· DBSelectorIDRouteCondition    

24、0;      用于查詢(xún)指定庫(kù)中指定的表,一次只能指定一個(gè)庫(kù),但可以指定多個(gè)表           構(gòu)造方法:DBSelectorIDRouteCondition(String logicTableName, String dbSelectorID, String. tables) 參數(shù)名含義參數(shù)名含義logicTableName邏輯表名,通常情況下為實(shí)際表名去掉后綴,例如實(shí)際表名為acct_00則邏輯表名為acctdbSelectorID數(shù)據(jù)源名稱(chēng),對(duì)應(yīng)PhysicalDataSourceBe

25、an中的name屬性tables實(shí)際的表名,可以是多個(gè)           示例conn = dataSource.getConnection();st = conn.createStatement();RouteCondition rc = new DBSelectorIDRouteCondition("acct", "master_0", "acct_00", "acct_01");ThreadLocalMap.put(ThreadLocalStrin

26、g.ROUTE_CONDITION, rc);System.out.println("start " + System.currentTimeMillis();rs = st.executeQuery("select * from acct where acctname in ('zhangsan306', 'zhangsan10094', 'zhangsan128')");1. 分庫(kù)分表規(guī)則對(duì)DBSelectorIDRouteCondition無(wú)效,所以where子句也不要求包含分庫(kù)分表字段2. 另外,如

27、果指定了多個(gè)真實(shí)表名,那么在SQL語(yǔ)句中不要使用分頁(yè),排序等操作3. 代碼會(huì)查詢(xún)master_0對(duì)應(yīng)的庫(kù)中的acct_00和acct_01兩張表·   SimpleCondition             用于分離分庫(kù)分表鍵和查詢(xún)語(yǔ)句,通過(guò)指定的分庫(kù)分表鍵找到物理數(shù)據(jù)庫(kù)和表,在該表上執(zhí)行指定的SQL語(yǔ)句             構(gòu)造方法:默認(rèn)無(wú)參構(gòu)造方法          &

28、#160;  示例conn = dataSource.getConnection();pst = conn.prepareStatement("select * from acct where acctname = ?");pst.setString(1, "zhangsan160");SimpleCondition sc = new SimpleCondition();sc.setVirtualTableName("acct");sc.put("acctno", new Comparative(Comp

29、arative.Equivalent,"100100000000000108");ThreadLocalMap.put(ThreadLocalString.ROUTE_CONDITION, sc);rs = pst.executeQuery();1. 分庫(kù)分表規(guī)則對(duì)SimpleCondition有效,根據(jù)sc.put(“分庫(kù)分表鍵”,”分庫(kù)分表鍵值”)來(lái)確定具體對(duì)哪張表執(zhí)行SQL,如果分庫(kù)分表為單鍵并且put了多次不同的值,則以最后一個(gè)值為準(zhǔn)2. 對(duì)分庫(kù)分表字段使用等于、大于、小于等運(yùn)算時(shí),使用Comparative指定,Comparative類(lèi)中提供了一系列的靜態(tài)字段用于

30、指定運(yùn)算規(guī)則3. 最后執(zhí)行的SQL語(yǔ)句的where子句可以不包含分庫(kù)分表鍵。·   AdvanceCondition             類(lèi)似SimpleCondition,AdvanceCondition可以在指定分庫(kù)分表鍵值的時(shí)候使用or或者and運(yùn)算,而SimpleCondition不可以。             AdvanceCondition繼承自SimpleCondition,提供了兩個(gè)靜態(tài)方法,分別用于支持

31、and和or運(yùn)算。             構(gòu)造方法:默認(rèn)無(wú)參構(gòu)造方法             示例conn = dataSource.getConnection();pst = conn.prepareStatement("select * from acct where acctname = ?");pst.setString(1, "zhangsan180");AdvanceCondition ac = new

32、 AdvanceCondition();ac.setVirtualTableName("acct");ac.put("acctno", AdvanceCondition.or(AdvanceCondition.getComparative(AdvanceCondition.EQ, "100100000000000108"),AdvanceCondition.getComparative(AdvanceCondition.EQ, "100100000000000103");   

33、0;        ThreadLocalMap.put(ThreadLocalString.ROUTE_CONDITION, ac);rs = pst.executeQuery();1. ac.put(“acctno”, AdvanceCondition.or.)表示將“100100000000000108” or acctno=”100100000000000103”作為分庫(kù)分表的鍵值來(lái)定位數(shù)據(jù)庫(kù)與表,對(duì)應(yīng)的結(jié)果可能有多個(gè)2. and的使用與or類(lèi)似,但有一點(diǎn)需要注意傳給and的幾個(gè)Comparative對(duì)象條件不能是互

34、斥的。比如cust_no>3 and cust_no=2,像這種ZDAL會(huì)報(bào)異常。3. 如果分庫(kù)分表字段有兩個(gè)或兩個(gè)以上,針對(duì)每一個(gè)字段使用了or或and方法,這樣有部分字段就有多個(gè)值,ZDAL會(huì)使用每一個(gè)值進(jìn)行計(jì)算。比如:拆分字段:cust_no1,cust_no2拆分條件:return #cust_no1#+#cust_no2#AdvanceCondition.put("cust_no1",or(new Comparative(3,1),new Comparative(3,2);AdvanceCondition.put("cust_no2",o

35、r(new Comparative(3,3),new Comparative(3,4);運(yùn)行時(shí),拆分結(jié)果是:4(1+3),5(1+4或者2+3),6(2+4)。4. 根據(jù)找到的數(shù)據(jù)庫(kù)與表來(lái)執(zhí)行指定的SQL語(yǔ)句·   JoinCondition             用來(lái)支持單庫(kù)中的join查詢(xún),注意是單庫(kù),也就是說(shuō)多表查詢(xún)的幾張表必須在同一個(gè)數(shù)據(jù)庫(kù)中             構(gòu)造方法:默認(rèn)無(wú)參構(gòu)造方法   

36、;          示例conn = dataSource.getConnection();pst = conn.prepareStatement("select a.*, b.* from acct a, cif b where a.cifno = b.cifno and a.acctname = ?");pst.setString(1, "zhangsan100");JoinCondition jc = new JoinCondition();jc.setVirtualTableName("

37、;acct");jc.addVirtualJoinTableName("cif");jc.put("acctno", "100100000000000160"); /主表分表鍵jc.setDBType(DBType.DB2);ThreadLocalMap.put(ThreadLocalString.ROUTE_CONDITION, jc);rs = pst.executeQuery();1. 分庫(kù)分表規(guī)則對(duì)JoinCondition依然有效,由jc.put("acctno", "10010000

38、0000000160")來(lái)指定主表(virtualTableName)分表鍵值,從表服從主表規(guī)則執(zhí)行查詢(xún)。也就是通過(guò)jc.put()方法指定的字段值進(jìn)行分表如果得到主表是acct_00則從表也是cif_00,主表和從表都位于同一個(gè)數(shù)據(jù)庫(kù)中2. 如果配置主表的disableFullTableScan為false,這種情況下是允許主表存在于多個(gè)數(shù)據(jù)庫(kù)中的。查詢(xún)執(zhí)行的時(shí)候首先會(huì)根據(jù)分表鍵找到表實(shí)際表名,然后再遍歷所有庫(kù)中的實(shí)際表名3. 除了從表后綴服從主表后綴這種方式外,還有一種指定真實(shí)從表表名的規(guī)則。就上面的例子來(lái)說(shuō),可以將jc.addVirtualJoinTableName("

39、;cif");改為jc.addVirtualJoinTableName("cif,cif_00");這種方式是直接指定了從表的真實(shí)表名,ZDAL在解析從表表名時(shí),直接使用逗號(hào)后面真實(shí)表名,而不再服從主表后綴。·   DirectlyRouteCondition             暫不支持4.2 增刪改語(yǔ)句三種SQL語(yǔ)句執(zhí)行方式與查詢(xún)一樣,不過(guò)在語(yǔ)法上還有一些限制:            分庫(kù)分表字段的

40、值必須確定;             分庫(kù)分表字段不能出現(xiàn)多個(gè)值的情況,即在SQL語(yǔ)句中,分庫(kù)分表字段值必須唯一而且只能出現(xiàn)一次;             如果設(shè)置提交方式為手動(dòng)提交,執(zhí)行時(shí),不會(huì)對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)作出更改,如果需要提交,則執(zhí)行Cmit()方法,不能直接執(zhí)行“commit”語(yǔ)句,因?yàn)閆DAL只支持select,insert,update,delete四種語(yǔ)句。(1)       關(guān)于

41、insert語(yǔ)句的說(shuō)明:             執(zhí)行插入時(shí),一條SQL不能同時(shí)對(duì)多張表執(zhí)行插入,無(wú)論是否設(shè)置事務(wù)提交類(lèi)型。ZDAL一旦發(fā)現(xiàn)多張表執(zhí)行插入,就拋出異常(throw new SQLException("mapping many actual tables"))。(2)       關(guān)于update語(yǔ)句的說(shuō)明:             當(dāng)一條SQL語(yǔ)句在多張表上進(jìn)行

42、update時(shí),可能會(huì)出現(xiàn)數(shù)據(jù)不一致的情況,因?yàn)楦驴赡茉谀硯讖埍砩喜僮魇。伋霎惓?,而其他的表操作成功,ZDAL對(duì)操作成功的表并未做回滾處理。(3)       關(guān)于delete語(yǔ)句的說(shuō)明:             當(dāng)一條SQL語(yǔ)句在多張表上進(jìn)行刪除操作時(shí),可能會(huì)出現(xiàn)數(shù)據(jù)不一致的情況,因?yàn)閯h除可能在某幾張表上操作失敗,并拋出異常,而其他的表操作成功,ZDAL對(duì)操作成功的表并未做回滾處理。5. 日志支持Zdal提供兩類(lèi)日志:     

43、;        zdal-client-config.log:初始化的日志信息,主要打印appName, appDsName, dbmode, configPath, 分庫(kù)分表規(guī)則,groupRule, failoverRule, 動(dòng)態(tài)failover, markdown, markup等動(dòng)態(tài)推送的日志信息             zdal-datasource-pool.log:各個(gè)物理數(shù)據(jù)源連接池的連接狀態(tài)日志信息以及超時(shí)連接剔除的日志,異常連接的日志信息等。連接池狀態(tài)每30秒打

44、印一行,例如²  連接池狀態(tài)日志²  例如:2015-07-28 20:27:55,746 / - WARN  zdal-datasource-pool - shardDataSource.slave_0min:3-max:7-canUse:6-managed:0-using:0-maxUsed:0-createCount:0-destroyCount:0²  說(shuō)明slave_0數(shù)據(jù)源名稱(chēng)min:3最小連接數(shù)max:7最大連接數(shù)canUse:6可用的連接數(shù)managed:0連接池中管理的連接數(shù)=createCount-des

45、troyCountusing:0正在使用的連接數(shù)maxUsed:0高峰期需要的最大連接數(shù)createCount:0創(chuàng)建過(guò)的連接數(shù)destroyCount:0銷(xiāo)毀過(guò)的連接數(shù)  超時(shí)連接剔除日志  例如:2014-01-03 17:40:17,387 / - WARN  zdal-datasource-pool - WARN # destroy a connection of poolName = tradecore50.physics39 of removeTimeout  異常連接剔除日志  例如:2013-12-25:2013-12-25 0

46、0:03:40,515 / - WARN  zdal-datasource-pool - WARN # destroy a connection of poolName = DS_POOL_TDDL.physics03_bak of returnConnection6. Zdal與iBatis結(jié)合使用說(shuō)明       Zdal從數(shù)據(jù)源層提供對(duì)分庫(kù)分表的支持,它對(duì)外暴露出一個(gè)符合JDBC規(guī)范的DataSource。iBatis則是基于DataSource之上的應(yīng)用層數(shù)據(jù)訪(fǎng)問(wèn)框架,因此通過(guò)將iBatis的數(shù)據(jù)源配置成Zdal對(duì)外暴露的數(shù)據(jù)源就可以將

47、二者無(wú)縫集成。7. 基于Zdal的數(shù)據(jù)庫(kù)設(shè)計(jì)與使用原則             僅對(duì)增長(zhǎng)快速的表進(jìn)行分庫(kù)分表             從效率的角度出發(fā),盡可能的將一個(gè)表的不同切分放在不同庫(kù)中             設(shè)計(jì)表的開(kāi)始就要選一個(gè)或多個(gè)鍵作為分庫(kù)分表鍵             由于Zdal內(nèi)置LRU的緩存,所以

48、使用時(shí)盡量使用PreparedStatement,以增加命中率減少SQL解析開(kāi)銷(xiāo)8. FAQ8.1 ZDAL支持的SQL語(yǔ)法有哪些?             基本的增刪改查             運(yùn)算符>, >=, <, <=, +, -, *, /             not like, like, 在分庫(kù)分表字段上使用時(shí),必須使用RouteConditi

49、on對(duì)象             in             is null, is not null , 在分庫(kù)分表字段上使用時(shí),必須使用RouteCondition對(duì)象             sum, count, max, min, order by, 但不推薦使用在分庫(kù)分表鍵上,avg只能在單表查詢(xún)時(shí)使用,這里的單表指的是一張真實(shí)的表,不是邏輯表,另外,多個(gè)聚集函數(shù)也不能同時(shí)

50、出現(xiàn)在一個(gè)對(duì)多表的查詢(xún)中,只能在單表查詢(xún)中使用             嵌套查詢(xún):嵌套內(nèi)表名和嵌套外表名必須一致,分庫(kù)分表鍵可以出現(xiàn)多次,但是對(duì)分庫(kù)分表鍵執(zhí)行的運(yùn)算必須完全一致            as別名與表名限定,用括號(hào)提升優(yōu)先級(jí)             mysql limit分頁(yè),oracle rownum分頁(yè)和db2 rownumber分頁(yè)     

51、;       some, any, all ,但是在這三個(gè)關(guān)鍵字后面只能使用子查詢(xún)             group by支持在單表上使用,這里的單表指的是一張真實(shí)的表,不是邏輯表             在一個(gè)查詢(xún)中,分庫(kù)分表字段可以出現(xiàn)多次,但是計(jì)算庫(kù)表時(shí),以第一次出現(xiàn)的值為準(zhǔn)             Distinct只能在單表上查詢(xún)時(shí)使用

52、8.2 分庫(kù)分表時(shí)SQL語(yǔ)句寫(xiě)法             未使用線(xiàn)程變量繞過(guò)SQL解析且規(guī)則中未配置disableFullTableScan=false(默認(rèn)為true)時(shí)where子句必須包含分庫(kù)分表鍵,反之視情況而定8.3 Zdal對(duì)事務(wù)的支持             zdal對(duì)事務(wù)提供有限的支持,他支持基于單庫(kù)的事務(wù),如果在一個(gè)事務(wù)過(guò)程中出現(xiàn)了多個(gè)不同的數(shù)據(jù)源,則系統(tǒng)會(huì)拋出異常。zdal不支持跨庫(kù)進(jìn)行事務(wù),跨庫(kù)事務(wù)本身會(huì)耗費(fèi)很多寶貴的資源,在大型分布

53、式系統(tǒng)中應(yīng)該盡量避免使用分布式事務(wù)處理機(jī)制,可以通過(guò)補(bǔ)償(如xts)等方式保證分布式環(huán)境中的數(shù)據(jù)的最終一致性。同時(shí),如果在一個(gè)事務(wù)中使用了非ZdalDataSource管理的數(shù)據(jù)源,Spring和Zdal都不能夠保證事務(wù)的ACID。如果是針對(duì)單個(gè)數(shù)據(jù)庫(kù)的事務(wù),使用的方式與以前的使用方式完全一致。如果需要使用spring的數(shù)據(jù)庫(kù)事務(wù)管理,則只需要使用TransactionAwareDataSourceProxy對(duì)ZdalDataSource進(jìn)行包裝后使用TranscationManager進(jìn)行管理即可            

54、示例Connection conn = dataSource.getConnection();conn.setAutoCommit(false);try     .    mit(); catch (Exception e)     conn.rollback(); finally     if (pst != null)        pst.close();    

55、0;  pst = null;        if (conn != null)        conn.close();       conn = null;    8.4 ZDAL可以做數(shù)據(jù)遷移工作嗎?       zdal不會(huì)幫助用戶(hù)在改寫(xiě)數(shù)據(jù)的時(shí)候做遷移工作,因此不能夠期望Zdal在業(yè)務(wù)中使用sql改寫(xiě)了分庫(kù)分表?xiàng)l件項(xiàng)的值的時(shí)候做

56、delete+insert操作。這樣做本身是不符合預(yù)期的,同時(shí)在分布式業(yè)務(wù)系統(tǒng)中也是不推薦使用的。如果確實(shí)有這樣的需要,請(qǐng)于業(yè)務(wù)端進(jìn)行delete+insert操作。由于可能進(jìn)行刪除添加的操作可能發(fā)生在不同的數(shù)據(jù)庫(kù)中,在發(fā)生這樣的情況時(shí),請(qǐng)通過(guò)業(yè)務(wù)邏輯保證數(shù)據(jù)的一致性。Zdal不會(huì)對(duì)這類(lèi)操作提供任何保證。8.5 編寫(xiě)自己的分庫(kù)分表parser             Zdal支持java靜態(tài)方法編寫(xiě)分庫(kù)分表規(guī)則,方法返回值為數(shù)字。對(duì)于分庫(kù)規(guī)則,zdal會(huì)利用這個(gè)數(shù)字去對(duì)應(yīng)規(guī)則配置中的物理數(shù)據(jù)源的位置來(lái)找到使用哪個(gè)物理數(shù)據(jù)源來(lái)

57、執(zhí)行SQL;對(duì)于分表規(guī)則,zdal會(huì)利用這個(gè)數(shù)字計(jì)算出表的后綴信息來(lái)確定最終在哪個(gè)物理表上執(zhí)行SQL。最后在規(guī)則配置的時(shí)候需要指定類(lèi)的全路徑.方法名(參數(shù)列表);             示例在XML文件中的配置如下:<property name="dbRuleArray">    <list>  <value>   return com.cmbc.test.TestClass.parser

58、DbIndex(#cust_no#);  </value>    </list></property>TestClass類(lèi)中需要下面靜態(tài)方法:public static int parserDbIndex(String cust_no) /每個(gè)庫(kù)有3個(gè)物理表與之對(duì)應(yīng)    return Integer.valueOf(cust_no.substring(cust_no.length() - 1) % 3;8.6 Zdal是否支持讀寫(xiě)分離?      在Group,Shard_group兩種配置模式中是支持讀寫(xiě)分離的,通過(guò)讀寫(xiě)的權(quán)重進(jìn)行控制,如:group_0=ds0:r10w10,ds1:r10w0 ,說(shuō)明ds0這個(gè)數(shù)據(jù)源可讀可寫(xiě),ds1是只讀8.7  Zdal如何管理連接,是否有連接泄露的問(wèn)題?      Zdal的每次數(shù)據(jù)庫(kù)操作所用的連接是與ZDatasource關(guān)聯(lián)的,而不是與數(shù)據(jù)表關(guān)聯(lián)的,連接的管理是可靠的。8.8 如何對(duì)分庫(kù)分表字段執(zhí)行范圍查詢(xún)?對(duì)分庫(kù)分表字段執(zhí)行范圍查詢(xún),必須在配置文件中對(duì)TableR

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論