如果是 IT 老鳥,對(duì)于中間件、數(shù)據(jù)庫中間件這些名詞一定都不陌生,但是如果是程序員新人,如果你向他解釋:“中間件就是和業(yè)務(wù)無關(guān)的技術(shù)組件”;有些新人可能依然會(huì)比較懵,啥是組件?什么叫和業(yè)務(wù)無關(guān)?
那么就讓我先舉個(gè)形象點(diǎn)兒的例子。
中間件是什么
干 IT 太累了,我準(zhǔn)備辭職開了個(gè)燒烤攤,賣羊肉串;
賣羊肉串首先就得有羊肉,于是我就聯(lián)系了很多養(yǎng)殖場,我又是一個(gè)比較負(fù)責(zé)人的人,為了保證羊肉的質(zhì)量,我就去考察了一家又一家養(yǎng)殖場,同時(shí)我也是個(gè)“小氣”的人,所以我考察過程中,和對(duì)方談判、比價(jià),最終選了一個(gè)養(yǎng)殖場作為我的羊肉供應(yīng)商,為我提供羊肉。
經(jīng)營了一陣子,這個(gè)養(yǎng)殖場提供的羊肉質(zhì)量沒有以前好了,那么我就重新考察、談判、比價(jià),如此反復(fù),我投入了大量的時(shí)間和精力。
于是我找到了一個(gè)信得過的代理公司,約定要羊肉的質(zhì)量和數(shù)量,談好價(jià)錢,以后我只找代理商拿貨,具體代理商找的哪家養(yǎng)殖場我不去過問,甚至代理商可以送貨上門。
在這個(gè)例子里面,賣燒烤就是業(yè)務(wù),我的燒烤攤是業(yè)務(wù)端,養(yǎng)殖場是底層,而這個(gè)信得過的代理公司,就是中間件。
數(shù)據(jù)庫中間件:數(shù)據(jù)庫就是底層,我們寫的程序就是業(yè)務(wù)端,數(shù)據(jù)庫中間件就是(和業(yè)務(wù)無關(guān))的可以實(shí)現(xiàn)數(shù)據(jù)庫一些功能的組件。
分庫分表
當(dāng)項(xiàng)目的數(shù)據(jù)量不斷增大,單臺(tái)數(shù)據(jù)庫已經(jīng)不足以支撐我們的業(yè)務(wù)量時(shí),通常我們都會(huì)采用分庫分表的策略。
如果分庫分表自己在代碼中實(shí)現(xiàn)的話,需要管理對(duì)個(gè)數(shù)據(jù)源,執(zhí)行一次查詢,需要定位到數(shù)據(jù)保存在哪個(gè)數(shù)據(jù)源上;當(dāng)執(zhí)行插入操作時(shí),又需要確認(rèn)需要將數(shù)據(jù)保存在哪個(gè)數(shù)據(jù)源中;
分庫分表不僅有 SQL 解析和路由的問題,同時(shí)還會(huì)有 SQL 改寫、并行執(zhí)行、結(jié)果集合并等問題;所以項(xiàng)目經(jīng)常會(huì)使用分庫分表的組件,來屏蔽這些復(fù)雜的功能。
這類數(shù)據(jù)庫中間件的實(shí)現(xiàn)方案基本上有兩種:
1. Proxy 代理模式
在應(yīng)用程序和數(shù)據(jù)庫中間,單獨(dú)部署一個(gè)代理層,所有的連接和數(shù)據(jù)庫操作都發(fā)給這個(gè)代理層,由代理層去做底層的實(shí)現(xiàn)。
這樣做對(duì)開發(fā)人員來說,是完全不需要知道下面做了什么的,甚至不需要做任何的代碼改造,就可以完成接入;當(dāng)然 Proxy 代理模式對(duì)代理層的高可用提出了很高的挑戰(zhàn),實(shí)現(xiàn)起來也很復(fù)雜。
常見的框架有:MyCat(支持 MySQL, Oracle, DB2, PostgreSQL, SQL Server等主流數(shù)據(jù)庫)、Cobar(阿里,已停止維護(hù))、MySQL-Proxy、Atlas(360)、sharing-sphere(當(dāng)當(dāng))等等。
2. Client 客戶端模式
這種方式需要對(duì)現(xiàn)有程序進(jìn)行改造,項(xiàng)目代碼中需要加入分庫分表功能的框架,同時(shí)也需要對(duì)代碼中的配置或 SQL 做相應(yīng)的修改。
Client 的模式,不需要有代理層,也就不需要考慮代理層高可用的問題(去中心化),實(shí)現(xiàn)起來也相對(duì)簡單;當(dāng)然缺點(diǎn)也很明顯,代碼的侵入性比較強(qiáng),并且需要考慮版本升級(jí)的問題。
常見的框架有:TDDL(阿里,新名字DRDS)、zebra(美團(tuán))、sharding-jdbc(當(dāng)當(dāng),這個(gè)做的也不錯(cuò))等等。
數(shù)據(jù)增量訂閱與消費(fèi)
這個(gè)是基于對(duì)數(shù)據(jù)庫增量日志解析,提供增量數(shù)據(jù)訂閱和消費(fèi);最有名的是阿里的 Canal。
Canal 通過監(jiān)聽 Mysql 的 binlog 日志來獲取數(shù)據(jù),binlog 設(shè)置為 row 模式,能夠獲取到每一條新增、刪除、修改的日志,同時(shí)還能獲取到修改前后的數(shù)據(jù)。
通常我們可以利用這個(gè)中間件,實(shí)時(shí)感知到 Mysql 中的數(shù)據(jù)變化,將其數(shù)據(jù)更新到 NoSQL 數(shù)據(jù)中,比如 MongoDB、ES 等等;通常項(xiàng)目組加入這些非關(guān)系數(shù)據(jù)庫,可以減輕數(shù)據(jù)庫查詢壓力、在分庫分表的架構(gòu)中,還能起到全局查詢的作用。
其它
除此之外,還有數(shù)據(jù)庫同步中間件,比如阿里的Otter,基于數(shù)據(jù)庫增量日志解析,準(zhǔn)實(shí)時(shí)同步數(shù)據(jù),支持兩個(gè)庫都可以寫入,寫入的數(shù)據(jù)同步到另外的庫;數(shù)據(jù)庫遷移中間件,實(shí)現(xiàn)不同數(shù)據(jù)庫之間的數(shù)據(jù)遷移,比如阿里的yugong,實(shí)現(xiàn)了 Oracle 到 Mysql 的數(shù)據(jù)遷移。
總之,項(xiàng)目根據(jù)需要,可以引入解決問題的中間件或框架,但同時(shí)也要注意,引入這些中間件或框架可能會(huì)帶來新的問題,一定要有相應(yīng)的評(píng)估和解決方案。
會(huì)點(diǎn)代碼的大叔 | 文【原創(chuàng)】