ShardingSphere入門實戰(2)-Sharding-Proxy使用
阿新 • • 發佈:2020-08-03
Sharding-Proxy定位為透明化的資料庫代理端,提供封裝了資料庫二進位制協議的服務端版本,用於完成對異構語言的支援。 目前先提供MySQL/PostgreSQL版本,它可以使用任何相容MySQL/PostgreSQL協議的訪問客戶端。本文主要介紹Sharding-Proxy的基本使用,文中使用到的軟體版本:sharding-proxy 4.1.1、MySQL 5.7.26、Java 1.8.0_191。
1、Sharding-Proxy和Sharding-JDBC的區別
2、Sharding-Proxy安裝
2.1、下載並解壓
https://shardingsphere.apache.org/document/current/cn/downloads/
tar zxvfapache-shardingsphere-4.1.1-sharding-proxy-bin.tar.gz
2.2、修改配置檔案
conf/server.yaml
authentication: users: root: password: root sharding: password: sharding authorizedSchemas: sharding_db,master_slave_db props: max.connections.size.per.query: 1 acceptor.size: 16 # The default value is available processors count * 2. executor.size: 16 # Infinite by default. proxy.frontend.flush.threshold: 128 # The default value is 128. # LOCAL: Proxy will run with LOCAL transaction. # XA: Proxy will run with XA transaction. # BASE: Proxy will run with B.A.S.E transaction. proxy.transaction.type: LOCAL proxy.opentracing.enabled: false proxy.hint.enabled: false query.with.cipher.column: true sql.show: true allow.range.query.with.inline.sharding: false
conf/config-sharding.yaml
schemaName: sharding_db dataSources: ds0: url: jdbc:mysql://10.49.196.10:3306/itest username: admin password: Root_123! connectionTimeoutMilliseconds: 30000 idleTimeoutMilliseconds: 60000 maxLifetimeMilliseconds: 1800000 maxPoolSize: 50 ds1: url: jdbc:mysql://10.49.196.20:3306/itest username: admin password: Root_123! connectionTimeoutMilliseconds: 30000 idleTimeoutMilliseconds: 60000 maxLifetimeMilliseconds: 1800000 maxPoolSize: 50 shardingRule: tables: t_user: #邏輯表名,在一個庫裡分表:ds0.t_user_0,ds0.t_user_1 actualDataNodes: ds0.t_user_$->{0..1} tableStrategy: #表分片策略 inline: #行表示式分片策略 shardingColumn: user_id #分片的欄位 algorithmExpression: t_user_$->{user_id % 2} #分片的演算法 t_dept: #分庫,兩個庫裡建系統的表:ds0.t_dept,ds1.t_dept actualDataNodes: ds$->{0..1}.t_dept databaseStrategy: #資料庫分片策略 inline: #行表示式分片策略 shardingColumn: dept_id #分片的欄位 algorithmExpression: ds$->{dept_id % 2} #分片的演算法
conf/config-master_slave.yaml
schemaName: master_slave_db
dataSources:
master:
url: jdbc:mysql://10.49.196.10:3306/itest
username: admin
password: Root_123!
slave0:
url: jdbc:mysql://10.49.196.20:3306/itest
username: admin
password: Root_123!
masterSlaveRule:
name: ds_ms
masterDataSourceName: master
slaveDataSourceNames:
- slave0
3、使用JDBC訪問Sharding-Proxy
package com.inspur.demo.shardingsphere; import com.inspur.demo.shardingsphere.util.JdbcUtil; import org.apache.shardingsphere.api.hint.HintManager; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; import javax.sql.DataSource; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class ShardingProxyCase { private static Logger logger = LoggerFactory.getLogger(ShardingProxyCase.class); /** * 資料分片 * t_user在同一個庫裡分表(t_user_0,t_user_1) * t_dept分庫 */ @Test public void fragmentation() { Connection con = null; try { Class.forName("com.mysql.cj.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://10.49.196.10:3307/sharding_db", "sharding", "sharding"); con.setAutoCommit(false); Statement st = con.createStatement(); //插入ds0.t_user_0表 st.executeUpdate("insert into t_user(user_id,user_name,age) values(110,'趙雲2', 30)"); //插入ds0.t_user_1表 st.executeUpdate("insert into t_user(user_id,user_name,age) values(111,'張飛2', 31)"); //插入ds0.t_dept表 st.executeUpdate("insert into t_dept(dept_id,dept_name) values(110,'dept10-2')"); //插入ds1.t_dept表 st.executeUpdate("insert into t_dept(dept_id,dept_name) values(111,'dept11-2')"); ResultSet rs = st.executeQuery("select user_id,user_name from t_user where user_id in(110,111)"); while (rs.next()) { logger.info("user_id={},user_name={}", rs.getString("user_id"), rs.getString("user_name")); } rs = st.executeQuery("select dept_id,dept_name from t_dept where dept_id in(110,111)"); while (rs.next()) { logger.info("dept_id={},dept_name={}", rs.getString("dept_id"), rs.getString("dept_name")); } con.commit(); } catch (Exception e) { JdbcUtil.rollback(con); e.printStackTrace(); } finally { JdbcUtil.close(con); } } /** * 讀寫分離,主庫寫,從庫讀 * 同一執行緒且同一資料庫連線內,如有寫入操作,以後的讀操作均從主庫讀取,用於保證資料一致性 */ @Test public void readWrite() { Connection con = null; try { Class.forName("com.mysql.cj.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://10.49.196.10:3307/master_slave_db", "sharding", "sharding"); Statement st = con.createStatement(); //從slave0讀資料 ResultSet rs = st.executeQuery("select * from t_student"); while (rs.next()) { System.out.println(rs.getString("id") + "|" + rs.getString("name")); } //寫入master st.executeUpdate("insert into t_student(id,name) values(600,'測試')"); //這邊應該從master讀資料,但是還是從slave0讀取資料,可能是ShardingProxy的bug rs = st.executeQuery("select * from t_student"); while (rs.next()) { System.out.println(rs.getString(1) + "|" + rs.getString(2)); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtil.close(con); } } }
資料分配和讀寫分離訪問了不同schema;在讀寫分離的例子中第二次查詢應從master讀資料,但是還是從slave0讀取資料,不知是我配置錯了還是ShardingProxy的bug,知道的同學告訴下哈。