前言
爲了減輕每臺MySQL主機的訪問壓力,還能夠對MySQL進行讀寫分離,實際上,主從複製和讀寫分離通常就是聯合使用的。java
找到一份好的資料也是學習過程當中,很是重要的一個點。你的檢索能力越強,你就會越容易找到最合適你的資料。mysql
我這邊也整理了一些最新的面試題資料和Java架構學習資料,學習技術內容包含有:Spring,Dubbo,MyBatis, RPC,源碼分析,高併發、高性能、分佈式,性能優化,微服務 高級架構開發等等。。面試
有須要的小夥伴能夠戳這裏免費領取,暗號:CSDN。spring
這篇水文來聊一下MySQL的讀寫分離。藉助於一些數據庫中間件,實現起來賊容易,一看就會!sql
MySQL讀寫分離
MySQL讀寫分離基本原理是讓master數據庫處理寫操做,slave數據庫處理讀操做。master將寫操做的變動同步到各個slave節點。
MySQL讀寫分離能提升系統性能:
數據庫
- 物理服務器增長,機器處理能力提高。拿硬件換性能。
- slave能夠配置myiasm引擎,提高查詢性能以及節約系統開銷。
- master直接寫是併發的,slave經過主庫發送來的binlog恢復數據是異步的。
- slave能夠單獨設置一些參數來提高其讀的性能。
- 增長冗餘,提升可用性。
如何實現讀寫分離
MySQL官方提供了MySQL Proxy,可是已經不建議使用了:
與此同時它建議咱們使用MySQL Router,再可是,MySQL Router不只功能少,並且須要在應用程序代碼中指定讀/寫的不一樣端口,在實際生產環境中應該沒人會這樣用。
其實,當前已經有很多比較不錯的MySQL中間件,像shardingsphere-jdbc,mycat,amoeba等,這些都是比較不錯的選擇。
這裏,咱們使用Apache開源項目ShardingSphere的JDBC來實現MySQL的讀寫分離。#
apache
ShardingSphere-JDBC
ShardingSphere的JDBC組件,稱之爲Sharding-JDBC,它是一個輕量級的Java框架,在Java的JDBC層提供的額外服務。 它使用客戶端直連數據庫,以jar包形式提供服務,無需額外部署和依賴,可理解爲加強版的JDBC驅動,徹底兼容JDBC和各類ORM框架。性能優化
這就意味着,在項目中咱們不須要額外安裝什麼軟件,直接引入Jar包依賴,就能夠實現數據庫的分庫分表、讀寫分離等。服務器
說的直白一點,Sharding-JDBC就是包含了分庫分表讀寫分離功能的JDBC,所以咱們能夠直接把Sharding-JDBC當作普通的JDBC來使用。mybatis
Sharding-JDBC實現讀寫分離的核心概念
主庫
- 添加、更新以及刪除數據操做所使用的數據庫,目前僅支持單主庫。
從庫
- 查詢數據操做所使用的數據庫,可支持多從庫。
- 咱們使用一主兩從的MySQL數據庫架構來實現主從複製和讀寫分離。
主從同步
- 將主庫的數據異步的同步到從庫的操做。因爲主從同步的異步性,從庫與主庫的數據會短期內不一致。
負載均衡策略
- 若是有多個從庫,能夠經過負載均衡策略將查詢請求疏導至不一樣的從庫。
基於Sharding-JDBC的MySQL讀寫分離代碼實現
- 主從複製主機配置:
主從同步的數據庫爲shardingsphere_demo:
log-bin=master-bin binlog-format=ROW server-id=1 binlog-do-db=shardingsphere_demo
shardingsphere_demo庫有一個表叫laogong:
create table laogong( id int, name varchar(20), age int );
- 建立SpringBoot項目,引入Jar包
引入ShardingSphere的Jar包依賴:
<dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.1.1</version> </dependency>
還用到了druid鏈接池,mybatis,mysql驅動,這裏不展現了。
- 配置文件
配置是整個Sharding-JDBC的核心,是Sharding-JDBC中惟一與應用開發者打交道的模塊。
配置模塊也是Sharding-JDBC的門戶,經過它能夠快速清晰的理解Sharding-JDBC所提供的功能。
配置讀寫分離
根據前文主從複製主機的信息,配置以下:
spring: shardingsphere: # 數據源相關配置 datasource: # 數據源名稱 names: master,s1,s2 # MySQL master數據源 master: # 數據庫鏈接池 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://192.168.2.158:3306/shardingsphere_demo? serverTimezone=UTC username: root password: 123456 # 兩個slave數據源 s1: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://192.168.2.159:3306/shardingsphere_demo?serverTimezone=UTC username: root password: 123456 s2: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://192.168.2.157:3306/shardingsphere_demo? serverTimezone=UTC username: root password: 123456 masterslave: load-balance-algorithm-type: round_robin name: ms master-data-source-name: master slave-data-source-names: s1,s2 # 其餘屬性 props: # 開啓SQL顯示 sql.show: true
- 建立實體類和Mapper類
實體類的代碼這裏不貼了,侮辱智商
Mapper類:
@Repository @Mapper public interface LaogongMapper { @Insert("insert into laogong(id, name, age) values(#{id}, #{name}, #{age})") public void addLaogong(Laogong laogong); @Select("select * from laogong where id=#{id}") public Laogong queryLaogong(Integer id); }
- 測試
測試寫入數據
向laogong表插入5條數據:
@Test public void testMSInsert(){ for (int i = 1; i <= 5; i++) { Laogong laogong = new Laogong(); laogong.setId(i); laogong.setName("xblzer" + i); laogong.setAge(new Random().nextInt(30)); laogongMapper.addLaogong(laogong); } }
運行結果:
能夠看到,插入的SQL語句,所有往master主庫寫入數據。
- 測試讀取數據
讀取id=1的數據,循環讀取10次,看都從哪一個庫讀取:
@Test public void testMSQuery(){ for (int i = 0; i < 10; i++) { Laogong laogong = laogongMapper.queryLaogong(1); System.out.println(laogong); } }
結果驗證:
只從S一、S2這兩個從庫中讀取數據。
經過以上兩個讀取和寫入數據的測試,能夠可到,經過Sharding-JDBC真的很方便就幫咱們實現了讀寫分離!這個時候咱們能夠說真香了!
最後
基於Sharding-JDBC的MySQL讀寫分離用起來真是很方便,並且ShardingSphere 已於2020年4月16日成爲 Apache 軟件基金會的頂級項目了,相信ShardingSphere會很快的火起來的。
咱們項目上已經用這個作MySQL分庫分表讀寫分離了。此次這篇文章只提到了讀寫分離,其實Sharding-JDBC還能夠實現不少功能:
- 數據分片(分庫&分表)
- 讀寫分離
- 分佈式事務
- 分佈式治理
- 數據加密
- …
ShardingSphere已經造成了一個生態圈,其功能仍在不斷完善。
本次導航結束,以上。