資料庫中介軟體MyCat
什麼是MyCat?
檢視官網的介紹是這樣說的
- 一個徹底開源的,面向企業應用開發的大資料庫叢集
- 支援事務、ACID、可以替代MySQL的加強版資料庫
- 一個可以視為MySQL叢集的企業級資料庫,用來替代昂貴的Oracle叢集
- 一個融合記憶體快取技術、NoSQL技術、HDFS大資料的新型SQL Server
- 結合傳統資料庫和新型分散式資料倉庫的新一代企業級資料庫產品
- 一個新穎的資料庫中介軟體產品
主要特性:
- 支援SQL92標準
- 支援MySQL、Oracle、DB2、SQL Server、PostgreSQL等DB的常見SQL語法
- 遵守Mysql原生協議,跨語言,跨平臺,跨資料庫的通用中介軟體代理。
- 基於心跳的自動故障切換,支援讀寫分離,支援MySQL主從,以及galera cluster叢集。
- 支援Galera for MySQL叢集,Percona Cluster或者MariaDB cluster
- 基於Nio實現,有效管理執行緒,解決高併發問題。
- 支援資料的多片自動路由與聚合,支援sum,count,max等常用的聚合函式,支援跨庫分頁。
- 支援單庫內部任意join,支援跨庫2表join,甚至基於caltlet的多表join。
- 支援通過全域性表,ER關係的分片策略,實現了高效的多表join查詢。
- 支援多租戶方案。
- 支援分散式事務(弱xa)。
- 支援XA分散式事務(1.6.5)。
- 支援全域性序列號,解決分散式下的主鍵生成問題。
- 分片規則豐富,外掛化開發,易於擴充套件。
- 強大的web,命令列監控。
- 支援前端作為MySQL通用代理,後端JDBC方式支援Oracle、DB2、SQL Server 、 mongodb 、巨杉。
- 支援密碼加密
- 支援服務降級
- 支援IP白名單
- 支援SQL黑名單、sql注入攻擊攔截
- 支援prepare預編譯指令(1.6)
- 支援非堆記憶體(Direct Memory)聚合計算(1.6)
- 支援PostgreSQL的native協議(1.6)
- 支援mysql和oracle儲存過程,out引數、多結果集返回(1.6)
- 支援zookeeper協調主從切換、zk序列、配置zk化(1.6)
- 支援庫內分表(1.6)
- 叢集基於ZooKeeper管理,線上升級,擴容,智慧優化,大資料處理(2.0開發版)
下載及安裝:
到官網根據系統型別進行下載:http://mycat.io/
將下載檔案解壓,目錄如下:
各個目錄簡要說明:
bin:啟動目錄
catlet: 擴充套件功能
conf:配置檔案目錄
server.xml:是Mycat伺服器引數調整和使用者授權的配置檔案
schema.xml:是邏輯庫定義和表以及分片定義的配置檔案
rule.xml: 是分片規則的配置檔案,分片規則的具體一些引數資訊單獨存放為檔案,也在這個目錄下,配置檔案修改需要重啟MyCAT
log4j.xml: 日誌存放在logs/log中,每天一個檔案,日誌的配置是在conf/log4j.xml中,根據自己的需要可以調整輸出級別為debug,debug級別下,會輸出更多的資訊,方便排查問題
autopartition-long.txt,partition-hash-int.txt,sequence_conf.properties, sequence_db_conf.properties 分片相關的id分片規則配置檔案
lib:jar包目錄
logs :日誌目錄
進入bin目錄,通過管理員身份開啟DOS視窗,分別執行命令:
mycat install
mycat start
這樣就可以啟動mycat了。
核心配置
server.xml : 設定賬號、引數等
schema.xml : 物理資料庫和資料庫表的配置
rule.xml : 分片(分庫分表)規則
關於配置的詳細介紹可以參考 https://www.cnblogs.com/joylee/p/7513038.html 或者官網 http://www.mycat.io/document/mycat-definitive-guide.pdf
示例
首次認識mycat,最容易是從示例著手去了解,比如此次示例是結合mysql完成資料的分庫分表,進行橫向擴充套件。
首先需要準備幾個mysql的伺服器,通過docker構建,具體怎麼可以參考網上,大致步驟如下:
1、下載mysql映象: docker pull mysql
2、啟動容器:docker run -di -p 32768:3306 --name mysql1 -e MYSQL_ROOT_PASSWORD=123456 mysql ,輸入容器id
3、通過容器id進入容器,docker exec -it <id> /bin/bash
4、進入mysql:mysql -u root -p -> 123456
5、新增遠端連線使用者與密碼:GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456';
6、許可權:flush privileges;
如果不出意外則可以連線,因為我是通過本地虛擬機器安裝docker,預設埠192.168.99.100。現在根據下載的映象啟動3個容器,修改不同的埠。
通過客戶端工具分別連線以上三個資料庫,並且建表:
建立資料庫:TESTDB
建表:
CREATE TABLE `employee` (
`id` int(11) NOT NULL,
`name` varchar(56) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1、修改server.xml配置檔案
<user name="root" defaultAccount="true">
<property name="password">123456</property><!-- 連線時用這個名字,比如 jdbc:mysql://localhost:8066/TESTDB -->
<property name="schemas">TESTDB</property>
</user>
2、修改schema.xml
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100">
<table name="employee" primaryKey="ID" dataNode="dn1,dn2,dn3" rule="mod-long" />
</schema>
<!-- name節點名,與上對應;dataHost:真實資料庫配置;database:資料庫表配置 -->
<dataNode name="dn1" dataHost="host1" database="TESTDB" />
<dataNode name="dn2" dataHost="host2" database="TESTDB" />
<dataNode name="dn3" dataHost="host3" database="TESTDB" /><dataHost name="host1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select 1</heartbeat>
<writeHost host="hostS1" url="192.168.99.100:32768" user="root" password="123456" />
</dataHost>
<dataHost name="host2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select 1</heartbeat>
<writeHost host="hostS2" url="192.168.99.100:32769" user="root" password="123456" />
</dataHost>
<dataHost name="host3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select 1</heartbeat>
<writeHost host="hostS3" url="192.168.99.100:39770" user="root" password="123456" />
</dataHost>
3、修改rule.xml
上面<table>配置了rule="mod-long",在rule.xml有相關的描述,修改下面引數,與上面dataNode數量對應
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">3</property>
</function>
這樣mycat的配置就完成了,由於修改了配置,我們將mycat重啟,進入bin,mycat restart。
測試
由於之前使用了mybatis-plus+springboot的專案,所有就用了這個:
application-mycat.properties:
mybatis-plus.mapper-locations=classpath*:com/sucl/sbmp/*/mapper/**Mapper.xml mybatis-plus.type-aliases-package=com.sucl.sbmp.*.entity mybatis-plus.global-config.refresh=true #mybatis-plus.global-config.db-config.db-type=mysql mybatis-plus.configuration.map-underscore-to-camel-case=true mybatis-plus.configuration.cache-enabled=false mp.datasource.driver-class-name=com.mysql.jdbc.Driver mp.datasource.url=jdbc:mysql://localhost:8066/TESTDB?useUnicode=true&useSSL=false&characterEncoding=utf8 mp.datasource.username=root mp.datasource.password=123456 mp.datasource.validation-query=select '1' mp.datasource.testOnBorrow=true
實體:
@Data public class Employee { @TableId(type = IdType.INPUT) private long id; @TableField(value = "name") private String name; }
mapper:
public interface EmployeeMapper extends BaseMapper<Employee> { }
service:
@Service @Transactional public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper,Employee> implements EmployeeService { }
測試:
@ActiveProfiles("mycat") @RunWith(SpringRunner.class) @SpringBootTest public class SbmpTest { @Autowired private EmployeeService employeeService; @Transactional @Rollback(false) @Test public void save(){ List<Employee> employees = new ArrayList<>(); for(int i=0;i<100;i++){ Employee employee = new Employee(); employee.setId(i); employee.setName("name"+i); employees.add(employee); } employeeService.saveBatch(employees); } @Test public void get(){ List<Employee> employees = employeeService.list(null); employees.stream().forEach(System.out::println); } }
分別執行兩個方法,會根據id在三個資料庫中分別插入資料:
查詢時則可以檢視三個表