分而治之 -- 淺談分庫分表及實踐之路

来源:https://www.cnblogs.com/Jcloud/archive/2023/06/01/17448035.html
-Advertisement-
Play Games

今天想聊一下分庫分表,因為對於快速增長的業務來說,這個是無法迴避的一環。之前我在做商城相關的SAAS系統,商品池是一個存儲瓶頸,商品池數量會基於租戶增長和運營變得指數級增長,短短幾個月就能漲到幾千萬的數據,而運營半年後就可能過億。而對於訂單這種數據,也會跟著業務的成長,也會變得愈發巨大。 ...


前言

之前總在聊微服務, 微服務本身也是分散式系統,其實微服務的核心思想是分而治之,把一個複雜的單體系統,按照業務的交付,分成不同的自服務,以降低資深複雜度,同時可以提升系統的擴展性。

今天想聊一下分庫分表,因為對於快速增長的業務來說,這個是無法迴避的一環。之前我在做商城相關的SAAS系統,商品池是一個存儲瓶頸,商品池數量會基於租戶增長和運營變得指數級增長,短短幾個月就能漲到幾千萬的數據,而運營半年後就可能過億。而對於訂單這種數據,也會跟著業務的成長,也會變得愈發巨大。

存儲層來說,提升大數據量下的存儲和查詢性能,就涉及到了另一個層面的問題,但思想還是一樣的,分而治之。

我們面臨什麼樣的問題

關係型資料庫在大於一定數據量的情況下檢索性能會急劇下降。在面對海量數據情況時,所有數據都存於一張表,顯然會輕易超過資料庫表可承受的。

此外單純的分表雖然可以解決數據量過大導致檢索變慢的問題,但無法解決過多併發請求訪問同一個庫,導致資料庫響應變慢的問題。所以需要分庫來解決單資料庫實例性能瓶頸問題。

資料庫架構方案

在講具體解決方案之前,我們需要先瞭解一下資料庫的三種架構涉及方案。

1. Shared Everything

一般指的是單個主機的環境,完全透明共用的CPU/記憶體/硬碟,並行處理能力是最差的,一般不考慮大規模的併發需求,架構比較簡單,一般的應用需求基本都能滿足。

2. Shared Disk

各處理單元使用自己的私有CPU和Memory,共用磁碟系統。典型的代表是Oracle RAC、DB2 PureScale。例如Oracle RAC,他用的是共用存儲,做到了數據共用,可通過增加節點來提高並行處理的能力,擴展能力較好,使用Storage Area Network (SAN),光纖通道連接到多個伺服器的磁碟陣列,降低網路消耗,提高數據讀取的效率,常用於併發量較高的OLTP應用。其類似於SMP(對稱多處理)模式,但是當存儲器介面達到飽和的時候,增加節點並不能獲得更高的性能,同時更多的節點,則增加了運維的成本。

3. Shared Nothing

各處理單元都有自己私有的CPU/記憶體/硬碟等,Nothing,顧名思義,不存在共用資源,類似於MPP(大規模並行處理)模式,各處理單元之間通過協議通信,並行處理和擴展能力更好。典型代表DB2 DPF、帶分庫分表的MySQL Cluster,各節點相互獨立,各自處理自己的數據,處理後的結果可能向上層彙總或在節點間流轉。

我們常說的Sharding其實就是Shared Nothing,他是將某個表從物理存儲上被水平分割,並分配給多台伺服器(或多個實例),每台伺服器可以獨立工作,具備共同的schema,例如MySQL Proxy和Google的各種架構,只需增加伺服器數就可以增加處理能力和容量。

至於MPP,指的是大規模並行分析資料庫(Analytical Massively Parallel Processing (MPP) Databases),他是針對分析工作負載進行了優化的資料庫,一般需要聚合和處理大型數據集。MPP資料庫往往是列式的,因此MPP資料庫通常將每一列存儲為一個對象,而不是將表中的每一行存儲為一個對象。這種體繫結構使複雜的分析查詢可以更快,更有效地處理。例如TeraData、Greenplum,GaussDB100、TBase。

基於以上的這幾種架構方案,我們可以給出大數據量存儲的解決方案:

以上幾種解決方案各有利弊,分區模式最大的問題是準share everything架構,無法水平擴展cpu和記憶體,所以基本可以排除;nosql本身其實是個非常好的備選方案,但是nosql(包括大部分開源newsql)硬體消耗非常大,運維成本較高。而常用的一種方案就是基於Mysql的分庫分表方案。

分庫分表架構方案

對於分庫分表,首先看一下市面上有哪些產品。

業界組件 原廠 功能特性 備註
DBLE 愛可生開源社區 專註於mysql的高可擴展性的分散式中間件 基於MyCAT開發出來的增強版。
Meituan Atlas 美團 讀寫分離、單庫分表 目前已經在原廠逐步下架。
Cobar 阿裡(B2B) Cobar 中間件以 Proxy 的形式位於前臺應用和實際資料庫之間,對前臺的開放的介面是 MySQL 通信協議 開源版本中資料庫只支持 MySQL,並且不支持讀寫分離。
MyCAT 阿裡 是一個實現了 MySQL 協議的伺服器,前端用戶可以把它看作是一個資料庫代理,用 MySQL 客戶端工具和命令行訪問,而其後端可以用MySQL 原生協議與多個 MySQL 伺服器通信 MyCAT 基於阿裡開源的 Cobar 產品而研發
Atlas 360 讀寫分離、靜態分表 2015年後已經不在維護
Kingshard 開源項目 由 Go 開發高性能 MySQL Proxy 項目,在滿足基本的讀寫分離的功能上,Kingshard 的性能是直連 MySQL 性能的80%以上。
TDDL 阿裡淘寶 動態數據源、讀寫分離、分庫分表 TDDL 分為兩個版本, 一個是帶中間件的版本, 一個是直接Java版本
Zebra 美團點評 實現動態數據源、讀寫分離、分庫分表、CAT監控 功能齊全且有監控,接入複雜、限制多。
MTDDL 美團點評 動態數據源、讀寫分離、分散式唯一主鍵生成器、分庫分表、連接池及SQL監控
Vitess 谷歌、Youtube 集群基於ZooKeeper管理,通過RPC方式進行數據處理,總體分為,server,command line,gui監控 3部分 Youtube 大量應用
DRDS 阿裡 DRDS(Distributed Relational Database Service)專註於解決單機關係型資料庫擴展性問題,具備輕量(無狀態)、靈活、穩定、高效等特性,是阿裡巴巴集團自主研
Sharding-proxy apache開源項目 提供MySQL版本,它可以使用任何相容MySQL協議的訪問客戶端(如:MySQL Command Client, MySQL Workbench等)操作數據,對DBA更加友好。嚮應用程式完全透明,可直接當做MySQL使用。適用於任何相容MySQL協議的客戶端。 Apache項目,定位為透明化的資料庫代理端,提供封裝了資料庫二進位協議的服務端版本,用於完成對異構語言的支持。
Sharding jdbc apache開源項目 完全相容JDBC和各種ORM框架。適用於任何基於Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。基於任何第三方的資料庫連接池,如:DBCP,C3P0, BoneCP, Druid, HikariCP等。支持任意實現JDBC規範的資料庫。目前支持MySQL,Oracle,SQLServer和PostgreSQL Apache項目,定位為輕量級Java框架,在Java的JDBC層提供的額外服務。 它使用客戶端直連資料庫,以jar包形式提供服務,無需額外部署和依賴,可理解為增強版的JDBC驅動

對於分庫分表的產品模式,又分為兩種,中間件模式和客戶端模式。

1. 中間件模式其優缺點

中間件模式獨立進程,所以可以支持異構語言,對當前程式沒有侵入性,對業務方來說是透明的mysql服務,但是缺點也非常明顯,硬體消耗大、運維成本高(尤其是在本地化實施情況下),同時因為對關係型資料庫增加了代理,會造成問題難調試。

2. 客戶端模式優缺點

客戶端模式的主要缺點是對代碼有侵入,所以基本只能支持單語言,同時因為每個客戶端都要對schema建立連接,所以如果資料庫實例不多,需要對連接數仔細控制,但是客戶端模式的優點也非常明顯,首先從架構上它是去中心化的,這樣就避免了中間件模式的proxy故障問題,同時因為沒有中間層性能高、靈活可控,而且因為沒有proxy層,不需要考慮proxy的高可用和集群,運維成本也比較低。

sharding-jdbc接入實戰

sharding-jdbc其實是這些產品中最為大家熟知的,也是因為它定位為輕量級 Java 框架,在 Java 的 JDBC 層提供的額外服務。 它使用客戶端直連資料庫,以 jar 包形式提供服務,無需額外部署和依賴,可理解為增強版的 JDBC 驅動,完全相容 JDBC 和各種 ORM 框架。適用於任何基於 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接使用 JDBC。而且在社區活躍度,代碼質量等方面,也是很不錯的。接下來,我講詳細講一下接入細節。

1. 組件集成

<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId> <version> 5.0.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.4.0</version>
</dependency> 

2. bean配置

配置sharding jdbc數據源並且加入到動態數據源中,用於數據源路由。

修改原配置中心對應服務的mysql數據源配置,對不分庫分表的數據源配置為動態數據源預設路由

3. sharing JDBC配置

spring.shardingsphere.enabled=true #shardingsphere開關 
spring.shardingsphere.props.sql.show=true 
spring.shardingsphere.mode.type=Standalone #在使用配置中心的情況下,使用standalone模式即可(memery、standalone、cluster三種模式) 
spring.shardingsphere.mode.repository.type=File #standalone模式下使用File,即當前配置文件 
spring.shardingsphere.mode.overwrite=true # 本地配置是否覆蓋配置中心配置。如果可覆蓋,每次啟動都以本地配置為準。 
spring.shardingsphere.datasource.names=ds-0,ds-1 #配置數據源名字,真實數據源 
#配置ds-0數據源 
spring.shardingsphere.datasource.ds-0.jdbc-url=jdbc:mysql://**** 
spring.shardingsphere.datasource.ds-0.type=com.zaxxer.hikari.HikariDataSource 
spring.shardingsphere.datasource.ds-0.driver-class-name=com.mysql.jdbc.Driver 
spring.shardingsphere.datasource.ds-0.username= 
spring.shardingsphere.datasource.ds-0.password= 
#配置ds-1數據源 
spring.shardingsphere.datasource.ds-1.jdbc-url=jdbc:mysql://****
spring.shardingsphere.datasource.ds-1.type=com.zaxxer.hikari.HikariDataSource 
spring.shardingsphere.datasource.ds-1.driver-class-name=com.mysql.jdbc.Driver 
spring.shardingsphere.datasource.ds-1.username= 
spring.shardingsphere.datasource.ds-1.password= 
#配置模式資料庫分片鍵和相關的表 
spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-column=user_id 
spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-algorithm-name=database-inline 
spring.shardingsphere.rules.sharding.binding-tables[0]=t_order,t_order_item 
spring.shardingsphere.rules.sharding.broadcast-tables=t_address #配置廣播表,即所有庫中都會同步增刪的表 

以上是一些基本配置,還有一些業務場景配置,大家可以參考開源社區文檔: https://shardingsphere.apache.org/document/4.1.0/cn/overview/

總結

對於具體業務場景,我們首先是基於DDD的思想劃分業務單元,最開始先做好垂直分庫。接著是針對一些特定的業務增長量巨大的表,進行水平的分庫處理,比如商品子域中的商品池表,訂單子域中的訂單表等等。

而在分表維度,業務初期,就要最好垂直分表的設計。比如商品池設計中,只需要存儲關係信息,而商品詳情的信息單獨存儲在一個底表之中。

作者:京東物流 趙勇萍

來源:京東雲開發者社區


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # 修改表 ## 修改表名 ```SQL -- 1.將名為 table1 的表修改為 table2 ALTER TABLE table1 RENAME table2; -- 示例 ALTER TABLE aggregate_test RENAME aggregate_test1; -- 2.將表 e ...
  • 雖然之前收集過網名資料庫,比如:《4萬個性網名大全網路名稱大全ACCESS資料庫》、《8萬多個網名大全QQ網名ACCESS資料庫》,但是都包含有~!#@等特殊符號,而今天這份則是沒有特殊符號的,並且記錄數達到了71萬且網名沒有重覆。 分類統計:搞笑網名(20577)、男生網名(66783)、女生網名 ...
  • # [MySQL--SQL優化] # 1、insert優化(插入數據優化) - ## 建議使用批量插入 ```MYSQL # 批量插入避免頻繁連接斷開資料庫(一次連接插入多條數據) insert into 表名 values(數據1),(數據2),(數據3)...... ``` - ## 建議手動提 ...
  • 摘要:應用運維管理平臺(AOM)和Cassandra是兩個不可分割的組成部分,它們共同構成了一個高效的解決方案,可以幫助企業在應用運維業務上取得巨大的優勢。在這篇文章中,我們將介紹AOM和Cassandra的優勢和特點,揭曉它們如何為企業保持市場競爭力的秘密。 本文分享自華為雲社區《海量數據運維要給 ...
  • 背景 最近有個同事對字元串加索引,加完後,發現多了個奇奇怪怪的數字執行的SQL如下: alter table string_index_test add index `idx_name` (`name`) USING BTREE; 這個奇怪數字就是191,它很是疑惑,也沒指定索引的長度通過查看MyS ...
  • 英語類的數據其實已經有很多很多人,但是不同的需求適合的也會是各種的不同,甚至可能需要將多個相關的數據整合起來應用,而今天這份資料庫對於整合來說是非常方便的,因為它是以單詞為關鍵詞進行各種關聯的,也就是說只要是英語類的數據都可以與這份數據關聯起來。 這個數據的好處在於有17830個英語的真人讀音MP3 ...
  • 本文將從 [FTP Connector ](https://www.dtstack.com/resources/1044?src=szsm)的功能詳解,[自定義文件切割](https://www.dtstack.com/resources/1044?src=szsm)及[自定義 FileFormat ...
  • 電影臺詞中有不少令人難忘的好句子,很多時候,愛上一部電影不是因為鏡頭裡的帥哥靚女,不是因為故事情節的跌宕起伏,只是因為有那麼一句話,在主人公說出口的那一瞬間,擊中我們內心最柔軟的部分。本資料庫收錄經典電影臺詞大全,讓我們來欣賞每部電影的經典臺詞、經典對白。此外,還收錄了部分晚會、小品的經典臺詞。收錄 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...