經過讀寫分離的優化后,小王可算是輕松了一段時間,讀寫分離具體的方案請查看這篇文章:
Sharding-JDBC:查詢量大如何優化?
可是好景不長,業務發展是在太快了。數據庫中的數據量猛增,由於所有表都在一個數據庫中,導致服務器本地存儲快滿了。
從上圖我們可以看的出來,由於表的數量較多,每個表的數據量也較大,但是還沒到水平拆分的地步。目前遇到的問題是服務器的存儲不夠了,短期內還不用水平拆分,那么方案呼之欲出了:垂直拆分。
解釋下什么是垂直拆分?
我們都知道,一個數據庫它是由N張表構成,每個表存儲的數據都不一樣,都對應着各自的業務。
所謂的垂直切分其實就是分類存儲,大部分都是按業務類型進行分類。相同的類型存儲在相同的庫上,不同的類型存儲在不同的庫上,這樣也就將數據或者說壓力分擔到不同的庫上面 。
比如我們可以將用戶相關的放一起,訂單相關的放一起,行為日志相關的放一起,依次來推下去。
- 優點:
拆分之后業務規划清晰,數據維護簡單,分擔了數據集中存儲的壓力。
- 缺點:
缺點也很明顯,多表join查詢無法實現,只能通過接口方式解決,提高了系統復雜度等問題。
做垂直拆分其實跟讀寫分離是一樣的,本質上還是多數據源的問題,本文中先考慮最簡單的垂直拆分方式,垂直拆分+讀寫分離我們下篇文章進行講解。
垂直拆分步驟
至於怎么整合Sharding-JDBC就不在講解了,上篇文章有講解過,直接開始和興步驟。
假設我們拆分成了2個庫,分別是ds_0和ds_1,每個庫中的表不同,ds_0中放了user表,SQL腳本如下:
CREATE DATABASE `ds_0` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
CREATE TABLE `user`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ds_1中放了loudong表,SQL腳本如下:
CREATE DATABASE `ds_1` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
CREATE TABLE `loudong` (
`id` varchar(20) NOT NULL,
`city` varchar(20) NOT NULL,
`region` varchar(20) NOT NULL,
`name` varchar(20) NOT NULL,
`ld_num` varchar(10) NOT NULL,
`unit_num` varchar(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
最核心的還是數據源的配置以及綁定:
spring.shardingsphere.datasource.names=ds0,ds1
# ds0數據源
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456
# ds1數據源
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://localhost:3306/ds_1?characterEncoding=utf-8
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
# 綁定loudong表所在節點
spring.shardingsphere.sharding.tables.loudong.actual-data-nodes=ds1.loudong
# 綁定user表所在節點
spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds0.user
# 設置自增ID
spring.shardingsphere.sharding.tables.user.key-generator.column=id
# 設置自增ID算法
spring.shardingsphere.sharding.tables.user.key-generator.type=SNOWFLAKE
配置完之后該怎么用還是怎么用,完全不用改變一行代碼。sharding-jdbc底層會對數據源進行接管。
如果我們不用sharding-jdbc的話,你同樣需要配置2個數據源,這個其實差不多,最復雜的就是你在操作數據庫的時候需要知道當前的操作是哪個數據源,因為每個數據源中的表都不一樣,通過sharding-jdbc框架屏蔽了這些復雜的操作。
垂直拆分下的讀寫分離步驟
從最開始的單庫多表,到讀寫分離,再到垂直拆分多個庫。
循序漸進的為大家講解高並發,大數據量下的數據庫解決方案。並引入開源的Sharding-JDBC來實現具體的方案。
垂直拆分后進一步提升性能的方式就是垂直拆分多庫的讀寫分離,如下圖:
要實習這個功能,我們只需要在上面的基礎上,為每個庫增加一個從節點的配置就可以了,然后用master-slave-rules將主從數據源進行綁定,如下:
spring.shardingsphere.datasource.names=ds0,ds0slave,ds1,ds1slave
# ds0主數據源
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456
# ds0從數據源
spring.shardingsphere.datasource.ds0slave.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0slave.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0slave.url=jdbc:mysql://localhost:3306/ds0slave?characterEncoding=utf-8
spring.shardingsphere.datasource.ds0slave.username=root
spring.shardingsphere.datasource.ds0slave.password=123456
# ds1主數據源
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://localhost:3306/ds_1?characterEncoding=utf-8
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
# ds1從數據源
spring.shardingsphere.datasource.ds1slave.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1slave.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1slave.url=jdbc:mysql://localhost:3306/ds1slave?characterEncoding=utf-8
spring.shardingsphere.datasource.ds1slave.username=root
spring.shardingsphere.datasource.ds1slave.password=123456
# 綁定loudong表所在節點
spring.shardingsphere.sharding.tables.loudong.actual-data-nodes=ds1.loudong
# 綁定user表所在節點
spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds0.user
spring.shardingsphere.sharding.tables.user.key-generator.column=id
spring.shardingsphere.sharding.tables.user.key-generator.type=SNOWFLAKE
# 讀寫分離
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=ds0
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=ds0slave
spring.shardingsphere.sharding.master-slave-rules.ds1.master-data-source-name=ds1
spring.shardingsphere.sharding.master-slave-rules.ds1.slave-data-source-names=ds1slave
源碼參考:https://github.com/yinjihuan/sharding-jdbc
覺得不錯的記得關注下哦,給個Star吧!