互聯網三高-數據庫高并發之分庫分表ShardingJDBC

1?ShardingJDBC介紹

? ? ? ? 1.1 常見概念術語

? ? ? ? ? ? ? ? ① 數據節點Node:數據分片的最小單元,由數據源名稱和數據表組成

? ? ? ? ? ? ? ? ? ? ? ? 如:ds0.product_order_0

? ? ? ? ? ? ? ? ② 真實表:再分片的數據庫中真實存在的物理表

? ? ? ? ? ? ? ? ? ? ? ? 如:product_order_0

? ? ? ? ? ? ? ? ③ 邏輯表:相同邏輯和數據結構表的總稱

? ? ? ? ? ? ? ? ? ? ? ? 如:product_order

? ? ? ? ? ? ? ? ④ 綁定規則:指分片規則一致的主表和子表

? ? ? ? ? ? ? ? ? ? ? ? 如:order表和order_item表,都是按照order_id分片

? ? ? ? ? ? ? ? 綁定表之間的多表關聯查詢不會出現笛卡爾積關聯,關聯查詢效率提升

? ? ? ? 1.2 常見分片算法

? ? ? ? ? ? ? ? 分片鍵:用于分片的數據庫字段,是將數據庫(表)水平拆分的關鍵字段

? ? ? ? ? ? ? ??ShardingJDBC既支持單分片鍵,也支持多個字段進行分片

? ? ? ? ? ? ? ? 分片策略

????????????????

? ? ? ? ? ? ? ? ? ? ? ? ① 行表達式分片:InlineShardingStrategy

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 只支持單分片鍵

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 使用groovy表達式,提供對SQL語言的 = 和 IN 的分片操作支持

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 如:product_order_$->{user_id % 2} => product_order_0 和 product_order_1

? ? ? ? ? ? ? ? ? ? ? ? ② 標準分片:StandardShardingStrategy

????????????????????????????????只支持單分片鍵

????????????????????????????????PreciseShardingAlgorithm:精準分片,處理?= 和 IN 的分片操作

????????????????????????????????RangeShardingAlgorithm:范圍分片,處理?BETWEEN AND?的分片操作

? ? ? ? ? ? ? ? ? ? ? ? ③ 復合分片:ComplexShardingStrategy

????????????????????????????????支持多分片鍵

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 提供??= 、 IN 和?BETWEEN AND?的分片操作

? ? ? ? ? ? ? ? ? ? ? ? ④ Hint分片:HintShardingStrategy

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 無需配置分片鍵,外部手動指定分片鍵

? ? ? ? ? ? ? ? ? ? ? ? ⑤ 不分片:NoneShardingStrategy

2 快速入門

? ? ? ? SpringBoot整合ShardingJDBC

(1)導入依賴

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.5.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.38</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.5.5</version></dependency>
</dependencies>

(2)編寫啟動類

@SpringBootApplication
@EnableTransactionManagement
@MapperScan("com.pandy.mapper")
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}
}

(3)創建數據庫、表(2個庫,4個表)

CREATE TABLE `product_order_0` (`id` bigint NOT NULL AUTO_INCREMENT,`out_trade_no` varchar(64) DEFAULT NULL COMMENT '訂單唯一標識',`state` varchar(11) DEFAULT NULL COMMENT 'NEW 未支付訂單,PAY已經支付訂單,CANCEL超時取消訂單',`create_time` datetime DEFAULT NULL COMMENT '訂單生成時間',`pay_amount` decimal(16,2) DEFAULT NULL COMMENT '訂單實際支付價格',`nickname` varchar(64) DEFAULT NULL COMMENT '昵稱',`user_id` bigint DEFAULT NULL COMMENT '用戶id',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

(4)編寫實體類

@Data
@TableName("product_order")
@EqualsAndHashCode(callSuper = false)
public class ProductOrderDO {@TableId(value = "id",type = IdType.AUTO)private Long id;private String outTradeNo;private String state;private Date createTime;private Double payAmount;private String nickname;private Long userId;
}

(5)編寫配置信息-分庫分表(這里以分表為例,以user_id為分片鍵)

# 打印執行的數據庫以及語句
spring.shardingsphere.props.sql.show=true# 數據源 db0
spring.shardingsphere.datasource.names=ds0,ds1# 第一個數據庫
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://192.168.5.135:3306/sharding_db_0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root# 第二個數據庫
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://192.168.5.135:3306/sharding_db_1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root# 指定product_order表的數據分布情況,配置數據節點,行表達式標識符使用 ${...} 或 $->{...},
# 但前者與 Spring 本身的文件占位符沖突,所以在 Spring 環境中建議使用 $->{...}
spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds0.product_order_$->{0..1}# 指定product_order表的分片策略,分片策略包括【分片鍵和分片算法】
spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.algorithm-expression=product_order_$->{user_id % 2}

(6)單元測試

@Test
public void testInsertProductOrder() {for(int i=0; i<10; i++) {ProductOrderDO orderDO = new ProductOrderDO();orderDO.setOutTradeNo(UUID.randomUUID().toString().replaceAll("-",""));orderDO.setCreateTime(new Date());orderDO.setPayAmount(100d);orderDO.setState("NEW");orderDO.setNickname("pandy-" + i);orderDO.setUserId(Long.parseLong(i + ""));productOrderMapper.insert(orderDO);}
}

分庫分表執行邏輯

(7)主鍵重復問題

? ? ? ? 使用自增主鍵,出現主鍵ID重復問題

3 分庫分表常見主鍵ID生成策略

? ? ? ? 需求:

? ? ? ? ? ? ? ? ① 性能強勁

? ? ? ? ? ? ? ? ② 全局唯一

? ? ? ? ? ? ? ? ③ 防止惡意用戶根據ID規則來猜測和獲取數據

? ? ? ? 3.1 業界常見解決方案

? ? ? ? ? ? ? ? (1)自增ID,設置不同的自增步長

? ? ? ? ? ? ? ? ? ? ? ? 缺點:① 未來擴容比較麻煩

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ② 主從切換時不一致可能會導致重復ID

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ③ 性能瓶頸

? ? ? ? ? ? ? ? (2)UUID

UUID.randomUUID().toString().replaceAll("-","");

? ? ? ? ? ? ? ? ? ? ? ? 優點:性能非常高,沒有網絡消耗

? ? ? ? ? ? ? ? ? ? ? ? 缺點:① 無序的字符串,不具備趨勢自增特性

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ② UUID太長,不易于存儲,浪費存儲空間

? ? ? ? ? ? ? ? (3)Redis發號器

? ? ? ? ? ? ? ? ? ? ? ? 利用Redis的incr 或incrby 來實現,原子操作,線程安全

? ? ? ? ? ? ? ? ? ? ? ? 缺點:① 需要占用網絡資源,增加系統復雜性

? ? ? ? ? ? ? ? (4)snowflake雪花算法

? ? ? ? ? ? ? ? ? ? ? ? twitter開源的分布式ID生成算法

? ? ? ? ? ? ? ? ? ? ? ? 生成的ID中包含時間戳,所以生成的ID按照時間遞增

? ? ? ? ? ? ? ? ? ? ? ? 部署多臺服務器,需要保證系統時間一樣,機器編號不一樣

? ? ? ? ? ? ? ? ? ? ? ? 缺點:依賴系統時間(時鐘回撥問題)

? ? ? ? ? ? ? ? 配置使用shardingjdbc的雪花算法

# 配置ID使用雪花算法
spring.shardingsphere.sharding.key-generator.column=id
spring.shardingsphere.sharding.key-generator.type=SNOWFLAKE

? ? ? ? 看一下源碼,?shardingjdbc的雪花算法是怎么解決時鐘回撥問題的?

4 廣播表和綁定表配置?

? ? ? ? 廣播表:指所有的分片數據源中都存在的表,表結構和表中的數據在每個數據庫中均完全一致

? ? ? ? ? ? ? ? 如:字典表,配置表等

(1)創建一個配置表

CREATE TABLE `config` (`id` bigint unsigned NOT NULL COMMENT '主鍵id',`config_key` varchar(1024) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '配置key',`config_value` varchar(1024) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '配置value',`type` varchar(128) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '類型',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

(3)創建實體類

@Data
@TableName("config")
@EqualsAndHashCode(callSuper = false)
public class ConfigDO {@TableId(value = "id")private Long id;private String configKey;private String configValue;private String type;
}

(3)添加廣播表配置

#配置廣播表
spring.shardingsphere.sharding.broadcast-tables=config

(4)測試代碼?

@Test
public void insertConfig() {ConfigDO configDO = new ConfigDO();configDO.setConfigKey("iphone");configDO.setConfigValue("iphone16秒殺廣告");configDO.setType("AD");configMapper.insert(configDO);
}

5 分庫分表核心流程

? ? ? ? 解析 --> 路由 --> 改寫?--> 執行?--> 結果歸并

? ? ? ? (1)解析

? ? ? ? ? ? ? ? 詞法解析

? ? ? ? ? ? ? ? 語法解析

? ? ? ? (2)路由

? ? ? ? ? ? ? ? 分片路由(帶分片鍵):直接路由,標準路由,笛卡爾積路由

? ? ? ? ? ? ? ? 廣播路由(不帶分片鍵):全庫表路由,全庫路由,全實例路由

? ? ? ? (3)改寫

? ? ? ? ? ? ? ? 將邏輯SQL改寫為可以正確執行的真實SQL

? ? ? ? (4)執行

? ? ? ? ? ? ? ? 采用自動化的執行引擎

? ? ? ? ? ? ? ? 內存限制模式:適用于OLAP(連接數量不做限制,多線程并發執行)

? ? ? ? ? ? ? ? 連接限制模式:適用于OLAP(1庫1線程,多庫多線程,保證數據庫資源足夠多使用)

? ? ? ? (5)結果歸并

? ? ? ? ? ? ? ? 從各個數據節點獲取多數據結果集,組合成為一個結果集

? ? ? ? ? ? ? ? 流式歸并:每一次從結果集中獲取到數據

? ? ? ? ? ? ? ? 內存歸并:分片結果集的數據存儲在內存中

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/76734.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76734.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/76734.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

BM25、BGE以及text2vec-base-chinese的區別

BM25、BGE以及text2vec-base-chinese的區別 BM25 原理:BM25(Best Matching 25)是一種基于概率檢索模型的算法,它通過考慮查詢詞與文檔之間的匹配程度、文檔的長度等因素,來計算文檔對于查詢的相關性得分。具體來說,它會給包含查詢詞次數較多、文檔長度適中的文檔更高的分…

Python中try用法、內置異常類型與自定義異常類型拓展

目錄 try介紹與語法格式try具體使用案例except的異常類型簡介案例內置的常見異常類型自定義異常類型繼承關系用途 注意事項 try介紹與語法格式 在 Python 里&#xff0c;try 語句主要用于異常處理&#xff0c;其作用是捕獲并處理代碼運行期間可能出現的異常&#xff0c;避免程…

【第41節】windows的中斷與異常及異常處理方式

目錄 一、中斷與異常處理 1.1 中斷與異常 1.2 IDT 1.3 異常的概念 1.4 異常分類 二、windows異常處理方式 2.1 概述 2.2 結構化異常處理 2.3 向量化異常處理之VEH 2.4 向量化異常處理之VCH 2.5 默認的異常處理函數 2.6 如何手動安裝 SEH 節點 2.7 異常處理的優先級…

分布式日志治理:Log4j2自定義Appender寫日志到RocketMQ

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家&#xff0c;歷代文學網&#xff08;PC端可以訪問&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移動端可微信小程序搜索“歷代文學”&#xff09;總架構師&#xff0c;15年工作經驗&#xff0c;精通Java編…

【HTML】html文件

HTML文件全解析&#xff1a;搭建網頁的基石 在互聯網的廣袤世界里&#xff0c;每一個絢麗多彩、功能各異的網頁背后&#xff0c;都離不開HTML文件的默默支撐。HTML&#xff0c;即超文本標記語言&#xff08;HyperText Markup Language&#xff09;&#xff0c;作為網頁創建的基…

oracle命令上下左右鍵無法使用如何解決?

1、問題如圖 2、解決辦法 (1) 安裝readline yum -y install readline* &#xff08;2&#xff09;安裝 rlwrap ##下載 wget http://files.cnblogs.com/files/killkill/rlwrap-0.30.tar.gz.zip ##解壓 tar -xzvf rlwrap-0.30.tar.gz.zip ##編譯安裝 ./configure make &&…

vue事假機制都有哪些

Vue 的事件機制主要包含以下幾種類型和方式&#xff0c;可以分為組件內部事件、父子組件通信事件、原生 DOM 事件封裝、修飾符增強等&#xff0c;下面詳細分類介紹&#xff1a; 一、DOM 事件綁定&#xff08;最基礎的事件&#xff09; 使用 v-on&#xff08;或簡寫 &#xff0…

系統編程2(消息隊列)

? 消息隊列概念 Linux系統中消息隊列&#xff08;Message Queue&#xff09;是進程間通信的一種方式&#xff0c;這種通信機制的好處是可以傳輸指定類型(用戶可以自行定義)的數據&#xff0c;相同類型的數據根據到達順序在隊列中進行排隊。 當然&#xff0c;不同類型的數據不…

Pytorch深度學習框架60天進階學習計劃 - 第41天:生成對抗網絡進階(二)

Pytorch深度學習框架60天進階學習計劃 - 第41天&#xff1a;生成對抗網絡進階&#xff08;二&#xff09; 7. 實現條件WGAN-GP # 訓練條件WGAN-GP def train_conditional_wgan_gp():# 用于記錄損失d_losses []g_losses []# 用于記錄生成樣本的多樣性&#xff08;通過類別分…

python 微博爬蟲 01

起因&#xff0c; 目的: ?下載單個視頻&#xff0c;完成。? 獲取某用戶的視頻列表&#xff0c;完成。剩下的就是&#xff0c; 根據視頻列表&#xff0c;逐個下載視頻&#xff0c;我沒做&#xff0c;沒意思。獲取視頻的評論&#xff0c;以后再說。 關鍵點記錄: 1. 對一個視…

Servlet、HTTP與Spring Boot Web全面解析與整合指南

目錄 第一部分&#xff1a;HTTP協議與Servlet基礎 1. HTTP協議核心知識 2. Servlet核心機制 第二部分&#xff1a;Spring Boot Web深度整合 1. Spring Boot Web架構 2. 創建Spring Boot Web應用 3. 控制器開發實踐 4. 請求與響應處理 第三部分&#xff1a;高級特性與最…

vue中根據html動態渲染內容2.0

上次使用的是p標簽用的contenteditable代替的可編輯的input&#xff0c;最后實現還是選擇了用el-input的textarea方式。 一開始考慮的是需要根據用戶輸入自動撐開輸入框&#xff0c;所以選擇了p標簽可編輯。 最后發現還是el-input會更好一點&#xff0c;只不過需要處理輸入框撐…

CentOS 系統磁盤擴容并掛載到根目錄(/)的詳細步驟

在使用 CentOS 系統時&#xff0c;經常會遇到需要擴展磁盤空間的情況。例如&#xff0c;當虛擬機的磁盤空間不足時&#xff0c;可以通過增加磁盤容量并將其掛載到根目錄&#xff08;/&#xff09;來解決。以下是一個完整的操作流程&#xff0c;詳細介紹了如何將新增的 10G 磁盤…

LINUX基礎 [二] - Linux常見指令

目錄 &#x1f4bb;前言 &#x1f4bb;指令 &#x1f3ae;ls指令 &#x1f3ae;pwd指令 &#x1f3ae;whoami指令 &#x1f3ae;cd指令 &#x1f3ae;clear指令 &#x1f3ae;touch指令 &#x1f3ae;mkdir指令 &#x1f3ae;rmdir指令 &#x1f3ae;rm指令 &#…

基于php的成績分析和預警與預測網站(源碼+lw+部署文檔+講解),源碼可白嫖!

摘要 人類現已邁入二十一世紀&#xff0c;科學技術日新月異&#xff0c;經濟、資訊等各方面都有了非常大的進步&#xff0c;尤其是資訊與網絡技術的飛速發展&#xff0c;對政治、經濟、軍事、文化、教育等各方面都有了極大的影響。 利用電腦網絡的這些便利&#xff0c;發展一套…

《從底層邏輯剖析:分布式軟總線與傳統計算機硬件總線的深度對話》

在科技飛速發展的當下&#xff0c;我們正見證著計算機技術領域的深刻變革。計算機總線作為信息傳輸的關鍵樞紐&#xff0c;其發展歷程承載著技術演進的脈絡。從傳統計算機硬件總線到如今備受矚目的分布式軟總線&#xff0c;每一次的變革都為計算機系統性能與應用拓展帶來了質的…

Spring Boot 3.5新特性解析:自動配置再升級,微服務開發更高效

&#x1f4dd; 摘要 Spring Boot 3.5作為Spring生態的最新版本&#xff0c;帶來了多項令人振奮的改進。本文將深入解析其中最核心的自動配置增強特性&#xff0c;以及它們如何顯著提升微服務開發效率。通過詳細的代碼示例和通俗易懂的講解&#xff0c;您將全面了解這些新特性在…

【前端】webpack一本通

今日更新完畢&#xff0c;不定期補充&#xff0c;建議關注收藏點贊。 目錄 簡介Loader和Plugin的不同&#xff1f;&#xff08;必會&#xff09; 使用webpack默認只能處理js文件 ->引入加載器對JS語法降級&#xff0c;兼容低版本語法合并文件再次打包進階 工作原理Webpack 的…

leetcode 264. Ugly Number II

動態規劃解決。 關鍵是理解如何生成新的丑數。這道題和經典的斐波那契數列問題其實是一樣的。求第n個數&#xff0c;需要用第n個數前面的數來求。不同的是&#xff0c;斐波那契數列不會重復。而本題的丑數&#xff0c;會重復出現。 class Solution { public:int nthUglyNumbe…

深入理解 HTML5 語義元素:提升網頁結構與可訪問性

引言 在構建網頁的過程中&#xff0c;合理的結構與清晰的語義對于網頁的質量、可維護性以及搜索引擎優化&#xff08;SEO&#xff09;都至關重要。HTML5 引入了一系列語義元素&#xff0c;為開發者提供了更精準描述網頁內容的工具。本文將深入探討 HTML5 語義元素的作用、使用…