A. 如何實現數據遷移
數據遷移(又稱分級存儲管理,hierarchical storage management,hsm)是一種將離線存儲與在線存儲融合的技術。它將高速、高容量的非在線存儲設備作為磁碟設備的下一級設備,然後將磁碟中常用的 數據按指定的策略自動遷移到磁帶庫(簡稱帶庫)等二級大容量存儲設備上。當需要使用這些數據時,分級存儲系統會自動將這些數據從下一級存儲設備調回到上一 級磁碟上。對於用戶來說,上述數據遷移操作完全是透明的,只是在訪問磁碟的速度上略有怠慢,而在邏輯磁碟的容量上明顯感覺大大提高了。
數據遷移是將很少使用或不用的文件移到輔助存儲系統(如磁帶或光碟)的存檔過程。這些文件通常是需在未來任何時間可進行方便訪問的圖像文檔或歷史信息。遷移工作與備份策略相結合,並且仍要求定期備份。還包括電腦數據遷移,遷移舊電腦(舊系統)中的數據、應用程序、個性化設置等到新電腦(新系統),在系統升級後很有必要。
B. 資料庫架構選型與落地,看這篇就夠了
隨著時間和業務的發展,資料庫中的數據量增長是不可控的,庫和表中的數據會越來越大,隨之帶來的是更高的 磁碟 、 IO 、 系統開銷 ,甚至 性能 上的瓶頸,而單台伺服器的 資源終究是有限 的。
因此在面對業務擴張過程中,應用程序對資料庫系統的 健壯性 , 安全性 , 擴展性 提出了更高的要求。
以下,我從資料庫架構、選型與落地來讓大家入門。
資料庫會面臨什麼樣的挑戰呢?
業務剛開始我們只用單機資料庫就夠了,但隨著業務增長,數據規模和用戶規模上升,這個時候資料庫會面臨IO瓶頸、存儲瓶頸、可用性、安全性問題。
為了解決上述的各種問題,資料庫衍生了出不同的架構來解決不同的場景需求。
將資料庫的寫操作和讀操作分離,主庫接收寫請求,使用多個從庫副本負責讀請求,從庫和主庫同步更新數據保持數據一致性,從庫可以水平擴展,用於面對讀請求的增加。
這個模式也就是常說的讀寫分離,針對的是小規模數據,而且存在大量讀操作的場景。
因為主從的數據是相同的,一旦主庫宕機的時候,從庫可以 切換為主庫提供寫入 ,所以這個架構也可以提高資料庫系統的 安全性 和 可用性 ;
優點:
缺點:
在資料庫遇到 IO瓶頸 過程中,如果IO集中在某一塊的業務中,這個時候可以考慮的就是垂直分庫,將熱點業務拆分出去,避免由 熱點業務 的 密集IO請求 影響了其他正常業務,所以垂直分庫也叫 業務分庫 。
優點:
缺點:
在資料庫遇到存儲瓶頸的時候,由於數據量過大造成索引性能下降。
這個時候可以考慮將數據做水平拆分,針對數據量巨大的單張表,按照某種規則,切分到多張表裡面去。
但是這些表還是在同一個庫中,所以庫級別的資料庫操作還是有IO瓶頸(單個伺服器的IO有上限)。
所以水平分表主要還是針對 數據量較大 ,整體業務 請求量較低 的場景。
優點:
缺點:
四、分庫分表
在資料庫遇到存儲瓶頸和IO瓶頸的時候,數據量過大造成索引性能下降,加上同一時間需要處理大規模的業務請求,這個時候單庫的IO上限會限制處理效率。
所以需要將單張表的數據切分到多個伺服器上去,每個伺服器具有相應的庫與表,只是表中數據集合不同。
分庫分表能夠有效地緩解單機和單庫的 性能瓶頸和壓力 ,突破IO、連接數、硬體資源等的瓶頸。
優點:
缺點:
註:分庫還是分表核心關鍵是有沒有IO瓶頸 。
分片方式都有什麼呢?
RANGE(范圍分片)
將業務表中的某個 關鍵欄位排序 後,按照順序從0到10000一個表,10001到20000一個表。最常見的就是 按照時間切分 (月表、年表)。
比如將6個月前,甚至一年前的數據切出去放到另外的一張表,因為隨著時間流逝,這些表的數據被查詢的概率變小,銀行的交易記錄多數是採用這種方式。
優點:
缺點:
HASH(哈希分片)
將訂單作為主表,然後將其相關的業務表作為附表,取用戶id然後 hash取模 ,分配到不同的數據表或者資料庫上。
優點:
缺點:
講到這里,我們已經知道資料庫有哪些架構,解決的是哪些問題,因此, 我們在日常設計中需要根據數據的特點,數據的傾向性,數據的安全性等來選擇不同的架構 。
那麼,我們應該如何選擇資料庫架構呢?
雖然把上面的架構全部組合在一起可以形成一個強大的高可用,高負載的資料庫系統,但是架構選擇合適才是最重要的。
混合架構雖然能夠解決所有的場景的問題,但是也會面臨更多的挑戰,你以為的完美架構,背後其實有著更多的坑。
1、對事務支持
分庫分表後(無論是垂直還是水平拆分),就成了分布式事務了,如果依賴資料庫本身的分布式事務管理功能去執行事務,將付出高昂的性能代價(XA事務);如果由應用程序去協助控制,形成程序邏輯上的事務,又會造成編程方面的負擔(TCC、SAGA)。
2、多庫結果集合並 (group by,order by)
由於數據分布於不同的資料庫中,無法直接對其做分頁、分組、排序等操作,一般應對這種多庫結果集合並的查詢業務都需要採用數據清洗、同步等其他手段處理(TIDB、KUDU等)。
3、數據延遲
主從架構下的多副本機制和水平分庫後的聚合庫都會存在主數據和副本數據之間的延遲問題。
4、跨庫join
分庫分表後表之間的關聯操作將受到限制,我們無法join位於不同分庫的表(垂直),也無法join分表粒度不同的表(水平), 結果原本一次查詢就能夠完成的業務,可能需要多次查詢才能完成。
5、分片擴容
水平分片之後,一旦需要做擴容時。需要將對應的數據做一次遷移,成本代價都極高的。
6、ID生成
分庫分表後由於資料庫獨立,原有的基於資料庫自增ID將無法再使用,這個時候需要採用其他外部的ID生成方案。
一、應用層依賴類(JDBC)
這類分庫分表中間件的特點就是和應用強耦合,需要應用顯示依賴相應的jar包(以Java為例),比如知名的TDDL、當當開源的 sharding-jdbc 、蘑菇街的TSharding等。
此類中間件的基本思路就是重新實現JDBC的API,通過重新實現 DataSource 、 PrepareStatement 等操作資料庫的介面,讓應用層在 基本 不改變業務代碼的情況下透明地實現分庫分表的能力。
中間件給上層應用提供熟悉的JDBC API,內部通過 sql解析 、 sql重寫 、 sql路由 等一系列的准備工作獲取真正可執行的sql,然後底層再按照傳統的方法(比如資料庫連接池)獲取物理連接來執行sql,最後把數據 結果合並 處理成ResultSet返回給應用層。
優點
缺點
二、中間層代理類(Proxy)
這類分庫分表中間件的核心原理是在應用和資料庫的連接之間搭起一個 代理層 ,上層應用以 標準的MySQL協議 來連接代理層,然後代理層負責 轉發請求 到底層的MySQL物理實例,這種方式對應用只有一個要求,就是只要用MySQL協議來通信即可。
所以用MySQL Navicat這種純的客戶端都可以直接連接你的分布式資料庫,自然也天然 支持所有的編程語言 。
在技術實現上除了和應用層依賴類中間件基本相似外,代理類的分庫分表產品必須實現標準的MySQL協議,某種意義上講資料庫代理層轉發的就是MySQL協議請求,就像Nginx轉發的是Http協議請求。
比較有代表性的產品有開創性質的Amoeba、阿里開源的Cobar、社區發展比較好的 Mycat (基於Cobar開發)等。
優點
缺點
JDBC方案 :無中心化架構,兼容市面上大多數關系型資料庫,適用於開發高性能的輕量級 OLTP 應用(面向前台)。
Proxy方案 :提供靜態入口以及異構語言的支持,適用於 OLAP 應用(面向後台)以及對分片資料庫進行管理和運維的場景。
混合方案 :在大型復雜系統中存在面向C端用戶的前台應用,也有面向企業分析的後台應用,這個時候就可以採用混合模式。
JDBC 採用無中心化架構,適用於 Java 開發的高性能的輕量級 OLTP 應用;Proxy 提供靜態入口以及異構語言的支持,適用於 OLAP 應用以及對分片資料庫進行管理和運維的場景。
ShardingSphere是一套開源的分布式資料庫中間件解決方案組成的生態圈,它由 Sharding-JDBC 、 Sharding-Proxy 和 Sharding-Sidecar (計劃中)這3款相互獨立的產品組成,他們均提供標准化的數據分片、分布式事務和資料庫治理功能,可適用於如Java同構、異構語言、容器、雲原生等各種多樣化的應用場景。
ShardingSphere提供的核心功能:
Sharding-Proxy
定位為透明化的 資料庫代理端 ,提供封裝了 資料庫二進制協議的服務端版本 ,用於完成對 異構語言的支持 。
目前已提供MySQL版本,它可以使用 任何兼容MySQL協議的訪問客戶端 (如:MySQL Command Client, MySQL Workbench, Navicat等)操作數據,對DBA更加友好。
向 應用程序完全透明 ,可直接當做MySQL使用。
適用於任何兼容MySQL協議的客戶端。
Sharding-JDBC
定位為 輕量級Java框架 ,在Java的JDBC層提供的額外服務。 它使用客戶端直連資料庫,以jar包形式提供服務,無需額外部署和依賴,可理解為 增強版的JDBC驅動,完全兼容JDBC和各種ORM框架 。
以電商SaaS系統為例,前台應用採用Sharding-JDBC,根據業務場景的差異主要分為三種方案。
分庫(用戶)
問題解析:頭部企業日活高並發高,單獨分庫避免干擾其他企業用戶,用戶數據的增長緩慢可以不分表。
拆分維度:企業ID分庫
拆分策略:頭部企業單獨庫、非頭部企業一個庫
分庫分表(訂單)
問題解析:訂單數據增長速度較快,在分庫之餘需要分表。
拆分維度:企業ID分庫、用戶ID分表
拆分策略:頭部企業單獨庫、非頭部企業一個庫,分庫之後用戶ID取模拆分表
單庫分表(附件)
問題解析:附件數據特點是並發量不大,只需要解決數據增長問題,所以單庫IO足以支撐的情況下分表即可。
拆分維度:用戶ID分表
拆分策略:用戶ID取模分表
問題一:分布式事務
分布式事務過於復雜也是分布式系統最難處理的問題,由於篇幅有限,後續會開篇專講這一塊內容。
問題二:分布式ID
問題三:跨片查詢
舉個例子,以用戶id分片之後,需要根據企業id查詢企業所有用戶信息。
sharding針對跨片查詢也是能夠支持的,本質上sharding的跨片查詢是採用同時查詢多個分片的數據,然後聚合結果返回,這個方式對資源耗費比較大,特別是對資料庫連接資源的消耗。
假設分4個資料庫,8個表,則sharding會同時發出32個SQL去查詢。一下子消耗掉了32個連接;
特別是針對單庫分表的情況要注意,假設單庫分64個表,則要消耗64個連接。如果我們部署了2個節點,這個時候兩個節點同時查詢的話,就會遇到資料庫連接數上限問題(mysql默認100連接數)
問題四:分片擴容
隨著數據增長,每個片區的數據也會達到瓶頸,這個時候需要將原有的分片數量進行增加。由於增加了片區,原先的hash規則也跟著變化,造成了需要將舊數據做遷移。
假設原先1個億的數據,hash分64個表,現在增長到50億的數據,需要擴容到128個表,一旦擴容就需要將這50億的數據做一次遷移,遷移成本是無法想像的。
問題五:一致性哈希
首先,求出每個 伺服器的hash值 ,將其配置到一個 0~2^n 的圓環上 (n通常取32)
其次,用同樣的方法求出待 存儲對象的主鍵 hash值 ,也將其配置到這個圓環上。
然後,從數據映射到的位置開始順時針查找,將數據分布到找到的第一個伺服器節點上。
一致性hash的優點在於加入和刪除節點時只會影響到在哈希環中相鄰的節點,而對其他節點沒有影響。
所以使用一致性哈希在集群擴容過程中可以減少數據的遷移。
好了,這次分享到這里,我們日常的實踐可能只會用到其中一種方案,但它不是資料庫架構的全貌,打開技術視野,才能更好地把存儲工具利用起來。
老規矩,一鍵三連,日入兩千,點贊在看,年薪百萬!
本文作者:Jensen
7年Java老兵,小米主題設計師,手機輸入法設計師,ProcessOn特邀講師。
曾涉獵航空、電信、IoT、垂直電商產品研發,現就職於某知名電商企業。
技術公眾號 【架構師修行錄】 號主,專注於分享日常架構、技術、職場干貨,Java Goals:架構師。
交個朋友,一起成長!
C. mysql資料庫讀寫分離中間層代理插件都有哪些
mysql-proxy是官方提供的mysql中間件產品可以實現負載平衡,讀寫分離,failover等,但其不支持大數據量的分庫分表且性能較差。 其他mysql開源中間件產品有:Atlas,cobar,tddl。你可以查閱一下相關信息和各自的優缺點。
D. 資料庫中排序的對比及使用條件詳解
假定MySQL伺服器和PHP伺服器都已經按照最適合的方式來配置,那麼系統的可伸縮性(Scalability)和用戶感知性能(User-perceived
Performance)是我們追求的主要目標。在實際運行中,MYSQL
中數據往往以
HASH
tables、BTREE
等方式存貯於內存,操作速度很快;同時INDEX
已經進行了一些預排序;很多應用中,MySQL
排序是首選。
PHP與MySQL相比具有如下優勢:
1、考慮整個網站的可伸縮性和整體性能,在應用層(PHP)中排序明顯會降低資料庫的負載,從而提升整個網站的擴展能力。而資料庫的排序,實際上成本是非常高的,消耗內存、CPU,如果並發的排序很多,DB
很容易到瓶頸。
2、如果在應用層(PHP)和MYSQL之間還存在數據中間層,合理利用,PHP會有更好的收益。
3、PHP在內存中的數據結構專門針對具體應用來設計,比資料庫更為簡潔、高效;
4、PHP不用考慮數據災難恢復問題,可以減少這部分的操作損耗;
5、PHP不存在表的鎖定問題;
6、MySQL中排序,請求和結果返回還需要通過網路連接來進行,而PHP中排序之後就可以直接返回了,減少了網路IO。
至於執行速度,差異應該不會很大,除非應用設計有問題,造成大量不必要的網路IO。另外,應用層要注意PHP
的
Cache
設置,如果超出會報告內部錯誤;此時要根據應用做好評估,或者調整Cache。具體選擇,將取決於具體的應用。
列出一些PHP中執行排序更優的情況:
1、數據源不在MySQL
中,存在硬碟、內存或者來自網路的請求等;
2、數據存在
MySQL
中,量不大,而且沒有相應的索引,此時把數據取出來用PHP排序更快;
3、數據源來自於多個MySQL
伺服器,此時從多個
MySQL
中取出數據,然後在PHP中排序更快;
4、除了MySQL
之外,存在其他數據源,比如硬碟、內存或者來自網路的請求等,此時不適合把這些數據存入MySQL
後再排序;
列出一些必須在MySQL中排序的實例:
1、MySQL中已經存在這個排序的索引;
2、MySQL中數據量較大,而結果集需要其中很小的一個子集;比如
1000000
行數據,取TOP
10;
3、對於一次排序、多次調用的情況,比如統計聚合的情形,可以提供給不同的服務使用,那麼在MySQL
中排序是首選的。另外,對於數據深度挖掘,通常做法是在應用層做完排序等復雜操作,把結果存入MySQL即可,便於多次使用。
4、不論數據源來自哪裡,當數據量大到一定的規模後,由於佔用內存/Cache
的關系,不再適合PHP中排序了;此時把數據復制、導入或者存在MySQL
,並用INDEX
優化,是優於PHP
的。不過,用
Java,甚至
C++
來處理這類操作會更好。
有些類似大數據集聚合或者匯總的數據,在客戶端排序得不償失。當然,也有用類似搜索引擎的思路來解決類似應用的情況。
從網站整體考慮,就必須加入人力和成本的考慮。假如網站規模和負載較小,而人力有限(人數和能力都可能有限),此時在應用層(PHP)做排序要做不少開發和調試工作,耗費時間,得不償失;不如在DB
中處理,簡單快速。對於大規模的網站,電力、伺服器的費用很高,在系統架構上精打細算,可以節約大量的費用,是公司持續發展之必要;此時如果能在應用層(PHP)
進行排序並滿足業務需求,盡量在應用層進行。
關於PHP中執行排序與MySQL中執行排序的相關知識就介紹到這里了,希望本次的介紹能夠對您有所收獲!
E. 負載均衡 後 mysql 怎麼連不上
MySQL Proxy就是這么一個中間層代理,簡單的說,MySQL Proxy就是一個連接池,負責將前台應用的連接請求轉發給後台的資料庫,並且通過使用lua腳本,可以實現復雜的連接控制和過濾,從而實現讀寫分離和負載平衡。
對於應用來說,MySQL Proxy是完全透明的,應用則只需要連接到MySQL Proxy的監聽埠即可。當然,這樣proxy機器可能成為單點失效,但完全可以使用多個proxy機器做為冗餘,在應用伺服器的連接池配置中配置到多個proxy的連接參數即可。建議proxy別跟mysql資料庫安裝在一台伺服器中。
F. MySQL的sharding的程序是不是要自己開發的
不一定需要自己開發。Shard層可以位於:
1、DAO層:一般需要自行開發,可以靈活定製
2、ORM層:比如guzz、Hibernate Shard
3、JDBC API層:比較難,有一個商業產品dbShards
4、應用伺服器與資料庫之間通過代理實現:MySQL Proxy、amoeba.....
一 背景
當資料庫中的數據量越來越大時,不論是讀還是寫,壓力都會變得越來越大。採用MySQL
Replication多master多slave方案,在上層做負載均衡,雖然能夠一定程度上緩解壓力。但是當一張表中的數據變得非常龐大時,壓力還是
非常大的。試想,如果一張表中的數據量達到了千萬甚至上億級別的時候,不管是建索引,優化緩存等,都會面臨巨大的性能壓力。
二 定義
數據sharding,也稱作數據切分,或分區。是指通過某種條件,把同一個資料庫中的數據分散到多個資料庫或多台機器上,以減小單台機器壓力。
三 分類
數據分區根據切分規則,可以分為兩類:
1、垂直切分
數據的垂直切分,也可以稱之為縱向切分。將資料庫想像成為由很多個一大塊一大塊的「數據塊」(表)組成,我們垂直的將這些「數據塊」切開,然後將他們分散
到多台資料庫主機上面。這樣的切分方法就是一個垂直(縱向)的數據切分。以表為單位,把不同的表分散到不同的資料庫或主機上。規則簡單,實施方便,適合業
務之間耦合度低的系統。
Sharding詳解" title="MySQL Sharding詳解" height="373" width="553">
垂直切分的優點
(1)資料庫的拆分簡單明了,拆分規則明確;
(2)應用程序模塊清晰明確,整合容易;
(3)數據維護方便易行,容易定位;
垂直切分的缺點
(1)部分表關聯無法在資料庫級別完成,需要在程序中完成;
(2)對於訪問極其頻繁且數據量超大的表仍然存在性能平靜,不一定能滿足要求;
(3)事務處理相對更為復雜;
(4) 切分達到一定程度之後,擴展性會遇到限制;
(5)過讀切分可能會帶來系統過渡復雜而難以維護。
2、水平切分
一般來說,簡單的水平切分主要是將某個訪問極其平凡的表再按照某個欄位的某種規則來分散到多個表之中,每個表中包含一部分數據。以行為單位,將同一個表中的數據按照某種條件拆分到不同的資料庫或主機上。相對復雜,適合單表巨大的系統。
Sharding詳解" title="MySQL Sharding詳解" height="372" width="553">
水平切分的優點
(1)表關聯基本能夠在資料庫端全部完成;
(2)不會存在某些超大型數據量和高負載的表遇到瓶頸的問題;
(3)應用程序端整體架構改動相對較少;
(4)事務處理相對簡單;
(5)只要切分規則能夠定義好,基本上較難遇到擴展性限制;
水平切分的缺點
(1)切分規則相對更為復雜,很難抽象出一個能夠滿足整個資料庫的切分規則;
(2)後期數據的維護難度有所增加,人為手工定位數據更困難;
(3)應用系統各模塊耦合度較高,可能會對後面數據的遷移拆分造成一定的困難。
3、聯合切分
實際的應用場景中,除了那些負載並不是太大,業務邏輯也相對較簡單的系統可以通過上面兩種切分方法之一來解決擴展性問題之外,恐怕其他大部分業務邏輯稍微
復雜一點,系統負載大一些的系統,都無法通過上面任何一種數據的切分方法來實現較好的擴展性,而需要將上述兩種切分方法結合使用,不同的場景使用不同的切
分方法。
Sharding詳解" title="MySQL Sharding詳解" height="480" width="342">
聯合切分的優點
(1)可以充分利用垂直切分和水平切分各自的優勢而避免各自的缺陷;
(2)讓系統擴展性得到最大化提升;
聯合切分的缺點
(1)資料庫系統架構比較復雜,維護難度更大;
(2)應用程序架構也相對更復雜;
四 實現方案
現在 Sharding 相關的軟體實現其實不少,基於資料庫層、DAO 層、不同語言下也都不乏案例。限於篇幅,此處只作一下簡要的介紹。
1、 Mysql Proxy + HASCALE
一套比較有潛力的方案。其中MySQL Proxy 是用 Lua 腳本實現的,介於客戶端與伺服器端之間,扮演 Proxy
的角色,提供查詢分析、失敗接管、查詢過濾、調整等功能。目前的 0.6 版本還做不到讀、寫分離。HSCALE 則是針對 MySQL Proxy 插件,也是用
Lua 實現的,對 Sharding 過程簡化了許多。需要指出的是,MySQL Proxy 與 HSCALE
各自會帶來一定的開銷,但這個開銷與集中式數據處理方式單條查詢的開銷還是要小的。
MySQLProxy是MySQL官方提供的一個資料庫代理層產品,和MySQLServer一樣,同樣是一個基於GPL開源協議的開源產品。可用來監視、分析或者傳輸他們之間的通訊信息。他的靈活性允許你最大限度的使用它,目前具備的功能主要有連接路由,Query分析,Query過濾和修改,負載均衡,以及基本的HA機制等。
實際上,MySQLProxy本身並不具有上述所有的這些功能,而是提供了實現上述功能的基礎。要實現這些功能,還需要通過我們自行編寫LUA腳本來實現。
MySQLProxy實際上是在客戶端請求與MySQLServer之間建立了一個連接池。所有客戶端請求都是發向MySQLProxy,然後經由MySQLProxy進行相應的分析,判斷出是讀操作還是寫操作,分發至對應的MySQLServer上。對於多節點Slave集群,也可以起做到負載均衡的效果。以下是MySQLProxy的基本架構圖:
Sharding詳解" title="MySQL Sharding詳解" height="480" width="420">
通過上面的架構簡圖,我們可以很清晰的看出MySQLProxy在實際應用中所處的位置,以及能做的基本事情。關於MySQLProxy更為詳細的實施細則在MySQL官方文檔中有非常詳細的介紹和示例,感興趣的讀者朋友可以直接從MySQL官方網站免費下載或者在線閱讀,我這里就不累述浪費紙張了。
http://forge.mysql.com/wiki/MySQL_Proxy
2、 Hibernate Shards
這是 Google 技術團隊貢獻的項目(http://www.hibernate.org/414.html),該項目是在對Google 財務系統數據
Sharding 過程中誕生的。因為是在框架層實現的,所以有其獨特的特性:標準的 Hibernate 編程模型,會用 Hibernate
就能搞定,技術成本較低;相對彈性的 Sharding 策略以及支持虛擬 Shard 等。
3、 Spock Proxy
這也是在實際需求中產生的一個開源項目,基於Mysql Proxy擴展。Spock(http://www.spock.com/)是一個人員查找的 Web
2.0 網站。通過對自己的單一 DB 進行有效 Sharding化 而產生了Spock
Proxy(http://spockproxy.sourceforge.net/ ) 項目,Spock Proxy 算得上 MySQL Proxy
的一個分支,提供基於范圍的 Sharding 機制。Spock 是基於 Rails 的,所以Spock Proxy 也是基於 Rails 構建,關注 ROR
的朋友不應錯過這個項目。
http://spockproxy.sourceforge.net/
4、 Amoeba for MySQL
Amoeba是一個基於Java開發的,專注於解決分布式資料庫數據源整合Proxy程序的開源框架,基於GPL3開源協議。目前,Amoeba已經具有Query路由,Query過濾,讀寫分離,負載均衡以及HA機制等相關內容。
Amoeba 主要解決的以下幾個問題:
(1)數據切分後復雜數據源整合;
(2)提供數據切分規則並降低數據切分規則給資料庫帶來的影響;
(3)降低資料庫與客戶端的連接數;
(4)讀寫分離路由。
我們可以看出,Amoeba所做的事情,正好就是我們通過數據切分來提升資料庫的擴展性所需要的。
Amoeba並不是一個代理層的Proxy程序,而是一個開發資料庫代理層Proxy程序的開發框架,目前基於Amoeba所開發的Proxy程序有AmoebaForMySQL和AmoebaForAladin兩個。
AmoebaForMySQL主要是專門針對MySQL資料庫的解決方案,前端應用程序請求的協議以及後端連接的數據源資料庫都必須是MySQL。對於客戶端的任何應用程序來說,AmoebaForMySQL和一個MySQL資料庫沒有什麼區別,任何使用MySQL協議的客戶端請求,都可以被AmoebaForMySQL解析並進行相應的處理。下如可以告訴我們AmoebaForMySQL的架構信息(出自Amoeba開發者博客):
Sharding詳解" title="MySQL Sharding詳解" height="480" width="384">
AmoebaForAladin則是一個適用更為廣泛,功能更為強大的Proxy程序。他可以同時連接不同資料庫的數據源為前端應用程序提供服務,但是僅僅接受符合MySQL協議的客戶端應用程序請求。也就是說,只要前端應用程序通過MySQL協議連接上來之後,AmoebaForAladin會自動分析Query語句,根據Query語句中所請求的數據來自動識別出該所Query的數據源是在什麼類型資料庫的哪一個物理主機上面。下圖展示了AmoebaForAladin的架構細節(出自Amoeba開發者博客):
Sharding詳解" title="MySQL Sharding詳解" height="480" width="384">
咋一看,兩者好像完全一樣嘛。細看之後,才會發現兩者主要的區別僅在於通過MySQLProtocalAdapter處理之後,根據分析結果判斷出數據源資料庫,然後選擇特定的JDBC驅動和相應協議連接後端資料庫。
其實通過上面兩個架構圖大家可能也已經發現了Amoeba的特點了,他僅僅只是一個開發框架,我們除了選擇他已經提供的ForMySQL和ForAladin這兩款產品之外,還可以基於自身的需求進行相應的二次開發,得到更適應我們自己應用特點的Proxy程序。
當對於使用MySQL資料庫來說,不論是AmoebaForMySQL還是AmoebaForAladin都可以很好的使用。當然,考慮到任何一個系統越是復雜,其性能肯定就會有一定的損失,維護成本自然也會相對更高一些。所以,對於僅僅需要使用MySQL資料庫的時候,我還是建議使用AmoebaForMySQL。
AmoebaForMySQL的使用非常簡單,所有的配置文件都是標準的XML文件,總共有四個配置文件。分別為:
(1)amoeba.xml:主配置文件,配置所有數據源以及Amoeba自身的參數設置;
(2)rule.xml:配置所有Query路由規則的信息;
(3)functionMap.xml:配置用於解析Query中的函數所對應的Java實現類;
(4)rullFunctionMap.xml:配置路由規則中需要使用到的特定函數的實現類;
如果您的規則不是太復雜,基本上僅需要使用到上面四個配置文件中的前面兩個就可完成所有工作。Proxy程序常用的功能如讀寫分離,負載均衡等配置都在amoeba.xml中進行。此外,Amoeba已經支持了實現數據的垂直切分和水平切分的自動路由,路由規則可以在rule.xml進行設置。
目前Amoeba少有欠缺的主要就是其在線管理功能以及對事務的支持了,曾經在與相關開發者的溝通過程中提出過相關的建議,希望能夠提供一個可以進行在線維護管理的命令行管理工具,方便在線維護使用,得到的反饋是管理專門的管理模塊已經納入開發日程了。另外在事務支持方面暫時還是Amoeba無法做到的,即使客戶端應用在提交給Amoeba的請求是包含事務信息的,Amoeba也會忽略事務相關信息。當然,在經過不斷完善之後,我相信事務支持肯定是Amoeba重點考慮增加的feature。
關於Amoeba更為詳細的使用方法讀者朋友可以通過Amoeba開發者博客(http://amoeba.sf.net)上面提供的使用手冊獲取,這里就不再細述了。
案例(http://pengranxiang.iteye.com/blog/1145342)
操作文檔(http://docs.hexnova.com/amoeba/chap-getting-started.html)
5、 HiveDB
和前面的MySQLProxy以及Amoeba一樣,HiveDB同樣是一個基於Java針對MySQL資料庫的提供數據切分及整合的開源框架,只是目前的HiveDB僅僅支持數據的水平切分。主要解決大數據量下資料庫的擴展性及數據的高性能訪問問題,同時支持數據的冗餘及基本的HA機制。
HiveDB的實現機制與MySQLProxy和Amoeba有一定的差異,他並不是藉助MySQL的Replication功能來實現數據的冗餘,而是自行實現了數據冗餘機制,而其底層主要是基於HibernateShards來實現的數據切分工作。
在HiveDB中,通過用戶自定義的各種Partitionkeys(其實就是制定數據切分規則),將數據分散到多個MySQLServer中。在訪問的時候,在運行Query請求的時候,會自動分析過濾條件,並行從多個MySQLServer中讀取數據,並合並結果集返回給客戶端應用程序。
單純從功能方面來講,HiveDB可能並不如MySQLProxy和Amoeba那樣強大,但是其數據切分的思路與前面二者並無本質差異。此外,HiveDB並不僅僅只是一個開源愛好者所共享的內容,而是存在商業公司支持的開源項目。
下面是HiveDB官方網站上面一章圖片,描述了HiveDB如何來組織數據的基本信息,雖然不能詳細的表現出太多架構方面的信息,但是也基本可以展示出其在數據切分方面獨特的一面了。
Sharding詳解" title="MySQL Sharding詳解" height="471" width="553">
http://www.hivedb.org/
6、 DataFabric
application-level sharding
master/slave replication
https://github.com/bpot/data_fabric
7、PL/Proxy
前面幾個都是針對MySQL 的 Sharding 方案,PL/Proxy 則是針對 PostgreSQL 的,設計思想類似 Teradata 的
Hash 機制,數據存儲對客戶端是透明的,客戶請求發送到 PL/Proxy 後,由這里分布式存儲過程調用,統一分發。 PL/Proxy
的設計初衷就是在這一層充當」數據匯流排」的職責,所以,當數據吞吐量支撐不住的時候,只需要增加更多的 PL/Proxy 伺服器即可。大名鼎鼎的 Skype 用的就是
PL/Proxy 的解決方案。
8、Pyshards
這是個基於Python的解決方案。該工具的設計目標還有個 Re-balancing 在裡面,這倒是個比較激進的想法。目前只支持 MySQL
資料庫。
http://code.google.com/p/pyshards/wiki/Pyshards
9、其他實現數據切分及整合的解決方案
除了上面介紹的幾個數據切分及整合的整體解決方案之外,還存在很多其他同樣提供了數據切分與整合的解決方案。如基於MySQLProxy的基礎上做了進一步擴展的HSCALE,通過Rails構建的SpockProxy,以及基於Pathon的Pyshards等等。
不管大家選擇使用哪一種解決方案,總體設計思路基本上都不應該會有任何變化,那就是通過數據的垂直和水平切分,增強資料庫的整體服務能力,讓應用系統的整體擴展能力盡可能的提升,擴展方式盡可能的便捷。
只要我們通過中間層Proxy應用程序較好的解決了數據切分和數據源整合問題,那麼資料庫的線性擴展能力將很容易做到像我們的應用程序一樣方便,只需要通過添加廉價的PCServer伺服器,即可線性增加資料庫集群的整體服務能力,讓資料庫不再輕易成為應用系統的性能瓶頸。
五 注意事項
下面我們所說的分區,主要是指水平分區。
1、在實施分區前,我們可以查看所安裝版本的mysql是否支持分區:
mysql> show variables like "%partition%";
如果支持則會顯示:
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| have_partitioning | YES |
+-------------------+-------+
2、分區適用於一個表的所有數據和索引,不能只對數據分區而不對索引分區,反之亦然,同時也不能只對表的一部分進行分區。
3、分區類型
(1)RANGE 分區:基於屬於一個給定連續區間的列值,把多行分配給分區。
(2)LIST 分區:類似於按RANGE分區,區別在於LIST分區是基於列值匹配一個離散值集合中的某個值來進行選擇。
(3)HASH分區:基於用戶定義的表達式的返回值來進行選擇的分區,該表達式使用將要插入到表中的這些行的列值進行計算(新浪微博採用的方案)。
(4)KEY 分區:類似於按HASH分區,區別在於KEY分區只支持計算一列或多列,且MySQL
伺服器提供其自身的哈希函數。必須有一列或多列包含整數值。
無論使用何種類型的分區,分區總是在創建時就自動的順序編號,且從0開始記錄。當有一新行插入到一個分區表中時,就是使用這些分區編號來識別正確的分區。
4、MySQL提供了許多修改分區表的方式。添加、刪除、重新定義、合並或拆分已經存在的分區是可能的。所有這些操作都可以通過使用ALTER TABLE
命令的分區擴展來實現。
5、可以對已經存在的表進行分區,直接使用alter table命令即可。
G. mysql讀寫分離,應用層分離好還是中間層好
應用層分離:控制上的靈活度更高,實現也簡單,隨時可以調整策略。但帶來的問題就是增加應用層的復雜性以及額外的開發工作,均衡設置、安全防護、分流什麼的,不太好加強。適合中小型項目吧,畢竟到後期的擴容方面有點麻煩。
中間層分離:專業的事還是專業的proxy來負責,應用層專心做應用層的事,中間層按規則做讀寫的分離。擴容均衡起來得心應手,連接池、健康切換,這樣都是應用層無法實現的。適合大型超大型項目