自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

數(shù)據(jù)庫(kù)中間件cobar調(diào)研筆記

開(kāi)發(fā) 開(kāi)發(fā)工具
分庫(kù)后,join怎么實(shí)現(xiàn),group by怎么實(shí)現(xiàn)?13年底負(fù)責(zé)數(shù)據(jù)庫(kù)中間件設(shè)計(jì)時(shí)的調(diào)研筆記,拿出來(lái)和大家分享,輕拍。

13年底負(fù)責(zé)數(shù)據(jù)庫(kù)中間件設(shè)計(jì)時(shí)的調(diào)研筆記,拿出來(lái)和大家分享、輕拍。

一、cobar是什么

  • 阿里開(kāi)源的mysql的中間件服務(wù)
  • 使用mysql協(xié)議
  • 對(duì)上游,cobar就是傳統(tǒng)mysql數(shù)據(jù)庫(kù)
  • 對(duì)上游,它屏蔽后端分布式mysql集群

畫(huà)外音:數(shù)據(jù)庫(kù)中間件有基于服務(wù)端的,也有基于客戶端的,cobar屬于前者。

二、cobar應(yīng)用場(chǎng)景舉例

obar應(yīng)用場(chǎng)景舉例

邏輯上:

  • 數(shù)據(jù)庫(kù)dbtest(虛擬的)
  • 表tb1和tb2

物理上:

  • tb1表的數(shù)據(jù)在dbtest1(物理的)的tb1上
  • tb2表的一部分?jǐn)?shù)據(jù)在dbtest2(物理的)的tb2上,另外一部分在dbtest3(物理的)的tb2上

三、cobar使用方式

  • 命令行:連dbtest虛擬庫(kù)
  • JDBC:也是連dbtest虛擬庫(kù)

cobar使用方式

查看db:

查看db

可看到dbtest1、dbtest2、dbtest3對(duì)用戶透明。

查看table:

查看table

可看到有tb1和tb2兩張表。

插入一些數(shù)據(jù),對(duì)用戶而言,后端的分布式mysql是透明的:

  • 對(duì)tb1,數(shù)據(jù)實(shí)際上存在dbtest1的tb1中
  • 對(duì)tb2,數(shù)據(jù)實(shí)際上存儲(chǔ)在dbtest2和dbtest3的tb2中

畫(huà)外音:從其官網(wǎng)上看,自12年12月之后,cobar就沒(méi)有再更新過(guò),官方微博也非常不活躍,不清楚現(xiàn)在它在阿里的使用情況,知道的同學(xué)請(qǐng)說(shuō)一說(shuō)。

四、cobar不支持什么

  • 不支持夸庫(kù)join,分頁(yè),排序,子查詢
  • set語(yǔ)句會(huì)被忽略(事務(wù)和字符集設(shè)置除外)
  • 如果分庫(kù),insert必須包含patition key(否則麻煩大了)
  • 如果分庫(kù),patition key不能被update
  • 不支持讀寫(xiě)分離
  • 不支持存儲(chǔ)過(guò)程
  • 如果使用JDBC,rewriteBatchedStatements,useServerPrepStmts,BLOB, BINARY, VARBINARY字段不能使用setBlob()或setBinaryStream()

五、cobar支持什么

1. 分布式數(shù)據(jù)庫(kù):通過(guò)分庫(kù)實(shí)現(xiàn)

  • 支持一張表放到不同的庫(kù)
  • 支持不同的表放入不同的庫(kù)

需要注意:不支持將test拆分成test_1,test_2,test_3并放入同一個(gè)庫(kù)中這樣的拆分方式。

畫(huà)外音:后者正是360的atals的做法(atlas只支持單實(shí)例單庫(kù)分表)。

2. HA:通過(guò)到mysql的心跳實(shí)現(xiàn)

  • 主機(jī)掛了會(huì)自動(dòng)切換回備機(jī),但主機(jī)恢復(fù),需要手動(dòng)切回
  • 只檢測(cè)主備異常,不關(guān)心主備數(shù)據(jù)同步(需要dba手動(dòng)配)

畫(huà)外音:需要注意,cobar是需要用戶自己來(lái)實(shí)現(xiàn)負(fù)載均衡的,方式有三種:

  • 自己使用軟件例如LVS
  • 自己使用硬件例如F5
  • cobar提供了命令獲取集群信息,用戶可以根據(jù)這些信息做負(fù)載均衡;當(dāng)然,淘寶已經(jīng)實(shí)現(xiàn)了一個(gè)具有負(fù)載均衡功能的cobar客戶端產(chǎn)品-cobar.driver

3. SQL路由

在分庫(kù)的情況下,cobar會(huì)從sql中提取partition key列,來(lái)判斷SQL被路由到哪一個(gè)分庫(kù)進(jìn)行執(zhí)行;如果沒(méi)有帶partition key,則會(huì)將SQL分發(fā)到所有分庫(kù)執(zhí)行。

4. 示例

tb1(id INT)

假設(shè)以id切分?jǐn)?shù)據(jù),后端分了N個(gè)庫(kù):

  1. insert into tb1 values(1); 
  2. => N個(gè)庫(kù)都會(huì)執(zhí)行插入,因?yàn)闆](méi)有帶partition key; 
  1. insert into tb1(id) values(1); 
  2. => 只會(huì)路由到1個(gè)庫(kù),帶了partition key; 
  1. update tb1 set id=2 where id=1
  2. => 不支持,不能修改partition key; 

畫(huà)外音:SQL帶上partition key對(duì)cobar來(lái)說(shuō),非常非常重要,并且partition key不支持修改(修改了庫(kù)就不對(duì)了喲)。

cobar不允許在同一個(gè)連接中切換庫(kù)。

畫(huà)外音:數(shù)據(jù)庫(kù)連接和庫(kù)是綁定關(guān)系。

不建議通過(guò)cobar來(lái)執(zhí)行DDL語(yǔ)句。

畫(huà)外音:所以建庫(kù),建索引什么的,還是直連mysql自己搞吧。

5. COBAR自定義語(yǔ)句

(1) 查詢cobar節(jié)點(diǎn)的狀態(tài)

cobar允許管理員通過(guò)管理命令上線和下線cobar節(jié)點(diǎn)。

(2) 查詢cobar集群的狀態(tài)

查詢cobar集群的狀態(tài)

被定義在一個(gè)cobar集群中的cobar節(jié)點(diǎn)之間都會(huì)發(fā)送心跳,所謂的心跳就是上面提到的show cobra_status; 這樣的話,就為每一個(gè)cobar節(jié)點(diǎn)提供了知道同一個(gè)集群內(nèi)的所有cobar信息的機(jī)會(huì)。當(dāng)然,被下線,或者心跳超時(shí)的cobar節(jié)點(diǎn)的信息不會(huì)被顯示出來(lái)。

(3) 查詢SQL語(yǔ)句的路由情況

查詢SQL語(yǔ)句的路由情況

SQL語(yǔ)句前加上explain即可知道SQL語(yǔ)句的路由情況。

6. 事務(wù)的支持

cobar對(duì)單庫(kù)保持事務(wù)的強(qiáng)一致性。

對(duì)分庫(kù)保持事務(wù)的弱一致性。

分庫(kù)后事務(wù)提交包含兩個(gè)階段:

  • 執(zhí)行階段:SQL按照規(guī)則被路由到多個(gè)分庫(kù),此時(shí)發(fā)生錯(cuò)誤,還能回滾
  • 提交階段:提交階段出錯(cuò),無(wú)法正確回滾

事務(wù)的支持

兩個(gè)階段之間,執(zhí)行與提交串行處理,階段內(nèi)部各個(gè)分庫(kù)并行處理。

畫(huà)外音:額,基本就是不支持分布式事務(wù)。

六、cobar系統(tǒng)架構(gòu)

1. 系統(tǒng)模塊圖

系統(tǒng)模塊圖

畫(huà)外音:從模塊圖來(lái)看,cobar的結(jié)構(gòu)還是挺清晰的:

(1) 前端對(duì)上游的連接池

(2) 后端對(duì)下游mysql的連接池

(3) 對(duì)每一個(gè)請(qǐng)求,會(huì)經(jīng)過(guò):

  • SQL分析
  • SQL路由
  • SQL執(zhí)行
  • 投遞給后端mysql

(4) 對(duì)每一個(gè)響應(yīng),需要做結(jié)果合并

2. 數(shù)據(jù)流圖

數(shù)據(jù)流圖和上述模塊圖對(duì)應(yīng):

數(shù)據(jù)流圖和上述模塊圖對(duì)應(yīng)

3. 網(wǎng)絡(luò)模型

采用異步網(wǎng)絡(luò)模型:

采用異步網(wǎng)絡(luò)模型

4. 結(jié)果合并

會(huì)把多個(gè)物理庫(kù)的結(jié)果集合并,再返回給上游:

會(huì)把多個(gè)物理庫(kù)的結(jié)果集合并,再返回給上游

七、cobar路由算法

  • partition key是int時(shí):好辦,直接取模
  • partition key是string時(shí):f(string) = hash(string) % 1024

假設(shè)分4個(gè)庫(kù):

  • 哈希結(jié)果0-255 -> 庫(kù)1
  • 哈希結(jié)果256-511 -> 庫(kù)2
  • 哈希結(jié)果512-767 -> 庫(kù)3
  • 哈希結(jié)果768-1024 -> 庫(kù)4

如何擴(kuò)容:

  • 哈希結(jié)果0-255 -> 庫(kù)1

拆分后:

  • 哈希結(jié)果0-127 -> 庫(kù)1.1
  • 哈希結(jié)果128-255 -> 庫(kù)1.2

數(shù)據(jù)非均勻分布路由:

  • 哈希結(jié)果0-511(513范圍) -> 庫(kù)1
  • 哈希結(jié)果512-767(256范圍) -> 庫(kù)2
  • 哈希結(jié)果768-895(128范圍) -> 庫(kù)3
  • 哈希結(jié)果896-1023(128范圍) -> 庫(kù)4

八、cobar對(duì)于SQL的轉(zhuǎn)發(fā)

1. 帶partition key單記錄查詢

帶partition key單記錄查詢

直接根據(jù)partition key路由。

2. 帶partition key的IN查詢

帶partition key的IN查詢

將IN進(jìn)行拆分,請(qǐng)求發(fā)到對(duì)應(yīng)多個(gè)分庫(kù),然后將結(jié)果集合并。

3. 不帶partition key的where查詢

不帶partition key的where查詢

假設(shè)partition key是user字段,在product字段上的where查詢,會(huì)將請(qǐng)求廣播到所有分庫(kù),然后將結(jié)果集合并。

4. 二維partition key

一張表的多個(gè)字段同時(shí)作為定位庫(kù)的拆分字段,仍以上圖的visit(product, user, info)為例,可以以product和user兩個(gè)字段來(lái)同時(shí)來(lái)定位庫(kù)。

二維partition key

橫坐標(biāo)product屬性取hash,縱坐標(biāo)user屬性取hash。

二維partition key

 

  1. SELECT * FROM visit WHERE product=‘ColaCola’ AND user=‘A’ 

對(duì)于上述業(yè)務(wù)需求,同時(shí)帶有兩個(gè)列作為查詢條件,可以直接定位到庫(kù)7。

但是,此時(shí)如果只有其中的一個(gè)字段作為查詢條件,反而得查詢多個(gè)庫(kù),再做聚合:

聚合

  1. SELECT * FROM visit WHERE product=‘ColaCola’ 

對(duì)于上述業(yè)務(wù)需求,就必須查詢庫(kù)3,7,11,15了。

畫(huà)外音:不懂為什么要按照雙key來(lái)做路由,單key路由,對(duì)于雙key的查詢,也沒(méi)有增加多少數(shù)據(jù)掃描量啊,加入雙key反而使得某些情況下策略復(fù)雜了,帶來(lái)的收益也不高。

5. 小結(jié)

對(duì)的,對(duì)于where,cobar就是這樣的處理方式:

  • 根據(jù)字段的一致性hash分布數(shù)據(jù)
  • 多維拆分
  • 根據(jù)where中的partition key分發(fā)查詢
  • SQL語(yǔ)句變換,分發(fā)至各個(gè)分庫(kù)執(zhí)行,對(duì)結(jié)果進(jìn)行合并

九、cobar的高級(jí)特性

1. JOIN有限的處理

JOIN有限的處理

如上,兩個(gè)表都進(jìn)行了分庫(kù),JOIN需求如下:

  1. SELECT * FROM tb1 INNER JOIN tb2 
  2.     ON tb1.MEMBER_ID=tb2.NAME 

結(jié)果集理應(yīng)如下:

方案一:迭代查詢

  1. FOR row1 IN select * FROM tb1{ 
  2.     ADD( 
  3.         SELECT* FROM tb2 WHERE 
  4.           tb2.name = row1.member_id 
  5.     )TO RESULT 

畫(huà)外音:我去,外層循環(huán)是對(duì)tb1中的所有記錄,在tb2來(lái)一遍掃描,bt1數(shù)據(jù)量大的情況下,這哪里受得了?

方案二:夸庫(kù)索引

對(duì)于tb1和tb2存在的潛在JOIN需求,對(duì)JOIN列建立夸庫(kù)索引。

  • 直接JOIN查詢:建立了夸庫(kù)索引后,對(duì)于JOIN的直接查詢,就是idx索引表內(nèi)的數(shù)據(jù)的合并就是結(jié)果
  • JOIN后帶WHERE條件:
    1. SELECT * FROM tb1 INNER JOIN tb2 
    2. ON tb1.MEMBER_ID=tb2.NAME 
    3.       WHEREtb1.id=5 

此時(shí)需要改寫(xiě)SQL語(yǔ)句,直接在索引表上進(jìn)行查詢:

  1. 此時(shí)需要改寫(xiě)SQL語(yǔ)句,直接在索引表上進(jìn)行查詢: 
  2. SELECT * FROM idx WHERE id1=5 

此處需要注意:

  • 索引表的partition key:WHERE條件所在表的partition key,作為索引表的partition key
  • 索引必須包含參與JOIN相關(guān)表的主鍵,JOIN字段,包含WHERE條件的字段
  • 索引的更新:需要分布式事務(wù)的支持

2. GROUP BY的處理

GROUP BY的處理

以上表為例,patition key是ID,要在C1上進(jìn)行GROUP BY操作:

  1. SELECT SUM(price) FROM tb1 GROUP BY c1; 

改寫(xiě)SQL語(yǔ)句,先在各個(gè)分庫(kù)上GROUP BY一次,并將sum計(jì)算出來(lái):

  1. SELECT SUM(price), c1 FROM tb1 GROUP BY c1 ORDER BY c1; 

各分庫(kù)進(jìn)行GROUP BY + ORDER BY + sum之后,根據(jù)排序后的c1及對(duì)應(yīng)sum結(jié)果,歸并一遍后即得到最終結(jié)果。

3. 小結(jié)

對(duì)于復(fù)雜語(yǔ)句,可以這樣處理:

  • 對(duì)于JOIN,可以迭代查詢,或者使用分布式索引
  • 對(duì)于GROUP BY,需要增加查詢列,以及ORDER BY

13年底的調(diào)研筆記,文中的“畫(huà)外音”是我當(dāng)時(shí)的批注,希望能讓大家對(duì)cobar能有一個(gè)初步的認(rèn)識(shí),有疑問(wèn)之處,歡迎交流。

【本文為51CTO專欄作者“58沈劍”原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來(lái)源: 51CTO專欄
相關(guān)推薦

2017-12-01 05:04:32

數(shù)據(jù)庫(kù)中間件Atlas

2017-11-27 05:36:16

數(shù)據(jù)庫(kù)中間件TDDL

2018-02-24 19:37:33

Java8數(shù)據(jù)庫(kù)中間件

2011-08-10 13:03:58

CJDBC數(shù)據(jù)庫(kù)集群

2017-05-23 18:55:05

mysql-proxy數(shù)據(jù)庫(kù)架構(gòu)

2017-07-26 09:41:28

MyCATSQLMongoDB

2017-12-01 05:40:56

數(shù)據(jù)庫(kù)中間件join

2017-11-27 06:01:37

數(shù)據(jù)庫(kù)中間件中間層

2017-12-11 13:30:49

Go語(yǔ)言數(shù)據(jù)庫(kù)中間件

2017-07-18 17:35:16

數(shù)據(jù)庫(kù)MyCATPreparedSta

2017-11-03 11:02:08

數(shù)據(jù)庫(kù)中間件

2017-11-30 08:56:14

數(shù)據(jù)庫(kù)中間件架構(gòu)師

2024-12-06 08:29:29

2017-07-18 17:07:40

數(shù)據(jù)庫(kù) MyCATJoin

2021-07-27 05:49:59

MySQL數(shù)據(jù)庫(kù)中間件

2020-10-15 08:34:32

數(shù)據(jù)庫(kù)中間件漫談

2009-01-20 10:45:55

Oracle數(shù)據(jù)庫(kù)中間件

2018-11-07 15:30:19

數(shù)據(jù)庫(kù)NewSQLNoSQL

2022-04-01 10:55:30

數(shù)據(jù)庫(kù)混合云建設(shè)

2009-11-10 16:48:23

中間件操作系統(tǒng)數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)