集群的最主要瓶頸是:磁盤(pán)。當(dāng)我們面臨集群作戰(zhàn)的時(shí)候,我們所希望的是即讀即得??墒敲鎸?duì)大數(shù)據(jù),讀取數(shù)據(jù)需要經(jīng)過(guò)磁盤(pán)IO,這里可以把IO理解為水的管道。管道越大越強(qiáng),我們對(duì)于T級(jí)的數(shù)據(jù)讀取就越快。所以IO的好壞,直接影響了集群對(duì)于數(shù)據(jù)的處理。
集群的瓶頸提出多種看法,其中網(wǎng)絡(luò)和磁盤(pán)io的爭(zhēng)議比較大。這里需要說(shuō)明的是網(wǎng)絡(luò)是一種稀缺資源,而不是瓶頸。
對(duì)于磁盤(pán)IO:(磁盤(pán)IO:磁盤(pán)輸出輸出)
當(dāng)我們面臨集群作戰(zhàn)的時(shí)候,我們所希望的是即讀即得??墒敲鎸?duì)大數(shù)據(jù),讀取數(shù)據(jù)需要經(jīng)過(guò)IO,這里可以把IO理解為水的管道。管道越大越強(qiáng),我們對(duì)于T級(jí)的數(shù)據(jù)讀取就越快。所以IO的好壞,直接影響了集群對(duì)于數(shù)據(jù)的處理。
這里舉幾個(gè)例子,讓大家來(lái)參考一下。
案例一
自從使用阿里云以來(lái),我們遇到了三次故障(一、二、三),這三次故障都與磁盤(pán)IO高有關(guān)。
第一次故障發(fā)生在跑zzk.cnblogs.com索引服務(wù)的云 服務(wù)器上,當(dāng)時(shí)的Avg.Disk Read Queue Length高達(dá)200多;
第二次故障發(fā)生在跑images.cnblogs.com靜態(tài)文件的云服務(wù)器上,當(dāng)時(shí)的Avg.Disk Read Queue Length在2左右(后來(lái)分析,對(duì)于圖片站點(diǎn)這樣的直接讀文件進(jìn)行響應(yīng)的應(yīng)用,Disk Read Queue Length達(dá)到這個(gè)值會(huì)明顯影響響應(yīng)速度);
第三次故障發(fā)生在跑數(shù)據(jù)庫(kù)服務(wù)的云服務(wù)器上,當(dāng)時(shí)的Avg. Disk Write Queue Length達(dá)到4~5,造成很多的數(shù)據(jù)庫(kù)寫(xiě)入操作超時(shí)。
(這里既提到“硬盤(pán)”,又提到“磁盤(pán)”,我們這樣界定的:在云服務(wù)器中看到的硬盤(pán)叫磁盤(pán)[虛擬出來(lái)的硬盤(pán)],在集群中的物理硬盤(pán)叫硬盤(pán))
這三次的磁盤(pán)IO高都不是我們?cè)品?wù)器內(nèi)的應(yīng)用引起的,最直接的證據(jù)就是將云服務(wù)遷移至另一個(gè)集群之后,問(wèn)題立即解決。也就是說(shuō)云服務(wù)器的磁盤(pán)IO高是因 為它所在的集群的硬盤(pán)IO高。
集群的硬盤(pán)IO是集群內(nèi)所有云服務(wù)器的磁盤(pán)IO的累加,集群的硬盤(pán)IO高是因?yàn)榧褐心承┰品?wù)器的磁盤(pán)IO過(guò)高。而我們自 己的云服務(wù)器內(nèi)的應(yīng)用產(chǎn)生的磁盤(pán)IO在正常范圍,問(wèn)題出在其他用戶(hù)的云服務(wù)器產(chǎn)生過(guò)多的磁盤(pán)IO,造成整個(gè)集群硬盤(pán)IO高,從而影響了我們。
為什么其他云服務(wù)器引起的硬盤(pán)IO問(wèn)題會(huì)影響到我們?問(wèn)題的根源就在于集群的硬盤(pán)IO被集群中的所有云服務(wù)器所共享,而且這種共享沒(méi)有被有效的限制、沒(méi)有 被有效的隔離,大家都在爭(zhēng)搶這個(gè)資源,同時(shí)爭(zhēng)搶的人太多,就會(huì)排長(zhǎng)多。
而且對(duì)于每個(gè)云服務(wù)器來(lái)說(shuō),也不知道有多少臺(tái)云服務(wù)器在爭(zhēng)搶?zhuān)瑥脑品?wù)器使用者的角 度根本無(wú)法躲開(kāi)這個(gè)爭(zhēng)搶?zhuān)痪拖裨谑啦?huì)期間,你起再早去排隊(duì),也得排超長(zhǎng)的隊(duì)。
如果每個(gè)云服務(wù)器使用的硬盤(pán)IO資源是被限制或隔離的,其他云服務(wù)器產(chǎn)生再 多的磁盤(pán)IO也不會(huì)影響到我們的云服務(wù)器;就像在一個(gè)小區(qū),你一個(gè)人租了一套房子,其他的一套房子即使住了100人,也不會(huì)影響到你。
你可以買(mǎi)到CPU、內(nèi)存、帶寬、硬盤(pán)空間,你卻買(mǎi)不到一心一意為你服務(wù)的硬盤(pán)IO,這就是當(dāng)前阿里云虛擬化平臺(tái)設(shè)計(jì)時(shí)未考慮到的一個(gè)重要問(wèn)題。
經(jīng)過(guò)與阿里云技術(shù)人員的溝通,得知他們已經(jīng)意識(shí)到這個(gè)問(wèn)題,希望這個(gè)問(wèn)題能早日得到解決。
—————————————————————————————————————————————
案例2
云計(jì)算之路-遷入阿里云后:20130314云服務(wù)器故障經(jīng)過(guò)
首先向大家致歉,這次云服務(wù)器故障發(fā)現(xiàn)于17:30左右,18:30左右恢復(fù)正常,給大家?guī)?lái)了麻煩,請(qǐng)大家諒解!
故障的原因是云服務(wù)器所在的集群負(fù)載過(guò)高,磁盤(pán)寫(xiě)入性能急劇下降,造成很多數(shù)據(jù)庫(kù)寫(xiě)入操作超時(shí)。后來(lái)恢復(fù)正常的解決方法是將云服務(wù)器遷移至另一個(gè)集群。
下面是故障發(fā)生的主要經(jīng)過(guò):
今天上午9:15左右一位園友通過(guò)郵件反饋在訪(fǎng)問(wèn)園子時(shí)遇到502 Bad Gateway錯(cuò)誤.
這是由阿里云負(fù)載均衡器返回的錯(cuò)誤,Tegine是由阿里巴巴開(kāi)發(fā)的開(kāi)源Web服務(wù)器。我們猜測(cè)阿里云提供的負(fù)載均衡服務(wù)可能是通過(guò)Tegine反向代理實(shí)現(xiàn)的。
這個(gè)錯(cuò)誤頁(yè)面表示負(fù)載均衡器檢測(cè)到負(fù)載均衡中的云服務(wù)器返回了無(wú)效的響應(yīng),比如500系列錯(cuò)誤。
我們將這個(gè)情況通過(guò)工單反饋給了阿里云,得到的處理反饋是繼續(xù)觀察,可能是這位用戶(hù)的網(wǎng)絡(luò)線(xiàn)路的臨時(shí)問(wèn)題導(dǎo)致。
由于我們?cè)谶@個(gè)時(shí)間段沒(méi)遇到這個(gè)問(wèn)題,也沒(méi)有其他用戶(hù)反饋這個(gè)問(wèn)題,我們也認(rèn)可了繼續(xù)觀察的處理方式。
(根據(jù)我們后來(lái)的分析,出現(xiàn)502 Bad Gateway錯(cuò)誤可能是集群出現(xiàn)了瞬時(shí)負(fù)載高的情況)
下午17:20左右,我們自己也遇到了502 Bad Gateway錯(cuò)誤,持續(xù)了大約1-2分鐘。見(jiàn)下圖:
出問(wèn)題期間,我們趕緊登錄到兩臺(tái)云服務(wù)器查看情況,發(fā)現(xiàn)IIS并發(fā)連接數(shù)增長(zhǎng)至原來(lái)的30多倍,而B(niǎo)ytes Send/sec為0,而且兩臺(tái)云服務(wù)器都是同樣的情況。我們當(dāng)時(shí)推斷,這兩臺(tái)云服務(wù)器本身應(yīng)該沒(méi)有問(wèn)題,問(wèn)題可能出在它們與數(shù)據(jù)庫(kù)服務(wù)器之間的網(wǎng)絡(luò)通 信。我們繼續(xù)將這個(gè)情況通過(guò)工單反饋給阿里云。
剛把工單填好,我們就接到園友的電話(huà)反饋說(shuō)博客后臺(tái)不能發(fā)布文章,我們一測(cè)試,果然不能發(fā)布,報(bào)數(shù)據(jù)庫(kù)超時(shí)錯(cuò)誤,見(jiàn)下圖:
但打開(kāi)現(xiàn)有的文章速度很快,也就是說(shuō)讀正常,寫(xiě)有問(wèn)題。趕緊登錄數(shù)據(jù)庫(kù)服務(wù)器通過(guò)性能監(jiān)視器查看磁盤(pán)IO情況,果然磁盤(pán)寫(xiě)入性能有問(wèn)題,見(jiàn)下圖:
Avg. Disk Write Queue Length超過(guò)1就說(shuō)明有問(wèn)題了,現(xiàn)在平均已經(jīng)到了4~5。進(jìn)入阿里云網(wǎng)站上的管理控制臺(tái)一看,磁盤(pán)IO問(wèn)題就更明顯了,見(jiàn)下圖:
繼續(xù)向阿里云反饋情況,得到的反饋是這臺(tái)云服務(wù)器IOPS太高了,見(jiàn)下圖:
于是,阿里云工作人員將這臺(tái)云服務(wù)器遷移至另一個(gè)集群,問(wèn)題立刻解決。
—————————————————————————————————————————————-
案例三
14:17左右,我們看到了這條閃存。立即進(jìn)入博客后臺(tái)測(cè)試,發(fā)現(xiàn)提交時(shí)會(huì)出現(xiàn)如下的錯(cuò)誤:
"Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding."
這是數(shù)據(jù)庫(kù)寫(xiě)入超時(shí)的錯(cuò)誤,對(duì)這個(gè)錯(cuò)誤信息我們記憶猶新。之前遇到過(guò)兩次(3月14日、4月2日),都是數(shù)據(jù)庫(kù)服務(wù)器所在的云服務(wù)器磁盤(pán)IO問(wèn)題引起的。
登上云服務(wù)器,查看Windows性能監(jiān)視器,發(fā)現(xiàn)日志文件所在的磁盤(pán)的IO監(jiān)測(cè)數(shù)據(jù)Avg.Disk Write Queue Length平均值在5以上。性能監(jiān)視器中這個(gè)值的縱坐標(biāo)最高值是1,可想而知5是多么高的一個(gè)值。性能監(jiān)視器中的走勢(shì)圖幾乎是一條直線(xiàn)。見(jiàn)下圖(最高值 竟然達(dá)到了20,真恐怖):
(為什么數(shù)據(jù)庫(kù)寫(xiě)入超時(shí)會(huì)表現(xiàn)于日志文件所在的磁盤(pán)IO高?因?yàn)閿?shù)據(jù)庫(kù)恢復(fù)模式用的是Full,對(duì)數(shù)據(jù)庫(kù)的數(shù)據(jù)寫(xiě)入,會(huì)先在日志中進(jìn)行寫(xiě)入操作。)
這次問(wèn)題與3月14日磁盤(pán)IO問(wèn)題的表現(xiàn)是一樣的,所以我們斷定這次也是同樣的原因,是云服務(wù)器所在集群的磁盤(pán)IO負(fù)載高引起的。
14:19,我們向阿里云提交了工單,特地在標(biāo)題中加了“緊急”;
14:23,阿里云客服回復(fù)說(shuō)正在核實(shí)我們提交的問(wèn)題;
14:31,阿里云客服回復(fù)說(shuō)已反饋給相關(guān)部門(mén)檢查;
14:42,沒(méi)有阿里云客服的進(jìn)一步消息,我們就回復(fù)說(shuō)“如果短時(shí)間內(nèi)解決不了,希望盡快進(jìn)行集群遷移”(3月14日就是通過(guò)集群遷移解決這個(gè)問(wèn)題的,阿里云的技術(shù)人員也說(shuō)過(guò)對(duì)于集群負(fù)載高引起的磁盤(pán)IO問(wèn)題,目前唯一的解決辦法就是集群遷移);
14:47,阿里云客服只回復(fù)說(shuō)正在處理;
14:59,還是沒(méi)消息,我們心急如焚(40分鐘過(guò)去了,連個(gè)說(shuō)法都沒(méi)有),在工單中說(shuō):“能不能先做集群遷移?”;
然后,接到阿里云客服的電話(huà),說(shuō)集群中其他云服務(wù)器占用的磁盤(pán)IO高影響了我們,他們正在處理。。。
過(guò)了會(huì),阿里云客服又打電話(huà)過(guò)來(lái)說(shuō)可能是我們?cè)品?wù)器中的系統(tǒng)或應(yīng)用導(dǎo)致服務(wù)器磁盤(pán)寫(xiě)入卡死,讓我們重啟一下云服務(wù)器。(這樣的考慮可能是因?yàn)檫@時(shí)集群的負(fù)載已經(jīng)降下來(lái),但我們的云服務(wù)器磁盤(pán)IO還是高。)
15:23左右,我們重啟了數(shù)據(jù)庫(kù)服務(wù)器,但問(wèn)題依舊。
15:30,阿里云客服終于決定進(jìn)行集群遷移(從提交工單到?jīng)Q定集群遷移耗時(shí)1小10分鐘)
15:45,完成集群遷移(上次遷移5分鐘不到,這次用了15分鐘,這也是阿里云客服所說(shuō)的進(jìn)行集群遷移所需的最長(zhǎng)時(shí)間)
遷移之后,傻眼了,磁盤(pán)IO(Avg.Disk Write Queue Length)還是那么高!
為什么這次集群遷移不能像上次那樣立即解決問(wèn)題?我們猜測(cè)有兩個(gè)可能的原因:
1、遷移后所在的集群磁盤(pán)IO負(fù)載依然高;
2、 云服務(wù)器上出現(xiàn)磁盤(pán)IO很高的這個(gè)分區(qū)放的都是數(shù)據(jù)庫(kù)日志文件,可能這個(gè)時(shí)間段日志寫(xiě)入操作比平時(shí)頻繁(但暴增幾乎沒(méi)有可能)而且所有日志文件在同一個(gè)分 區(qū),超過(guò)了云服務(wù)器磁盤(pán)IO的某個(gè)極限,造成磁盤(pán)IO性能驟降(可能性比較大,依據(jù)是云計(jì)算之路-入阿里云后:解決images.cnblogs.com 響應(yīng)速度慢的詭異問(wèn)題)。雖然之前使用物理服務(wù)器時(shí),日志文件也是放在同一個(gè)分區(qū),從未出現(xiàn)過(guò)這個(gè)問(wèn)題,但現(xiàn)在云服務(wù)器的磁盤(pán)IO能力無(wú)法與物理服務(wù)器相 比,而且磁盤(pán)IO會(huì)被集群上其他云服務(wù)器爭(zhēng)搶?zhuān)ㄔ斠?jiàn)云計(jì)算之路-遷入阿里云后:?jiǎn)栴}的根源——買(mǎi)到她的“人”,卻買(mǎi)不到她的“心”)。
不管是哪一個(gè)原因,要解決問(wèn)題只有一招也是最后一招——減輕日志文件所在的磁盤(pán)分區(qū)的IO壓力。
怎么減壓呢?根據(jù)“遷入阿里云后的一些心得”一文中的“提高整體磁盤(pán)IO性能的小偏方”,另外購(gòu)買(mǎi)一塊磁盤(pán)空間,然后將存放博文內(nèi)容的數(shù)據(jù)庫(kù)CNBlogsText(大文本數(shù)據(jù)寫(xiě)入,對(duì)磁盤(pán)IO產(chǎn)生的壓力很大)的日志文件移至獨(dú)立的磁盤(pán)分區(qū)。
在SQL Server中,無(wú)法在線(xiàn)完成將數(shù)據(jù)庫(kù)日志文件從一個(gè)磁盤(pán)分區(qū)移至另一個(gè)磁盤(pán)分區(qū)。需要先detach數(shù)據(jù)庫(kù),然后將日志文件復(fù)制至目標(biāo)分區(qū),然后再attach這個(gè)數(shù)據(jù)庫(kù);在attach時(shí),將日志文件的位置修改為新的路徑。
于是,在別無(wú)選擇的情況下,我們CNBlogsText數(shù)據(jù)庫(kù)進(jìn)行detach操作,并且選擇了drop connections,哪知在detach的過(guò)程中悲劇發(fā)生了,detach失敗了,錯(cuò)誤是:
Transaction (Process ID 124) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
在 detach的過(guò)程中竟然發(fā)生了死鎖,然后“被犧牲”了。讓人困惑的是,不是drop connections嗎,怎么還會(huì)發(fā)生死鎖?可能drop connections是在detach操作正式開(kāi)始前,在detach的過(guò)程中,還會(huì)發(fā)生數(shù)據(jù)庫(kù)寫(xiě)入操作,這時(shí)的寫(xiě)入操作引發(fā)了deadlock。為什 么偏偏要讓detach犧牲?不合情理。
detach失敗后,CNBlogsText數(shù)據(jù)庫(kù)就處于Single User狀態(tài)。繼續(xù)detach,同樣的錯(cuò)誤,同樣的“被犧牲”。
于是,重啟了一下SQL Server服務(wù)。重啟之后,CNBlogsText數(shù)據(jù)庫(kù)的狀態(tài)變?yōu)榱薎n Recovery。
這時(shí)時(shí)間已經(jīng)到了16:45。
這樣的In Recovery狀態(tài)以前沒(méi)遇到過(guò),不知如何處理,也不敢輕舉妄動(dòng)。
過(guò)了一段時(shí)間,刷新了一下SQL Server的Databases列表,CNBlogsText數(shù)據(jù)庫(kù)又顯示為之前的Single User狀態(tài)。(原來(lái)重啟SQL Server之后,會(huì)自動(dòng)先進(jìn)入In Recovery狀態(tài),再進(jìn)入到Single User狀態(tài))
針對(duì)Single User狀態(tài)問(wèn)題,在工單中咨詢(xún)了阿里云客服,阿里云客服聯(lián)系了數(shù)據(jù)庫(kù)工程師,得到的建議是進(jìn)行這樣的操作:alter database $db_name SET multi_user
于是,執(zhí)行了這樣的SQL:
exec sp_dboption 'CNBlogsText', N'single', N'false'
出現(xiàn)錯(cuò)誤提示:
Database 'CNBlogsText' is already open and can only have one user at a time.
Single User狀態(tài)依舊,出現(xiàn)這個(gè)錯(cuò)誤可能是因?yàn)檫@個(gè)數(shù)據(jù)庫(kù)不斷地有寫(xiě)入操作,搶占著Single User狀態(tài)下只允許唯一的數(shù)據(jù)庫(kù)連接。
(更新:后來(lái)從阿里云DBA那學(xué)習(xí)到解決這個(gè)問(wèn)題的方法:
select spid from sys.sysprocesses where dbid=DB_ID('dbname'); --得到當(dāng)前占用數(shù)據(jù)庫(kù)的進(jìn)程id kill [spid] go alter login [username] disable --禁用新的訪(fǎng)問(wèn) go use cnblogstext go alter database cnblogstext set multi_user with rollback immediate go
)
當(dāng)時(shí)的情形下,我們不夠冷靜,急著想完成detach操作。覺(jué)得屏蔽CNBlogsText數(shù)據(jù)庫(kù)的所有寫(xiě)入操作可能需要禁止這臺(tái)服務(wù)器的所有數(shù)據(jù)庫(kù)連接,這樣會(huì)影響整站的正常訪(fǎng)問(wèn),所以沒(méi)從這個(gè)角度下手。
這時(shí)時(shí)間已經(jīng)到了17:08。
我們也準(zhǔn)備了最最后一招,假如實(shí)在detach不了,假如日志文件也出了問(wèn)題,我們可以通過(guò)數(shù)據(jù)文件恢復(fù)這個(gè)數(shù)據(jù)庫(kù)。這個(gè)場(chǎng)景我們遇到過(guò),也實(shí)際成功操作過(guò),詳見(jiàn):SQL Server 2005數(shù)據(jù)庫(kù)日志文件損壞的情況下如何恢復(fù)數(shù)據(jù)庫(kù)。所需的SQL語(yǔ)句如下:
use master alter database dbname set emergency declare @databasename varchar(255) set @databasename='dbname' exec sp_dboption @databasename, N'single', N'true' --將目標(biāo)數(shù)據(jù)庫(kù)置為單用戶(hù)狀態(tài) dbcc checkdb(@databasename,REPAIR_ALLOW_DATA_LOSS) dbcc checkdb(@databasename,REPAIR_REBUILD) exec sp_dboption @databasename, N'single', N'false'--將目標(biāo)數(shù)據(jù)庫(kù)置為多用戶(hù)狀態(tài)
即使最最后一招也失敗了,我們?cè)诹硗庖慌_(tái)云服務(wù)器上有備份,在異地也有備份,都有辦法恢復(fù),只不過(guò)需要的恢復(fù)時(shí)間更長(zhǎng)一些。
想到這些,內(nèi)心平靜了一些,認(rèn)識(shí)到當(dāng)前最重要的是拋開(kāi)內(nèi)疚、緊張、著急,冷靜面對(duì)。
我們?cè)诠沃欣^續(xù)咨詢(xún)阿里云客服,阿里云客服聯(lián)系了數(shù)據(jù)庫(kù)工程師,讓我們加一下這位工程師的阿里旺旺。
我們的電腦上沒(méi)裝阿里旺旺,于是打算自己再試試,如果還是解決不了,再求助阿里云的數(shù)據(jù)庫(kù)工程師。
在網(wǎng)上找了一個(gè)方法:SET DEADLOCK_PRIORITY NORMAL(來(lái)源),沒(méi)有效果。
時(shí)間已經(jīng)到了17:38。
這時(shí),我們冷靜地分析一下:detach時(shí),因?yàn)樗梨i“被犧牲”;從單用戶(hù)改為多用戶(hù)時(shí),提示“Database 'CNBlogsText' is already open and can only have one user at a time.”??赡芏际且?yàn)槌绦蛑胁粩嗟貙?duì)這個(gè)數(shù)據(jù)庫(kù)有寫(xiě)入操作。試試修改一下程序,看看能不能屏蔽所有對(duì)這個(gè)數(shù)據(jù)庫(kù)的寫(xiě)入操作,然后再將數(shù)據(jù)庫(kù)恢復(fù)為多 用戶(hù)狀態(tài)。
修改好程序,18:00之后進(jìn)行了更新。沒(méi)想到更新之后,將單用戶(hù)改為多用戶(hù)的SQL就能執(zhí)行了:
exec sp_dboption 'CNBlogsText', N'single', N'false'
于是,Single User狀態(tài)消失,CNBlogsText數(shù)據(jù)庫(kù)恢復(fù)了正常狀態(tài),然后嘗試detach,一次成功。
接著將日志文件復(fù)制到新購(gòu)的磁盤(pán)分區(qū)中,以新的日志路徑attach數(shù)據(jù)庫(kù)。attach成功之后,CNBlogsText數(shù)據(jù)庫(kù)恢復(fù)正常,博客后臺(tái)可以正常發(fā)布博文,CNBlogsText數(shù)據(jù)庫(kù)日志文件所在分區(qū)的磁盤(pán)IO(單獨(dú)的磁盤(pán)分區(qū))也正常。問(wèn)題就這么解決了。
當(dāng)全部恢復(fù)正常,如釋重負(fù)的時(shí)候,時(shí)間已經(jīng)到了18:35。
原以為可以用