摘要:并且這種格式?jīng)]有事先對時間序列的數(shù)量做任何限制。使用格式來存儲時間序列數(shù)據(jù)的兩種可能的。其中存放了時間列序列列和數(shù)值列三列。隨著數(shù)據(jù)規(guī)模的繼續(xù)增長,基于的應(yīng)用程序越來越不適合處理這樣規(guī)模的時間序列數(shù)據(jù)了。
就像我們在前一章提到的,一個時間序列是一系列數(shù)值,每個數(shù)值都伴隨著一個時間值,代表數(shù)據(jù)被記錄時的時間。時間序列數(shù)據(jù)存入后就很少再需要修改了,查詢時經(jīng)常是查詢一個連續(xù)時間段的數(shù)據(jù),也可能查詢匯總或者聚合后的數(shù)據(jù)。時間序列數(shù)據(jù)庫是一種儲存多個時間序列的方式,在其中檢索一個或幾個時間序列的某一個特定時間段的數(shù)據(jù)是特別高效的。同樣地,主要用來查詢一個時間段數(shù)據(jù)的應(yīng)用程序也適合使用時間序列數(shù)據(jù)庫來實現(xiàn)。像之前所解釋的,本書的主題是存儲和處理大規(guī)模時間序列數(shù)據(jù),為了實現(xiàn)這個目標(biāo),首選技術(shù)是非關(guān)系型NoSQL數(shù)據(jù)庫,比如Apache HBase或MapR-DB。
為大規(guī)模時間序列數(shù)據(jù)庫的實際實現(xiàn)提供務(wù)實的建議,是本書的目標(biāo),所以我們需要聚焦于一些可以簡化和增強真實世界中應(yīng)用程序發(fā)展進(jìn)程的一些基本步驟。我們會簡單看看適用于中小型數(shù)據(jù)集的方法,然后深入探究我們主要關(guān)注的問題:如何實現(xiàn)大規(guī)模TSDB。
為了得到一個扎實的實現(xiàn),有幾種可供選擇的設(shè)計方法。如何選擇取決于數(shù)據(jù)的屬性。有多少種不同的時間序列?獲得的數(shù)據(jù)是什么類型的?使用怎樣的速度采集數(shù)據(jù)?需要存儲多久的數(shù)據(jù)?這些問題的答案有助于我們確定最優(yōu)的實現(xiàn)策略。
這一章中的主要思想路線
盡管我們已經(jīng)提到處理時間序列數(shù)據(jù)的一些主要方面,這一章會比之前更深入地探討存儲和訪問時間序列數(shù)據(jù)的基本方法。第四章會提供如何使用現(xiàn)有開源軟件來最好地實現(xiàn)這些概念的建議。這兩章有比較多的內(nèi)容需要理解。然后你就可以記住如果將這些關(guān)鍵的想法集中到一起而不是迷失在細(xì)節(jié)中,這里是一個本章內(nèi)容的一個簡單路線圖:
平面文件
對時間序列數(shù)據(jù)來說是受限的工具,不適合快速增長的數(shù)據(jù),查詢起來也會效率低下
真正的數(shù)據(jù)庫:關(guān)系型數(shù)據(jù)庫
擴展性不好,常見的星型模式(star schema)不適合處理時間序列數(shù)據(jù)
真正的數(shù)據(jù)庫:非關(guān)系型NoSQL數(shù)據(jù)庫
首選方案,因為它可擴展型好、高效、能快速響應(yīng)基于時間段的查詢
基本設(shè)計
使用包含時間序列ID的唯一row key,列是不同時間偏移的數(shù)值
存儲多于一個時間序列
可選設(shè)計
使用寬表逐點存儲數(shù)據(jù)
混合寬表和blob類型的設(shè)計
將數(shù)據(jù)緩存到內(nèi)存,然后blob直寫
我們已經(jīng)回顧了主要思想,現(xiàn)在我們更詳細(xì)地重溫一下并且解釋它們的重要性。
最簡單的數(shù)據(jù)存儲:平面文件你可以擴展非常簡單的設(shè)計(比如簡單的二維表),使用更聰明的文件格式來使其更先進(jìn),比如列存儲的Parquet格式。Parquet是一個有效并且簡單的現(xiàn)代化格式,可以存儲時間和一些可選值。圖3-1展示了兩種記錄時間序列數(shù)據(jù)的Parquet schema。左圖中的schema適合你已經(jīng)知道怎么合理使用時間序列數(shù)據(jù)的情況,它是一個特定場景的存儲方案。例子中,只存了明確指定的4個時間序列的數(shù)據(jù)(一個存放時間的t和一個存放數(shù)據(jù)的tempIn組合起來,為一個時間序列。t和它對應(yīng)的tempIn、pressureIn、tempOut、pressureOut即4個時間序列),如果需要增加新的,就需要修改schema。右圖中的Parguet schema抽象程度更高,對你想要往文件里嵌入更多元數(shù)據(jù)的場景更適合。并且這種格式?jīng)]有事先對時間序列的數(shù)量做任何限制。如果你想要構(gòu)建一個給其他人使用的時間序列庫,右邊的格式會更合適一些。
圖3-1。使用Parquet格式來存儲時間序列數(shù)據(jù)的兩種可能的schema。左邊的schema使用固定的類型名稱將問題域確定了。在不改變schema的情況下,只可以存儲4個時間序列。相反地,右邊的schema更加靈活,你可以增加新的時間序列。另外它的抽象層次也更高,把幾個單一的時間序列(一對time、value)按照tags分組,然后放到一個多帶帶的block中。
這樣的一種時間序列數(shù)據(jù)(特別是使用類似Parquet格式的情況)是非常有用的,但前提是你需要分析的時間序列數(shù)量相對較小,并且所感興趣的時間范圍相對于單個文件所存儲數(shù)據(jù)的時間跨度很大(比如每個文件存放一個月的數(shù)據(jù),你查的時候也應(yīng)該每次查一個月的數(shù)據(jù),而不是每次查一天的)。
系統(tǒng)最初使用平面文件來實現(xiàn)是一種非常普遍的情況,而且不久之后這種簡單的實現(xiàn)不再適應(yīng)快速增長的數(shù)據(jù)的情況也是很普遍的?;締栴}是單一文件中的時間序列數(shù)量增加了,任何特定的查詢中,真正有用的數(shù)據(jù)占所讀取數(shù)據(jù)的比例就下降了,因為多數(shù)讀取到的數(shù)據(jù)其實是屬于其他時間序列的。
同樣地,在文件中的時間跨度比平均查詢的時間范圍已經(jīng)長很多的情況,真正有用的數(shù)據(jù)占所被讀取數(shù)據(jù)的比例又下降了,因為文件中的大部分?jǐn)?shù)據(jù)已經(jīng)在你感興趣的時間范圍之外了(比如數(shù)據(jù)記錄了1個月的數(shù)據(jù),而查詢時一般只查某一天的,那為了定位到這一天,需要先讀大量前邊的實際不需要的數(shù)據(jù))。努力解決這些問題的同時一般又會引入其他的問題。使用大量的文件來確保每個文件中只有較少的時間序列,會使文件數(shù)量大幅增長。同樣地,減少每個文件所存儲數(shù)據(jù)的時間范圍會使得文件數(shù)量翻倍增長。當(dāng)在一個類似Apache Hadoop中HDFS的文件系統(tǒng)存儲數(shù)據(jù)時,大量的文件會導(dǎo)致嚴(yán)重的穩(wěn)定性問題。基于Hadoop的上層系統(tǒng),如MapR可以輕松處理大量的文件,但檢索和管理大量的小文件也是很低效的,因為需要增加很多搜索時間。
為了避免這些問題,很自然的一步是轉(zhuǎn)而使用某些形式的真正的數(shù)據(jù)庫來存儲這些數(shù)據(jù)。選擇合適的數(shù)據(jù)庫的方法并不是顯而易見的,但基于數(shù)據(jù)庫的類型和它的設(shè)計方案,你有幾個選項。我們會研究這些問題來幫助你作選擇。
改用真正的數(shù)據(jù)庫:RDBMS怎么樣?即使是經(jīng)過良好分區(qū)的平面文件,在處理大規(guī)模時間序列數(shù)據(jù)時也會力不從心,所以你也行會考慮使用某些類型的真正的數(shù)據(jù)庫。當(dāng)?shù)谝淮卧跀?shù)據(jù)庫中存儲時間序列數(shù)據(jù)時,使用所謂的星型模式(star schema)設(shè)計,并且將數(shù)據(jù)存放到RDBMS是個很誘人的選擇。在這樣一種數(shù)據(jù)庫設(shè)計中,核心數(shù)據(jù)存放在事實表(fact table),就像圖3-2展示的那樣。
圖3-2。將時間序列數(shù)據(jù)存放到RDBMS的一個事實表的設(shè)計。其中存放了時間(TIme列)、序列ID(Time series ID列)和數(shù)值(Value列)三列。序列的細(xì)節(jié)存放在維表(dimension table)中(這一對Time、Value是一個時間序列,但這個時間序列的細(xì)節(jié),比如Value的含義是什么,存放在另一張表中,可以使用Time series ID去那個表查)。
在星型模式中,一個表存儲主要的數(shù)據(jù),并且會引用其他表(維表)。該設(shè)計一個核心假定是維表要相對小巧,而且不常變動。圖3-2中的時間序列事實表里,唯一被引用的維表,就是存放這個時間序列詳細(xì)信息的維表,它的內(nèi)容是表中數(shù)據(jù)(Value列)的含義。比如,如果我們的時間序列數(shù)據(jù)是從一個工廠的泵或者其他設(shè)備從采集的,我們會希望在獲取這個泵的多個維度的數(shù)據(jù),如入口和出口的壓強和溫度、泵在不同頻段的震動和泵自身的溫度等。這其中的每個泵的每一個維度,都是一個多帶帶的時間序列,每個時間序列會有類似泵的序列號、位置、商標(biāo)、型號等信息,這些信息都存放在維表中。
實際上一些應(yīng)用程序已經(jīng)使用像這樣的星型模式來存放時間序列數(shù)據(jù)了。我們在多數(shù)NoSQL數(shù)據(jù)庫中也可以使用這樣的設(shè)計。星型模式解決了有大量不同時間序列的問題,在數(shù)據(jù)點的規(guī)模達(dá)到數(shù)億甚至數(shù)十億的情況下也可以工作得很好。然而就像我們在第一章中看到的,即使是19世紀(jì)的航運數(shù)據(jù)也會產(chǎn)生上十億的數(shù)據(jù)點。在2014年,納斯達(dá)克證券交易所在過去三個月就會處理十億規(guī)模的交易量。記錄一個中型計算機集群的運行環(huán)境的話,一天會產(chǎn)生五億的數(shù)據(jù)點。
并且簡單地將這些數(shù)據(jù)存儲起來是一回事,對其檢索和處理就是另一回事了。現(xiàn)代的應(yīng)用程序如機器學(xué)習(xí)系統(tǒng)甚至狀態(tài)顯示系統(tǒng)都需要每秒檢索和處理上百萬的數(shù)據(jù)點。
雖然RDBMS可以擴展到這些大小、速度需求的下限,但帶來的消耗和引入的復(fù)雜性會急劇上升。隨著數(shù)據(jù)規(guī)模的繼續(xù)增長,基于RDBMS的應(yīng)用程序越來越不適合處理這樣規(guī)模的時間序列數(shù)據(jù)了。使用星型模式但轉(zhuǎn)而使用NoSQL數(shù)據(jù)庫的話,也沒有特別的幫助,因為這個問題的核心是星型模式帶來的,而不只是數(shù)據(jù)量。
使用寬表(wide table)的NoSQL數(shù)據(jù)庫星型模式所觸及的核心問題是每次測量都要使用一行。一個增加時間序列數(shù)據(jù)庫中數(shù)據(jù)檢索速度的技術(shù)是在每一行存儲很多數(shù)值。在一些像Apache HBase或者M(jìn)apR-DB的NoSQL數(shù)據(jù)庫中,列的數(shù)量幾乎是不受限制的,只要任何特定一行中有數(shù)據(jù)的列的數(shù)量在幾十萬之內(nèi)。這種能力可以被用來在每行存放多個數(shù)值。這樣做的話,數(shù)據(jù)點就可以被更高速地檢索,因為掃描數(shù)據(jù)的最大速度部分取決于需要掃描的行的數(shù)量,部分取決于待檢索數(shù)據(jù)點的總數(shù),部分取決于待檢索數(shù)據(jù)的總量。減少行的數(shù)量,就大幅減少了一部分檢索開銷,檢索速度就提升了。圖3-3展示了使用寬表來減少時間序列數(shù)據(jù)行數(shù)量的一種方式。這個技術(shù)和OpenTSDB(一個開源的數(shù)據(jù)庫,我們會在第四章詳細(xì)講到)之中使用的默認(rèn)表結(jié)構(gòu)很相似。需要注意這樣的表設(shè)計,和那些需要提前定義詳細(xì)schema的系統(tǒng)的表設(shè)計是很不一樣的。有一件事情,如果你想把schema寫下來,那將異常龐大。
圖3-3,在NoSQL時間序列數(shù)據(jù)庫中一個寬表的使用。關(guān)鍵的結(jié)構(gòu)是直觀的,在真正的應(yīng)用程序中,使用的會是一個二進(jìn)制的格式,但這樣順序的屬性是一樣的。
因為HBase和MapR-DB都是按照主鍵的順序來存儲數(shù)據(jù),圖3-3中的鍵設(shè)計會導(dǎo)致每行包含一小段時間的數(shù)據(jù)在磁盤上是連續(xù)存儲的(因為Row key是按時間順序增長,HBase和MapR-DB是按列族存放數(shù)據(jù)的,Data values中的數(shù)據(jù)就會全部按照時間順序存放在磁盤上)。這個設(shè)計意味著檢索一個特定時間段的數(shù)據(jù),涉及的主要是順序磁盤操作,就會比數(shù)據(jù)按行分散開的情況快很多。為了從這個表結(jié)構(gòu)獲得性能優(yōu)勢,每個時間窗口的采樣點要足夠富裕,這樣就可以減少行的數(shù)量,從而提升檢索速度。典型情況,時間窗口會被調(diào)整成每一行包括100-1000采樣點的樣子。
混合模式設(shè)計的NoSQL數(shù)據(jù)庫圖3-3中的表設(shè)計可以繼續(xù)改進(jìn),通過將一行中的所有數(shù)據(jù)壓縮成一個單一的被稱作blob的數(shù)據(jù)結(jié)構(gòu)。Blob可以高度壓縮,所以需要從磁盤讀取的數(shù)據(jù)量就更少了。并且,如果使用HBase來存儲時間序列數(shù)據(jù),每行只有一列的情況會減少了每列數(shù)據(jù)在HBase所使用的磁盤文件格式上的開銷,這樣又進(jìn)一步提高了性能。圖3-4的混合式表結(jié)構(gòu)中,一些行的數(shù)據(jù)已經(jīng)被壓縮,另一些行沒有。
圖3-4。在混合模式設(shè)計中,行中的數(shù)據(jù)可以被存儲成一個單一的數(shù)據(jù)結(jié)構(gòu)(blob)。注意實際壓縮的數(shù)據(jù)更可能是二進(jìn)制的格式。這里使用JSON格式顯示是為了更容易理解。
圖3-3中的寬表格式可以進(jìn)化成圖3-4的壓縮格式(blob樣式),只要確保那些被壓縮的行對應(yīng)的時間窗口不會或者很少再有新增的數(shù)據(jù)。一般地,一旦時間窗口結(jié)束后,新的數(shù)據(jù)就不屬于這個時間窗口了,然后對這個時間窗口中數(shù)據(jù)的壓縮就可以開始了。因為在同一行中,已壓縮和未壓縮的數(shù)據(jù)可以共存,如果在對行壓縮之后,又有新數(shù)據(jù)過來了,可以再簡單地重新壓縮這一行,將新數(shù)據(jù)合并進(jìn)來。
圖3-5展示的是概念上的混合式時間序列數(shù)據(jù)庫的數(shù)據(jù)流。
在后臺將數(shù)據(jù)從舊格式轉(zhuǎn)換成blob格式,會讓renderer(圖3-5中所顯示的)檢索數(shù)據(jù)并繪制出來的速度有質(zhì)的提升。例如,在4個節(jié)點的MapR集群中,數(shù)據(jù)以壓縮格式存放的話,3千萬的數(shù)據(jù)點可以在大概20秒內(nèi)被檢索、聚合、繪制出來。
圖3-5?;旌鲜綍r間序列數(shù)據(jù)庫的數(shù)據(jù)流。數(shù)據(jù)從數(shù)據(jù)源到達(dá)catcher,然后被插入到NoSQL數(shù)據(jù)庫中。之后blob maker在后臺定時將數(shù)據(jù)壓縮成blob格式。數(shù)據(jù)由renderer檢索和格式化。
再進(jìn)一步:blob直寫設(shè)計(The Direct Blob Insertion Design)壓縮舊數(shù)據(jù)依然存在一個性能瓶頸。因為數(shù)據(jù)以未壓縮的格式插入進(jìn)來,每個數(shù)據(jù)點到來后都需要對行做一個更新來將數(shù)值插入到數(shù)據(jù)庫中。對行的更新操作會限制數(shù)據(jù)的插入速度到每個集群中的每個節(jié)點上只有每秒2萬個數(shù)據(jù)點。
另一方面,圖3-6中的blob直寫方式的數(shù)據(jù)流允許插入速度增加了大概1千倍。為什么blob直寫方式會帶來如此大的性能提升?基本的區(qū)別是blob maker被轉(zhuǎn)移到catcher和NoSQL時間序列數(shù)據(jù)庫之間了。使用這種方式,blob maker就可以從內(nèi)存的數(shù)據(jù)緩存中直接讀取輸入的數(shù)據(jù),而不是從存儲層的寬表中提取之前已經(jīng)被寫入進(jìn)去的數(shù)據(jù)。
基本的思想是數(shù)據(jù)到達(dá)后先被存放在內(nèi)存中。這些數(shù)據(jù)同時也被寫入到日志文件中。這些日志文件就是圖3-6中的restart logs,它們是在Hadoop系統(tǒng)存放的平面文件,不是存儲層的一部分。Restart logs允許內(nèi)存中的數(shù)據(jù)緩存被重新導(dǎo)入,在數(shù)據(jù)管道必須被重建的時候。
在正常操作中,在時間窗口的末尾,新的內(nèi)存中數(shù)據(jù)結(jié)構(gòu)會被創(chuàng)建,現(xiàn)在舊的內(nèi)存中數(shù)據(jù)結(jié)構(gòu)就可以用來創(chuàng)建壓縮的blob然后寫入數(shù)據(jù)庫了。一旦blob被寫入了,日志文件就被刪除了。這樣就無需像之前的混合設(shè)計中將數(shù)據(jù)兩次寫入。在圖3-5中的混合設(shè)計中,全部的輸入數(shù)據(jù)流都會逐點寫入到存儲層,然后再被blob maker讀取。讀的情況和寫大致一樣。一旦數(shù)據(jù)被壓縮成了blob,它又被寫入到數(shù)據(jù)庫中。相反地,在圖3-6的blob直寫設(shè)計的數(shù)據(jù)流中,完整的數(shù)據(jù)流只寫入到內(nèi)存中(這樣速度很快),而不是寫入到數(shù)據(jù)庫中。數(shù)據(jù)在壓縮成blob之前不會被寫入到數(shù)據(jù)庫,所以寫入速度大幅提升。數(shù)據(jù)庫操作的次數(shù)從之前數(shù)據(jù)點的數(shù)量變成了blob的數(shù)量,很容易將次數(shù)減少到之前幾千分之一這樣的量級。
圖3-6。Blob直寫方式的數(shù)據(jù)流。Catcher在內(nèi)存中暫存數(shù)據(jù),并且將其寫入到restart logs中。Blob maker周期地從緩存中讀取數(shù)據(jù),然后將壓縮成的blob寫入到數(shù)據(jù)庫中。這個設(shè)計的性能提升來自于renderer可以同時從內(nèi)存和數(shù)據(jù)庫中獲取數(shù)據(jù)。
blob直寫方式的優(yōu)勢是什么?一個真實世界的例子展示了它可以做什么。使用了這個架構(gòu),僅使用了一個10節(jié)點的MapR集群中的4個節(jié)點,就可以實現(xiàn)每秒往MapR-DB的表中插入超過一億的數(shù)據(jù)點。這些節(jié)點都有著很高的性能,其中每個節(jié)點有15個CPU核、大量內(nèi)存和12塊高配置磁盤,但你使用多數(shù)硬件都可以達(dá)到這個性能級別的1/5到1/2。
這個性能級別聽起來是用來處理海量數(shù)據(jù)的,可能超出了我們所需要的處理能力,但是在第五章我們會展示為什么這樣的性能是非常有用的,即使是對那些相對溫和的應(yīng)用程序。
為什么關(guān)系型數(shù)據(jù)庫不是很合適在這一點,詢問為什么一個關(guān)系型數(shù)據(jù)庫不能處理和使用混合模式的MapR-DB或者HBase所能承受的插入和分析數(shù)據(jù)的負(fù)載是公平的。當(dāng)只有blob數(shù)據(jù)被插入而不使用寬表的情況,這個問題特別有趣,因為現(xiàn)代關(guān)系型數(shù)據(jù)庫通常支持blob或者array類型。
這個問題的答案是,關(guān)系型數(shù)據(jù)庫主要解決的問題不是提高插入和檢索數(shù)據(jù)的速度,它現(xiàn)在這樣運行是有其合理性的。使用關(guān)系型數(shù)據(jù)庫的主要原因也不是因為它有更好的性能。如果使用關(guān)系系型數(shù)據(jù)庫的blob格式存儲數(shù)據(jù),就意味著需要放棄大多數(shù)其他好處。此外,SQL沒有提供一個好的抽象方法,來隱藏訪問blob格式數(shù)據(jù)中的細(xì)節(jié)。SQL不能用任何合理的方式來訪問這些數(shù)據(jù),并且像多行事務(wù)等特性也完全派不上用場了。事務(wù)在這里還會成為問題,因為即使不使用,它也會成為一種消耗。一個關(guān)系型數(shù)據(jù)庫需要滿足多行事務(wù)的需求,這使它更難被擴展到多個節(jié)點上。盡管使用如Oracle的高成本數(shù)據(jù)庫可以在單個節(jié)點實現(xiàn)很高的性能。而使用類似Apache Hbase或者M(jìn)apR-DB的NoSQL數(shù)據(jù)庫,你可以簡單地通過加硬件的方式實現(xiàn)更高的性能。
為自己用不到的特性買單的模式在一些高性能系統(tǒng)中是存在的。為了可擴展而犧牲傳統(tǒng)關(guān)系型數(shù)據(jù)庫的一些固有特性也是常見的,但即使你這樣做了,還是得不到自己想要的擴展性。在這種情況,使用類似HBase或者M(jìn)apR-DB的替代方案是有實質(zhì)上的好處的,因為你同時得到了性能和可擴展性。
混合模式設(shè)計:我可以從哪得到一個?這些寬表、blob混合的表設(shè)計是非常誘人的。它們所許諾的巨大性能級別令人興奮,而且它們能運行在有容錯機制、基于Hadoop的系統(tǒng)(比如MapR),從運維的角度看也是很吸引人的。這些新方法都不是空想,它們已經(jīng)被構(gòu)建出來,并且被證明有著驚人的結(jié)果。然而我們在這里呈現(xiàn)的,很大程度都是概念上的東西。有真正已經(jīng)實現(xiàn)的嗎?下一章我們會講到如何使用OpenTSDB(一個開源時間序列數(shù)據(jù)庫工具)和幾個開源的MapR擴展,來實現(xiàn)這些新的設(shè)計。結(jié)果是利用本章所描述的概念以達(dá)到高性能的時間序列數(shù)據(jù)庫是現(xiàn)代使用場景所需要的。
付費解決 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等領(lǐng)域相關(guān)問題,靈活定價,歡迎咨詢,微信 ly50247。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/17462.html
摘要:后端服務(wù)將后端服務(wù)視為可拔插的資源后端服務(wù)是一種在應(yīng)用在網(wǎng)絡(luò)上正常運行時消費的任意一種服務(wù)。一份因子應(yīng)用的部署可以不經(jīng)過任何代碼修改將本地數(shù)據(jù)庫替換成第三方的服務(wù)如。因子應(yīng)用將這些數(shù)據(jù)庫看做可拔插資源,在部署時是松耦合的。 IV 后端服務(wù) 將后端服務(wù)視為可拔插的資源 后端服務(wù)是一種在應(yīng)用在網(wǎng)絡(luò)上正常運行時消費的任意一種服務(wù)。包括數(shù)據(jù)庫(如MySQL或CouchDB),消息/隊列系統(tǒng)(如...
摘要:文章來自原文在給開發(fā)者的源碼系列的第三篇文章,我們打算擴展上一篇文章來幫助理解內(nèi)部是怎么工作的。進(jìn)入在的核心代碼中,變量被稱為。要轉(zhuǎn)換一個為值,就調(diào)用函數(shù)。有了這個東西,我們可以看到函數(shù)馬上調(diào)用函數(shù)。 文章來自:http://www.hoohack.me/2016/02/12/phps-source-code-for-php-developers-part3-variables-ch...
摘要:前言這將是一個分為兩部分,內(nèi)容是關(guān)于在生產(chǎn)環(huán)境下,跑應(yīng)用的最佳實踐。潛在的攻擊者可以通過它們進(jìn)行針對性的攻擊。 前言 這將是一個分為兩部分,內(nèi)容是關(guān)于在生產(chǎn)環(huán)境下,跑Express應(yīng)用的最佳實踐。第一部分會關(guān)注安全性,第二部分最會關(guān)注性能和可靠性。當(dāng)你讀這篇文章時,假設(shè)你已經(jīng)對Node.js和web開發(fā)有所了解,并且對生產(chǎn)環(huán)境有了概念。 概覽 生產(chǎn)環(huán)境,指的是軟件生命循環(huán)中的某個階段。...
摘要:如果期間有其它線程更新了,則會先拿到新的值重新運算一次多運算的競爭條件這些運算符成功避免了單運算中的競爭條件。 作者:Lin Clark 譯者:Cody Chan 原帖鏈接:Avoiding race conditions in SharedArrayBuffers with Atomics 這是圖解 SharedArrayBuffers 系列的第三篇: 內(nèi)存管理碰撞課程 圖...
閱讀 3659·2021-10-09 09:58
閱讀 1202·2021-09-22 15:20
閱讀 2503·2019-08-30 15:54
閱讀 3520·2019-08-30 14:08
閱讀 897·2019-08-30 13:06
閱讀 1827·2019-08-26 12:16
閱讀 2687·2019-08-26 12:11
閱讀 2517·2019-08-26 10:38