當前位置:編程學習大全網 - 源碼下載 - Mysqlproxy源代碼

Mysqlproxy源代碼

隨著時間和業務的發展,數據庫中數據的增長是不可控的,庫和表中的數據會越來越大,帶來更高的磁盤、IO、系統開銷甚至性能瓶頸,而單臺服務器的資源畢竟是有限的。

因此,在業務擴展的過程中,應用對數據庫系統的健壯性、安全性和可擴展性提出了更高的要求。

下面,我就讓妳從數據庫架構,選型,落地開始。

數據庫將面臨哪些挑戰?

在創業初期,我們只用壹個單機數據庫就夠了。然而,隨著業務的增長,數據規模和用戶規模增加,此時,數據庫將面臨IO瓶頸、存儲瓶頸、可用性和安全性問題。

為了解決上述問題,從數據庫中衍生出不同的架構來解決不同的場景需求。

數據庫的寫操作和讀操作是分開的,主庫接收寫請求,從庫的多個副本用於處理讀請求。從庫和主庫同步更新數據以保持數據壹致性,從庫可以橫向擴展以面對讀取請求的增加。

這種模式也叫讀寫分離,針對的是小規模的數據,有大量的讀取操作。

因為主從數據是壹樣的,壹旦主庫宕機,從庫可以切換到主庫提供寫入,所以這種架構也可以提高數據庫系統的安全性和可用性;

優勢:

缺點:

在數據庫遇到IO瓶頸的過程中,如果IO集中在某壹塊業務上,此時可以考慮的是將熱點業務縱向拆分出來,避免其他正常業務受到熱點業務密集IO請求的影響,所以縱向分支也叫業務分支。

優勢:

缺點:

當數據庫遇到存儲瓶頸時,索引性能會因數據量過大而下降。

這時候可以考慮橫向拆分數據,按照壹定的規則,將數據量巨大的單個表拆分成多個表。

但是這些表還是在同壹個庫中,所以庫級的數據庫操作還是存在IO瓶頸(單臺服務器的IO是有上限的)。

所以橫向子表主要針對數據量大,整體業務請求低的場景。

優勢:

缺點:

第四,子庫和子表

當數據庫遇到存儲瓶頸和IO瓶頸時,索引性能會因為數據量大而下降,同時需要處理大規模的業務請求。此時單個數據庫的IO上限會限制處理效率。

所以需要把單個表的數據劃分到多個服務器上,每個服務器都有對應的庫和表,但是表中的數據集是不壹樣的。

子庫子表可以有效緩解單機單庫的性能瓶頸和壓力,突破IO、連接數和硬件資源的瓶頸。

優勢:

缺點:

註:是否存在IO瓶頸是子數據庫或子表的關鍵。

碎片化方法有哪些?

範圍(範圍切片)

對業務表中的壹個關鍵字段排序後,將是壹個從0到10000的表,壹個從10001到20000的表。最常見的是時間劃分(月表,年表)。

比如把半年前甚至壹年前的數據剪下來放到另壹個表中,因為隨著時間的推移,這些表中的數據出現的概率變小了,大部分銀行交易記錄都是這樣。

優勢:

缺點:

哈希(哈希片)

以訂單為主表,再以其相關的業務表為附表,取用戶id再哈希模塊,分布到不同的數據表或數據庫。

優勢:

缺點:

此時,我們已經知道數據庫具有什麽樣的架構,以及它解決了什麽問題。所以我們在日常設計中需要根據數據的特點、傾向性、安全性來選擇不同的架構。

那麽,我們應該如何選擇數據庫架構呢?

雖然以上所有架構都可以組合起來形成壹個強大的高可用高負載的數據庫系統,但最重要的是選擇合適的架構。

混合架構雖然可以解決場景中的所有問題,但也會面臨更多的挑戰。妳認為完美的建築背後其實有更多的坑。

1,交易支持

將數據庫分成表(無論是垂直還是水平)後,就變成了分布式事務。如果依靠數據庫本身的分布式事務管理功能來執行事務,我們將付出很高的性能代價(XA事務);如果用應用程序輔助控制,會造成編程的負擔(TCC,SAGA)。

2.多數據庫結果的分組依據(排序依據)。

由於數據分布在不同的數據庫中,無法直接進行分頁、分組、排序等操作。壹般而言,其他方式(TIDB、庫都等。)來處理多數據庫結果聚合的查詢業務。

3.數據延遲

無論是主從架構下的多副本機制,還是水平庫分離後的聚合庫,都會存在主數據和副本數據之間的延遲問題。

4.跨庫連接

子數據庫和子表劃分後,表與表之間的關聯操作將受到限制。我們不能連接位於不同子數據庫中的表(縱向)或連接不同粒度的表(橫向)。因此,壹次查詢即可完成的業務可能需要多次查詢。

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協議請求壹樣。

代表產品有首創的阿米巴、阿裏的開源Cobar、社區開發較好的Mycat(基於Cobar)。

優勢

劣勢

JDBC方案:非集中式架構,兼容市面上大多數關系數據庫,適合開發高性能輕量級OLTP應用(面向前臺)。

代理方案:提供靜態門戶和異構語言支持,適用於OLAP應用(面向後臺)以及管理和操作碎片化數據庫的場景。

混合方案:大型復雜系統中有面向C端用戶的前臺應用和面向企業分析的後臺應用,此時可以采用混合模式。

JDBC采用分散式架構,適合Java開發的高性能輕量級OLTP應用。代理提供靜態門戶和異構語言支持,適用於OLAP應用程序以及管理和操作碎片化數據庫的場景。

ShardingSphere是壹個開源分布式數據庫中間件解決方案的生態系統,由三個獨立的產品組成,Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(計劃中)。它們都提供了標準化的數據分片、分布式事務和數據庫治理功能,可以應用於Java同構、異構語言、容器和雲原生等多種應用場景。

ShardingSphere提供的核心功能:

分片代理

定位為透明的數據庫代理,它提供了封裝數據庫二進制協議的服務器版本,以支持異構語言。

目前已經提供了MySQL版本,可以使用任何兼容MySQL協議的access客戶端(如MySQL命令客戶端、MySQL Workbench、Navicat等。)來操作數據,對DBA更友好。

對應用程序完全透明,可以直接作為MySQL使用。

適用於任何兼容MySQL協議的客戶端。

沙爾丁-JDBC

定位為輕量級spring mvc,它在Java的JDBC層提供額外的服務。它使用客戶端直接連接數據庫,以jar包的形式提供服務,不需要額外的部署和依賴。可以理解為增強的JDBC驅動,完全兼容JDBC和各種ORM框架。

以電子商務SaaS系統為例,前臺應用采用分片-JDBC,根據業務場景的不同主要分為三種方案。

子庫(用戶)

問題分析:頭部企業日常活躍度高並發度高,數據庫單獨劃分,避免打擾其他企業用戶。用戶數據增長緩慢,可以分表。

拆分維:企業ID分支庫

拆分策略:頭部企業獨立庫,非頭部企業壹庫。

子倉庫和子表(訂單)

問題分析:訂單數據增長很快,除了庫還需要分表。

拆分維度:企業ID子庫和用戶ID子表。

拆分策略:頭部企業有單獨的庫,非頭部企業有庫。拆分庫後,用戶ID帶模塊拆分表。

單庫子表(附件)

問題分析:附件數據的特點是小並發,只需要解決數據增長的問題,所以如果單個庫IO足夠支撐的話,可以分表。

拆分維度:用戶ID子表

拆分策略:用戶ID模塊化表。

問題1:分布式事務

分布式事務的復雜性也是分布式系統中最難處理的問題。由於篇幅有限,接下來的會議將集中討論這部分內容。

問題2:分布式ID

問題三:跨片查詢

比如按用戶id切片後,需要根據企業id查詢該企業的所有用戶信息。

Harding還可以支持跨片查詢。本質上,Harding的跨切片查詢是同時查詢多個切片的數據,然後將結果聚合回來。這種方法消耗大量資源,尤其是連接到數據庫的資源。

假設有4個數據庫和8個表,分片會同時發送32條SQL進行查詢。壹次消耗32個連接;

特別是對於單個數據庫劃分為表的情況,需要註意的是,如果單個數據庫劃分為64個表,將消耗64個連接。如果我們部署兩個節點,此時如果兩個節點同時查詢,就會遇到數據庫連接數上限的問題(mysql默認為100個連接)。

問題4:分段擴展

隨著數據的增長,各個區域的數據也會達到瓶頸。這時候就需要增加原來的切片數量。由於面積的增加,原來的哈希規則也發生了變化,導致需要遷移舊數據。

假設原來1億的數據,hash分成64個表,現在50億的數據需要擴展到128個表。壹旦擴容,50億的數據需要遷移壹次,遷移成本難以想象。

問題5:壹致的哈希

首先找到每臺服務器的哈希值,配置在0 ~ 2 n (n壹般取32)的環上。

其次,要存儲的對象的主鍵的哈希值也是用同樣的方法得到的,也是在這個環上配置的。

然後,從映射數據的位置開始,順時針搜索數據,並將其分發到找到的第壹個服務器節點。

壹致哈希的好處是增加和刪除節點只會影響哈希環中的鄰居節點,不會影響其他節點。

因此,使用壹致哈希可以減少集群擴展過程中的數據遷移。

好了,這次分享到這裏,我們的日常實踐可能只使用其中壹種方案,但並不是數據庫架構的全貌。只有打開技術視野,才能更好地利用存儲工具。

老規矩,壹鍵三連,壹天兩千,喜歡看,年薪百萬!

作者:詹森

7年Java資深人士,小米主題設計師,手機輸入法設計師,ProcessOn特邀講師。

曾涉足航空、電信、物聯網和垂直電商產品研發,現就職於某知名電商公司。

技術微信官方賬號架構師實操大師,專註於分享日常架構、技術和職場幹貨,Java目標:架構師。

交個朋友,壹起成長!

  • 上一篇:規劃局源代碼
  • 下一篇:PHP程序員未來的發展方向
  • copyright 2024編程學習大全網