前言
之前總在聊微服務, 微服務本身也是分布式系統,其實微服務的核心思想是分而治之,把一個復雜的單體系統,按照業務的交付,分成不同的自服務,以降低資深復雜度,同時可以提升系統的擴展性,
今天想聊一下分庫分表,因為對于快速增長的業務來說,這個是無法回避的一環,之前我在做商城相關的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的思想劃分業務單元,最開始先做好垂直分庫,接著是針對一些特定的業務增長量巨大的表,進行水平的分庫處理,比如商品子域中的商品池表,訂單子域中的訂單表等等,
而在分表維度,業務初期,就要最好垂直分表的設計,比如商品池設計中,只需要存盤關系資訊,而商品詳情的資訊單獨存盤在一個底表之中,
作者:京東物流 趙勇萍
來源:京東云開發者社區
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/554054.html
標籤:其他
上一篇:海量資料運維要給力,GaussDB(for Cassandra)來助力
下一篇:返回列表
