[原]redis&mysql的事務(wù)為什么區(qū)別會(huì)這么大

本文主要是討論redis的事務(wù)和傳統(tǒng)事務(wù)(mysql)在設(shè)計(jì)上的區(qū)別和背后的設(shè)計(jì)決策的借鑒意義

可能大多數(shù)人都會(huì)覺(jué)得這個(gè)不是很正常,兩個(gè)不一樣的數(shù)據(jù)庫(kù)子姜,有各自的優(yōu)勢(shì)和不同的應(yīng)用場(chǎng)景趴腋,事務(wù)處理上有點(diǎn)區(qū)別有什么奇怪的啤呼,這宋舷。巷怜。葛超。確實(shí)沒(méi)錯(cuò),but....了解采取這種決策方式背后的意圖和對(duì)相同實(shí)現(xiàn)方式不同場(chǎng)景下的設(shè)計(jì)決策對(duì)比的思考延塑,對(duì)我們現(xiàn)實(shí)的項(xiàng)目設(shè)計(jì)中采取哪些方案是很有幫助的绣张。

先來(lái)看看redis和mysql對(duì)于事務(wù)處理涉及到的相關(guān)命令:


image.png

當(dāng)然mysql在事務(wù)回滾上還有更多的玩法,例如:SAVEPOINT

從這里你至少會(huì)發(fā)現(xiàn):redis沒(méi)有提供和回滾有關(guān)的命令关带,或者你會(huì)覺(jué)得還能接受侥涵,至少如果在事務(wù)執(zhí)行過(guò)程中出現(xiàn)問(wèn)題了,redis整個(gè)的事務(wù)還能回滾宋雏,然而芜飘,實(shí)際并不是這樣的,redis的事務(wù)中好芭,就算其中一個(gè)執(zhí)行失敗了燃箭,后面的事務(wù)還是會(huì)繼續(xù)進(jìn)行!并不是你理想中的舍败,整個(gè)事務(wù)就失敗了招狸。

來(lái)看看redis的官方文檔是如何定義redis的原子性:

Either all of the commands or none are processed, so a Redis transaction is also atomic.
意思是:事務(wù)中的命令要么全部被執(zhí)行,要么全部都不執(zhí)行邻薯,所以redis的事務(wù)也是原子性

所以裙戏,你會(huì)看到文檔中強(qiáng)調(diào):

It's important to note that even when a command fails, all the other commands in the queue are processed – Redis will not stop the processing of commands.

而mysql事務(wù)的原子性的定義:一個(gè)事務(wù)(transaction)中的所有操作,要么全部完成厕诡,要么全部不完成累榜,不會(huì)結(jié)束在中間某個(gè)環(huán)節(jié)。事務(wù)在執(zhí)行過(guò)程中發(fā)生錯(cuò)誤,會(huì)被回滾(Rollback)到事務(wù)開(kāi)始前的狀態(tài)壹罚,就像這個(gè)事務(wù)從來(lái)沒(méi)有執(zhí)行過(guò)一樣葛作。

到這里,我們整理一下redis和mysql的事務(wù)的區(qū)別:
1猖凛,沒(méi)有提供回滾相關(guān)的命令赂蠢,無(wú)法像mysql一樣提供任意時(shí)刻任意點(diǎn)的回滾
2,事務(wù)執(zhí)行過(guò)程中有某條/某些命令執(zhí)行失敗了辨泳, 事務(wù)隊(duì)列中的其他命令仍然會(huì)繼續(xù)執(zhí)行 —— Redis 不會(huì)停止和回滾執(zhí)行事務(wù)中的命令虱岂。

所以從這兩點(diǎn)上看出,redis必須保證每條命令成功執(zhí)行菠红,否則這個(gè)事務(wù)就不符合事務(wù)的標(biāo)準(zhǔn):1第岖,無(wú)法保證原子性 2,無(wú)法保證一致性

通過(guò)redis對(duì)事務(wù)介紹的文檔中看出設(shè)計(jì)者對(duì)于redis事務(wù)設(shè)計(jì)的兩個(gè)特征:
1试溯,不考慮事務(wù)執(zhí)行命令時(shí)外界上下文邏輯
2蔑滓,基于redis單線程模型實(shí)現(xiàn)的事務(wù)處理

不考慮事務(wù)執(zhí)行命令的外界上下文邏輯

redis執(zhí)行事務(wù)的過(guò)程:MULTI 命令開(kāi)啟一個(gè)事務(wù)后, 客戶端向服務(wù)器發(fā)送任意多條命令遇绞, 這些命令不會(huì)立即被執(zhí)行烫饼, 而是被放到一個(gè)隊(duì)列中, 當(dāng) EXEC命令被調(diào)用時(shí)试读, 隊(duì)列中的命令才會(huì)被執(zhí)行杠纵。

在這里,你可以發(fā)現(xiàn)redis觸發(fā)事務(wù)的執(zhí)行時(shí)是脫離外部業(yè)務(wù)邏輯的上下文關(guān)系的钩骇,這一點(diǎn)和mysql完全不同:mysql的每個(gè)語(yǔ)句是可以充分的結(jié)合到整個(gè)業(yè)務(wù)過(guò)程中比藻,也就是事務(wù)開(kāi)啟時(shí),外界上下文的觸發(fā)的每一步操作都是同步執(zhí)行的倘屹, 會(huì)對(duì)訪問(wèn)同一資源的其他事務(wù)造成影響银亲,這也是mysql事務(wù)應(yīng)用廣泛之處,并通過(guò)多版本控制實(shí)現(xiàn)不同隔離級(jí)別狀態(tài)的任意的回滾纽匙。

而redis這種簡(jiǎn)單粗暴的事務(wù)方式的帶來(lái)的直接好處是:
1务蝠,擺脫的來(lái)自于外界的阻塞,阻塞這一點(diǎn)對(duì)于要求高性能的redis來(lái)說(shuō)是絕對(duì)不可接受的烛缔,而在mysql上馏段,你會(huì)時(shí)不時(shí)看到長(zhǎng)事務(wù)導(dǎo)致了整個(gè)系統(tǒng)的性能問(wèn)題。
2践瓷,剝離了外部不可控的因素院喜,redis事務(wù)就只是命令的集合,所以redis設(shè)計(jì)者發(fā)現(xiàn)傳統(tǒng)事務(wù)都支持的回滾(roll back)這種操作完全是多余的:

Redis commands can fail only if called with a wrong syntax (and the problem is not detectable during the command queueing), or against keys holding the wrong data type: this means that in practical terms a failing command is the result of a programming errors, and a kind of error that is very likely to be detected during development, and not in production.Redis is internally simplified and faster because it does not need the ability to roll back.
從上面可以看到設(shè)計(jì)者的理由:
1晕翠,Redis 事務(wù)的報(bào)錯(cuò)只會(huì)因?yàn)殄e(cuò)誤的語(yǔ)法而失敗或是命令用在了錯(cuò)誤類(lèi)型的鍵上面喷舀,這也就是說(shuō),失敗的命令是由編程錯(cuò)誤造成(人為)的,而這些錯(cuò)誤應(yīng)該在開(kāi)發(fā)的過(guò)程中被發(fā)現(xiàn)硫麻,而不應(yīng)該出現(xiàn)在生產(chǎn)環(huán)境中爸邢。
好像很有道理。拿愧。甲棍。說(shuō)白了redis不想為你的人為失誤買(mǎi)單。赶掖。
2,因?yàn)椴恍枰貪L七扰,所以redis內(nèi)部更簡(jiǎn)潔和高效

每個(gè)系統(tǒng)在設(shè)計(jì)時(shí)當(dāng)然都希望更健壯奢赂,可以考慮更多的異常情況和有相應(yīng)的處理機(jī)制,但隨之而來(lái)就讓系統(tǒng)更加的復(fù)雜和性能損耗颈走,在事務(wù)處理上:事務(wù)的隔離級(jí)別越高膳灶,性能就越低,數(shù)據(jù)庫(kù)系統(tǒng)也只能在這兩個(gè)中進(jìn)行權(quán)衡和取舍立由,從這里我們也可以看出: redis選擇了性能轧钓,而放棄了可能因?yàn)橥獠咳藶閱?wèn)題而導(dǎo)致數(shù)據(jù)不一致問(wèn)題(mysql事務(wù)剛好相反)发魄。

基于redis單線程模型實(shí)現(xiàn)的事務(wù)處理

可能你會(huì)疑問(wèn)上面redis會(huì)有隔離級(jí)別而導(dǎo)致性能問(wèn)題骏啰?
redis確實(shí)沒(méi)有,因?yàn)檫@些為redis的高性能讓步值骇,redis可以說(shuō)是天然的串行化的隔離級(jí)別道盏,redis事務(wù)是保證在執(zhí)行事務(wù)中的一連串操作時(shí)不受其他客戶端的命令打斷而柑,達(dá)到串行執(zhí)行的目的。配合上 WATCH就可以實(shí)現(xiàn)和mysql的串行化隔離級(jí)別的效果
而從這一執(zhí)行效果可以看到荷逞,redis還是基于現(xiàn)有的單線程模型來(lái)實(shí)現(xiàn)事務(wù)媒咳,這更能佐證一點(diǎn):設(shè)計(jì)者為了保證高性能,寧愿放棄一些外部因素導(dǎo)致事務(wù)的數(shù)據(jù)不一致問(wèn)題种远,雖然redis可以通過(guò)多線程來(lái)實(shí)現(xiàn)來(lái)引入事務(wù)回滾并能確保事務(wù)過(guò)程中的redis服務(wù)的可用性涩澡。

總結(jié)

到這里,我們知道了坠敷,redis的事務(wù)只要正確執(zhí)行(沒(méi)有人為失誤)妙同,也是同樣滿足傳統(tǒng)事務(wù)的四大特性(ACID),也了解了redis事務(wù)的使用場(chǎng)景以及做出這些決策背后的原因,可見(jiàn):
數(shù)據(jù)庫(kù)系統(tǒng)事務(wù)設(shè)計(jì)中膝迎,保證一個(gè)事務(wù)完整執(zhí)行渐溶,原本數(shù)據(jù)一致性應(yīng)該是首要位置,因此弄抬,系統(tǒng)設(shè)計(jì)中必然要考慮到更多的異常的不可控的情況和相應(yīng)的處理機(jī)制茎辐,從而保證系統(tǒng)自身的數(shù)據(jù)安全, 而在redis中,我們看到了另外一種可能:為了保證redis的高性能而在設(shè)計(jì)決策上所做的妥協(xié)和調(diào)整拖陆, 雖然保證嚴(yán)格的一致性似乎對(duì)于嚴(yán)謹(jǐn)?shù)氖聞?wù)設(shè)計(jì)方案來(lái)說(shuō)會(huì)更讓人接受弛槐,但這對(duì)于redis來(lái)說(shuō),其實(shí)僅僅只是一個(gè)局部的功能依啰,從整個(gè)系統(tǒng)的角度上乎串,高性能和效率才是redis的初衷,從而也理解redis事務(wù)的特殊之處和其應(yīng)用場(chǎng)景速警。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末叹誉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子闷旧,更是在濱河造成了極大的恐慌长豁,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忙灼,死亡現(xiàn)場(chǎng)離奇詭異匠襟,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)该园,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)酸舍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人里初,你說(shuō)我怎么就攤上這事啃勉。” “怎么了双妨?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵璧亮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我斥难,道長(zhǎng)枝嘶,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任哑诊,我火速辦了婚禮群扶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘镀裤。我一直安慰自己竞阐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布暑劝。 她就那樣靜靜地躺著骆莹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪担猛。 梳的紋絲不亂的頭發(fā)上幕垦,一...
    開(kāi)封第一講書(shū)人閱讀 52,475評(píng)論 1 312
  • 那天丢氢,我揣著相機(jī)與錄音,去河邊找鬼先改。 笑死疚察,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的仇奶。 我是一名探鬼主播貌嫡,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼该溯!你這毒婦竟也來(lái)了岛抄?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤狈茉,失蹤者是張志新(化名)和其女友劉穎夫椭,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體论皆,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年猾漫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了点晴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡悯周,死狀恐怖粒督,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情禽翼,我是刑警寧澤屠橄,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站闰挡,受9級(jí)特大地震影響锐墙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜长酗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一溪北、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夺脾,春花似錦之拨、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至菲茬,卻和暖如春吉挣,著一層夾襖步出監(jiān)牢的瞬間派撕,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工听想, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腥刹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓汉买,卻偏偏與公主長(zhǎng)得像衔峰,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蛙粘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361