本來我只是想寫一篇關(guān)于數(shù)據(jù)備份和慢查詢的文章筷狼。但隨著學(xué)習(xí)的深入劳吠,我發(fā)現(xiàn)更多更有趣的MySQL知識(shí)懒闷,導(dǎo)致最后寫了一個(gè)小系列。下面分享下我這次學(xué)習(xí)MySQL的一些感想告抄。
MySQL各種關(guān)鍵設(shè)計(jì)的啟發(fā):
-
事務(wù)設(shè)計(jì)啟發(fā):
在沒有深入學(xué)習(xí)MySQL之前喊积,事務(wù)對(duì)我來說就只是幾個(gè)簡單的特性(ACID)。深入學(xué)習(xí)之后玄妈,才知道了redo log
、binlog
和二階段提交
這些為了實(shí)現(xiàn)事務(wù)的具體技術(shù)髓梅。了解這些技術(shù)不單單使我對(duì)MySQL的理解提升一個(gè)層次拟蜻,還有更多實(shí)際的幫助。比如:知道怎么調(diào)優(yōu)(binlog要存什么格式枯饿、存多少天酝锅、redo log刷盤策略要怎么設(shè)定等等);知道磁盤寫入瓶頸可能在什么地方奢方,然后知道某些云廠商把用戶當(dāng)水魚搔扁;知道數(shù)據(jù)要回滾可以有什么方式爸舒,并且知道這些方式都是些什么原理等等。
游戲服務(wù)端有大量在分布式環(huán)境實(shí)現(xiàn)原子性的功能稿蹲,而這些功能實(shí)現(xiàn)的原理和MySQL的事務(wù)實(shí)現(xiàn)方式有很多共通的地方扭勉。比如如何保證玩家的一次購買行為只要付款成功,就一定會(huì)在游戲中發(fā)貨苛聘。注意對(duì)于大多數(shù)游戲來說涂炎,支付和游戲都是分開實(shí)現(xiàn)、部署的设哗,它們之間可能存在一條長長的鏈路唱捣。
又比如如何保證玩家A送給玩家B的禮物,玩家B一定會(huì)收到网梢。注意這個(gè)過程中玩家B可能在線或不在線震缭,甚至可能出現(xiàn)玩家A和玩家B同時(shí)操作同一份數(shù)據(jù)的可能,如果想通過無鎖操作那么借鑒MySQL的事務(wù)設(shè)計(jì)也是一個(gè)很好的選擇战虏。
-
鎖設(shè)計(jì)的啟發(fā):
MySQL的鎖知識(shí)體系非常復(fù)雜(這里討論的主要是InnoDB)拣宰,光是隔離級(jí)別(Read Uncommitted
、Read Committed
活烙、Repeatable Read
徐裸、Serializable
)就把我弄的一愣一愣的。還有不同類型的鎖(意向鎖啸盏、排它鎖重贺、共享鎖、意向排它鎖回懦、行數(shù)气笙、間隙、Next-Key鎖等等)怯晕,這些鎖組合起來的運(yùn)用更是讓人頭大潜圃。不過在認(rèn)真學(xué)習(xí)完之后,你會(huì)發(fā)現(xiàn)這些鎖的設(shè)計(jì)十分精巧地實(shí)現(xiàn)了不同的隔離級(jí)別舟茶√菲冢可能很多人不會(huì)喜歡如此復(fù)雜的鎖設(shè)計(jì),但是為了更好的并發(fā)和隔離的實(shí)現(xiàn)這是沒辦法的折中方案吧凉。
如果各位在MySQL學(xué)習(xí)上犯難隧出,我建議通過實(shí)際的SQL(insert、update阀捅、delete)一條一條地去執(zhí)行胀瞪,看看這些SQL都持有了什么鎖。
-
性能優(yōu)化啟發(fā):
因?yàn)楦鞣N客觀因素的限制(比如內(nèi)存不可能無限大饲鄙、事務(wù)需要各種隔離)凄诞,MySQL充滿了各種折中的設(shè)計(jì)圆雁。考慮各種要求帆谍,沒辦法做到所有情況最優(yōu)伪朽,只能做到綜合的最優(yōu)。比如Cache的使用(里面甚至還有像JVM內(nèi)存模型那樣的young和old區(qū))既忆、磁盤回寫策略(這里指批量延時(shí)回寫)驱负、臨時(shí)表的設(shè)計(jì)。
MySQL面臨的性能優(yōu)化上的問題患雇,在大多數(shù)項(xiàng)目中都會(huì)存在跃脊。要求就擺在你面前,但是機(jī)器預(yù)算是有限苛吱;JVM內(nèi)存就這么多酪术,Y區(qū)要多少、O區(qū)要多少翠储;前后端數(shù)據(jù)要不要加密绘雁,加密的話兩邊都有影響、不加密不安全援所;A技術(shù)更全庐舟、B技術(shù)更快等等。這些問題總是會(huì)要我們不斷抉擇住拭,這個(gè)時(shí)候就要根據(jù)自己實(shí)際的情況做分析挪略,找到平衡和折中。
-
慢查詢?nèi)罩镜膯l(fā):
我剛開始工作的時(shí)候甚至不知道慢查詢這個(gè)東西滔岳,當(dāng)時(shí)的項(xiàng)目也沒有慢查詢的治理這個(gè)理念杠娱。后面知道慢查詢之后,就逐漸嘗試優(yōu)化項(xiàng)目中不健康的SQL谱煤。雖然這個(gè)動(dòng)作對(duì)整個(gè)項(xiàng)目的運(yùn)行來看并沒有直接優(yōu)化的作用摊求,但是這種不斷讓項(xiàng)目更健康的嘗試極大程度上影響了我之后的工作習(xí)慣。
關(guān)于慢查詢我最直觀的感受就是:知道問題比解決問題重要刘离。在項(xiàng)目設(shè)計(jì)的時(shí)候室叉,性能、異常情況的記錄都是要認(rèn)真考慮的硫惕。
-
MySQL對(duì)大量數(shù)據(jù)的操作:
進(jìn)行大量數(shù)據(jù)操作是一件很痛苦的事太惠,比如超大規(guī)模的數(shù)據(jù)排序、比如搜索索引樹疲憋、比如返回大量數(shù)據(jù)給客戶端、比如兩個(gè)表的連表查詢等等梁只。對(duì)于這些操作數(shù)據(jù)庫不可能把數(shù)據(jù)全部加載到內(nèi)存里面再進(jìn)行處理缚柳。如何通過磁盤和其他技術(shù)來做到埃脏,這個(gè)和我們習(xí)慣使用內(nèi)存處理少量數(shù)據(jù)思路上有很大的不一樣(比如外排的實(shí)現(xiàn)、比如分段傳輸)秋忙。各位不妨嘗試了解一下彩掐。
上云的感想:
可能和其他公司不一樣,我之前的項(xiàng)目組首先上云的是數(shù)據(jù)庫而不是普通的云服務(wù)器(阿里的ECS灰追、亞馬遜的EC2)堵幽。這里說一下上云的感想:
經(jīng)歷過從本地部署MySQL到云MySQL的轉(zhuǎn)變(云實(shí)例也是一樣)。深深感覺到云服務(wù)帶來的生產(chǎn)力的解放弹澎。在沒有使用云服務(wù)之前朴下,即使通過腳本的幫助我們部署一臺(tái)線上MySQL服務(wù)器是一個(gè)很繁瑣的事情(當(dāng)時(shí)我們對(duì)容器技術(shù)的使用經(jīng)驗(yàn)并不足矣在線上使用)。比如部署主從機(jī)器苦蒿、對(duì)數(shù)據(jù)進(jìn)行冷備等等諸如此類的操作殴胧。即使搭建完成,后續(xù)的維護(hù)佩迟、監(jiān)控對(duì)經(jīng)驗(yàn)不豐富的運(yùn)維和開發(fā)同學(xué)來說還是充滿各種困難和陡峭的學(xué)習(xí)曲線(比如查看數(shù)據(jù)庫各項(xiàng)指標(biāo)就要操作很多命令团滥、死鎖分析又是一大堆專業(yè)文檔等著)。
后面在新項(xiàng)目組首次嘗試了云服務(wù)器报强,部署服務(wù)器分分鐘的事灸姊。要看監(jiān)控打開鏈接就行,甚至死鎖分析和壓測(cè)都幫忙弄好秉溉。極大提高生產(chǎn)力力惯,想要的給錢就行。云服務(wù)它是資源也是服務(wù)坚嗜,讓開發(fā)者用的舒心的還是他的服務(wù)夯膀。對(duì)云服務(wù)來說服務(wù)比資源更重要。不要只把云服務(wù)器當(dāng)成是一個(gè)部署在遠(yuǎn)端的機(jī)器苍蔬,不然無法充分挖掘他的寶藏诱建。里面包含的各種附加服務(wù)(比如監(jiān)控),都是業(yè)界先進(jìn)和成熟的方案碟绑。企業(yè)只有充分利用這些資源才能切實(shí)節(jié)約寶貴資金俺猿。不能有效運(yùn)用資源本身就是一種巨大的浪費(fèi)。
監(jiān)控系統(tǒng)的啟發(fā):
MySQL的各類監(jiān)控做的十分完善的格仲,sys
庫中的metrics
視圖就包含了大量數(shù)據(jù)庫運(yùn)行中的統(tǒng)計(jì)數(shù)據(jù)押袍;sys
庫中的processlist
視圖會(huì)有各個(gè)線程的詳細(xì)信息等等。只要用戶愿意(或者說用戶了解這些知識(shí))凯肋,MySQL的這些監(jiān)控和統(tǒng)計(jì)可以讓用戶全方位掌握當(dāng)前MySQL服務(wù)器的各種運(yùn)行狀態(tài)谊惭。我們的游戲服務(wù)器監(jiān)控就大量借鑒了MySQL的經(jīng)驗(yàn)(很多地方就是照抄),比如我們改造了鎖組件的代碼以支持統(tǒng)計(jì)評(píng)價(jià)鎖持有時(shí)間(avg、95%圈盔、99%這幾個(gè)方面)豹芯、鎖等待時(shí)間;緩存組件統(tǒng)計(jì)了緩存命中率驱敲、單個(gè)玩家緩存大小(avg铁蹈、95%、99%)众眨、緩存壽命等等握牧。如果你苦惱于不知道怎么優(yōu)化自己的數(shù)據(jù)庫(只知道數(shù)據(jù)庫很卡)、不知道數(shù)據(jù)庫當(dāng)前還有多少性能可以壓榨那么就應(yīng)該好好看看數(shù)據(jù)庫監(jiān)控這一部分娩梨。又或者你現(xiàn)在想設(shè)計(jì)一個(gè)服務(wù)器的監(jiān)控體系沿腰,但是不知道自己埋點(diǎn)是否充足,我就建議你看看MySQL的監(jiān)控體系姚建。
這里推薦一個(gè)數(shù)據(jù)庫的監(jiān)控工具:MySQL Exporter
總結(jié):
- 關(guān)系型數(shù)據(jù)庫經(jīng)過了幾十年的發(fā)展矫俺,一次小小的insert操作背后是無數(shù)人的努力和智慧的結(jié)晶,如果不探究一下這背后的東西將是巨大的遺憾和浪費(fèi)掸冤;
- 知識(shí)不是單點(diǎn)存在的厘托,如果想把單一知識(shí)點(diǎn)弄懂就需要其他大量的知識(shí)做支持。知道前因后果才算明白了這個(gè)知識(shí)點(diǎn)稿湿;
- 當(dāng)探索出事物背后的實(shí)現(xiàn)原理的時(shí)候铅匹,知識(shí)增長給人帶來的豁然開朗是非常快樂的饺藤。如果說有什么比這更快樂包斑,那我認(rèn)為是自己還想辦法證明了這個(gè)實(shí)現(xiàn)原理;
- 當(dāng)我們從電視涕俗、網(wǎng)絡(luò)了解一個(gè)人罗丰,而沒有實(shí)際接觸一個(gè)人的時(shí)候,這個(gè)人對(duì)你來說是概念和抽象的再姑。只有實(shí)際和ta接觸萌抵、了解之后,才能更細(xì)致感受到這個(gè)人的特質(zhì)元镀,這個(gè)時(shí)候ta對(duì)你來說才是一個(gè)具體的绍填、生靈活現(xiàn)的人而不是抽象和概念化的。這個(gè)情況放在技術(shù)上也是如此栖疑;
- 在數(shù)據(jù)庫領(lǐng)域讨永,如果沒有足夠底層知識(shí)的支撐,更高階的技術(shù)操作將無法進(jìn)行遇革。只是知道CRUD卿闹,就沒辦法進(jìn)行MySQL壓測(cè)和調(diào)優(yōu)揭糕。只是知道鎖的概念,就沒辦法弄清楚MySQL鎖是怎么回事更別談如何徹底解決和避免比原。使用一個(gè)自己完全不了解的東西不是不可以插佛,但是如果它一旦出現(xiàn)問題,那么解決這些問題往往會(huì)付出更高的代價(jià)量窘。