MyCat 之垂直分庫實戰

一)垂直分庫

什麼是垂直切分?通俗的講就是將我們的數據庫按照模塊劃分成不同的數據庫,以此來解決數據庫訪問的壓力。例如,下面的案例將會把原始包含訂單,用戶,商品,倉配等信息的數據庫劃分爲訂單庫,用戶庫,商品庫三個數據庫。但實際訪問還是相當於訪問一個數據庫一樣,這裏就需要藉助我們的MyCat來配置邏輯數據庫了

如果是在實際線上,若是爲了保證在作垂直分庫的時候不受影響,前一步我們需要完成各個節點的主從同步工作,這樣之後做了分庫,切換訪問mycat,才能保證數據不會錯亂。關於mysql的主從同步可以詳細看【Mysql 主從複製實戰

1)首先看一下我們的環境

所以在演示如何具體的劃分之前,需要按照上面的準備好我們演示環境

2)因爲我們這次只是演示數據庫的垂直分庫,所以只是涉及到了MyCat的【schema.xml】和【server.xml】,並不會用到【rule.xml】,所以這裏指出可以將關注重點放在【schema.xml】和【server.xml】兩個文件上面

3)創建我們連接mycat的用戶並授權,在我們配置【schema.xml】的時候需要用到

create user mycat@'192.168.124.%' identified by '123456';

grant select,insert,update,delete on *.* to mycat@'192.168.124.%';

4)下面就是配置我們的【schema.xml】

上面是我們原始數據庫的所有表,現在要做一個垂直的拆分,按照我們上面所說需要分成三個庫,下面看我們的詳細配置

打開【shcema.xml】,下面是詳細的配置

        <schema name="mycat_db" checkSQLschema="false" sqlMaxLimit="100">
	
		<table name="order_master" primarykey="order_id" dataNode="orderDB" />
		<table name="order_detail" primarykey="order_detail_id" dataNode="orderDB" />
		<table name="order_cart" primarykey="cart_id" dataNode="orderDB" />
		<table name="order_customer_addr" primarykey="customer_addr_id" dataNode="orderDB" />
		<table name="region_info" primarykey="region_id" dataNode="orderDB" />
		<table name="shipping_info" primarykey="ship_id" dataNode="orderDB" />
		<table name="warehouse_info" primarykey="w_id" dataNode="orderDB" />
		<table name="warehouse_proudct" primarykey="wp_id" dataNode="orderDB" />
		
		<table name="product_brand_info" primarykey="brand_id" dataNode="productDB" />
		<table name="product_category" primarykey="category_id" dataNode="productDB" />
		<table name="product_comment" primarykey="comment_id" dataNode="productDB" />
		<table name="product_info" primarykey="product_id" dataNode="productDB" />
		<table name="product_supplier_info" primarykey="supplier_id" dataNode="productDB" />
		<table name="product_pic_info" primarykey="product_pic_id" dataNode="productDB" />
		
		<table name="customer_balance_log" primarykey="balance_id" dataNode="customerDB" />
		<table name="customer_inf" primarykey="customer_inf_id" dataNode="customerDB" />
		<table name="customer_level_inf" primarykey="customer_level" dataNode="customerDB" />
		<table name="customer_login" primarykey="customer_id" dataNode="customerDB" />
		<table name="customer_login_log" primarykey="login_id" dataNode="customerDB" />
		<table name="customer_point_log" primarykey="point_id" dataNode="customerDB" />
	
	</schema>
	  
	 
	<dataNode name="orderDB" dataHost="mysql39" database="order_db" />
	<dataNode name="productDB" dataHost="mysql40" database="product_db" />
	<dataNode name="customerDB" dataHost="mysql41" database="customer_db" />
	
	
	<dataHost name="mysql39" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
		<heartbeat>select user()</heartbeat>
		<writeHost host="192.168.124.39" url="192.168.124.39:3306" user="mycat" password="123456"/>
	</dataHost>
	<dataHost name="mysql40" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
		<heartbeat>select user()</heartbeat>
		<writeHost host="192.168.124.40" url="192.168.124.40:3306" user="mycat" password="123456"/>
	</dataHost>
	<dataHost name="mysql41" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
		<heartbeat>select user()</heartbeat>
		<writeHost host="192.168.124.41" url="192.168.124.41:3306" user="mycat" password="123456"/>
	</dataHost>

5)配置我們的【server.xml】

        <system>
		
		<property name="serverPort">8066</property>
		<property name="managerPort">9066</property> 
		<property name="nonePasswordLogin">0</property> 
		<property name="bindIp">0.0.0.0</property>  
		<property name="frontWriteQueueSize">2048</property>  
		
		<property name="charset">utf-8</property>
		<property name="txIsolation">2</property> 
		<property name="processors">8</property> 
		<property name="idleTimeout">300000</property>
		<property name="sqlExecuteTimeout">300</property> 
		<property name="useSqlStat">0</property> 
		<property name="useGlobleTableCheck">0</property>  
		<property name="defaultMaxLimit">100</property>
		<property name="maxPacketSize">104857600</property>
		
	</system>
	

	<user name="root" defaultAccount="true">
		<property name="password">123456</property>
		<property name="schemas">mycat_db</property>
	</user>

接下來我們便可以使用【root】用戶去登陸mycat了,這裏注意:

<property name="schemas">mycat_db</property>   的mycat_db  一定要和我們【schema.xml】中的schema頭 name的名字一致

6)在我們任意一個數據庫節點登陸進行驗證

我們使用【mysql_node4】去驗證

mysql -uroot -p123456 -P8066 -h192.168.124.38

 登陸成功,然後看一下我們的數據庫,只有我們配置的一個邏輯數據庫【mycat_db】,查看一下表,顯示了原始數據庫的所有表,具體如下圖:

至此我們的mycat垂直分庫基本配置完畢。

7)簡單總結一下垂直分庫的優缺點

優點:

1)數據庫的拆分簡單明瞭,拆分規則明確

2)應用程序模塊清晰明確,整合容易

3)數據維護方便,容易定位

缺點:

1)部分表關聯無法在數據庫級別完成,需要在程序中完成

2)對於訪問極其頻繁且數據量超大的表任然存在性能瓶頸

3)切分達到一定程度之後,擴展性會遇到限制

 

 

二)冗餘數據清理

上面做分庫之前都是做了主從同步的,所以雖然我們現在將原始數據庫做了拆分,但是拆分之後還是有數據冗餘的,現在每一份數據庫都保留着最原始的所有數據庫表,所以現在我們需要做一下刪除冗餘數據的處理

具體操作其實也很簡單,

1)首先停止掉我們之前所有節點的主從同步機制

stop slave;

2)然後將對應模塊的數據庫中無用的表做一個刪除處理,這裏我直接使用客戶端手動去刪除就可以了。清理之後如下圖:

三個數據庫只是保留各自模塊的表

3)驗證

再次登陸我們的mycat

mysql -uroot -p123456 -P8066 -h192.168.124.38

查看對應的表

show tables;

還是我們配置的所有邏輯表,冗餘數據刪除成功

 

三)全局表的配置使用

爲何要使用全局表?當我們在做兩個模塊的聯合查詢的時候,因爲現在做了分庫,無法通過關聯的sql語句做查詢,通常我們的解決方案會有以下三種:

1)使用Mycat的全局表

2)相關表中做冗餘數據

3)使用API的方式獲取數據

鑑於講解mycat的使用,這裏簡單說一下mycat的全局表的配置

基本思路:

1)三個數據庫中需要各自保持一份表數據

2)修改我們【schema.xml】的邏輯表的全局配置

 

這裏我們使用節點2中 【region_info】表來做演示,這是一個省市的數據表

1)導出數據表

mysqldump -uroot -p order_db region_info > region_info;

2)分別將導出的表數據拷貝到節點3(192.168.124.40)和節點4(192.168.124.41)中

scp region_info [email protected]:/root

scp region_info [email protected]:/root

3)然後分別導入到各個數據庫中

mysql -uroot -p product_db < region_info

mysql -uroot -p customer_db < region_info

4)修改我們【schema.xml】中的配置

<table name="region_info" primaryKey="region_id" dataNode="orderDB,productDB,customerDB"  type="global"/>

5)再次啓動我們的mycat

mycat start

再次關聯查詢數據就可以查到了。配置了全局表之後,我們的mycat就會來維護這個全局表的數據。

如何驗證?

通過客戶端連接mycat,修改全局表的數據,分別查看各個節點全局表數據有沒有發生變化,變化了即表示全局表配置成功。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章