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