面試官:小夥子,ShardingSphere去學一下吧
一、ShardingSphere簡介
在資料庫設計時候考慮垂直分庫和垂直分表。隨著資料庫資料量增加,不要馬上考慮做水平切分,首先考慮快取處理,讀寫分離,使 用索引等等方式,如果這些方式不能根本解決問題了,再考慮做水平分庫和水平分表。
分庫分表導致的問題:
- 跨節點連線查詢問題(分頁、排序)
- 多資料來源管理問題
Apache ShardingSphere是一套開源的分散式資料庫中介軟體解決方案組成的生態圈,它由 JDBC、 Proxy和 Sidecar(規劃中)這 3 款相互獨立,卻又能夠混合部署配合使用的產品組成。 它們均提供標準化的資料分片、分散式事務和資料庫治理功能,可適用於如 Java同構、異構語言、雲原生等各種多樣化的應用場景。
Apache ShardingSphere定位為關係型資料庫中介軟體,旨在充分合理地在分散式的場 景下利用關係型資料庫的計算和儲存能力,而並非實現一個全新的關係型資料庫。 它通過關注不變,進而抓住事物本質。關係型資料庫當今依然佔有巨大市場,是各個公司核心業務的基石,未來也難於撼動,我們目前階段更加關注在原有基礎上的增量,而非顛覆。
二、Sharding-JDBC
Sharding-JDBC 是輕量級的 java 框架,是增強版的 JDBC 驅動,簡化對分庫分表之後資料相關操作。
新建專案並新增依賴:
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-parentartifactId>
<version>2.2.1.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.20version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>org.apache.shardingspheregroupId>
<artifactId>sharding-jdbc-spring-boot-starterartifactId>
<version>4.0.0-RC1version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.0.5version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
dependencies>
2.1 Sharding-JDBC實現水平分表
① 按照水平分表的方式,建立資料庫和資料庫表
水平分表規則:如果新增 cid是偶數把資料新增 course_1,如果是奇數新增到 course_2
CREATE TABLE `course_1` (
`cid` bigint(16) NOT NULL,
`cname` varchar(255) ,
`userId` bigint(16),
`cstatus` varchar(16) ,
PRIMARY KEY (`cid`)
)
② 編寫實體和 Mapper 類
@Data
public class Course {
private Long cid;
private String cname;
private Long userId;
private String cstatus;
}
@Repository
public interface CourseMapper extends BaseMapper<Course> {
}
③ 詳細配置檔案
spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
datasource:
names: m1
m1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.182.200:3306/course_db?serverTimezone=GMT%2B8
username: root
password: 1234
sharding:
tables:
course:
actual-data-nodes: m1.course_$->{1..2}
key-generator:
column: cid
type: SNOWFLAKE
table-strategy:
inline:
shardingcolumn: cid
algorithm-expression: course_$->{cid%2+1}
props:
sql:
show: true
mybatis-plus:
configuration:
map-underscore-to-camel-case: false
④ 測試
@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingSphereTestApplication {
@Autowired
CourseMapper courseMapper;
@Test
public void addCourse() {
for (int i = 1; i 10; i++) {
Course course = new Course();
course.setCname("java" + i);
course.setUserId(100L);
course.setCstatus("Normal" + i);
courseMapper.insert(course);
}
}
@Test
public void queryCourse() {
QueryWrapper<Course> wrapper = new QueryWrapper<>();
wrapper.eq("cid",493001315358605313L);
Course course = courseMapper.selectOne(wrapper);
System.out.println(course);
}
}
2.2 Sharding-JDBC實現水平分庫
① 需求分析
② 建立資料庫和表
③ 詳細配置檔案
spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
datasource:
names: m1,m2
m1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.182.200:3306/course_db_2?serverTimezone=GMT%2B8
username: root
password: 1234
m2:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.182.200:3306/course_db_3?serverTimezone=GMT%2B8
username: root
password: 1234
sharding:
tables:
course:
actual-data-nodes: m$->{1..2}.course_$->{1..2}
key-generator:
column: cid
type: SNOWFLAKE
database-strategy:
inline:
sharding-column: userId
algorithm-expression: m$->{userId%2+1}
table-strategy:
inline:
sharding-column: cid
algorithm-expression: course_$->{cid%2+1}
props:
sql:
show: true
mybatis-plus:
configuration:
map-underscore-to-camel-case: false
④ 測試程式碼
@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingSphereTestApplication {
@Autowired
CourseMapper courseMapper;
@Test
public void addCourse() {
for (int i = 1; i 20; i++) {
Course course = new Course();
course.setCname("java" + i);
int random = (int) (Math.random() * 10);
course.setUserId(100L + random);
course.setCstatus("Normal" + i);
courseMapper.insert(course);
}
}
@Test
public void queryCourse() {
QueryWrapper<Course> wrapper = new QueryWrapper<>();
wrapper.eq("cid", 493001315358605313L);
Course course = courseMapper.selectOne(wrapper);
System.out.println(course);
}
}
查詢實際對應的 SQL:
2.3 Sharding-JDBC操作公共表
公共表 :
- 儲存固定資料的表,表資料很少發生變化,查詢時候經常進行關聯
- 在每個資料庫中建立出相同結構公共表
① 思路分析
② 在對應資料庫建立公共表 t_udict,並建立對應實體和 Mapper``
CREATE TABLE `t_udict` (
`dict_id` bigint(16) NOT NULL,
`ustatus` varchar(16) ,
`uvalue` varchar(255),
PRIMARY KEY (`dict_id`)
)
③ 詳細配置檔案
spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
datasource:
names: m1,m2
m1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.182.200:3306/course_db_2?serverTimezone=GMT%2B8
username: root
password: 1234
m2:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.182.200:3306/course_db_3?serverTimezone=GMT%2B8
username: root
password: 1234
sharding:
tables:
course:
actual-data-nodes: m$->{1..2}.course_$->{1..2}
key-generator:
column: cid
type: SNOWFLAKE
database-strategy:
inline:
sharding-column: userId
algorithm-expression: m$->{userId%2+1}
table-strategy:
inline:
sharding-column: cid
algorithm-expression: course_$->{cid%2+1}
t_udict:
key-generator:
column: dict_id
type: SNOWFLAKE
broadcast-tables: t_udict
props:
sql:
show: true
mybatis-plus:
configuration:
map-underscore-to-camel-case: false
④ 進行測試
經測試:資料插入時會在每個庫的每張表中插入,刪除時也會刪除所有資料。
@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingSphereTestApplication {
@Autowired
UdictMapper udictMapper;
@Test
public void addUdict() {
Udict udict = new Udict();
udict.setUstatus("a");
udict.setUvalue("已啟用");
udictMapper.insert(udict);
}
@Test
public void deleteUdict() {
QueryWrapper<Udict> wrapper = new QueryWrapper<>();
wrapper.eq("dict_id", 493080009351626753L);
udictMapper.delete(wrapper);
}
}
2.4 Sharding-JDBC實現讀寫分離
為了確保資料庫產品的穩定性,很多資料庫擁有雙機熱備功能。也就是,第一臺資料庫伺服器是對外提供增刪改業務的生產伺服器;第二臺資料庫伺服器主要進行讀的操作。
Sharding-JDBC通過 sql語句語義分析,實現讀寫分離過程,不會做資料同步,資料同步通常資料庫叢集間會自動同步。
詳細配置檔案:
spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
datasource:
names: m0,s0
m0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.182.200:3306/course_db?serverTimezone=GMT%2B8
username: root
password: 1234
s0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.182.200:3307/course_db?serverTimezone=GMT%2B8
username: root
password: 1234
masterslave:
master-data-source-name: m0
slave-data-source-names: s0
props:
sql:
show: true
mybatis-plus:
configuration:
map-underscore-to-camel-case: false
經過測試:增刪改操作都是會通過 master資料庫,同時 master資料庫會同步資料給 slave資料庫;查操作都是通過 slave資料庫.
三、Sharding-Proxy
Sharding-Proxy定位為 透明化的資料庫代理端,提供封裝了資料庫二進位制協議的服務端版本,用於完成對異構語言的支援, 目前僅 MySQL和 PostgreSQL版本。
Sharding-Proxy是獨立應用,需要安裝服務,進行分庫分表或者讀寫分離配置,啟動使用。
今天就聊到這裡了,如果覺得本文對你有幫助,可以轉發關注支援一下
原文連結:https://my.oschina.net/u/4199331/blog/4705383?_from=gitee_search
如果覺得本文對你有幫助,可以點贊關注支援一下,也可以關注我公眾號,上面有更多技術乾貨文章以及相關資料共享,大家一起學習進步!
相關文章
- 面試官:小夥子,你給我簡單說一下RocketMQ 整合 Spring Boot吧面試MQSpring Boot
- 面試官:小夥子知道synchronized的最佳化過程嗎?我:嘚吧嘚吧嘚,面試官:出去!面試synchronized
- 面試官:小夥子,能聊明白JMM給你SSP!我:嘚吧嘚吧一萬字,直接征服面試官!面試
- 面試官:聊一下對框架配置載入的理解吧!面試框架
- 面試官:聊一聊索引吧面試索引
- 面試官:你給我說一下什麼是時間輪吧?面試
- 面試官:小夥子,你給我說一下Java中什麼情況會導致記憶體洩漏呢?面試Java記憶體
- 面試官:你給我說一下執行緒池裡面的幾個鎖吧。面試執行緒
- 面試官:說說資料庫事務吧面試資料庫
- 面試官:來寫個程式碼求一下兩個數的最大公約數吧面試
- 面試官:說一下你常用的加密演算法面試加密演算法
- 面試官: 說一下你做過哪些效能優化?面試優化
- 面試官:聊一下你對MySQL索引實現原理?面試MySql索引
- 面試官:要不我們聊一下“心跳”的設計?面試
- 面試官:介紹一下 Redis 三種叢集模式面試Redis模式
- 面試官:小夥子,夠了夠了,一個工廠模式你都在這說半個小時了!面試模式
- 面試官:你說你精通 Docker,那你來詳細說說 Dockerfile 吧面試Docker
- 面試官說:你來設計一個短連結生成系統吧面試
- 月薪不同的三人去面試,面試官問道:各自談談對 binder 的理解?面試
- 操蛋的面試官面試
- 吊打面試官——redis面試Redis
- 阿里面試官:HashMap 熟悉吧?好的,那就來聊聊 Redis 字典吧!阿里面試HashMapRedis
- 征服面試官:OkHttp 原理篇 掌握這篇面試題彙總,吊打面試官!HTTP面試題
- 面試官:談一下你對DDD的理解?我:馬什麼梅?面試
- 前端er來學習一下webWorker吧前端Web
- 面試官問我:看過sharding-jdbc的原始碼嗎?我吧啦吧啦說了一通!!面試JDBC原始碼
- 詢問面試官的面試問題面試
- 面試官:兄弟,說說基本型別和包裝型別的區別吧面試型別
- 面試官:我們來聊一聊Redis吧,你瞭解多少就答多少面試Redis
- 7年程式設計師去oppo面試遭淘汰,面試官冷笑:三本也想來大廠?程式設計師面試
- 去面試位元組跳動,有些話不吐不快!面試官最青睞的候選人標準!面試
- 面試官在“逗”你係列:陣列去重你會幾種呀?面試陣列
- 面試官眼中的Promise面試Promise
- 各位面試官有無好的簡歷 可否簡單分享一下呢面試
- 面試官問:請介紹一下MySQL資料庫的鎖機制?面試MySql資料庫
- 面試官:說一下記憶體溢位排查過程和工具?我...面試記憶體溢位
- 面試官:來給我說一下 Spring 中使用了那些設計模式?面試Spring設計模式
- Java 面試-吊打面試官系列 Redis 基礎Java面試Redis