如果你有部署過一些可擴(kuò)展系統(tǒng)的經(jīng)驗,你就會知道跟其它問題比起來,設(shè)計上的問題是嚴(yán)重的。編寫嚴(yán)謹(jǐn)?shù)拇a是一回事,而如何避免在系統(tǒng)設(shè)計過程中存在嚴(yán)重性的缺陷問題是另一回事。
這里有9個常見的問題——真的是很糟糕的設(shè)計選擇——這些問題會導(dǎo)致你的系統(tǒng)運行的很慢。與許多糟糕的決策不同,這些問題可以被逆轉(zhuǎn)。
如果你在一個查詢中select出了一位客戶的所有訂單,然后循環(huán)通過每個訂單中的每個訂單的行項,這是n次訪問數(shù)據(jù)庫加1。這種情況使用一個外部連接的查詢將更有效。如果你需要減少一次,那么你可以使用一種分頁形式。使用緩存的開發(fā)人員常常會意外地編寫n+1問題。你可以使用諸如Oracle Enterprise Monitor(OEM)或APM工具之類的數(shù)據(jù)庫監(jiān)視工具來發(fā)現(xiàn)這些情況,比如狡猾的內(nèi)向或簡單的查詢?nèi)罩居涗洝_€有更糟糕的版本,比如那些試圖在平板中存儲樹的人,而不是使用CTEs。在NoSQL數(shù)據(jù)庫中也存在類似的問題,因此沒有人是安全的。
哥兒們,我曾經(jīng)很討厭DB2和SQL Server。我現(xiàn)在仍然討厭他們的默認(rèn)鎖定模式。根據(jù)平臺的不同,DB2會為更新鎖定記錄的“頁面”。你終會鎖定那些與你所做的事情無關(guān)的記錄。行鎖更常見。一個長時間運行的事務(wù)對一行進(jìn)行一個小的更新,這不會對其他任何事情產(chǎn)生影響。所有其他查詢塊。與此同時,這些事務(wù)持有更多的鎖,從而造成了級聯(lián)性能問題。如果你在這兩個數(shù)據(jù)庫中,請打開并設(shè)計快照隔離。Oracle默認(rèn)使用一種快照隔離形式。有一些NoSQL數(shù)據(jù)庫可以被配置為偏執(zhí)程度的一致性。在你傷害自己之前,先了解它的鎖定模式。
這個問題有很多形式。有時它藏在圖書館里。多年以前,XML解析器使用名為Bean激活框架的Java庫來驗證MIME類型,該Java庫使用了與每個方法同步的舊Java“Hashtable”集合。這意味著所有進(jìn)行XML解析的線程終都在同一個位置排隊,造成了巨大的并發(fā)瓶頸。你可以通過閱讀線程轉(zhuǎn)儲找到這個問題。許多現(xiàn)代開發(fā)人員已經(jīng)習(xí)慣了為他們處理大多數(shù)線程的工具。這很好,直到有些事情不能正常工作。每個人都需要理解并發(fā)性。
如果你只需要一個惟一的ID,不要使用序列。只有在合理地需要每個ID時才使用一個序列。順序。序列是如何實現(xiàn)的?線程鎖。也就是說,所有的序列都是這樣的。另一種方法是使用隨機(jī)生成的UUID,使用安全隨機(jī)算法。盡管理論上有可能得到一份復(fù)制品,但在產(chǎn)生了幾萬億行之后,你仍然有更大的機(jī)會被隕石擊中頭部。我曾經(jīng)讓開發(fā)人員坐在我面前,光著頭戴著沒有隕石頭盔的頭盔,告訴我,即使是理論上的復(fù)制機(jī)會在他們的系統(tǒng)中都是可以接受的,但我猜他們對自己的生活并不重視。至少要用錫箔紙。
不管是數(shù)據(jù)庫,HTTP,還是別的什么,都要把這些東西進(jìn)行池化。在更大的系統(tǒng)上,不要嘗試同時打開它們,因為你會發(fā)現(xiàn)你的數(shù)據(jù)庫并不是這樣設(shè)計的!
你需要的內(nèi)存總比你所希望的要多。如果你選擇了犧牲其它方面從而交換得到內(nèi)存,那是不好的。我曾經(jīng)將我的Linux boxes設(shè)置為不允許交換,因為與默默地在后臺殺死我的軟件相比,我更想讓它們出現(xiàn)崩潰。
大多數(shù)高速緩存軟件都有“write behind”的能力,也就是將數(shù)據(jù)寫到至少兩臺機(jī)器上的內(nèi)存中,而不用等待磁盤。這“軟化”了讀寫波。終,如果寫吞吐量足夠高,那么在write-behind緩存崩潰之前,你將不得不阻塞以趕上進(jìn)度。在其他地方也存在類似的輸入/輸出同步,在日志文件之類的地方。一些軟件仍然經(jīng)常調(diào)用fsync,而這不是你想要的高端分布式可擴(kuò)展軟件——至少在很多幫助下是這樣。
一些軟件包仍然是圍繞進(jìn)程和子進(jìn)程設(shè)計的,每個進(jìn)程都有一個單獨的線程,特別是在Unix操作系統(tǒng)上。你可以把它們組合起來,對它們進(jìn)行復(fù)用,但這不是一個好的設(shè)計。每個進(jìn)程和子進(jìn)程都有自己的內(nèi)存空間。有時你可以分配另一個可怕的想法,叫做共享內(nèi)存。現(xiàn)在的軟件都具有管理多線程的進(jìn)程。現(xiàn)在的多核cpu中,這一比例要大得多,因為每個核心都可以同時處理多個線程。
假設(shè)一個分布式的文件系統(tǒng)和內(nèi)存中計算的火花使你的所有服務(wù)器節(jié)點協(xié)同工作,而生命是盛大的,對吧?實際上,你仍然有網(wǎng)卡和開關(guān)以及其他限制帶寬的東西。nic可以被綁定,并且交換器每秒的數(shù)據(jù)包數(shù)是固定的(這和一個1G的交換機(jī)不同,在所有的20個端口上都不能提供1G)。很好,你有很多節(jié)點都在發(fā)送數(shù)據(jù),但是它們會在自己的網(wǎng)卡,你的實際網(wǎng)絡(luò)帶寬,或者你的交換機(jī)實際可用的吞吐量上瓶頸嗎?
如果你正在編寫代碼和架構(gòu)系統(tǒng),那么希望你可以跳過這些陷阱。否則,請記住,一些老員工離開了這個行業(yè)然后開設(shè)酒吧這樣的事情是經(jīng)常會發(fā)生。
本站文章版權(quán)歸原作者及原出處所有 。內(nèi)容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負(fù)責(zé),本站只提供參考并不構(gòu)成任何投資及應(yīng)用建議。本站是一個個人學(xué)習(xí)交流的平臺,網(wǎng)站上部分文章為轉(zhuǎn)載,并不用于任何商業(yè)目的,我們已經(jīng)盡可能的對作者和來源進(jìn)行了通告,但是能力有限或疏忽,造成漏登,請及時聯(lián)系我們,我們將根據(jù)著作權(quán)人的要求,立即更正或者刪除有關(guān)內(nèi)容。本站擁有對此聲明的最終解釋權(quán)。