分片
經(jīng)常能夠聽(tīng)到這樣的建議:“要盡早分片,經(jīng)常分片。”我的建議則大為不同“除非不得已,不要分片”。假如有足夠的經(jīng)驗,明白不得不分片,那就要對分片做好準備,但仍然要等到需要分片的時(shí)候再進(jìn)行分片。分片存在一些問(wèn)題。

主要問(wèn)題是分片現在已經(jīng)很流行,而且人們分片做得太早、太頻繁。我看到的大多數系統,要么已經(jīng)做了分片,要么正在考慮做分片,實(shí)際上根本就不需要一一只需要對目前可用的商品硬件進(jìn)行充分利用即可。以我的觀(guān)點(diǎn)看來(lái),對一個(gè)中等規模的應用,就要將其構建在跨越數百臺低檔機器的分片架構上,試圖提供無(wú)限伸縮能力,是非常愚蠢的。其實(shí),只需要購買(mǎi)幾臺足夠好的機器,在工程上多做些考慮,就足夠了。對每個(gè)睜大眼睛、指著(zhù)分片的成功故事的人(我曾經(jīng)就是其中之一),我可以給你看一些沒(méi)有使用分片的大規模應用,只是靠了幾個(gè)聰明的人,就能運維這種大規模應用。我的同事,還有我,也曾經(jīng)看到過(guò)大量的最流行的分片應用,透過(guò)表面現象,內部卻是資源的極大浪費。
分片架構比你預想的要昂貴得多,甚至在短期內也是如此,長(cháng)期則一定如此。這方面的例子有:分片一旦建立,則無(wú)法為了重新均衡的目的而再次構建;或者使用一種過(guò)于簡(jiǎn)單的方法,如用簡(jiǎn)單的取模算法作為分片函數。用低劣的工程方法構建分片架構,無(wú)疑是一種短視行為,從而也是根本無(wú)法實(shí)現可伸縮的。對于真正重要的事情也就很難考慮和設計,如常見(jiàn)的失效情形。如果要在很多臺機器上分布應用,或哪怕只有幾臺,都要認真地考慮失效轉移和故障后回切。應用程序也可能需要考慮失效的容錯性,假如一部分數據集不可用,要能夠降級運行。
分片的第三個(gè)問(wèn)題涉及過(guò)度設計(overengineering)的風(fēng)險。大多數事情都很難做到正好,不是做過(guò)頭了,就是沒(méi)有做到位。害怕架構沒(méi)有足夠的靈活性,或害怕不知道怎么做到正好,很容易導致過(guò)度設計。這不僅使事情過(guò)于復雜,還會(huì )產(chǎn)生無(wú)休止的麻煩。
寫(xiě)入多臺主服務(wù)器
存在很多誘惑性的陷阱,其中之一就是,將復制拓撲中的多臺服務(wù)器配置成可寫(xiě)的,你認為這樣做就萬(wàn)事大吉了。通常的想法是,“這樣就能夠提高寫(xiě)操作的性能”或者“所有節點(diǎn)都是平等的,從而失效轉移就容易實(shí)現了。”然而,這兩者都是錯誤的。
在主-主配置中,通過(guò)向兩臺主服務(wù)器寫(xiě),是無(wú)法提高性能的。所有的寫(xiě)操作都要通過(guò)復制發(fā)送給從服務(wù)器,在每個(gè)節點(diǎn)上都要重復執行該寫(xiě)操作,所以,寫(xiě)操作從哪臺服務(wù)器上發(fā)出,是無(wú)關(guān)緊要的。
因為復制是異步執行的8,在多個(gè)位置進(jìn)行寫(xiě)操作非常容易出錯,而且幾乎肯定在很多情況下都會(huì )產(chǎn)生麻煩,這些情況包括失效轉移、應用程序錯誤、程序員錯誤,以及大量的其他常見(jiàn)情形。通常導致的結果有丟失數據,以及長(cháng)時(shí)間的、沒(méi)日沒(méi)夜的苦干,試圖將系統恢復到合理的、一致的狀態(tài)。試圖說(shuō)服你的老板或同事不要這樣做,肯定很困難,但一定要試試。
多級復制
如果可能的話(huà),盡量不要使用多級復制。使用一臺主服務(wù)器和N臺從服務(wù)器,而不是從服務(wù)器的從服務(wù)器的從服務(wù)器,要簡(jiǎn)單得多。麻花鏈鏈的從服務(wù)器結構,有的時(shí)候是有優(yōu)點(diǎn)的,但可能的話(huà)最好避免使用。孫子輩的從服務(wù)器和重孫子輩的從服務(wù)器很難管理,假如在這些從服務(wù)器和位于金字塔頂端的主服務(wù)器之間的中間級別上發(fā)生問(wèn)題的話(huà)。常見(jiàn)的問(wèn)題有復制延遲、服務(wù)器崩潰、錯誤以及網(wǎng)絡(luò )問(wèn)題。
環(huán)形復制(多于兩個(gè)節點(diǎn))
要像躲避瘟疫一樣避免使用環(huán)形復制,其失效情形,不管是數量還是復雜度,都大得超乎想象。就在幾天前,我接到一個(gè)請求支持的電話(huà),那是由5臺服務(wù)器構成的環(huán),在試圖移掉其中一臺而用另外的服務(wù)器替換時(shí),卻發(fā)生了語(yǔ)句死循環(huán)的問(wèn)題。這種架構非常脆弱,隨時(shí)都會(huì )引發(fā)災難。
依賴(lài)于DNS
我已經(jīng)說(shuō)過(guò)這一點(diǎn),但仍然值得再重復一次。DNS很脆弱,依賴(lài)于DNS最終會(huì )自食苦果。將DNS用于域名查詢(xún)是沒(méi)問(wèn)題的,但DNS不應該受失效轉移的影響。不要將循環(huán)DNS∞用于負載均衡。同理,也不要使用/letc/hosts,對這個(gè)文件的版本變更、管理以及部署都要是原子操作。
所謂的實(shí)體一屬性一值(EAV)設計模式
每當有人對我說(shuō),“我有一個(gè)托管的多租戶(hù)Saas應用…”我都能夠補充他的下半句:“你使用的是EAV,而且有性能問(wèn)題。”在你不知道最終的數據模式是什么,或者根本就沒(méi)有最終的數據模式時(shí),EAV是有誘惑力的。這往往出現在“托管的、多租戶(hù)的SaaS應用”中,這只是因為公司想銷(xiāo)售有靈活性的東西。他們想這樣告訴客戶(hù):“不管你的數據是什么樣的,都會(huì )適合我們的系統的。”但這并不是關(guān)系數據庫的工作方式。因為很快就會(huì )產(chǎn)生100個(gè)表的自連接(self-joins),而產(chǎn)生的查詢(xún)計劃除了由于搜索整個(gè)磁盤(pán)而產(chǎn)生的隨機IO之外,不會(huì )做更多的事情。這些搜索在網(wǎng)站建設索引中找到一點(diǎn)兒數據,然后將這些簡(jiǎn)單的值按行拼接起來(lái)一一這個(gè)過(guò)程很慢的。在 MYSQL中,你是無(wú)法做100個(gè)連接的, MYSQL的限制是每個(gè)查詢(xún)只能最多對61個(gè)表做連接,實(shí)際上不到20個(gè)表的時(shí)候就已經(jīng)有問(wèn)題了,因為執行計劃的計算太復雜了。
本文地址:http://havencoinwallet.com//article/3320.html