自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

你還不知道怎么做數(shù)據(jù)庫讀寫分離么,用這個中間件讓你性能提10倍

數(shù)據(jù)庫 其他數(shù)據(jù)庫
我們以mysql一主兩從架構(gòu)為例,也就是一個master節(jié)點(diǎn)下有兩個slave節(jié)點(diǎn),在這套架構(gòu)下,寫請求統(tǒng)一交給master節(jié)點(diǎn)處理,而讀請求交給slave節(jié)點(diǎn)處理。

前 言

訂單緩存方案上線之后,我們以為又開啟了歲月安好的日子,但是,在一周后的某一天,DBA直接跑來了,DBA直接說:“l(fā)eader讓我直接找你,是這樣的,上次加了緩存優(yōu)化后,效果確實(shí)不錯,但是我發(fā)現(xiàn)訂單查詢sql在今天的12:00至12:05之間有大量的慢sql,查詢時(shí)間超過了2.5s?!?/p>

這個時(shí)候,我們立馬開啟了排查問題模式,首先,check了一下上次加的緩存,發(fā)現(xiàn)緩存正常,然后接著根據(jù)DBA提供的信息搜索日志,此時(shí),發(fā)現(xiàn)在這個時(shí)間段訂單請求量突增,大概是平常訂單請求量的2到3倍,然后經(jīng)過了解,發(fā)現(xiàn)在這個時(shí)間段內(nèi),營銷系統(tǒng)那邊做了一些活動,導(dǎo)致訂單請求量突增。

說白了就是做了促銷活動后,大量下單的用戶會不斷刷新訂單來查詢訂單的信息,比如看一下訂單是否開始配送,此時(shí)大量的請求會打到了MySQL上去,此時(shí)單庫又抗不了這么讀請求,就導(dǎo)致了數(shù)據(jù)庫負(fù)載很高,從而嚴(yán)重降低了MySQL的查詢效率。

現(xiàn)在我們緩存也加過了,但是數(shù)據(jù)庫負(fù)載還是很高,此時(shí)該怎么辦呢?

其實(shí)也很簡單,既然單個庫扛不住,那就搞2個庫一起來抗唄,因?yàn)閷τ谕赓u訂單來說是典型的讀多寫少的場景,所以,在這個場景下,我們可以搞個一主兩從的架構(gòu)來進(jìn)行優(yōu)化,就像這樣:

也就是寫數(shù)據(jù)走主庫,而讀數(shù)據(jù)走從庫,可以看到,此時(shí)由于我們搞了2個從庫,這2個從庫可以一起來抗大量的讀請求。

非常關(guān)鍵的一點(diǎn)就是,從庫會通過主從復(fù)制,從主庫中不斷的同步數(shù)據(jù),以此來保證從庫的數(shù)據(jù)和主庫是一模一樣的,所以想要實(shí)現(xiàn)讀寫分離,那么,就先要了解主從復(fù)制是怎么玩兒的。

主從復(fù)制的原理是什么?

我們以mysql一主兩從架構(gòu)為例,也就是一個master節(jié)點(diǎn)下有兩個slave節(jié)點(diǎn),在這套架構(gòu)下,寫請求統(tǒng)一交給master節(jié)點(diǎn)處理,而讀請求交給slave節(jié)點(diǎn)處理。

為了保證slave節(jié)點(diǎn)和master節(jié)點(diǎn)的數(shù)據(jù)一致性,master節(jié)點(diǎn)在寫入數(shù)據(jù)之后,同時(shí)會把數(shù)據(jù)復(fù)制一份到自己的各個slave節(jié)點(diǎn)上。

在復(fù)制的過程中一共會使用到三個線程,一個是binlog dump線程,位于master節(jié)點(diǎn)上,另外兩個線程分別是I/O線程和SQL線程,它們都分別位于slave節(jié)點(diǎn)上,如下圖:

結(jié)合圖片,我們一起來看下主從復(fù)制的核心流程:

(1)當(dāng)master節(jié)點(diǎn)接收到一個寫請求時(shí),這個寫請求可能是增刪改操作,此時(shí)會把寫請求的操作都記錄到binlog日志中。

(2)master節(jié)點(diǎn)會把數(shù)據(jù)復(fù)制給slave節(jié)點(diǎn),如圖中的slave01節(jié)點(diǎn)和slave02節(jié)點(diǎn),這個過程,首先得要每個slave節(jié)點(diǎn)連接到master節(jié)點(diǎn)上,當(dāng)slave節(jié)點(diǎn)連接到master節(jié)點(diǎn)上時(shí),master節(jié)點(diǎn)會為每一個slave節(jié)點(diǎn)分別創(chuàng)建一個binlog dump線程,用于向各個slave節(jié)點(diǎn)發(fā)送binlog日志。

(3)binlog dump線程會讀取master節(jié)點(diǎn)上的binlog日志,然后將binlog日志發(fā)送給slave節(jié)點(diǎn)上的I/O線程。

(4)slave節(jié)點(diǎn)上的I/O線程接收到binlog日志后,會將binlog日志先寫入到本地的relaylog中,relaylog中就保存了binlog日志。

(5)slave節(jié)點(diǎn)上的SQL線程,會來讀取relaylog中的binlog日志,將其解析成具體的增刪改操作,把這些在master節(jié)點(diǎn)上進(jìn)行過的操作,重新在slave節(jié)點(diǎn)上也重做一遍,達(dá)到數(shù)據(jù)還原的效果,這樣就可以保證master節(jié)點(diǎn)和slave節(jié)點(diǎn)的數(shù)據(jù)一致性了。

主從復(fù)制的有幾種模式?

mysql的主從復(fù)制,分為全同步復(fù)制、異步復(fù)制、半同步復(fù)制和增強(qiáng)半同步復(fù)制 這四種。

全同步復(fù)制

首先,全同步復(fù)制,就是當(dāng)主庫執(zhí)行完一個事務(wù)之后,要求所有的從庫也都必須執(zhí)行完該事務(wù),才可以返回處理結(jié)果給客戶端;因此,雖然全同步復(fù)制數(shù)據(jù)一致性得到保證了,但是主庫完成一個事物需要等待所有從庫也完成,性能就比較低了。

異步復(fù)制

而異步復(fù)制,當(dāng)主庫提交事物后,會通知binlog dump線程發(fā)送binlog日志給從庫,一旦binlog dump線程將binlog日志發(fā)送給從庫之后,不需要等到從庫也同步完成事務(wù),主庫就會將處理結(jié)果返回給客戶端。

因?yàn)橹鲙熘还茏约簣?zhí)行完事務(wù),就可以將處理結(jié)果返回給客戶端,而不用關(guān)心從庫是否執(zhí)行完事務(wù),這就可能導(dǎo)致短暫的主從數(shù)據(jù)不一致的問題了,比如剛在主庫插入的新數(shù)據(jù),如果馬上在從庫查詢,就可能查詢不到。

而且,當(dāng)主庫提交事物后,如果宕機(jī)掛掉了,此時(shí)可能binlog還沒來得及同步給從庫,這時(shí)候如果為了恢復(fù)故障切換主從節(jié)點(diǎn)的話,就會出現(xiàn)數(shù)據(jù)丟失的問題,所以異步復(fù)制雖然性能高,但數(shù)據(jù)一致性上是較弱的。

mysql主從復(fù)制,默認(rèn)采用的就是異步復(fù)制這種復(fù)制策略。

半同步復(fù)制

半同步復(fù)制,顧名思義就是在同步和異步中做了折中選擇,我們可以結(jié)合著MySQL官網(wǎng)來看下是半同步主從復(fù)制的過程,來看下這樣圖:

當(dāng)主庫提交事務(wù)后,至少還需要一個從庫返回接受到binlog日志,并成功寫入到relaylog的消息,這個時(shí)候,主庫才會將處理結(jié)果返回給客戶端。

相比前2種復(fù)制方式,半同步復(fù)制較好地兼顧了數(shù)據(jù)一致性以及性能損耗的問題。

同時(shí),半同步復(fù)制也存在以下幾個問題:

  • 半同步復(fù)制的性能,相比異步復(fù)制而言有所下降,相比于異步復(fù)制是不需要等待任何從庫是否接收到數(shù)據(jù)的響應(yīng),而半同步復(fù)制則需要等待至少一個從庫確認(rèn)接收到binlog日志的響應(yīng),性能上是損耗更大的。
  • 主庫等待從庫響應(yīng)的最大時(shí)長是可以配置的,如果超過了配置的時(shí)間,半同步復(fù)制就會變成異步復(fù)制,那么,異步復(fù)制的問題同樣也就會出現(xiàn)了。
  • 在MySQL 5.7.2之前的版本中,半同步復(fù)制存在著幻讀問題的。

當(dāng)主庫成功提交事物并處于等待從庫確認(rèn)的過程中,這個時(shí)候,從庫都還沒來得及返回處理結(jié)果給客戶端,但因?yàn)橹鲙齑鎯σ鎯?nèi)部已經(jīng)提交事務(wù)了,所以,其他客戶端是可以到從主庫中讀到數(shù)據(jù)的。

但是,如果下一秒主庫突然掛了,就像這樣圖一樣:

此時(shí),下一次請求過來,因?yàn)橹鲙鞉炝?,就只能把請求切換到從庫中,因?yàn)閺膸爝€沒從主庫同步完數(shù)據(jù),所以,從庫中當(dāng)然就讀不到這條數(shù)據(jù)了,和上一秒讀取數(shù)據(jù)的結(jié)果對比,就造成了幻讀的現(xiàn)象了。

增強(qiáng)半同步復(fù)制

最后,增強(qiáng)半同步復(fù)制,是mysql 5.7.2后的版本對半同步復(fù)制做的一個改進(jìn),原理上幾乎是一樣的,主要是解決幻讀的問題。

主庫配置了參數(shù)rpl_semi_sync_master_wait_point = AFTER_SYNC 后,主庫在存儲引擎提交事物前,必須先收到從庫數(shù)據(jù)同步完成的確認(rèn)信息后,才能提交事務(wù),以此來解決幻讀問題。

可以參考下MySQL官網(wǎng)是怎么描述增強(qiáng)半同步主從復(fù)制過程的:

主從延遲問題和常規(guī)解決方案

主庫寫入的速度是很快的,因?yàn)橹鲙焓嵌嗑€程并發(fā)寫入的,但是,從庫是單線程從主庫拉取數(shù)據(jù)的,所以從庫從主庫復(fù)制數(shù)據(jù)的速度,就比較慢了,從而產(chǎn)生了主從延遲的問題。

mysql 從 5.6版本開始,就支持多線程復(fù)制,但是5.6版本是基于庫級別去操作,也就是說會給每個數(shù)據(jù)庫開啟一個線程,不同庫處理時(shí)在同一時(shí)間內(nèi)是互不影響的;但是,當(dāng)業(yè)務(wù)的壓力集中到一個庫時(shí),又會回到和單線程復(fù)制一樣的狀況了。

直到mysql 5.7版本,開始引入了基于組提交(group_commit)的概念,這個時(shí)候才 真正 支持多路復(fù)制功能,官方稱為enhanced multi-threaded slave(簡稱MTS),所以,推薦大家盡可能選擇MySQL 5.7之后的版本。

而主庫掛載的從庫數(shù)量過多,也會導(dǎo)致主從復(fù)制延遲的問題,一般我們是建議一個主庫掛載從庫的數(shù)量,在3~5個比較合適。

另外,我們執(zhí)行的SQL語句中,如果慢SQL語句過多,也會導(dǎo)致主從復(fù)制延遲,比如,我們工作中會遇到批量插入的場景,如果一批插入的數(shù)據(jù)量過大,就容易造成執(zhí)行時(shí)間過長。

假如,從執(zhí)行完一份 批量插入數(shù)據(jù)的SQL語句開始,到在從庫上能查到這些數(shù)據(jù)的這個過程中,如果耗費(fèi)了10秒,就導(dǎo)致主從庫之間就延遲10秒了;所以,SQL優(yōu)化會是一個常態(tài)化的工作,可以通過慢SQL日志或監(jiān)控平臺監(jiān)控慢SQL,如果單個數(shù)據(jù)寫入時(shí)間過長的話,可以將一批數(shù)據(jù)分片分批次寫入。

最后,如果出現(xiàn)網(wǎng)絡(luò)延遲或者機(jī)器的性能比較差,也會導(dǎo)致主從復(fù)制延遲的問題,這種情況沒什么可說的,及時(shí)優(yōu)化網(wǎng)絡(luò)提升機(jī)器性能就行了。

讀寫分離實(shí)戰(zhàn)

讀寫分離配置核心組件流程圖:

讀寫分離配置步驟

(1)配置文件中配置主從庫連接信息

(2)注入數(shù)據(jù)源

(3)數(shù)據(jù)源切換上下文,其中使用了ThreadLocal保存當(dāng)前線程的數(shù)據(jù)源

(4)繼承AbstractRoutingDataSource類重寫determineCurrentLookupKey方法實(shí)現(xiàn)數(shù)據(jù)源動態(tài)切換

(5)創(chuàng)建讀庫的自定義注解

(6)切面類

(7)需要走讀庫的業(yè)務(wù)方法上添加@ReadOnly注解,那么執(zhí)行這些業(yè)務(wù)方法時(shí)就會被切面攔截修改數(shù)據(jù)源從而走讀庫進(jìn)行查詢。

(8)寫主庫、讀從庫的效果

1)生成訂單

2)查詢訂單

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2018-02-24 19:37:33

Java8數(shù)據(jù)庫中間件

2022-01-24 16:42:48

bpftraceLinux工具

2017-11-27 06:01:37

數(shù)據(jù)庫中間件中間層

2017-11-30 08:56:14

數(shù)據(jù)庫中間件架構(gòu)師

2019-12-24 09:49:02

微軟英語瀏覽器

2016-07-22 17:55:07

云計(jì)算

2015-02-02 13:03:33

CIL堆棧

2020-02-09 16:18:45

Redis快 5 倍中間件

2021-01-14 05:23:32

高并發(fā)消息中間件

2021-07-27 05:49:59

MySQL數(shù)據(jù)庫中間件

2018-09-02 15:43:56

Python代碼編程語言

2020-12-14 07:51:16

JS 技巧虛值

2022-07-17 06:53:24

微服務(wù)架構(gòu)

2022-05-05 12:02:45

SCSS函數(shù)開發(fā)

2010-05-19 09:01:00

2014-11-21 10:25:18

Java

2021-10-22 09:41:26

橋接模式設(shè)計(jì)

2021-07-09 10:11:34

Redis云數(shù)據(jù)技術(shù)

2019-11-29 16:49:42

HTML語言開發(fā)

2021-08-30 07:49:33

索引ICP Mysql
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號