亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

身為開(kāi)發(fā)人員,這些數(shù)據(jù)庫(kù)合知識(shí)不掌握不合適

作者 | Jaana Dogan,谷歌軟件工程師

譯者 | 彎月,責(zé)編 | 夕顏

出品 | CSDN(ID:CSDNnews)

大多數(shù)計(jì)算機(jī)系統(tǒng)都有某種需要保存到存儲(chǔ)系統(tǒng)的狀態(tài)。多年來(lái)我積累了許多數(shù)據(jù)庫(kù)知識(shí),大多都是從導(dǎo)致數(shù)據(jù)丟失和網(wǎng)站下線的設(shè)計(jì)錯(cuò)誤中吸取的教訓(xùn)。在以數(shù)據(jù)為主的系統(tǒng)中,數(shù)據(jù)庫(kù)是整個(gè)系統(tǒng)設(shè)計(jì)的核心,也是需要權(quán)衡的重點(diǎn)。盡管數(shù)據(jù)庫(kù)的工作原理不可忽視,但許多應(yīng)用程序開(kāi)發(fā)者看到的、經(jīng)歷過(guò)的問(wèn)題依然僅僅是冰山一角。在這篇文章中,我想分享一些我認(rèn)為特別有用的知識(shí)。

1  99.999%的情況下網(wǎng)絡(luò)耗時(shí)不是問(wèn)題,只不過(guò)是運(yùn)氣好

人們經(jīng)常說(shuō)如今的網(wǎng)絡(luò)很穩(wěn)定,也有人爭(zhēng)論許多系統(tǒng)宕機(jī)都是因?yàn)榫W(wǎng)絡(luò)故障。現(xiàn)在這方面的研究很有限,而且多數(shù)研究都集中在擁有獨(dú)立網(wǎng)絡(luò)、專用硬件和配備了專人負(fù)責(zé)的大型組織中。

google的Spanner(Google的分布式數(shù)據(jù)庫(kù))實(shí)現(xiàn)了99.999%的服務(wù)在線,他們的研究表明,僅有7.6%的問(wèn)題是由網(wǎng)絡(luò)導(dǎo)致的,盡管他們將高可用性歸功于專用的網(wǎng)絡(luò)。2014年Bailis和Kingsbury的調(diào)查(https://cacm.acm.org/magazines/2014/9/177925-the-network-is-reliable/fulltext)挑戰(zhàn)了1994年P(guān)eter Deutsh發(fā)表的“分布式計(jì)算的陷阱”(https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing)。網(wǎng)絡(luò)真的可靠嗎?

除了這些巨頭之外,互聯(lián)網(wǎng)上并沒(méi)有太完整的調(diào)查。大型供應(yīng)商也沒(méi)有提供足夠的有關(guān)客戶網(wǎng)絡(luò)故障的數(shù)據(jù)。云提供商的網(wǎng)絡(luò)導(dǎo)致的故障同樣會(huì)導(dǎo)致部分互聯(lián)網(wǎng)宕機(jī)數(shù)個(gè)小時(shí),但這也僅僅是一小部分許多人能注意到的故障而已。有時(shí)候,許多我們不得而知的網(wǎng)絡(luò)宕機(jī)也會(huì)造成巨大影響。云服務(wù)的客戶也不一定能夠注意到自己遇到的問(wèn)題。當(dāng)網(wǎng)絡(luò)宕機(jī)時(shí),客戶并不能確定故障是由供應(yīng)商的網(wǎng)絡(luò)故障導(dǎo)致的。對(duì)于他們而言,第三方服務(wù)就是黑盒子。只有那些供應(yīng)商自己才能估計(jì)出影響的范圍。

與那些大企業(yè)的系統(tǒng)相比,如果你的系統(tǒng)中網(wǎng)絡(luò)問(wèn)題導(dǎo)致的宕機(jī)只占很小比例,那么只能說(shuō)你的運(yùn)氣好。網(wǎng)絡(luò)依然會(huì)受到各種傳統(tǒng)問(wèn)題的影響,如硬件故障、拓?fù)渥兓⒐芾砼渲酶淖儯约皵嚯姷取5易罱?tīng)說(shuō),鯊魚也會(huì)導(dǎo)致網(wǎng)絡(luò)故障(https://twitter.com/rakyll/status/1249891472993693696)。

 

ACID有很多含義

ACID指原子性、一致性、孤立性和持久性。這些是數(shù)據(jù)庫(kù)事務(wù)需要保證的幾項(xiàng)特性,只有保障這幾項(xiàng)特性才能在崩潰、錯(cuò)誤、硬件故障等極端情況下保證數(shù)據(jù)的有效性。沒(méi)有ACID或類似的保障,應(yīng)用程序開(kāi)發(fā)者就不能判斷哪些應(yīng)該由數(shù)據(jù)庫(kù)負(fù)責(zé),哪些應(yīng)該由開(kāi)發(fā)者自己負(fù)責(zé)。絕大多數(shù)關(guān)系型事務(wù)數(shù)據(jù)庫(kù)都試圖遵循ACID,但新的標(biāo)準(zhǔn)(如NoSQL)催生了一大批不保證ACID的數(shù)據(jù)庫(kù),因?yàn)锳CID的實(shí)現(xiàn)代價(jià)相當(dāng)大。

我剛剛?cè)胄袝r(shí),曾經(jīng)和技術(shù)領(lǐng)導(dǎo)爭(zhēng)論過(guò)ACID是否已經(jīng)過(guò)時(shí)。可以說(shuō),ACID只是一個(gè)松散的描述,而不是嚴(yán)格的實(shí)現(xiàn)標(biāo)準(zhǔn)。如今,我認(rèn)為ACID非常有用,因?yàn)樗峁┝艘淮箢惖膯?wèn)題(以及一大類可能的解決方案)。

并非每個(gè)數(shù)據(jù)庫(kù)都支持ACID,即使是實(shí)現(xiàn)了ACID的數(shù)據(jù)庫(kù),對(duì)于ACID的解讀也不盡相同。其原因之一就是實(shí)現(xiàn)ACID需要做出的妥協(xié)非常多。數(shù)據(jù)庫(kù)通常聲稱自己符合ACID,但在某些極端情況下依然會(huì)有不同的解釋,或者它們對(duì)于那些“不太可能發(fā)生”的情況的處理方法也不一樣。開(kāi)發(fā)者至少可以在較高層次上理解數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方式,理解它們何時(shí)會(huì)出現(xiàn)問(wèn)題,以及設(shè)計(jì)上的取舍。

最有爭(zhēng)議的莫過(guò)于MongoDB的ACID實(shí)現(xiàn)(即使在第四版發(fā)行后該爭(zhēng)論依然存在。)MongoDB很長(zhǎng)時(shí)間都不支持日志,盡管它每隔60秒(甚至更長(zhǎng))才會(huì)向磁盤保存一次數(shù)據(jù)。考慮如下情況:應(yīng)用程序發(fā)出了兩個(gè)寫請(qǐng)求(w1和w2)。Mongo能將第一個(gè)寫請(qǐng)求持久化,但w2的持久化會(huì)因?yàn)橛布收隙 ?/p>身為開(kāi)發(fā)人員,這些數(shù)據(jù)庫(kù)合知識(shí)不掌握不合適

該圖演示了MongoDB在寫入磁盤之前失敗時(shí)的數(shù)據(jù)情況。

將數(shù)據(jù)提交到磁盤是一項(xiàng)昂貴的操作,避免提交能夠以犧牲持久性的代價(jià)換來(lái)性能的提升。今天,MongoDB已經(jīng)支持日志,但臟寫操作依然可能會(huì)影響數(shù)據(jù)的持久性,因?yàn)槟J(rèn)情況下MongoDB每隔100毫秒提交一次數(shù)據(jù)。因此,即使有日志支持,類似的情況依然可能發(fā)生,盡管發(fā)生故障時(shí)導(dǎo)致的變化丟失會(huì)少很多。

3每個(gè)數(shù)據(jù)庫(kù)的一致性和隔離性的能力都不同

在ACID屬性中,一致性和隔離性在不同實(shí)現(xiàn)之間最大的區(qū)別,因?yàn)閷?shí)現(xiàn)上的妥協(xié)更多。一致性和隔離性都是非常昂貴的功能。兩者都要求協(xié)調(diào),為了保證數(shù)據(jù)一致性,這兩者都會(huì)導(dǎo)致競(jìng)爭(zhēng)的發(fā)生。當(dāng)需要在多個(gè)數(shù)據(jù)中心水平擴(kuò)展時(shí)(特別是跨越不同地理區(qū)域的多個(gè)數(shù)據(jù)中心時(shí)),該問(wèn)題就愈發(fā)嚴(yán)重。關(guān)于這個(gè)現(xiàn)象更一般的解釋參見(jiàn)CAP理論。值得指出的是,應(yīng)用程序能夠處理一部分不一致性的問(wèn)題,有經(jīng)驗(yàn)的程序員也可以添加額外的邏輯,因此不必完全依賴數(shù)據(jù)庫(kù)。

數(shù)據(jù)庫(kù)通常提供不同的隔離層,這樣應(yīng)用程序開(kāi)發(fā)者可以選取性價(jià)比最佳的隔離層使用。較弱的隔離速度較快,但可能會(huì)引發(fā)數(shù)據(jù)競(jìng)爭(zhēng)。強(qiáng)隔離會(huì)消除可能的數(shù)據(jù)競(jìng)爭(zhēng),但速度比較慢,而且可能會(huì)引入數(shù)據(jù)沖突,從而拖慢數(shù)據(jù)庫(kù)速度,甚至?xí)?dǎo)致宕機(jī)。

身為開(kāi)發(fā)人員,這些數(shù)據(jù)庫(kù)合知識(shí)不掌握不合適

現(xiàn)有并發(fā)模型及其關(guān)系概覽

SQL標(biāo)準(zhǔn)只定義了四層隔離,盡管無(wú)論從理論還是從實(shí)踐來(lái)看,更多的隔離層也是可能的。jepson.io(https://jepsen.io/consistency)提供了對(duì)于以后并發(fā)模型的另一種觀點(diǎn),你可以閱讀一下。例如,Google的Spanner能夠保證帶有時(shí)鐘同步的外部序列化,而且這是一個(gè)標(biāo)準(zhǔn)中沒(méi)有定義的、更強(qiáng)的隔離層。

SQL標(biāo)準(zhǔn)中提到的隔離級(jí)別如下:

  • 可序列化(最嚴(yán)格,最昂貴):在同一個(gè)事務(wù)中,按順序執(zhí)行與并行執(zhí)行能夠產(chǎn)生相同的效果。串行執(zhí)行是指每個(gè)事務(wù)在下一個(gè)事務(wù)開(kāi)始之前執(zhí)行完成。需要指出,序列化通常實(shí)現(xiàn)為“快照隔離”(如Oracle),而快照隔離并非SQL標(biāo)準(zhǔn)的內(nèi)容。

  • 可重復(fù)的讀操作:當(dāng)前事務(wù)中未提交的讀操作僅對(duì)當(dāng)前事務(wù)可見(jiàn),而其他事務(wù)造成的讀操作是不可見(jiàn)的。

  • 讀提交:未提交的讀操作對(duì)于其他事務(wù)不可見(jiàn)。只有提交的寫操作才可見(jiàn),但可能會(huì)出現(xiàn)影子讀取的問(wèn)題。如果另一個(gè)事務(wù)插入并提交了新行,那么當(dāng)前事務(wù)可能會(huì)看到新的數(shù)據(jù)。

  • 未提交的讀操作(不太嚴(yán)格,但比較廉價(jià)):允許臟讀取,事務(wù)可以看到其他事務(wù)尚未提交的改變。在實(shí)踐中,該級(jí)別可以用來(lái)返回大致的聚合結(jié)果,如在表上執(zhí)行COUNT(*)操作。

可序列化的級(jí)別允許發(fā)生的數(shù)據(jù)競(jìng)爭(zhēng)最少,但實(shí)現(xiàn)起來(lái)最昂貴,會(huì)給系統(tǒng)引入最多的數(shù)據(jù)競(jìng)爭(zhēng)。其他隔離級(jí)別比較廉價(jià),但會(huì)增加數(shù)據(jù)競(jìng)爭(zhēng)的可能性。一些數(shù)據(jù)庫(kù)允許自己設(shè)置隔離級(jí)別,另一些數(shù)據(jù)庫(kù)則不支持某些隔離級(jí)別。

即使自稱支持某些隔離級(jí)別的數(shù)據(jù)庫(kù),也需要仔細(xì)檢查其行為,理解其實(shí)際的操作:

身為開(kāi)發(fā)人員,這些數(shù)據(jù)庫(kù)合知識(shí)不掌握不合適

不同數(shù)據(jù)庫(kù)的不同隔離級(jí)別的實(shí)現(xiàn)。

 

在無(wú)法保持鎖的情況下可以采用樂(lè)觀鎖

鎖的實(shí)現(xiàn)可能非常昂貴,不僅因?yàn)樗鼤?huì)引入數(shù)據(jù)競(jìng)爭(zhēng),還要求應(yīng)用程序與數(shù)據(jù)庫(kù)服務(wù)器之間存在穩(wěn)定的連接。排他鎖可能會(huì)更嚴(yán)重地受到網(wǎng)絡(luò)分區(qū)的影響,并導(dǎo)致難以識(shí)別和解決的死鎖。如果無(wú)法持有排他鎖,則可以選擇樂(lè)觀鎖。

樂(lè)觀鎖指的是,在讀取行時(shí),記錄版本號(hào)以及最近修改的時(shí)間戳或其校驗(yàn)和。然后,您可以在更改記錄之前檢查版本是否沒(méi)有原子更改。

UPDATE productsSET name = 'Telegraph receiver', version = 2WHERE id = 1 AND version = 1

如果另一個(gè)更新之前更改了該行,則對(duì)產(chǎn)品表的更新將影響0行。如果沒(méi)有更早的更新,它將影響1行,并且我們可以判斷我們的更新已成功。

5 除了臟讀取和數(shù)據(jù)丟失之外,還有其他的異常情況

在討論數(shù)據(jù)一致性時(shí),通常我們會(huì)將注意力放在可能會(huì)導(dǎo)致臟讀取和數(shù)據(jù)丟失的數(shù)據(jù)競(jìng)爭(zhēng)上。然而數(shù)據(jù)的異常情況并不止這兩種。

這類異常的一個(gè)例子是寫偏斜。寫偏斜很難識(shí)別,因?yàn)槲覀儧](méi)有特意尋找它們。寫偏斜的原因不是發(fā)生臟讀取或數(shù)據(jù)丟失,而是數(shù)據(jù)的邏輯約束被破壞。

例如,假設(shè)某個(gè)監(jiān)控應(yīng)用程序要求隨時(shí)必須有一個(gè)操作員在值守。

身為開(kāi)發(fā)人員,這些數(shù)據(jù)庫(kù)合知識(shí)不掌握不合適

在上述情況中,如果兩個(gè)事務(wù)都成功提交,則會(huì)發(fā)生寫偏斜。盡管沒(méi)有發(fā)生任何臟讀取,也沒(méi)有發(fā)生數(shù)據(jù)丟失,數(shù)據(jù)的一致性也會(huì)被破壞,因?yàn)閮蓚€(gè)操作員都被分配了值守任務(wù)。

可序列化的隔離、結(jié)構(gòu)設(shè)計(jì)或數(shù)據(jù)庫(kù)約束可以幫助消滅寫偏斜問(wèn)題。開(kāi)發(fā)者應(yīng)該能夠在開(kāi)發(fā)過(guò)程中識(shí)別出這種異常,并在生產(chǎn)環(huán)境中避免這種數(shù)據(jù)異常。話雖如此,識(shí)別代碼中可能出現(xiàn)的寫偏斜非常困難。即使在大型系統(tǒng)中,如果不同的團(tuán)隊(duì)負(fù)責(zé)同一個(gè)表上的不同功能,而缺乏互相交流,也會(huì)出現(xiàn)這種問(wèn)題。

6  數(shù)據(jù)庫(kù)和我對(duì)于順序的理解不一致

數(shù)據(jù)庫(kù)的核心功能之一就是保證順序,但數(shù)據(jù)庫(kù)理解的順序可能與應(yīng)用程序開(kāi)發(fā)者看到的順序不一致。數(shù)據(jù)庫(kù)看到的事務(wù)順序是按照接收的時(shí)間排序的,而不是開(kāi)發(fā)者認(rèn)為的順序。在高并發(fā)系統(tǒng)中,事務(wù)的執(zhí)行順序很難預(yù)測(cè)。

在開(kāi)發(fā)期間,尤其是在使用非阻塞庫(kù)時(shí),較差的代碼風(fēng)格和可讀性可能會(huì)導(dǎo)致以下問(wèn)題:用戶認(rèn)為事務(wù)可以順序執(zhí)行,即使它們可以以任何順序到達(dá)數(shù)據(jù)庫(kù)。下面的程序使T1和T2看起來(lái)將被順序調(diào)用,但是如果這些函數(shù)是非阻塞的并且立即以承諾返回,則調(diào)用的順序?qū)⑷Q于它們?cè)跀?shù)據(jù)庫(kù)中收到的時(shí)間。

身為開(kāi)發(fā)人員,這些數(shù)據(jù)庫(kù)合知識(shí)不掌握不合適

如果要求原子性(完整提交或放棄所有操作),而且順序很重要,那么操作T1和T2應(yīng)該在同一個(gè)數(shù)據(jù)庫(kù)事務(wù)中運(yùn)行。

7應(yīng)用程序?qū)拥姆制赡苄枰趹?yīng)用程序之外實(shí)現(xiàn)

分片是數(shù)據(jù)庫(kù)水平擴(kuò)展的一種方式。盡管一些數(shù)據(jù)庫(kù)能夠自動(dòng)實(shí)現(xiàn)水平擴(kuò)展,但也有一些數(shù)據(jù)庫(kù)不能,或者不擅長(zhǎng)該功能。如果數(shù)據(jù)架構(gòu)師和開(kāi)發(fā)者能夠預(yù)測(cè)數(shù)據(jù)點(diǎn)訪問(wèn)方式,那么可以在用戶的層次實(shí)現(xiàn)水平分片,而不是將該任務(wù)交給數(shù)據(jù)庫(kù)。這稱為應(yīng)用程序?qū)拥姆制?/p>

“應(yīng)用程序?qū)臃制?rdquo;這個(gè)名字通常會(huì)帶來(lái)錯(cuò)誤的印象——分片存在于應(yīng)用程序服務(wù)之間。然而,分片功能可以實(shí)現(xiàn)為數(shù)據(jù)庫(kù)之上的一層。根據(jù)數(shù)據(jù)增長(zhǎng)和數(shù)據(jù)結(jié)構(gòu)的迭代方式,分片需求可能會(huì)變得非常復(fù)雜。如果能迭代實(shí)現(xiàn)某些策略,而不需要重新部署應(yīng)用程序服務(wù)器,是最理想的。

身為開(kāi)發(fā)人員,這些數(shù)據(jù)庫(kù)合知識(shí)不掌握不合適

應(yīng)用程序服務(wù)器與分片服務(wù)解耦合的例子

將分片作為單獨(dú)的服務(wù)可以提高迭代分片策略的能力,而不必重新部署應(yīng)用程序。應(yīng)用程序級(jí)分片系統(tǒng)的此類示例之一是Vitess。Vitess為MySQL提供了水平分片,并允許客戶端通過(guò)MySQL協(xié)議連接到它,并且它在彼此不認(rèn)識(shí)的各個(gè)MySQL節(jié)點(diǎn)上分片了數(shù)據(jù)。

8  AUTOINCREAMENT可能有害

AUTOINCREMENT是生成主鍵的常用方式。利用它生成ID的情況數(shù)不勝數(shù),但有些數(shù)據(jù)庫(kù)也會(huì)使用專門的ID生成方式。下面是使用自增和使用專用主鍵生成方式的一些優(yōu)缺點(diǎn):

  • 在分布式數(shù)據(jù)庫(kù)系統(tǒng)中,自增可能會(huì)很困難。需要全局鎖才能生成ID。如果生成UUID,則數(shù)據(jù)庫(kù)的各個(gè)節(jié)點(diǎn)之間不需要任何合作。帶有鎖的自增可能會(huì)導(dǎo)致數(shù)據(jù)沖突,可能會(huì)導(dǎo)致分布式下的插入操作產(chǎn)生嚴(yán)重的性能降級(jí)。一些數(shù)據(jù)庫(kù)如MySQL可能會(huì)要求特殊的配置,才能正確地在雙主架構(gòu)中實(shí)現(xiàn)自增。這種配置很容易搞錯(cuò),從而導(dǎo)致寫操作失敗。

  • 一些數(shù)據(jù)庫(kù)具有基于主鍵的分區(qū)算法。順序ID可能會(huì)導(dǎo)致無(wú)法預(yù)測(cè)的熱點(diǎn),并且可能會(huì)使某些分區(qū)不堪重負(fù),而另一些分區(qū)則保持空閑狀態(tài)。

  • 訪問(wèn)數(shù)據(jù)庫(kù)中行的最快方法是通過(guò)其主鍵。如果有更好的方法來(lái)標(biāo)識(shí)記錄,則順序ID可能會(huì)使表中最重要的列成為無(wú)意義的值。請(qǐng)盡可能選擇一個(gè)全局唯一的自然主鍵(例如用戶名)。

在采用自增ID或UUID作為索引、分區(qū)或分片時(shí)需要認(rèn)真考慮哪種方式最合適。

 

過(guò)時(shí)的數(shù)據(jù)可能有用且無(wú)鎖

多版本并發(fā)控制(MVCC)引入了許多我們上面談過(guò)的一致性功能。一些數(shù)據(jù)庫(kù)(如Postgres,Spanner)使用了MVCC來(lái)保證每個(gè)事務(wù)都看到一個(gè)快照(數(shù)據(jù)庫(kù)過(guò)去的某個(gè)版本)。事務(wù)和快照依然可以序列化,以保證一致性。在從舊的快照中讀取時(shí),你讀到的是過(guò)時(shí)的數(shù)據(jù)。

讀取稍稍過(guò)時(shí)的數(shù)據(jù)可能很有用,例如從數(shù)據(jù)中生成分析報(bào)告,或者計(jì)算大致的聚合值。

讀取過(guò)時(shí)數(shù)據(jù)的第一個(gè)好處就是延遲(特別是當(dāng)數(shù)據(jù)庫(kù)分布在不同物理地區(qū)時(shí))。MVCC數(shù)據(jù)庫(kù)的第二個(gè)好處就是,它允許只讀事務(wù)無(wú)鎖執(zhí)行。如果能夠接受過(guò)時(shí)數(shù)據(jù), 那么在存在大量讀取的應(yīng)用程序中,無(wú)鎖是最大的優(yōu)勢(shì)。

身為開(kāi)發(fā)人員,這些數(shù)據(jù)庫(kù)合知識(shí)不掌握不合適

即使太平洋另一側(cè)的數(shù)據(jù)庫(kù)中存在最新版本,應(yīng)用程序服務(wù)器依然從本地副本中讀取5秒之前的舊數(shù)據(jù)。

數(shù)據(jù)庫(kù)會(huì)自動(dòng)清理舊版本,在某些情況下,你可以按需進(jìn)行清理。例如,Postgres允許用戶按需使用VACUUM命令,同時(shí)也會(huì)每隔一段時(shí)間自動(dòng)執(zhí)行清理。Spanner會(huì)定時(shí)執(zhí)行垃圾回收來(lái)清理超過(guò)一個(gè)小時(shí)的舊版本。

 

只要存在時(shí)鐘,就會(huì)發(fā)生時(shí)鐘偏斜

計(jì)算中最隱秘的秘密就是所有時(shí)間的API都是謊言。我們的機(jī)器無(wú)法準(zhǔn)確知道當(dāng)前時(shí)間。我們的計(jì)算機(jī)都包含一個(gè)石英晶體,該石英晶體會(huì)產(chǎn)生一個(gè)計(jì)時(shí)信號(hào)。但是石英晶體無(wú)法準(zhǔn)確地計(jì)算時(shí)間,總會(huì)比實(shí)際的時(shí)鐘快或慢。每天的漂移可能長(zhǎng)達(dá)20秒。為了準(zhǔn)確起見(jiàn),我們的計(jì)算機(jī)上的時(shí)間需要不時(shí)地與實(shí)際時(shí)間同步。

我們使用NTP服務(wù)器進(jìn)行同步,但是同步本身可能出現(xiàn)網(wǎng)絡(luò)延遲。與同一數(shù)據(jù)中心中的NTP服務(wù)器同步可能需要一些時(shí)間,與公用NTP服務(wù)器同步可能會(huì)導(dǎo)致更多偏差。

原子鐘和GPS時(shí)鐘是確定當(dāng)前時(shí)間的更好來(lái)源,但是它們太昂貴,并且需要復(fù)雜的設(shè)置,因此無(wú)法安裝在每臺(tái)機(jī)器上。考慮到這些限制,數(shù)據(jù)中心通常會(huì)使用多層方法。原子鐘或GPS時(shí)鐘能夠提供準(zhǔn)確的計(jì)時(shí),它們的時(shí)間會(huì)通過(guò)另一臺(tái)服務(wù)器廣播到其他機(jī)器。這意味著每臺(tái)機(jī)器都會(huì)在一定程度上偏離實(shí)際當(dāng)前時(shí)間。

還有復(fù)雜的情況。應(yīng)用程序和數(shù)據(jù)庫(kù)通常位于不同的計(jì)算機(jī)中(甚至可能位于不同的數(shù)據(jù)中心)。不僅分布在幾臺(tái)計(jì)算機(jī)上的數(shù)據(jù)庫(kù)節(jié)點(diǎn)無(wú)法在時(shí)間上達(dá)成共識(shí),應(yīng)用服務(wù)器時(shí)鐘和數(shù)據(jù)庫(kù)節(jié)點(diǎn)時(shí)鐘也無(wú)法達(dá)成共識(shí)。

Google的TrueTime在這里采用了不同的方法。大多數(shù)人認(rèn)為Google在時(shí)鐘方面的進(jìn)步可以歸因于對(duì)原子鐘和GPS時(shí)鐘的使用,但這只是一部分原因。TrueTime的實(shí)際工作原理如下:

  • TrueTime使用兩個(gè)不同的源:GPS和原子鐘。這些鐘表的失敗模式不同,因此同時(shí)使用兩種可以提高可靠性。

  • TrueTime使用了非傳統(tǒng)的API。它返回一個(gè)時(shí)間范圍,實(shí)際的時(shí)間位于下界和上界之間的任意地方。Google的分布式數(shù)據(jù)庫(kù)Spanner會(huì)一直等待,直到它能確信當(dāng)前的時(shí)間超過(guò)了某個(gè)特定時(shí)間。該方法給系統(tǒng)引入了一些延遲,特別是當(dāng)主服務(wù)器廣播的不確定較高時(shí),但即使在全球分布式的情況下依然能夠提供正確性。

身為開(kāi)發(fā)人員,這些數(shù)據(jù)庫(kù)合知識(shí)不掌握不合適

Spanner的組件使用TrueTime,其中TT.now返回一個(gè)時(shí)間范圍,這樣Spanner可以插入sleep來(lái)確保當(dāng)前時(shí)間超過(guò)某個(gè)特定時(shí)間。

對(duì)當(dāng)前時(shí)間的信心下降,意味著Spanner操作可能需要更多時(shí)間。因此,盡管不可能擁有精確的時(shí)鐘,但高可信度對(duì)于性能依然很重要。

 

延遲有很多含義

對(duì)于“延遲”一詞每個(gè)人的理解都不同。在數(shù)據(jù)庫(kù)中,延遲通常稱為“數(shù)據(jù)庫(kù)延遲”,而不是客戶端感知的延遲。客戶端看到的延遲是數(shù)據(jù)庫(kù)延遲和網(wǎng)絡(luò)延遲之和。在調(diào)試不斷升級(jí)的問(wèn)題時(shí),能夠識(shí)別客戶端和數(shù)據(jù)庫(kù)延遲至關(guān)重要。收集和顯示指標(biāo)時(shí),請(qǐng)始終考慮同時(shí)使用兩者。

 

評(píng)測(cè)性能需要針對(duì)每個(gè)事務(wù)進(jìn)行

有時(shí),數(shù)據(jù)庫(kù)在宣傳其性能和限制時(shí)會(huì)使用讀寫吞吐量和延遲作為指標(biāo)。而實(shí)際上,在評(píng)估新數(shù)據(jù)庫(kù)的性能時(shí),更全面的方法是分別評(píng)估關(guān)鍵操作(每個(gè)查詢和/或每個(gè)事務(wù))。例如:

  • 在表X(包含五千萬(wàn)行數(shù)據(jù),并帶有約束)中插入一行并填充關(guān)聯(lián)數(shù)據(jù)的寫吞吐量和延遲。

  • 當(dāng)每個(gè)用戶的平均朋友數(shù)為500時(shí),查詢給定用戶的朋友的朋友的延遲。

  • 當(dāng)每個(gè)用戶訂閱了500個(gè)賬號(hào),每個(gè)賬號(hào)每小時(shí)有X條消息時(shí),獲取時(shí)間線的最新100條記錄的延遲。

評(píng)測(cè)和實(shí)驗(yàn)應(yīng)當(dāng)包含這種極端用例,才能確信數(shù)據(jù)庫(kù)是否能夠滿足你的性能要求。類似的經(jīng)驗(yàn)法則是,在收集延遲數(shù)據(jù)和設(shè)定服務(wù)水平目標(biāo)時(shí)也要用這種細(xì)致的用例。

 

嵌套事務(wù)的弊大于利

并非每個(gè)數(shù)據(jù)庫(kù)都支持嵌套事務(wù),但是當(dāng)嵌套數(shù)據(jù)庫(kù)支持嵌套事務(wù)時(shí),嵌套事務(wù)可能會(huì)導(dǎo)致出人意料的編程錯(cuò)誤,這些錯(cuò)誤通常很難被發(fā)現(xiàn),直到你發(fā)現(xiàn)數(shù)據(jù)異常。

如果想避免嵌套事務(wù),客戶端庫(kù)通常可以幫你檢測(cè)并避免嵌套事務(wù)。如果無(wú)法避免,則必須注意避免出現(xiàn)子事務(wù)會(huì)導(dǎo)致已提交的事務(wù)意外中止的意外情況。

將事務(wù)封裝在不同的層中可能會(huì)導(dǎo)致令人驚訝的嵌套事務(wù)案例,并且從可讀性的角度來(lái)看,其意圖會(huì)很難理解。看一看以下程序:

身為開(kāi)發(fā)人員,這些數(shù)據(jù)庫(kù)合知識(shí)不掌握不合適

上述代碼的結(jié)果是什么?它會(huì)回滾兩個(gè)事務(wù),還是只會(huì)回滾內(nèi)層事務(wù)?如果這段代碼依賴于庫(kù)中的多個(gè)層,每個(gè)層都封裝了事務(wù)處理?我們?cè)鯓硬拍茏R(shí)別并改善這種情況?

想像一個(gè)包含多個(gè)操作(如newAccount)的數(shù)據(jù)層,該數(shù)據(jù)層已經(jīng)實(shí)現(xiàn)了自己的事務(wù)處理。數(shù)據(jù)層無(wú)需自己創(chuàng)建事務(wù)就能實(shí)現(xiàn)高層操作。于是,業(yè)務(wù)邏輯可以啟動(dòng)事務(wù)、在事務(wù)中執(zhí)行操作,然后提交或放棄。

身為開(kāi)發(fā)人員,這些數(shù)據(jù)庫(kù)合知識(shí)不掌握不合適
 

14  事務(wù)不應(yīng)該維持應(yīng)用程序狀態(tài)

應(yīng)用程序開(kāi)發(fā)者也許想在事務(wù)中使用應(yīng)用程序狀態(tài),以更新特定的值,或修改查詢參數(shù)。需要考慮的一個(gè)關(guān)鍵因素就是要使用正確的作用域。客戶端通常會(huì)在發(fā)生網(wǎng)絡(luò)問(wèn)題時(shí)重試整個(gè)事務(wù)。如果事務(wù)依賴于某個(gè)狀態(tài),而該狀態(tài)可能在其他地方被修改,那么事務(wù)就可能會(huì)在數(shù)據(jù)競(jìng)爭(zhēng)發(fā)生時(shí)讀取錯(cuò)誤的值。事務(wù)應(yīng)當(dāng)注意應(yīng)用程序內(nèi)的數(shù)據(jù)競(jìng)爭(zhēng)。

身為開(kāi)發(fā)人員,這些數(shù)據(jù)庫(kù)合知識(shí)不掌握不合適

上述事務(wù)每次運(yùn)行時(shí)會(huì)增加序列數(shù)字,而不管實(shí)際執(zhí)行結(jié)果如何。如果網(wǎng)絡(luò)故障導(dǎo)致提交失敗,那么第二次嘗試時(shí)就會(huì)使用不同的序列數(shù)字進(jìn)行查詢。

15  查詢計(jì)劃器可以報(bào)告數(shù)據(jù)庫(kù)的信息

查詢計(jì)劃器可以給出查詢?cè)跀?shù)據(jù)庫(kù)中的執(zhí)行方式。它還會(huì)分析查詢并在執(zhí)行之前進(jìn)行優(yōu)化。計(jì)劃期只能提供一些大致的估計(jì)。怎樣才能得到下述查詢的結(jié)果呢?

SELECT * FROM articles where author = "rakyll" order by title;

有兩種方式可以獲取結(jié)果:

  • 全表掃描:掃描表中的每一條記錄,返回作者名字匹配的所有文章,然后排序

  • 索引掃描:使用索引找到匹配的ID,獲取這些行,然后排序

查詢計(jì)劃器的職責(zé)就是判斷哪種方式最合適。查詢計(jì)劃器得到的信號(hào)很有限,因此可能會(huì)導(dǎo)致不理想的決定。DBA或開(kāi)發(fā)者應(yīng)該使用這些信息來(lái)診斷并對(duì)效率不高的查詢進(jìn)行調(diào)優(yōu)。新版數(shù)據(jù)庫(kù)可以調(diào)整查詢計(jì)劃器并進(jìn)行自我診斷。慢查詢報(bào)告、延遲問(wèn)題報(bào)告、執(zhí)行時(shí)間報(bào)告等也有助于優(yōu)化查詢。

查詢計(jì)劃器提供的某些指標(biāo)可能很混亂,特別是有關(guān)延遲或CPU時(shí)間的指標(biāo)。作為查詢計(jì)劃器的輔助,跟蹤和執(zhí)行路徑工具也有助于診斷這些問(wèn)題。不過(guò)并不是每個(gè)數(shù)據(jù)庫(kù)都提供這些工具。

 

在線遷移非常復(fù)雜,但不是不可能

實(shí)時(shí)在線遷移意味著從一個(gè)數(shù)據(jù)庫(kù)遷移到另一個(gè)數(shù)據(jù)庫(kù),中途不停止服務(wù),還要保證數(shù)據(jù)的正確性。如果在同種數(shù)據(jù)庫(kù)之間遷移,那么在線遷移就能容易些,但如果使用新的數(shù)據(jù)庫(kù),再加上不同的性能要求和表結(jié)構(gòu),遷移就會(huì)變得更加復(fù)雜。

在線遷移有不同的模型,下面是其中一種:

  • 開(kāi)始對(duì)兩個(gè)數(shù)據(jù)庫(kù)進(jìn)行雙重寫入。在此階段,新數(shù)據(jù)庫(kù)不會(huì)擁有所有數(shù)據(jù),但新數(shù)據(jù)會(huì)出現(xiàn)在新數(shù)據(jù)庫(kù)中。一旦對(duì)這一步充滿信心,就可以繼續(xù)進(jìn)行第二步。

  • 在兩個(gè)數(shù)據(jù)庫(kù)上同時(shí)啟用讀取路徑。

  • 主要使用新的數(shù)據(jù)庫(kù)進(jìn)行讀寫操作。

  • 停止在舊的數(shù)據(jù)庫(kù)上進(jìn)行寫入操作,但讀取操作依然在舊的數(shù)據(jù)庫(kù)上進(jìn)行。此時(shí),新的數(shù)據(jù)庫(kù)并不包含所有新數(shù)據(jù),在讀取舊數(shù)據(jù)時(shí),可能依然需要使用舊的數(shù)據(jù)庫(kù)。

  • 此時(shí),舊的數(shù)據(jù)庫(kù)是只讀的。將新數(shù)據(jù)庫(kù)中缺少的數(shù)據(jù)填入。遷移完成后,所有的讀寫路徑都可以使用新的數(shù)據(jù)庫(kù),舊的數(shù)據(jù)庫(kù)就可以移除了。

如果需要更多案例研究,可以閱讀Stripe的這篇詳盡的文章(https://stripe.com/blog/online-migrations)。

 

數(shù)據(jù)庫(kù)的顯著增長(zhǎng)表明不確定性

數(shù)據(jù)庫(kù)增長(zhǎng)會(huì)帶來(lái)不可預(yù)料的規(guī)模問(wèn)題。對(duì)數(shù)據(jù)庫(kù)內(nèi)部原理的理解越多,我們對(duì)于規(guī)模的預(yù)見(jiàn)就越少,但有些東西是無(wú)法預(yù)料的。

數(shù)據(jù)庫(kù)增長(zhǎng)會(huì)導(dǎo)致以前對(duì)于數(shù)據(jù)規(guī)模和網(wǎng)絡(luò)容量需求的假設(shè)變得無(wú)效。這時(shí)就需要進(jìn)行大規(guī)模結(jié)構(gòu)修改、大規(guī)模操作改善、容量問(wèn)題改善、重新考慮部署、遷移到其他數(shù)據(jù)庫(kù)等方式來(lái)避免服務(wù)中斷。

永遠(yuǎn)不要假設(shè)你只需要理解當(dāng)前數(shù)據(jù)庫(kù)的內(nèi)部原理,因?yàn)橐?guī)模會(huì)引發(fā)新的問(wèn)題。無(wú)法預(yù)料的熱點(diǎn)、不均衡的數(shù)據(jù)分布、無(wú)法預(yù)料的容量和硬件問(wèn)題,日益增長(zhǎng)的流量和新的網(wǎng)絡(luò)分區(qū),都會(huì)讓你不得不重新考慮數(shù)據(jù)庫(kù)、數(shù)據(jù)模型、部署模型和部署規(guī)模等問(wèn)題。

原文鏈接:

https://medium.com/@rakyll/things-i-wished-more-developers-knew-about-databases-2d0178464f78

本文為CSDN翻譯文章,轉(zhuǎn)載請(qǐng)注明出處

分享到:
標(biāo)簽:數(shù)據(jù)庫(kù)
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定