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