存儲-海量數據-(持續數據的增加和高併發解決方案)

目標

Ø 掌握數據庫的大數據處理方案和HA
Ø 掌握爲何須要數據庫中間件,何爲數據庫中間件
Ø 掌握不一樣場景所需的數據庫中間件特性
Ø 掌握數據庫中間件設計要點前端

 

 

海量數據分片之分庫分表

大數據處理-回顧分區

應對大數據的處理,在分庫分表以前,咱們能夠用分區,提高數據庫的性能java

大數據處理-分片理解

隨着業務的發展,業務愈來愈複雜,應用的模塊愈來愈多,總的數據量很大,高併發讀寫操做均超過單個 數據庫服務器的處理能力怎麼辦?node

 

數據分片指按照某個維度將存放在單一數據庫中的數據分散地存放至多個數據庫或表中
數據分片的有效手段是對關係型數據庫進行分庫和分表mysql

分庫又叫垂直拆分,或者縱向拆分,指的是按照業務模塊將數據分散到不一樣的數據庫服務器git

就是把本來存儲於一個庫的表拆分存儲到多個庫上,一般是將表按照功能模塊、關係密切程度劃分出來, 部署到不一樣的庫上。github

若是數據庫是由於表太多而形成海量數據,而且項目的各項業務邏輯劃分清晰、低耦合,那麼規則簡單明 了、容易實施的首選就是分庫。sql

 

大數據處理-分庫圖例

優勢:數據庫

Ø 拆分後業務清晰,拆分規則明確;
Ø 系統之間整合或擴展容易;
Ø 數據維護簡單。express

缺點:apache

Ø 部分業務表沒法join,只能經過接口方式解決,提升了系統複雜度;
Ø 受每種業務不一樣的限制存在單庫性能瓶頸,不易數據擴展跟性能提升;
Ø 事務處理複雜。

 

大數據處理-分表理解

垂直拆分能夠緩衝數據量和訪問量帶來的問題,但沒法根治。

若是單個表的數量很大,超出了單表的存儲上限,如電商網站的商品表、訂單表等該怎麼辦?
若是垂直拆分以後,表中的數據量依然超過單節點所能承載的閾值,則須要水平分片來進一步處理。

分表又叫水平切分,它再也不將數據根據業務邏輯分類,而是經過某個字段(或某幾個字段),根據某種規則或邏輯,將一個表的數據拆分紅多份,分別存儲在多個表結構同樣的表中,這多個表能夠存在一到多個庫中,每一個分片僅包含數據的一部分。

 

大數據處理-分表類型

分表又分紅垂直分表和水平分表:

Ø 垂直分表:將原本能夠在同一個表的內容,劃分爲多個表。(按照關係型數據庫的第三範式要求,是應該在同一個表的。)
Ø 水平分表:是把一個表複製成一樣表結構的不一樣表,而後把數據按照必定的規則劃分,分別存儲到這些表中,從而保證單表的容量不會太大,提高性能;固然這些結構同樣的表,能夠放在一個或多個數據庫中。

大數據處理-分表圖例

優勢:

Ø 拆分規則抽象好,join 操做基本能夠數據庫作;
Ø 不存在單庫大數據,高併發的性能瓶頸;
Ø 應用端改造較少;
Ø 提升了系統的穩定性跟負載能力。

缺點:

Ø 拆分規則難以抽象;
Ø 分片事務一致性難以解決;
Ø 數據屢次擴展難度跟維護量極大;
Ø 跨庫join 性能較差。

水平拆分—分片規則

水平對數據進行拆分最重要的是分片規則—拆分規則

能夠如何來拆分?

Ø 範圍:時間、數值;
Ø 列表:按地域、按組織、分類;
Ø 散列:hash(某個字段) % 分片數、一致性hash;
Ø 複合多種方式。

 

分庫分表會帶來的挑戰

分庫分表的技術難點

不管垂直拆分、水平拆分,都有共同的技術難點:

Ø 分佈式事務的問題;
Ø 跨節點Join的問題;
Ø 跨節點合併排序分頁問題;
Ø 多數據源管理問題。

須要一個這樣的東西

Ø 1 要能解析SQL
Ø 2 能支持讀寫分離
Ø 3 能支持從庫讀的負載均衡
Ø 4 支持分庫操做
Ø 5 支持分表操做
Ø 6 支持跨庫關聯查詢
Ø 7 對事務處理的支持
Ø 8 主鍵ID生成
Ø 9 數據源管理

 

數據庫中間件的分類和分庫分表實戰

數據庫中間件的兩種實現模式

客戶端模式,在應用程序中集成數據庫中間件模塊,經過該模塊來配置管理應用須要的一個(或者多個)數據源,以及訪問各個數據源,在模塊內完成數據的整合。

服務端(代理)模式,經過中間代理層來統一管理全部的數據源,後端數據庫集羣對前端應用程序透明,同時易於數據庫擴展。獨立的服務能提供更強的處理能力。適用於大型複雜系統。

經常使用數據庫中間件簡介

 

Mycat是什麼

Ø 一個完全開源的,面向企業應用開發的大數據庫集羣
Ø 支持事務、ACID、能夠替代MySQL的增強版數據庫
Ø 一個能夠視爲MySQL集羣的企業級數據庫,用來替代昂貴的Oracle集羣
Ø 一個融合內存緩存技術、NoSQL技術、HDFS大數據的新型SQL Server
Ø 結合傳統數據庫和新型分佈式數據倉庫的新一代企業級數據庫產品
Ø 一個新穎的數據庫中間件產品。

官網地址: http://www.mycat.io
Github地址: https://github.com/MyCATApache
Github上文檔地址: https://github.com/MyCATApache/Mycat-doc

Mycat 由來

2013年阿里的Cobar在社區使用過程當中發現存在一些比較嚴重的問題,及其使用限制,通過Mycat發起人第一次改良,第一代改良版——Mycat誕生。 Mycat開源之後,一些Cobar的用戶參與了Mycat的開發,最終Mycat發展成爲一個由衆多軟件公司的實力派架構師和資深開發人員維護的社區型開源軟件。

Mycat 課程安裝

Ø 1 JDK1.7+ Mycat是用java開發
Ø 2 MySQL統一5.7 鏡像地址: http://mirrors.163.com/mysql/Downloads/MySQL5.7/mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar
Ø 3 Mycat安裝包 下載地址: http://dl.mycat.io 當前最新版本:1.6.6.1

Mycat使用說明

Ø 1 源碼方式導入到IDE,源碼地址: https://github.com/MyCATApache/Mycat-Server.git
Ø 2 安裝包方式安裝,下載地址: http://dl.mycat.io

核心概念

數據庫中間件:對應用,mycat就是數據庫服務,mycat是後端數據庫集羣的代理

schema.xm

<mycat:schema>
 <schema name="testdb">
   <table name="orders" primaryKey="ID"type="global" dataNode="dn1,dn2" />
 </schema>
 <dataNode name="dn1" dataHost="dhost1" database="db1" />
 <dataHost name="dhost1" ...>
     <heartbeat>select user()</heartbeat>
     <writeHost host="hostM1" url="localhost:3306"...>
     <readHost host="hostS2" url="192.168.1.2:3306".../>
     </writeHost>
 </dataHost>
</mycat:schema>

邏輯概念:

Ø 邏輯庫:mycat數據庫服務中定義、管理的數據庫
Ø 邏輯表:邏輯庫中包含的需分庫分表存儲的表
Ø dataNode:數據節點(分片節點),邏輯表分片的存放節點。
Ø dataHost: 數據主機(節點主機),數據節點所在的主機。

物理概念

Ø writeHost:寫主機,真實的數據庫服務主機描述
Ø readHost:讀主機,真實的數據庫服務主機描述

 

分庫分表的優缺點和原則

大數據處理-分片優勢

Ø 解決磁盤系統最大文件限制,好比常見的有:
    FAT16(最大分區2GB,最大文件2GB)
    FAT32(最大分區32GB,最大容量2TB,最大文件32G)
    NTFS(最大分區2TB,最大容量,最大文件2TB)
    EXT3(最大文件大小: 2TB,最大文件極限: 僅受文件系統大小限制,最大分區/文件系統大小: 4TB,最大文件名長度: 255 字符)
Ø 減小增量數據寫入時的鎖對查詢的影響,減小長時間查詢形成的表鎖,影響寫入操做等鎖競爭的狀況,節省排隊的時間開支,增長呑吐量。
Ø 因爲單表數量降低,常見的查詢操做因爲減小了須要掃描的記錄,使得單表單次查詢所需的檢索行數變少,減小了磁盤IO,時延變短。

大數據處理-分庫原則

基本的思路就是分析業務功能,以及表間的聚合關係,把關係緊密的表放在一塊兒。分庫的粒度指的是在作切分時容許幾級的關聯表放在一塊兒,這個問題對應用程序實現有着很大的影響。關聯打斷的越多,則受影響的join操做越多。

實際的粒度掌控須要結合「業務緊密程度」和「表的數據量」兩個因素綜合考慮

Ø 若劃歸到一塊兒的表關係緊密,且數據量並不大,增速也很是緩慢,則適宜放在一塊兒,不須要再進行水平切分;
Ø 若劃歸到一塊兒的表的數據量巨大且增速迅猛,則勢必要在分庫的基礎上再進行分表,這就意味着原單一的庫還可能會被拆分紅多個庫,這會致使更多的複雜性,一開始最好就要考慮進去

對於垂直分表,一般是按照業務功能的使用頻次,把主要的、熱門的字段放在一塊兒作爲主要表;而後把不常 用的,按照各自的業務屬性進行彙集,拆分到不一樣的次要表中;主要表和次要表的關係通常都是一對一的。

對於水平分表,一般是按照具體的業務規則和數據的格式,選擇可以把數據進行合理拆分的業務數據作爲拆 分標準,以此來對數據進行拆分。

水平對數據進行拆分最重要的是分片規則—拆分規則

Ø 範圍:時間、數值;
Ø 列表:按地域、按組織、分類;
Ø 散列:hash(某個字段) % 分片數、一致性hash;
Ø 複合多種方式。

數據庫拆分原則

第一原則:能不切分儘可能不要切分
第二原則:若是要切分必定要選擇合適的切分規則,提早規劃好。
第三原則:數據切分儘可能經過數據冗餘或表分組(Table Group)來下降跨庫Join 的可能。
第四原則:因爲數據庫中間件對數據Join實現的優劣難以把握,並且實現高性能難度極大,業務讀取儘可能少使用多表Join。

 

實驗代碼

rule.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License"); 
	- you may not use this file except in compliance with the License. - You 
	may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 
	- - Unless required by applicable law or agreed to in writing, software - 
	distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT 
	WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the 
	License for the specific language governing permissions and - limitations 
	under the License. -->
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
	<tableRule name="rule1">
		<rule>
			<columns>id</columns>
			<algorithm>func1</algorithm>
		</rule>
	</tableRule>

	<tableRule name="rule2">
		<rule>
			<columns>user_id</columns>
			<algorithm>func1</algorithm>
		</rule>
	</tableRule>

	<tableRule name="sharding-by-intfile">
		<rule>
			<columns>sharding_id</columns>
			<algorithm>hash-int</algorithm>
		</rule>
	</tableRule>
	<tableRule name="auto-sharding-long">
		<rule>
			<columns>id</columns>
			<algorithm>rang-long</algorithm>
		</rule>
	</tableRule>
	<tableRule name="mod-long">
		<rule>
			<columns>uuid</columns>
			<algorithm>mod-long</algorithm>
		</rule>
	</tableRule>
	<tableRule name="sharding-by-murmur">
		<rule>
			<columns>id</columns>
			<algorithm>murmur</algorithm>
		</rule>
	</tableRule>
	<tableRule name="crc32slot">
		<rule>
			<columns>id</columns>
			<algorithm>crc32slot</algorithm>
		</rule>
	</tableRule>
	<tableRule name="sharding-by-month">
		<rule>
			<columns>create_time</columns>
			<algorithm>partbymonth</algorithm>
		</rule>
	</tableRule>
	<tableRule name="latest-month-calldate">
		<rule>
			<columns>calldate</columns>
			<algorithm>latestMonth</algorithm>
		</rule>
	</tableRule>
	
	<tableRule name="auto-sharding-rang-mod">
		<rule>
			<columns>id</columns>
			<algorithm>rang-mod</algorithm>
		</rule>
	</tableRule>
	
	<tableRule name="jch">
		<rule>
			<columns>id</columns>
			<algorithm>jump-consistent-hash</algorithm>
		</rule>
	</tableRule>

	<function name="murmur"
		class="io.mycat.route.function.PartitionByMurmurHash">
		<property name="seed">0</property>
		<property name="count">2</property>
		<property name="virtualBucketTimes">160</property>
	</function>

	<function name="crc32slot"
			  class="io.mycat.route.function.PartitionByCRC32PreSlot">
	</function>
	<function name="hash-int"
		class="io.mycat.route.function.PartitionByFileMap">
		<property name="mapFile">partition-hash-int.txt</property>
	</function>
	<function name="rang-long"
		class="io.mycat.route.function.AutoPartitionByLong">
		<property name="mapFile">autopartition-long.txt</property>
	</function>
	<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
		<!-- how many data nodes -->
		<property name="count">2</property>
	</function>

	<function name="func1" class="io.mycat.route.function.PartitionByLong">
		<property name="partitionCount">8</property>
		<property name="partitionLength">128</property>
	</function>
	<function name="latestMonth"
		class="io.mycat.route.function.LatestMonthPartion">
		<property name="splitOneDay">24</property>
	</function>
	<function name="partbymonth"
		class="io.mycat.route.function.PartitionByMonth">
		<property name="dateFormat">yyyy-MM-dd</property>
		<property name="sBeginDate">2015-01-01</property>
	</function>
	
	<function name="rang-mod" class="io.mycat.route.function.PartitionByRangeMod">
        	<property name="mapFile">partition-range-mod.txt</property>
	</function>
	
	<function name="jump-consistent-hash" class="io.mycat.route.function.PartitionByJumpConsistentHash">
		<property name="totalBuckets">3</property>
	</function>
</mycat:rule>

schema.xml

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
	<schema name="mydb1" checkSQLschema="true" sqlMaxLimit="100">
		<table name="t_order" primaryKey="uuid" autoIncrement="true" dataNode="dn1"/>
		<table name="t_user" primaryKey="uuid" autoIncrement="true" dataNode="dn2,dn3" rule="mod-long" />
	</schema>
	
	<dataNode name="dn1" dataHost="dhost1" database="orderdb" />
	<dataNode name="dn2" dataHost="dhost1" database="userdb" />
	<dataNode name="dn3" dataHost="dhost2" database="userdb" />
	
	<dataHost name="dhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native">
		<heartbeat>select user()</heartbeat>
		<writeHost host="myhostM1" url="192.168.100.201:3306" user="root" password="5462837zhu"></writeHost>
	</dataHost>
	<dataHost name="dhost2" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native">
		<heartbeat>select user()</heartbeat>
		<writeHost host="myhostM2" url="192.168.100.202:3306" user="root"	password="5462837zhu"></writeHost>
	</dataHost>
</mycat:schema>

 

server.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License"); 
	- you may not use this file except in compliance with the License. - You 
	may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 
	- - Unless required by applicable law or agreed to in writing, software - 
	distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT 
	WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the 
	License for the specific language governing permissions and - limitations 
	under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
	<user name="user">
		<property name="password">user</property>
		<property name="schemas">mydb1</property>
		<property name="readOnly">false</property>
	</user>

</mycat:server>
相關文章
相關標籤/搜索