摘自【mysql 讀寫(xiě)分離】10分鐘了解讀寫(xiě)分離的作用 ,原作者:開(kāi)心果汁
1、what 讀寫(xiě)分離
讀寫(xiě)分離,基本的原理是讓主數(shù)據(jù)庫(kù)處理事務(wù)性增、改、刪操作(INSERT、UPDATE、DELETE),而從數(shù)據(jù)庫(kù)處理SELECT查詢(xún)操作。數(shù)據(jù)庫(kù)復(fù)制被用來(lái)把事務(wù)性操作導(dǎo)致的變更同步到集群中的從數(shù)據(jù)庫(kù)。
2、why 那么為什么要讀寫(xiě)分離呢?
因?yàn)閿?shù)據(jù)庫(kù)的“寫(xiě)”(寫(xiě)10000條數(shù)據(jù)到oracle可能要3分鐘)操作是比較耗時(shí)的。
但是數(shù)據(jù)庫(kù)的“讀”(從oracle讀10000條數(shù)據(jù)可能只要5秒鐘)。
所以讀寫(xiě)分離,解決的是,數(shù)據(jù)庫(kù)的寫(xiě)入,影響了查詢(xún)的效率。
3、when 什么時(shí)候要讀寫(xiě)分離?
數(shù)據(jù)庫(kù)不一定要讀寫(xiě)分離,如果程序使用數(shù)據(jù)庫(kù)較多時(shí),而更新少,查詢(xún)多的情況下會(huì)考慮使用,利用數(shù)據(jù)庫(kù) 主從同步 。可以減少數(shù)據(jù)庫(kù)壓力,提高性能。當(dāng)然,數(shù)據(jù)庫(kù)也有其它優(yōu)化方案。memcache 或是 表折分,或是搜索引擎。都是解決方法。
4、主從復(fù)制與讀寫(xiě)分離
在實(shí)際的生產(chǎn)環(huán)境中,對(duì)數(shù)據(jù)庫(kù)的讀和寫(xiě)都在同一個(gè)數(shù)據(jù)庫(kù)服務(wù)器中,是不能滿(mǎn)足實(shí)際需求的。無(wú)論是在安全性、高可用性還是高并發(fā)等各個(gè)方面都是完全不能滿(mǎn)足實(shí)際需求的。因此,通過(guò)主從復(fù)制的方式來(lái)同步數(shù)據(jù),再通過(guò)讀寫(xiě)分離來(lái)提升數(shù)據(jù)庫(kù)的并發(fā)負(fù)載能力。有點(diǎn)類(lèi)似于前面我們學(xué)習(xí)過(guò)的rsync,但是不同的是rsync是對(duì)磁盤(pán)文件做備份,而mysql主從復(fù)制是對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)、語(yǔ)句做備份。
1
1
4.1、 mysq支持的復(fù)制類(lèi)型
1) 基于語(yǔ)句的復(fù)制。在服務(wù)器上執(zhí)行sql語(yǔ)句,在從服務(wù)器上執(zhí)行同樣的語(yǔ)句,mysql默認(rèn)采用基于語(yǔ)句的復(fù)制,執(zhí)行效率高。
2) 基于行的復(fù)制。把改變的內(nèi)容復(fù)制過(guò)去,而不是把命令在從服務(wù)器上執(zhí)行一遍。
3) 混合類(lèi)型的復(fù)制。默認(rèn)采用基于語(yǔ)句的復(fù)制,一旦發(fā)現(xiàn)基于語(yǔ)句無(wú)法精確復(fù)制時(shí),就會(huì)采用基于行的復(fù)制。
4.2、 復(fù)制的工作過(guò)程
1) 在每個(gè)事務(wù)更新數(shù)據(jù)完成之前,master在二進(jìn)制日志記錄這些改變。寫(xiě)入二進(jìn)制日志完成后,master通知存儲(chǔ)引擎提交事務(wù)。
2) Slave將master的binary log復(fù)制到其中繼日志。首先slave開(kāi)始一個(gè)工作線程(I/O),I/O線程在master上打開(kāi)一個(gè)普通的連接,然后開(kāi)始binlog dump process。binlog dump process從master的二進(jìn)制日志中讀取事件,如果已經(jīng)跟上master,它會(huì)睡眠并等待master產(chǎn)生新的事件,I/O線程將這些事件寫(xiě)入中繼日志。
3) Sql slave thread(sql從線程)處理該過(guò)程的最后一步,sql線程從中繼日志讀取事件,并重放其中的事件而更新slave數(shù)據(jù),使其與master中的數(shù)據(jù)一致,只要該線程與I/O線程保持一致,中繼日志通常會(huì)位于os緩存中,所以中繼日志的開(kāi)銷(xiāo)很小。
5、 mysql讀寫(xiě)分離原理
讀寫(xiě)分離就是在主服務(wù)器上修改,數(shù)據(jù)會(huì)同步到從服務(wù)器,從服務(wù)器只能提供讀取數(shù)據(jù),不能寫(xiě)入,實(shí)現(xiàn)備份的同時(shí)也實(shí)現(xiàn)了數(shù)據(jù)庫(kù)性能的優(yōu)化,以及提升了服務(wù)器安全。
6、前較為常見(jiàn)的Mysql讀寫(xiě)分離分為以下兩種:
1)基于程序代碼內(nèi)部實(shí)現(xiàn)
? ? 在代碼中根據(jù)select 、insert進(jìn)行路由分類(lèi),這類(lèi)方法也是目前生產(chǎn)環(huán)境下應(yīng)用最廣泛的。優(yōu)點(diǎn)是性能較好,因?yàn)槌绦蛟诖a中實(shí)現(xiàn),不需要增加額外的硬件開(kāi)支,缺點(diǎn)是需要開(kāi)發(fā)人員來(lái)實(shí)現(xiàn),運(yùn)維人員無(wú)從下手。
1
1
2) 基于中間代理層實(shí)現(xiàn)
? ? 代理一般介于應(yīng)用服務(wù)器和數(shù)據(jù)庫(kù)服務(wù)器之間,代理數(shù)據(jù)庫(kù)服務(wù)器接收到應(yīng)用服務(wù)器的請(qǐng)求后根據(jù)判斷后轉(zhuǎn)發(fā)到,后端數(shù)據(jù)庫(kù),有以下代表性的程序。
1
1
(1)mysql_proxy。mysql_proxy是Mysql的一個(gè)開(kāi)源項(xiàng)目,通過(guò)其自帶的lua腳本進(jìn)行sql判斷。
(2)Atlas。是由 Qihoo 360, Web平臺(tái)部基礎(chǔ)架構(gòu)團(tuán)隊(duì)開(kāi)發(fā)維護(hù)的一個(gè)基于MySQL協(xié)議的數(shù)據(jù)中間層項(xiàng)目。它是在mysql-proxy 0.8.2版本的基礎(chǔ)上,對(duì)其進(jìn)行了優(yōu)化,增加了一些新的功能特性。360內(nèi)部使用Atlas運(yùn)行的mysql業(yè)務(wù),每天承載的讀寫(xiě)請(qǐng)求數(shù)達(dá)幾十億條。支持事物以及存儲(chǔ)過(guò)程。
(3)Amoeba。由阿里巴巴集團(tuán)在職員工陳思儒使用序java語(yǔ)言進(jìn)行開(kāi)發(fā),阿里巴巴集團(tuán)將其用戶(hù)生產(chǎn)環(huán)境下,但是他并不支持事物以及存儲(chǔ)過(guò)程。
經(jīng)過(guò)上述簡(jiǎn)單的比較,不是所有的應(yīng)用都能夠在基于程序代碼中實(shí)現(xiàn)讀寫(xiě)分離,像一些大型的java應(yīng)用,如果在程序代碼中實(shí)現(xiàn)讀寫(xiě)分離對(duì)代碼的改動(dòng)就較大,所以,像這種應(yīng)用一般會(huì)考慮使用代理層來(lái)實(shí)現(xiàn),那么今天就使用Amoeba為例,完成主從復(fù)制和讀寫(xiě)分離。
MySQLProxy介紹
下面使用MySQL官方提供的數(shù)據(jù)庫(kù)代理層產(chǎn)品MySQLProxy搭建讀寫(xiě)分離。
MySQLProxy實(shí)際上是在客戶(hù)端請(qǐng)求與MySQLServer之間建立了一個(gè)連接池。所有客戶(hù)端請(qǐng)求都是發(fā)向MySQLProxy,然后經(jīng)由MySQLProxy進(jìn)行相應(yīng)的分析,判斷出是讀操作還是寫(xiě)操作,分發(fā)至對(duì)應(yīng)的MySQLServer上。對(duì)于多節(jié)點(diǎn)Slave集群,也可以起做到負(fù)載均衡的效果。