引言
先給大家介紹2個概念:數據的切分(Sharding)根據其切分規則的類型,可以分爲兩種切分模式。
切分模式
一種是按照不同的表(或者Schema)來切分到不同的數據庫(主機)之上,這種切可以稱之爲數據的垂直(縱向)切分;另外一種則是根據表中的數據的邏輯關係,將同一個表中的數據按照某種條件拆分到多臺數據庫(主機)上面,這種切分稱之爲數據的水平(橫向)切分。
垂直切分的最大特點就是規則簡單,實施也更爲方便,尤其適合各業務之間的耦合度非常低,相互影響很小,業務邏輯非常清晰的系統。在這種系統中,可以很容易做到將不同業務模塊所使用的表分拆到不同的數據庫中。根據不同的表來進行拆分,對應用程序的影響也更小,拆分規則也會比較簡單清晰。
水平切分於垂直切分相比,相對來說稍微複雜一些。因爲要將同一個表中的不同數據拆分到不同的數據庫中,對於應用程序來說,拆分規則本身就較根據表名來拆分更爲複雜,後期的數據維護也會更爲複雜一些。
爲什麼用MyCat
不管怎麼來說,數據切分雖然分散了單臺服務器負載,但是帶來了是設計和開發的複雜度。MyCat是一個開源的分佈式數據庫中間件,實現了MySQL協議的服務器,前端用戶可以把它看作是一個數據庫代理,用MySQL客戶端工具和命令行訪問,而其後端可以用MySQL原生協議與多個MySQL服務器通信,在MyCat裏,我們面向的是一個傳統的數據庫表,支持標準的SQL語句進行數據的操作,這樣一來,對前端業務系統來說,可以大幅降低開發難度,提升開發速度。
分庫分表實踐
基本環境
操作系統:CentOS / 7.1 (64bit)
JDK:1.8
MySQL:5.7
MyCat:1.6
業務目標
比如說我們現在有個實際的業務上設計需求,要將student和grade表進行垂直劃分,分別存儲不同的database中;還需要將student水平拆分,也要3個不同database存分別儲。如下圖所示,MyCat可以幫助實現這4個database的管理,而對於終端用戶來說,就像只操作student和grade兩張表,保證了中間件分庫分頁對程序員的透明性。
創建實際數據庫
首先,我們肯定需要創建4個database:beijing、shanghai、guangzhou、basic,並生成對應的表。可以看出,student和grade表存在於不同的數據庫,而且student表中的數據,分散存儲在3個不同的數據庫中:
create database beijing;
use beijing;
create table student(
id int primary key,
name varchar(8) not null,
grade int not null
);
create database shanghai;
use shanghai;
create table student(
id int primary key,
name varchar(8) not null,
grade int not null
);
create database guangzhou;
use guangzhou;
create table student(
id int primary key,
name varchar(8) not null,
grade int not null
);
create database basic;
use basic;
create table grade(
id int primary key,
name varchar(8) not null
);
安裝配置MyCat
比較簡單,下載Mycat-1.6-RELEASE,直接解壓縮即可。
爲了方便,將/mycat/bin
目錄添加到環境變量:
/etc/profile文件後增加設置export PATH=/data/mycat/bin:$PATH
讓profile立即生效:# source /etc/profile
配置server
編輯\mycat\conf\server.xml:
<user name="test">
<property name="password">test</property>
<property name="schemas">TESTDB</property>
</user>
這裏MyCat會幫助我們生成一個虛擬的邏輯database,我們命名爲TESTDB,並設置可以訪問的用戶名和密碼,默認訪問的端口號8066,其實MyCat還會提供一個管理端口:9066,方便我們對MyCat管理和監測,這個我們以後有機會再說。
配置schema
編輯\mycat\conf\schema.xml:
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<!-- 取模分片 -->
<table name="student" primaryKey="id" dataNode="dn1,dn2,dn3" rule="mod-long" />
<table name="grade" primaryKey="id" dataNode="dn4"/>
</schema>
<!-- 申明節點對應的database -->
<dataNode name="dn1" dataHost="localhost1" database="beijing" />
<dataNode name="dn2" dataHost="localhost1" database="shanghai" />
<dataNode name="dn3" dataHost="localhost1" database="guangzhou" />
<dataNode name="dn4" dataHost="localhost1" database="basic" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- 可讀寫的數據庫實例 -->
<writeHost host="hostM1" url="localhost:3306" user="root" password="******">
</writeHost>
</dataHost>
</mycat:schema>
schema是比較重要的一塊配置,主要維護了虛擬庫與實際庫的映射關係:
可以看到,虛擬的邏輯庫TESTDB中維護了2張表student和grade;
grade對應存儲在實際的數據庫節點dn4,也就是basic;
而student被拆分爲存儲在3個實際的數據庫節點,分別是beijing、shanghai、guangzhou,分片的算法取模,根據取模映射到不同的節點;
最後,我們將實際的訪問地址、訪問權限配置完成,當然,這裏還可以配置主從/讀寫分離配置,這塊不是本文討論的重點,我們以後單獨說。
啓動mycat: 進入到mycat下bin文件夾,點擊startup_nowrap.bat
啓動了後,使用navicat來對mycat進行管理。跟創建數據庫連接是一致的