當前位置:首頁 » 硬碟大全 » 緩存一致性鎖
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

緩存一致性鎖

發布時間: 2022-04-29 10:15:59

㈠ 分布式鎖是什麼

什麼是分布式鎖?實現分布式鎖的三種方式

在很多場景中,我們為了保證數據的最終一致性,需要很多的技術方案來支持,比如分布式事務、分布式鎖等。那具體什麼是分布式鎖,分布式鎖應用在哪些業務場景、如何來實現分布式鎖呢?

一 為什麼要使用分布式鎖

我們在開發應用的時候,如果需要對某一個共享變數進行多線程同步訪問的時候,可以使用我們學到的鎖進行處理,並且可以完美的運行,毫無Bug!

注意這是單機應用,後來業務發展,需要做集群,一個應用需要部署到幾台機器上然後做負載均衡,大致如下圖:

六、基於ZooKeeper的實現方式

ZooKeeper是一個為分布式應用提供一致性服務的開源組件,它內部是一個分層的文件系統目錄樹結構,規定同一個目錄下只能有一個唯一文件名。基於ZooKeeper實現分布式鎖的步驟如下:

(1)創建一個目錄mylock;
(2)線程A想獲取鎖就在mylock目錄下創建臨時順序節點;
(3)獲取mylock目錄下所有的子節點,然後獲取比自己小的兄弟節點,如果不存在,則說明當前線程順序號最小,獲得鎖;
(4)線程B獲取所有節點,判斷自己不是最小節點,設置監聽比自己次小的節點;
(5)線程A處理完,刪除自己的節點,線程B監聽到變更事件,判斷自己是不是最小的節點,如果是則獲得鎖。

這里推薦一個Apache的開源庫Curator,它是一個ZooKeeper客戶端,Curator提供的InterProcessMutex是分布式鎖的實現,acquire方法用於獲取鎖,release方法用於釋放鎖。

優點:具備高可用、可重入、阻塞鎖特性,可解決失效死鎖問題。

缺點:因為需要頻繁的創建和刪除節點,性能上不如Redis方式。

七、總結


上面的三種實現方式,沒有在所有場合都是完美的,所以,應根據不同的應用場景選擇最適合的實現方式。

在分布式環境中,對資源進行上鎖有時候是很重要的,比如搶購某一資源,這時候使用分布式鎖就可以很好地控制資源。
當然,在具體使用中,還需要考慮很多因素,比如超時時間的選取,獲取鎖時間的選取對並發量都有很大的影響,上述實現的分布式鎖也只是一種簡單的實現,主要是一種思想。

㈡ java里volatile關鍵字有什麼特性

Java語言中關鍵字 volatile 被稱作輕量級的 synchronized,與synchronized相比,volatile編碼相對簡單且運行的時的開銷較少,但能夠正確合理的應用好 volatile 並不是那麼的容易,因為它比使用鎖更容易出錯,接下來本文主要介紹 volatile 的使用准則,以及使用過程中需注意的地方。

為何使用volatile?

(1)簡易性:在某些需要同步的場景下使用volatile變數要比使用鎖更加簡單

(2)性能:在某些情況下使用volatile同步機制的性能要優於鎖

(3)volatile操作不會像鎖一樣容易造成阻塞

volatile特性

(1)volatile 變數具有 synchronized 的可見性特性,及如果一個欄位被聲明為volatile,java線程內存模型確保所有的線程看到這個變數的值是一致的

(2)禁止進行指令重排序

(3)不保證原子性

註:

① 重排序:重排序通常是編譯器或運行時環境為了優化程序性能而採取的對指令進行重新排序執行的一種手段

② 原子性:不可中斷的一個或一系列操作

③ 可見性:鎖提供了兩種主要特性:互斥和可見性,互斥即一次只允許一個線程持有某個特定的鎖,因此可使用該特性實現對共享數據的協調訪問協議,這樣,一次就只有一個線程能夠使用該共享數據。可見性要更加復雜一些,它必須確保釋放鎖之前對共享數據做出的更改對於隨後獲得該鎖的另一個線程是可見的。

volatile的實現原理

如果對聲明了volatile的變數進行寫操作,JVM就會向處理器發送一條Lock前綴的指令,該Lock指令會使這個變數所在緩存行的數據回寫到系統內存,根據緩存一致性協議,每個處理器都會通過嗅探在匯流排上傳輸的數據來檢查自己緩存的值是否已過期,當處理器發現自己的緩存行對應的地址被修改,就會將當前處理器的緩存行設置成無效狀態,在下次訪問相同內存地址時,強制執行緩存行填充。

正確使用volatile的場景

volatile 主要用來解決多線程環境中內存不可見問題。對於一寫多讀,是可以解決變數同步問題,但是如果多寫,就無法解決線程安全問題。如:

1、不適合使用volatile的場景(非原子性操作)

(1)反例

private static volatile int nextSerialNum = 0;

public static long generateSerialNum() {

return nextSerialNum++;

}

這個方法的目的是要確保每次調用都返回不同的自增值,然而結果並不理想,問題在於增量操作符(++)不是原子操作,實際上它是一個由讀取-修改-寫入操作序列組成的組合操作,如果第二個線程在第一個線程讀取舊值和寫回新值期間讀取這個域,第二個線程與第一個線程就會讀取到同一個值。

(2)正例

其實面對上面的反例場景可以使用JDK1.5 java.util.concurrent.atomic中提供的原子包裝類型來保證原子性操作

private static AtomicInteger nextSerialNum = new AtomicInteger(0);

public static long generateSerialNum() {

return nextSerialNum.getAndIncrement();

}

2、適合使用volatile的場景

在日常工作當中volatile大多被在狀態標志的場景當中,如:

要通過一個線程來終止另外一個線程的場景

(1)反例

private static boolean stopThread;

public static void main(String[] args) throws InterruptedException {

Thread th = new Thread(new Runnable() {

@Override

public void run() {

int i = 0;

while (!stopThread) {

i++;

}

}

});

th.start();

TimeUnit.SECONDS.sleep(2);

stopThread = true;

}

運行後發現該程序根本無法終止循環,原因是,java語言規范並不保證一個線程寫入的值對另外一個線程是可見的,所以即使主線程main函數修改了共享變數stopThread狀態,但是對th線程並不一定可見,最終導致循環無法終止。

(2)正例

private static volatile boolean stopThread;

public static void main(String[] args) throws InterruptedException {

Thread th = new Thread(new Runnable() {

@Override

public void run() {

int i = 0;

while (!stopThread) {

i++;

}

}

});

th.start();

TimeUnit.SECONDS.sleep(2);

stopThread = true;

}

通過使用關鍵字volatile修飾共享變數stopThread,根據volatile的可見性原則可以保證主線程main函數修改了共享變數stopThread狀態後對線程th來說是立即可見的,所以在兩秒內線程th將停止循環。

㈢ 有誰知道cache的發展過程

縱觀PC系統和CPU二十年的發展,隨著半導體加工工藝水平的不斷提高,CPU和存儲器的性能都有了很大的提高。
CPU頻率的提高,必然要求系統中存儲器的存取速度要提高,還要求其容量要增大。主存儲器DRAM容量的提高還是比較快的,但是DRAM讀取時間的提高卻很慢。從而在速度上與CPU主頻的提高產生了極不相配的情況,這樣會影響整個系統的性能。二十年來,CPU設計的問題之一就是解決高速CPU和低速DRAM之間的平衡或匹配問題,以求系統性能的整體提高。
在它們之間加入高速緩沖存儲器Cache,就是這個問題的解決方案之一。
Cache隨CPU的發展而不斷改變,可以概括為:從無到有,由小到大,先外後內,縱深配備,軟硬兼施。初期的CPU沒有Cache,在80386時期出現外部Cache;80486時期開始有內部僅8kB的Cache。Cache的分級也由L1和L2級,發展到L0和L3級的縱深配備;Cache的大小由當初的8kB,直到Merced的1~2MB。為了更好地利用Cache,還專門配有緩存控制指令。
本文回顧了在過去的二十年中,Cache技術的發展歷程,並對PC其它設備使用Cache技術作了簡單陳述。 PC初期無需Cache在八十年代初,由於CPU主頻很低,DRAM的存取時間甚至快於CPU存取時間,因此無需Cache。例如,當時PC機採用8088CPU,系統主頻為4.77MHz,一個基本匯流排周期為4拍,即840ns。此時64kB的DRAM存取周期200ns,造成DRAM等待CPU的執行的局面,無需Cache。
在PC/AT機採用80286CPU後,系統主頻增加到10MHz,1個基本匯流排周期為2拍,即200ns。此時必須用讀取時間為100ns的DRAM。在採用25MHz的80386DX時,一個基本匯流排周期為2拍,即80ns,當時已沒有速度相匹配的DRAM可用。解決方案有2種:一種是在基本匯流排周期中插入等待,降低CPU的處理能力;另一種是採用內部和外部Cache,使用SRAM晶元以提高存儲器的讀取速度。80386沒有L1 Cache80386初期主頻為20MHz。Intel公司十分重視80386的設計製造,把它定位於「新一代個人電腦架構」,想把一些新技術設計在晶元中。但由於當時工藝所限,內置高速緩存的晶元體積過大,造成成本上升,同時工期有限,幾經權衡,最後決定在80386晶元不設置高速緩沖存儲器,可以生產另外的Cache,以配合80386運作。
盡管人們意識到CPU主頻的增加與內存DRAM存取時間過慢的矛盾已愈加突出,但因條件所限,80386內部沒有L1 Cache,只有外部的Cache。80486出現Cache80486是由80386CPU加80387數字協處理器以及8kB Cache構成。
當CPU的時鍾頻率繼續增加時,外部Cache的SRAM晶元速度也要相應提高,這樣會增加系統成本,為此在設計80486時採用了內部Cache。
80486晶元內由8kB的Cache來存放指令和數據。同時,80486也可以使用處理器外部的第二級Cache,用以改善系統性能並降低80486要求的匯流排帶寬。Cache可以工作在80486所有的操作模式:實地址模式、保護模式和X86模式。對Cache的操作是由系統自動進行的,對程序員透明。而在多處理器系統中,可能要求系統軟體的干預。對於一般的計算機,在系統CMOS設置中均有Cache使用模式的設置。
80486內部Cache是一個4路組相聯Cache,在主存儲器中給定單元的數據能夠存儲在Cache內4個單元中的任何一個。這種4路相聯方式是高命中率的全相聯Cache和快速的直接映像Cache的一種折衷,因而能進行快速查找並獲得高的命中率。Peutium的分離L1 Cache和L2 CachePentium處理器採用了超標量結構雙路執行的流水線,有分支預測技術。
由於Pentium設計有2條並行整數流水線,可同時執行2條命令。整數單元的潛在處理能力實際可增加一倍,處理器也需要對命令和數據進進雙倍的訪問。為使這些訪問不互相干涉,Intel把在486上共用的內部Cache,分成2個彼此獨立的8kB代碼Cache和8kB數據Cache,這兩個Cache可以同時被訪問。這種雙路高速緩存結構減少了爭用Cache所造成的沖突,提高了處理器效能。Pentium的Cache還採用了回寫寫入方式,這同486的貫穿寫入方式相比,可以增加Cache的命中率。此外,還採用了一種稱為MESI高速緩存一致性協議,為確保多處理器環境下的數據一致性提供了保證。Pentium Pro內嵌式L2 Cache為使Pentium Pro的性能超過Pentium,必需使用創新的設計方法。Pentium Pro使用了新的超標量和級流水線技術,包括無序執行、動態分支預測和推測執行的動態執行新技術。它可以使CPU在一個時鍾周期執行3條微操作。CPU並行處理速度的加快,意味著它同時處理指令和數據的數量增加,為不使CPU處於等待狀態,需要重新設計Cache。
Pentium Pro在片內第一級Cache的設計方案中,使指令Cache與數據Cache分別設置。指令Cache的容量為8kB,採用2路組相聯映像方式。數據Cache的容量也為8kB,但採用4路組相聯映像方式。Pentium Pro採用MESI(修改、排他、共享、作廢)協議來維持Cache和主存儲器之間的一致性。通常,人們總以為,像Pentium Pro這樣的3路超標量結構的微處理器會採用更大容量的片內第一級Cache和更大的第二級Cache。然而,Intel公司的設計者卻選擇了另一條設計思路——設計一種Cache存儲階層結構,使得能夠從一個Cache流動到另一個Cache,而不用阻塞執行。
Pentium Pro採用了內嵌式或稱捆綁式L2Cache,大小為256kB或512kB。此時的L2已經用線路直接連到CPU上,益處之一就是減少了對急劇增多L1 Cache的需求。L2 Cache還能與CPU同步運行。即當L1 Cache不命中時,立刻訪問L2 Cache,不產生附加延遲。為進一步減少因要訪問的信息不在高速緩沖中時所帶來的性能損失,Pentium Pro的L1和L2都設計成非鎖定型。即當哪個Cache中沒有CPU所需的信息時,它不妨礙後面訪問Cache的處理過程。Cache可以直接處理最多4次的Cache缺頁情況,藉助CPU的內存有序緩沖區可以順序保存最多12次的內存訪問。非鎖定型Cache適用於Pentium Pro的亂序執行核心,因為在可能引發流水線延遲的長等待內存操作期間,這些Cache可以讓CPU繼續運行。
Pentium Pro的如此捆綁封裝,帶來器件成本提高。一方面專用的L2 cache晶元成本高,另一方面兩個不同功能的晶元只有放在一起聯結後才能最後測試其性能的完整性。而當其中有一個有缺陷時,兩個晶元都被報廢。在以後的Pentium Pro產品中,又將L2 Cache從晶元中去掉。Pentium MMX容量增大的L1和L2CachePentium MMX是能運行多媒體指令MMX的高能奔騰處理器。Pentium MMX具有改進的分支預測和增強型流水線技術,並將L1 Cache容量增加到32kB,L2 Cache為512kB。
Pentium MMX的片內L1數據和指令的Cache,每個增到16kB,4路相聯。較大的獨立內部Cache、減少平均內存存取時間,同時提供對近期所用指令和數據的快速存取,性能因此得到提高。數據Cache支持採用回寫方式更新內存。
由於CacheL1容量的增大,使當時的應用程序運行速度提高了10%左右。PentiumⅡ設有雙獨立匯流排連接L2 CachePentiumⅡ是Pentium Pro的改進型,具有MMX指令,使用動態執行技術,採用雙獨立匯流排結構。PentiumⅡ同樣有2級Cache,L1為32kB(指令和數據Cache各16kB)是Pentium Pro的一倍。L2為512kB。
Pentium Ⅱ與Pentium Pro在L2 Cache 的不同是由於製作成本原因。L2 Cache已不在內嵌晶元上,而是與CPU通過專用64位高速緩存匯流排相聯,與其它元器件共同被組裝在同一基板上,即「單邊接觸盒」上。雙獨立匯流排結構就是:L2高速緩存匯流排和處理器至主內存(Processor-to-main-memory)的系統匯流排。 PentiumⅡ處理器可以同時使用這兩條匯流排,與單一匯流排結構的處理器相比,該處理器可以進出兩倍多的數據,可允許 PentiumⅡ處理器的L2高速緩存比Pentium處理器的L2高速緩存要快1倍。隨著 PentiumⅡ處理器主頻的提高,L2高速緩存的速度也將加快。最後,流水線型系統匯流排可允許同時並行傳輸,而不是單個順序型傳輸。改進型的雙重獨立匯流排結構,可以產生超過與單匯流排結構三倍帶寬的性能。另外,在PentiumⅡ中,採用了ECC技術,此技術應用到二級高速緩存中,大大提高了數據的完整性和可靠性。
為開發低端市場,曾在 PentiumⅡ的基板上除去L2,犧牲一些性能,製造廉價CPU。這就是最初的Celeron處理器。以後的Celeron仍加有較小的片上L2 Cache,其大小為128kB。PentiumⅢ的L2 Cache增大PentiumⅢ也是基於Pentium Pro結構為核心,在原有MMX多媒體指令的基礎上,又增了70多條多媒體指令。它使用動態執行技術,採用雙獨立匯流排結構。
PentiumⅢ具有32kB非鎖定L1 Cache和512kB非鎖定L2 Cache。L2可擴充到1~2MB,具有更合理的內存管理,可以有效地對大於L2緩存的數據塊進行處理,使CPU、Cache和主存存取更趨合理,提高了系統整體性能。在執行視頻回放和訪問大型資料庫時,高效率的高速緩存管理使PⅢ避免了對L2 Cache的不必要的存取。由於消除了緩沖失敗,多媒體和其它對時間敏感的操作性能更高了。對於可緩存的內容,PⅢ通過預先讀取期望的數據到高速緩存里來提高速度,這一特色提高了高速緩存的命中率,減少了存取時間。Merced設有L0即將推出的第7代處理器Merced主頻可達1GHz。很明顯,對Cache的要求更高了。為此,lntel本著「大力提高執行單元和緩存間數據交換速度」的思想,在晶元內開發新的Cache,並增加L1 Cache的容量,來平衡CPU和DRAM間的速度。
為此,在Merced的片上最接近執行單元旁再設另一處Cache,稱為L0緩存,是指令/數據分離型。由於L0Cache在物理位置上比L1離執行單元更近,布線距離的縮短,使它與執行單元間的數據交換速度比L1還快,可以進一步提高工作主頻。
同時,還要在晶元內部配置超過1MB的大容量L1 Cache。晶元內部Cache比外部Cache更易於提升與執行單元間的數據傳送速度。內部Cache的加大,執行單元不易發生「等待」。現行的內部Cache容量僅為32kB~128kB。內部Cache容量的增加會引起晶元面積增大,提高製造成本。但大部分公司認為,由於內部Cache容量增大而導致成本的上揚,可以用製造技術來彌補。與Cache相配合的緩存控制指令為進一步發揮Cache的作用,改進內存性能並使之與CPU發展同步來維護系統平衡,一些製造CPU的廠家增加了控制緩存的指令。如Intel公司在PentiumⅢ處理器中新增加了70條3D及多媒體的SSE指令集。其中有很重要的一組指令是緩存控制指令。AMD公司在K6-2和K6-3中的3DNow!多媒體指令中,也有從L1數據Cache中預取最新數據的數據預取指令(Prefetch)。
PentiumⅢ處理器的緩存控制指令,用於優化內存連續數據流。針對數據流的應用需要對以前的Cache運作方式進行了改進,減少了一些不必要的中間環節,節省了時間,增加了CPU數據匯流排的實際可用帶寬,也提高了Cache的效率。
有兩類緩存控制指令。一類是數據據預存取(Prefetch)指令,能夠增加從主存到緩存的數據流;另一類是內存流優化處理(Memory Streaming)指令,能夠增加從處理器到主存的數據流。這兩類指令都賦予了應用開發人員對緩存內容更大控制能力,使他們能夠控制緩存操作以滿足其應用的需求。
數據預存取指令允許應用識別出所需的信息,並預先將其從主存中取出存入緩存。這樣一來,處理器可以更快地獲取信息,從而改進應用性能。為了進一步削減內存延遲,內存訪問還可以與計算機周期保持流水操作。例如,如果一個應用需要計算一些數值以供3D圖形使用,當它在計算一個值的同時就可以預取下一個需要計算的數值。
內存流優化處理指令允許應用越過緩存直接訪問主存。通常情況下,處理器寫出的數據都將暫時存儲在緩存中以備處理器稍後使用。如果處理器不再使用它,數據最終將被移至主存。然而,對於多媒體應用來就,通常不再需要使用這些數據。因此,這時將數據盡快地移到主存中則顯得至關重要。採用了PentiumⅢ處理器的內存流優化處理指令後,應用程序就能讓數據搭乘「直達快車」,直接到達主存。當數據流直接到達主存時,處理器負責維護緩存的一致性。因為這種方式避免了為數據流留出空間清空緩存的當前內容,從而也提高了緩存的利用率。
總而言之,緩存控制指令改進了進出處理器的數據據流,使處理器保持其高速率運作。通過這些指令(同時還需要一些專為其設計以使其發揮優勢的軟體),商業用戶可以在操作系統和圖形設備驅動程序中感受其性能優勢。Cache在PC中其它設備的應用Cache作為一種速度匹配技術,不僅用在提高CPU對內存的讀寫速度上,而且也用在CPU結構的其它部分和PC系統中。
PC的顯示系統中,由於3D應用的迅猛發展,大量的顯示內存使用著高速緩存技術,如前台緩存、後台緩存、深度緩存和紋理緩存等。
PC的磁碟系統中,為提高內存對磁碟(主要是硬碟)的讀寫速度,就要建立磁碟高速緩存。因為DRAM內存的存取速度對CPU來說較慢,但對磁碟的存取速度卻是很快的。這是因為磁碟存儲系統包含有磁頭的機械運動,而機械運動無法跟傳送電信號的電子速度相比。此外,磁頭中電與磁的信號轉換也對速度有影響。這樣,為了提高磁碟存取速度而採用Cache也就順理成章了。硬碟Cache無需使用高速的SRAM,它只需在內存(DRAM)中劃出一個區域,作為專用的磁碟緩沖區,採用一定的數據結構,即可實現磁碟存取的Cache技術。它的過程也是把即將訪問的數據整塊地拷貝到高速緩存區中,然後內存再到高速緩存中去逐個讀取數據。由於數據在RAM空間內部傳送要比在RAM與磁碟間傳送快得多,系統由此提高了存取速度。
硬碟的Cache可以放在常規內存中。不過,為了不佔用寶貴的用戶程序空間,通常是把它設在擴展內存或擴充內存里。硬碟Cache是由人們共知的SMARTDRIVE.EXE文件自動建立的,用戶只需在AUTOEXEC.BAT與CONFIG.SYS中加入相應的命令行就成了。
在較慢速的其它外圍設備和內存的數據交換中,在網路通訊中,都需要使用Cache技術。推而廣之,凡是在傳輸速度有較大差異的設備之間,都可以利用Cache的速度匹配技術。結束語PC中的Cache主要是為了解決高速CPU和低速DRAM內存間速度匹配的問題,是提高系統性能,降低系統成本而採用的一項技術。隨著CPU和PC的發展,20年來,現在的Cache已成為CPU和PC不可缺少的組成部分,是廣大用戶衡量系統性能優劣的一項重要指標。據預測,在21世紀初期,CPU主頻加快發展的趨勢,加上內存DRAM的存取時間也會提高,從系統的性價比考慮,Cache的配備仍然是重要的技術之一。

㈣ 分布式鎖的三種實現方式

分布式鎖的三種實現方式分別是:基於資料庫實現分布式鎖、基於緩存(Redis等)實現分布式鎖、基於Zookeeper實現分布式鎖。

一、基於資料庫實現分布式鎖

1、悲觀鎖

利用select … where … for update 排他鎖。

注意:其他附加功能與實現一基本一致,這里需要注意的是「where name=lock 」,name欄位必須要走索引,否則會鎖表。有些情況下,比如表不大,mysql優化器會不走這個索引,導致鎖表問題。

2、樂觀鎖

所謂樂觀鎖與前邊最大區別在於基於CAS思想,是不具有互斥性,不會產生鎖等待而消耗資源,操作過程中認為不存在並發沖突,只有update version失敗後才能覺察到,搶購和秒殺就是用了這種實現以防止超賣,通過增加遞增的版本號欄位實現樂觀鎖。

二、基於緩存(Redis等)實現分布式鎖

1、使用命令介紹:

(1)SETNX

SETNX key val:當且僅當key不存在時,set一個key為val的字元串,返回1;若key存在,則什麼都不做,返回0。

(2)expire

expire key timeout:為key設置一個超時時間,單位為second,超過這個時間鎖會自動釋放,避免死鎖。

(3)delete

delete key:刪除key

在使用Redis實現分布式鎖的時候,主要就會使用到這三個命令。

2、實現思想:

(1)獲取鎖的時候,使用setnx加鎖,並使用expire命令為鎖添加一個超時時間,超過該時間則自動釋放鎖,鎖的value值為一個隨機生成的UUID,通過此在釋放鎖的時候進行判斷。

(2)獲取鎖的時候還設置一個獲取的超時時間,若超過這個時間則放棄獲取鎖。

(3)釋放鎖的時候,通過UUID判斷是不是該鎖,若是該鎖,則執行delete進行鎖釋放。

三、基於Zookeeper實現分布式鎖

ZooKeeper是一個為分布式應用提供一致性服務的開源組件,它內部是一個分層的文件系統目錄樹結構,規定同一個目錄下只能有一個唯一文件名。

基於ZooKeeper實現分布式鎖的步驟如下:

(1)創建一個目錄mylock。

(2)線程A想獲取鎖就在mylock目錄下創建臨時順序節點。

(3)獲取mylock目錄下所有的子節點,然後獲取比自己小的兄弟節點,如果不存在,則說明當前線程順序號最小,獲得鎖。

(4)線程B獲取所有節點,判斷自己不是最小節點,設置監聽比自己次小的節點。

(5)線程A處理完,刪除自己的節點,線程B監聽到變更事件,判斷自己是不是最小的節點,如果是則獲得鎖。

(4)緩存一致性鎖擴展閱讀;

一、資料庫分布式鎖實現的缺點:

1、db操作性能較差,並且有鎖表的風險。

2、非阻塞操作失敗後,需要輪詢,佔用cpu資源。

3、長時間不commit或者長時間輪詢,可能會佔用較多連接資源。

二、Redis(緩存)分布式鎖實現的缺點:

1、鎖刪除失敗,過期時間不好控制。

2、非阻塞,操作失敗後,需要輪詢,佔用cpu資源。

三、ZK分布式鎖實現的缺點:

性能不如redis實現,主要原因是寫操作(獲取鎖釋放鎖)都需要在Leader上執行,然後同步到follower。

㈤ 以道大數據課程體系都講什麼

大數據技術在如今應用非常廣泛,許多想入行學習大數據培訓的童鞋不知從何學起,從哪兒開始學首先要根據你的基本情況而定,如果你是零基礎的也不需要擔心,先從基礎開始學起就好了,接下來學習基礎java開始、數據結構、關系型資料庫、linux系統操作,夯實基礎之後,再進入大數據的學習,例如:hadoop離線分析、Storm實時計算、spark內存計算的學習,以道教育大數據課程體系可以如下:
第一階段 WEB 開發基礎
HTML基礎
1、Html基本介紹
2、HTML語法規范
3、基本標簽介紹
4、HTML編輯器/文本文檔/WebStrom/elipse
5、HTML元素和屬性
6、基本的HTML元素
6.1 標題
6.2 段落
6.3 樣式和style屬性
6.3 鏈接 a
6.4 圖像 img
6.5 表格 table
6.6 列表 ul/ol/dl
7、 HTML注釋
8、表單介紹
9、Table標簽
10、DIV布局介紹
11、HTML列表詳解
HTML布局和Bootstrap
1、 HTML塊元素(block)和行內元素(inline)
2、使用div實現網頁布局
3、響應式WEB設計(Responsive Web Design)
4、使用bootstrap實現響應式布局
HTML表單元素
1、HTML表單 form
2、HTML表單元素
3、 HTML input的類型 type
4、 Html input的屬性
CSS基礎
1、CSS簡介及基本語法
2、在HTML文檔中使用CSS
3、CSS樣式
4、CSS選擇器
5、盒子模型
6、布局及定位
CSS高級/CSS3
1、尺寸和對齊
2、分類(clear/cursor/display/float/position/visibility)
3、導航欄
4、圖片庫
5、圖片透明
6、媒介類型 @media
7、CSS3
8、CSS3動畫效果
JavaScript基礎
1、JavaScript簡介
2、基本語法規則
3、在HTML文檔中使用JS
4、JS變數
5、JS數據類型
6、JS函數
7、JS運算符
8、流程式控制制
9、JS錯誤和調試
JavaScript對象和作用域
1、數字 Number
2、字元串String
3、日期 Date
4、數組
5、數學 Math
6、DOM對象和事件
7、BOM對象
8、Window對象
9、作用域和作用域鏈
10、JSON
Javascript庫
1、Jquery
2、Prototype
3、Ext Js
Jquery
1、Jquery基本語法
2、Jquery選擇器
3、Jquery事件
4、Jquery選擇器
5、Jquery效果和動畫
6、使用Jquery操作HTML和DOM
7、Jquery遍歷
8、Jquery封裝函數
9、Jquery案例
表單驗證和Jquery Validate
1、用Js對HTML表單進行驗證
2、Jquery Validata基本用法
3、默認校驗規則和提示信息
4、debug和ignore
5、更改錯誤信息顯示位置和樣式
6、全部校驗通過後的執行函數
7、修改驗證觸發方式
8、非同步驗證
9、自定義校驗方法
10、radio 和 checkbox、select 的驗證
Java基礎
1、關於Java
2、Java運行機制
3、第一個Java程序,注釋
4、Javac,Java,Javadoc等命令
5、標識符與關鍵字
6、變數的聲明,初始化與應用
7、變數的作用域
8、變數重名
9、基本數據類型
10、類型轉換與類型提升
11、各種數據類型使用細節
12、轉義序列
13、各種運算符的使用
流程式控制制
1、選擇控制語句if-else
2、選擇控制語句switch-case
3、循環控制語句while
4、循環控制語句do-while
5、循環控制語句for與增強型for
6、break,continue,return
7、循環標簽
8、數組的聲明與初始化
9、數組內存空間分配
10、棧與堆內存
11、二維(多維)數組
12、Arrays類的相關方法
13、main方法命令行參數
面向對象
1、面向對象的基本思想
2、類與對象
3、成員變數與默認值
4、方法的聲明,調用
5、參數傳遞和內存圖
6、方法重載的概念
7、調用原則與重載的優勢
8、構造器聲明與默認構造器
9、構造器重載
10、this關鍵字的使用
11、this調用構造器原則
12、實例變數初始化方式
13、可變參數方法
訪問許可權控制
1、包 package和庫
2、訪問許可權修飾符private/protected/public/包訪問許可權
3、類的訪問許可權
4、抽象類和抽象方法
5、介面和實現
6、解耦
7、Java的多重繼承
8、通過繼承來擴展介面
錯誤和異常處理
1、概念:錯誤和異常
2、基本異常
3、捕獲異常 catch
4、創建自定義異常
5、捕獲所有異常
6、Java標准異常
7、使用finally進行清理
8、異常的限制
9、構造器
10、異常匹配
11、異常使用指南
資料庫基礎(MySQL)
資料庫基礎(MySQL)
JDBC
1、Jdbc基本概念
2、使用Jdbc連接資料庫
3、使用Jdbc進行crud操作
4、使用Jdbc進行多表操作
5、Jdbc驅動類型
6、Jdbc異常和批量處理
7、Jdbc儲存過程
Servlet和JSP
1、Servlet簡介
2、Request對象
3、Response對象
4、轉發和重定向
5、使用Servlet完成Crud
6、Session和Coolie簡介
7、ServletContext和Jsp
8、El和Jstl的使用
Ajax
1、什麼是Ajax
2、XMLHttpRequest對象(XHR)
3、XHR請求
4、XHR響應
5、readystate/onreadystatechange
6、Jquery Ajax
7、JSON
8、案例:對用戶名是否可用進行伺服器端校驗
綜合案例
1、項目開發一般流程介紹
2、模塊化和分層
3、DButils
4、QueryRunner
5、ResultSetHandle
6、案例:用戶登錄/注冊,從前端到後端
第二階段 Java SE
訪問許可權和繼承
1、包的聲明與使用
2、import與import static
3、訪問許可權修飾符
4、類的封裝性
5、static(靜態成員變數)
6、final(修飾變數,方法)
7、靜態成員變數初始化方式
8、類的繼承與成員繼承
9、super的使用
10、調用父類構造器
11、方法的重寫與變數隱藏
12、繼承實現多態和類型轉換
13、instanceof
抽象類與介面
1、抽象類
2、抽象方法
3、繼承抽象類
4、抽象類與多態
5、介面的成員
6、靜態方法與默認方法
7、靜態成員類
8、實例成員類
9、局部類
10、匿名類
11、eclipse的使用與調試
12、內部類對外圍類的訪問關系
13、內部類的命名
Lambda表達式與常用類
1、函數式介面
2、Lambda表達式概念
3、Lambda表達式應用場合
4、使用案例
5、方法引用
6、枚舉類型(編譯器的處理)
7、包裝類型(自動拆箱與封箱)
8、String方法
9、常量池機制
10、String講解
11、StringBuilder講解
12、Math,Date使用
13、Calendars使用
異常處理與泛型
1、異常分類
2、try-catch-finally
3、try-with-resources
4、多重捕獲multi-catch
5、throw與throws
6、自定義異常和優勢
7、泛型背景與優勢
8、參數化類型與原生類型
9、類型推斷
10、參數化類型與數組的差異
11、類型通配符
12、自定義泛型類和類型擦出
13、泛型方法重載與重寫
集合
1 、常用數據結構
2 、Collection介面
3 、List與Set介面
4 、SortedSet與NavigableSet
5 、相關介面的實現類
6 、Comparable與Comparator
7、Queue介面
8 、Deque介面
9 、Map介面
10、NavigableMap
11、相關介面的實現類
12、流操作(聚合操作)
13、Collections類的使用
I/O流與反射
1 、File類的使用
2 、位元組流
3 、字元流
4 、緩存流
5 、轉換流
6 、數據流
7、對象流
8、類載入,鏈接與初始化
9 、ClassLoader的使用
10、Class類的使用
11、通過反射調用構造器
12、安全管理器
網路編程模型與多線程
1、進程與線程
2、創建線程的方式
3、線程的相關方法
4、線程同步
5、線程死鎖
6、線程協作操作
7、計算機網路(IP與埠)
8、TCP協議與UDP協議
9、URL的相關方法
10、訪問網路資源
11、TCP協議通訊
12、UDP協議通訊
13、廣播
SSM-Spring
1.Spring/Spring MVC
2.創建Spring MVC項目
3.Spring MVC執行流程和參數
SSM-Spring.IOC
1.Spring/Spring MVC
2.創建Spring MVC項目
3.Spring MVC執行流程和參數
SSM-Spring.AOP
1.Spring/Spring MVC
2.創建Spring MVC項目
3.Spring MVC執行流程和參數
SSM-Spring.Mybatis
1.MyBatis簡介
2.MyBatis配置文件
3.用MyBatis完成CRUD
4.ResultMap的使用
5.MyBatis關聯查詢
6.動態SQL
7.MyBatis緩沖
8.MyBatis-Generator
Socket編程
1.網路通信和協議
2.關於Socket
3.Java Socket
4.Socket類型
5.Socket函數
6.WebSocket
7.WebSocket/Spring MVC/WebSocket Ajax
IO/非同步
window對象
全局作用域
窗口關系及框架
窗口位置和大小
打開窗口
間歇調用和超時調用(靈活運用)
系統對話框
location對象
navigator對象
screen對象
history對象
NIO/AIO
1.網路編程模型
2.BIO/NIO/AIO
3.同步阻塞
4.同步非阻塞
5.非同步阻塞
6.非同步非阻塞
7.NIO與AIO基本操作
8.高性能IO設計模式
第三階段 Java 主流框架
MyBatis
1.mybatis框架原理分析
2.mybatis框架入門程序編寫
3.mybatis和hibernate的本質區別和應用場景
4.mybatis開發方法
5.SqlMapConfig配置文件講解
6.輸入映射-pojo包裝類型的定義與實現
7.輸出映射-resultType、resultMap
8.動態sql
9.訂單商品數據模型分析
10.高級映射的使用
11.查詢緩存之一級緩存、二級緩存
12.mybatis與spring整合
13. mybatis逆向工程自動生成代碼
Spring/Spring MVC
1. springmvc架構介紹
2. springmvc入門程序
3. spring與mybatis整合
4. springmvc註解開發—商品修改功能分析
5. springmvc註解開發—RequestMapping註解
6. springmvc註解開發—Controller方法返回值
7. springmvc註解開發—springmvc參數綁定過程分析
8. springmvc註解開發—springmvc參數綁定實例講解
9. springmvc與struts2的區別
10. springmvc異常處理
11. springmvc上傳圖片
12. springmvc實現json交互
13. springmvc對RESTful支持
14. springmvc攔截器
第四階段 關系型資料庫/MySQL/NoSQL
SQL基礎
1.SQL及主流產品
2.MySQL的下載與安裝(sinux/windows)
3.MySql的基本配置/配置文件
4.基本的SQL操作 DDL
5.基本的SQL操作 DML
6.基本的SQL操作 DCL
7.MySQL客戶端工具
8.MySQL幫助文檔
MySQL數據類型和運算符
1 數值類型
2 日期時間類型
3 字元串類型
4 CHAR 和 VARCHAR 類型
5 BINARY 和 VARBINARY 類型
6 ENUM 類型
7 SET 類型
8 算術運算符
9 比較運算符
10 邏輯運算符
11 位運算
12 運算符的優先順序
MySQL函數
1 字元串函數
2 數值函數
3 日期和時間函數
4 流程函數
5 其他常用函數
MySQL存儲引擎
1.MySQL支持的存儲引擎及其特性
2.MyISAM
3.InnoDB
4.選擇合適的存儲引擎
選擇合適的數據類型
1 CHAR 與 VARCHAR
2 TEXT 與 BLOB
3 浮點數與定點數
4 日期類型選擇
字元集
1 字元集概述
2 Unicode字元集
3 漢字及一些常見字元集
4 選擇合適的字元集
5 MySQL 支持的字元集
6 MySQL 字元集的設置 .
索引的設計和使用
1.什麼是索引
2.索引的類型
3.索引的數據結構 BTree B+Tree Hash
4.索引的存儲
5.MySQL索引
6.查看索引的使用情況
7.索引設計原則
視圖/存儲過程/函數/觸發器
1. 什麼是視圖
2. 視圖操作
3. 什麼是存儲過程
4. 存儲過程操作
5. 什麼是函數
6. 函數的相關操作
7. 觸發器
事務控制/鎖
1. 什麼是事務
2. 事務控制
3. 分布式事務
4. 鎖/表鎖/行鎖
5. InnoDB 行鎖爭用
6. InnoDB 的行鎖模式及加鎖方法7
7 InnoDB 行鎖實現方式7
8 間隙鎖(Next-Key 鎖)
9 恢復和復制的需要,對 InnoDB 鎖機制的影響
10 InnoDB 在不同隔離級別下的一致性讀及鎖的差異
11 表鎖
12 死鎖
SQL Mode和安全問題
1. 關於SQL Mode
2. MySQL中的SQL Mode
3. SQL Mode和遷移
4. SQL 注入
5. 開發過程中如何避免SQL注入
SQL優化
1.通過 show status 命令了解各種 SQL 的執行頻率
2. 定位執行效率較低的 SQL 語句
3. 通過 EXPLAIN 分析低效 SQL 的執行計劃
4. 確定問題並採取相應的優化措施
5. 索引問題
6.定期分析表和檢查表
7.定期優化表
8.常用 SQL 的優化
MySQL資料庫對象優化
1. 優化表的數據類型
2 散列化
3 逆規范化
4 使用中間表提高統計查詢速度
5. 影響MySQL性能的重要參數
6. 磁碟I/O對MySQL性能的影響
7. 使用連接池
8. 減少MySQL連接次數
9. MySQL負載均衡
MySQL集群
MySQL管理和維護
MemCache
Redis
在Java項目中使用MemCache和Redis
第五階段:操作系統/Linux、雲架構
Linux安裝與配置
1、安裝Linux至硬碟
2、獲取信息和搜索應用程序
3、進階:修復受損的Grub
4、關於超級用戶root
5、依賴發行版本的系統管理工具
6、關於硬體驅動程序
7、進階:配置Grub
系統管理與目錄管理
1、Shell基本命令
2、使用命令行補全和通配符
3、find命令、locate命令
4、查找特定程序:whereis
5、Linux文件系統的架構
6、移動、復制和刪除
7、文件和目錄的許可權
8、文件類型與輸入輸出
9、vmware介紹與安裝使用
10、網路管理、分區掛載
用戶與用戶組管理
1、軟體包管理
2、磁碟管理
3、高級硬碟管理RAID和LVM
4、進階:備份你的工作和系統
5、用戶與用戶組基礎
6、管理、查看、切換用戶
7、/etc/...文件
8、進程管理
9、linux VI編輯器,awk,cut,grep,sed,find,unique等
Shell編程
1、 SHELL變數
2、傳遞參數
3、數組與運算符
4、SHELL的各類命令
5、SHELL流程式控制制
6、SHELL函數
7、SHELL輸入/輸出重定向
8、SHELL文件包含
伺服器配置
1、系統引導
2、管理守護進程
3、通過xinetd啟動SSH服務
4、配置inetd
5、Tomcat安裝與配置
6、MySql安裝與配置
7、部署項目到Linux
第六階段:Hadoop生態系統
Hadoop基礎
1、大數據概論
2、 Google與Hadoop模塊
3、Hadoop生態系統
4、Hadoop常用項目介紹
5、Hadoop環境安裝配置
6、Hadoop安裝模式
7、Hadoop配置文件
HDFS分布式文件系統
1、認識HDFS及其HDFS架構
2、Hadoop的RPC機制
3、HDFS的HA機制
4、HDFS的Federation機制
5、 Hadoop文件系統的訪問
6、JavaAPI介面與維護HDFS
7、HDFS許可權管理
8、hadoop偽分布式
Hadoop文件I/O詳解
1、Hadoop文件的數據結構
2、 HDFS數據完整性
3、文件序列化
4、Hadoop的Writable類型
5、Hadoop支持的壓縮格式
6、Hadoop中編碼器和解碼器
7、 gzip、LZO和Snappy比較
8、HDFS使用shell+Java API
MapRece工作原理
1、MapRece函數式編程概念
2、 MapRece框架結構
3、MapRece運行原理
4、Shuffle階段和Sort階段
5、任務的執行與作業調度器
6、自定義Hadoop調度器
7、 非同步編程模型
8、YARN架構及其工作流程
MapRece編程
1、WordCount案例分析
2、輸入格式與輸出格式
3、壓縮格式與MapRece優化
4、輔助類與Streaming介面
5、MapRece二次排序
6、MapRece中的Join演算法
7、從MySQL讀寫數據
8、Hadoop系統調優
Hive數據倉庫工具
1、Hive工作原理、類型及特點
2、Hive架構及其文件格式
3、Hive操作及Hive復合類型
4、Hive的JOIN詳解
5、Hive優化策略
6、Hive內置操作符與函數
7、Hive用戶自定義函數介面
8、Hive的許可權控制
Hive深入解讀
1 、安裝部署Sqoop
2、Sqoop數據遷移
3、Sqoop使用案例
4、深入了解資料庫導入
5、導出與事務
6、導出與SequenceFile
7、Azkaban執行工作流
Sqoop與Oozie
1 、安裝部署Sqoop
2、Sqoop數據遷移
3、Sqoop使用案例
4、深入了解資料庫導入
5、導出與事務
6、導出與SequenceFile
7、Azkaban執行工作流
Zookeeper詳解
1、Zookeeper簡介
2、Zookeeper的下載和部署
3、Zookeeper的配置與運行
4、Zookeeper的本地模式實例
5、Zookeeper的數據模型
6、Zookeeper命令行操作範例
7、storm在Zookeeper目錄結構
NoSQL、HBase
1、HBase的特點
2、HBase訪問介面
3、HBase存儲結構與格式
4、HBase設計
5、關鍵演算法和流程
6、HBase安裝
7、HBase的SHELL操作
8、HBase集群搭建
第七階段:Spark生態系統
Spark
1.什麼是Spark
2.Spark大數據處理框架
3.Spark的特點與應用場景
4.Spark SQL原理和實踐
5.Spark Streaming原理和實踐
6.GraphX SparkR入門
7.Spark的監控和調優
Spark部署和運行
1.WordCount准備開發環境
2.MapRece編程介面體系結構
3.MapRece通信協議
4.導入Hadoop的JAR文件
5.MapRece代碼的實現
6.打包、部署和運行
7.打包成JAR文件
Spark程序開發
1、啟動Spark Shell
2、載入text文件
3、RDD操作及其應用
4、RDD緩存
5、構建Eclipse開發環境
6、構建IntelliJ IDEA開發環境
7、創建SparkContext對象
8、編寫編譯並提交應用程序
Spark編程模型
1、RDD特徵與依賴
2、集合(數組)創建RDD
3、存儲創建RDD
4、RDD轉換 執行 控制操作
5、廣播變數
6、累加器
作業執行解析
1、Spark組件
2、RDD視圖與DAG圖
3、基於Standalone模式的Spark架構
4、基於YARN模式的Spark架構
5、作業事件流和調度分析
6、構建應用程序運行時環境
7、應用程序轉換成DAG
Spark SQL與DataFrame
1、Spark SQL架構特性
2、DataFrame和RDD的區別
3、創建操作DataFrame
4、RDD轉化為DataFrame
5、載入保存操作與Hive表
6、Parquet文件JSON數據集
7、分布式的SQL Engine
8、性能調優 數據類型
深入Spark Streaming
1、Spark Streaming工作原理
2、DStream編程模型
3、Input DStream
4、DStream轉換 狀態 輸出
5、優化運行時間及內存使用
6、文件輸入源
7、基於Receiver的輸入源
8、輸出操作
Spark MLlib與機器學習
1、機器學習分類級演算法
2、Spark MLlib庫
3、MLlib數據類型
4、MLlib的演算法庫與實例
5、ML庫主要概念
6、演算法庫與實例
GraphX與SparkR
1、Spark GraphX架構
2、GraphX編程與常用圖演算法
3、GraphX應用場景
4、SparkR的工作原理
5、R語言與其他語言的通信
6、SparkR的運行與應用
7、R的DataFrame操作方法
8、SparkR的DataFrame
Scala編程開發
1、Scala語法基礎
2、idea工具安裝
3、maven工具配置
4、條件結構、循環、高級for循環
5、數組、映射、元組
6、類、樣例類、對象、伴生對象
7、高階函數與函數式編程
Scala進階
1、 柯里化、閉包
2、模式匹配、偏函數
3、類型參數
4、協變與逆變
5、隱式轉換、隱式參數、隱式值
6、Actor機制
7、高級項目案例
Python編程
1、Python編程介紹
2、Python的基本語法
3、Python開發環境搭建
4、Pyhton開發Spark應用程序
第八階段:Storm生態系統
storm簡介與基本知識
1、storm的誕生誕生與成長
2、storm的優勢與應用
3、storm基本知識概念和配置
4、序列化與容錯機制
5、可靠性機制—保證消息處理
6、storm開發環境與生產環境
7、storm拓撲的並行度
8、storm命令行客戶端
Storm拓撲與組件詳解
1、流分組和拓撲運行
2、拓撲的常見模式
3、本地模式與stormsub的對比
4、 使用非jvm語言操作storm
5、hook、組件基本介面
6、基本抽象類
7、事務介面
8、組件之間的相互關系
spout詳解 與bolt詳解
1、spout獲取數據的方式
2、常用的spout
3、學習編寫spout類
4、bolt概述
5、可靠的與不可靠的bolt
6、復合流與復合anchoring
7、 使用其他語言定義bolt
8、學習編寫bolt類
storm安裝與集群搭建
1、storm集群安裝步驟與准備
2、本地模式storm配置命令
3、配置hosts文件、安裝jdk
4、zookeeper集群的搭建
5、部署節點
6、storm集群的搭建
7、zookeeper應用案例
8、Hadoop高可用集群搭建
Kafka
1、Kafka介紹和安裝
2、整合Flume
3、Kafka API
4、Kafka底層實現原理
5、Kafka的消息處理機制
6、數據傳輸的事務定義
7、Kafka的存儲策略
Flume
1、Flume介紹和安裝
2、Flume Source講解
3、Flume Channel講解
4、Flume Sink講解
5、flume部署種類、流配置
6、單一代理、多代理說明
7、flume selector相關配置
Redis
1、Redis介紹和安裝、配置
2、Redis數據類型
3、Redis鍵、字元串、哈希
4、Redis列表與集合
5、Redis事務和腳本
6、Redis數據備份與恢復
7、Redis的SHELL操作

㈥ 英偉達nvidia如何設置效果最好

  1. 滑鼠在桌面單擊右鍵,點擊配置可交換NVIDIA卡。

    ㈦ volitate 原理

    volatile保證多線程可見性,volatile修飾的變數不會引起上下文切換和調度
    cpu緩存,cpu運算速度與內存讀寫不匹配,因為cpu運算速度比內存讀寫快的多
    從主內存中獲取或者寫入數據會花費很長時間,現在大多數cpu都不會直接訪問內存,而是訪問cpu緩存,cpu緩存是cpu與主內存之間的臨時存儲器,容量小,交換速度快,緩存中的數據是內存中的一小部分數據,是cpu即將訪問的。當cpu調用大量數據時候,就先從緩存中讀取從而加快讀取速度
    按照讀取順序與cpu結合的緊密程度,cpu緩存分為
    一級緩存:L1位於cpu內核旁邊,是與cpu結合最為緊密的cpu緩存
    二級緩存:L2分為內部和外部兩種晶元,內部晶元二級緩存運行速度與主頻相同,外部晶元二級緩存運行速度則只有主頻的一半
    三級緩存,只有高端的cpu才有
    每一級緩存中所存儲的數據都是下一級緩存中存儲的數據的一部分
    cpu要讀取一個數據的時候,首先從一級緩存中查找,如果沒有就從二級中查找,如果還沒有就從三級緩存中或者是內存總進行查找,一般來說,每級緩存的命中率大概有0.8左右,也就是全部數據量的0.8可以在一級緩存中查到,只有剩下的0.2總數據量從二級緩存中或者是三級緩存或者是內存中讀取

    緩存行:緩存是分line的,一個段對應一個緩存行,是cpu緩存種可分配的最小存儲單元,通常是64位元組:當cpu看到一條讀取內存的指令的時候,會把內存地址傳遞給一級緩存,一級緩存會檢查它是否有這個內存地址對應的緩存段,如果沒有就把整個緩存段從內存共或者更高級的緩存種載入進來。
    cpu執行計算的過程為:程序和數據被載入到主內存中,指令和數據被載入到cpu緩存中,cpu執行指令將結果寫入cpu緩存中,cpu緩存中的數據寫回到主內存中,但是這種方式僅限於單核cpu的時候
    如果伺服器是多核cpu呢,
    多核處理器中主內存核處理器一樣是分開的,這時候,L3作為統一的高速緩存共享,處理器1擁有自己的L1 L2

    這個時候當核0讀取了一個位元組根據局部性原理,與他相鄰的位元組同樣會被讀入核0的緩存中
    核3也讀取了同樣的一個位元組,根據局部性原理,與他相鄰的位元組同樣會被讀入到核3的數據中
    此時,核0和核3的緩存中擁有同樣的數據
    核0修改了那個位元組之後,被修改後那個位元組被回寫到了核0的緩存中,但是該信息並沒有回寫到主內存
    當核3訪問該數據的時候,造成該數據不同步
    為了解決這個問題**,當一個cpu修改緩存中的位元組的時候,**伺服器中其他cpu的會被通知他們的緩存將是為無效,這樣核1在修改緩存中的數據的時候,核3會發現自己的緩存中的數據已經無效,核0將自己的寫回到主內存中,然後核3將重新讀取該數據
    將代碼轉化為匯編指令的時候發現在匯編指令add之前有一個lock指令,lock指令就是關鍵。
    lock指令的作用:在修改內存的時候使用lock前綴指令調用加鎖的讀修改寫操作,保證多處理器系統總處理器之間進行可靠的通訊
    1.鎖匯流排,其他cpu對內存的讀寫請求會被阻塞,直到鎖釋放,不過實際候來的處理器都採用了緩存緩存代替鎖匯流排,因為匯流排開銷過大,鎖匯流排的時候其他cpu沒辦法訪問內存
    2.lock後的寫操作會回寫已經修改的數據,同時讓其他cpu相關緩存行失效,從而重新從內存中載入最新的數據
    3.不是內存屏障卻能完成內存屏障的功能,阻止屏障兩邊的指令重排序

    嗅探式的緩存一致性協議:所有內存的傳輸都發生在一條共享的匯流排上,而所有的處理器都能看到這條匯流排,緩存本身是獨立的,但是內存是共享的。所有的內存訪問都要進行仲裁,即同一個指令周期種只有一個cpu緩存可以讀寫數據。cpu緩存不僅在內存傳輸的時候與匯流排打交道,還會不斷的在嗅探匯流排上發生數據交換跟蹤其他緩存在做什麼,所以當一個cpu緩存代表它所屬的處理器讀寫內存的時候,其他的處理器都會得到通知(主動通知),他們以此使自己的緩存保存同步。只要某個處理器寫內存,其他處理器就馬上直到這塊內存在他們的緩存段種已經失效。。
    MESI協議是緩存一致性協議,在MESI協議中每個緩存行有四個狀態,Modified修改的,表示這行數據有效,數據被修改了和內存中的數據不一致,數據只存在當前cache中,Exclusive獨有的,這行數據有效,數據和內存中的數據一致,數據只存在在本cache中,Shared共享的,這行數據有效,數據和內存中的數據一致,數據存在很多cache中,Invalid這行數據無效,這里的Invalid shared modified都符合我們的嗅探式的緩存一致性協議,但是Exclusive表示獨占的,當前數據有效並且和內存中的數據一致,但是只在當前緩存中,Exclusive狀態解決了一個cpu緩存在讀寫內存的之前我們要通知其他處理器這個問題,只有當緩存行處於Exclusive和modified的時候處理器才能寫,也就是說只有在這兩種狀態之下,處理器是獨占這個緩存行的,當處理器想寫某個緩存行的時候,如果沒有獨占權就必須先發送一條我要獨占權的請求給匯流排,這個時候會通知處理器把他們擁有同一緩存段的拷貝失效,只要在獲得獨占權的時候處理器才能修改數據並且此時這個處理器直到這個緩存行只有一份拷貝並且只在它的緩存里,不會有任何沖突,反之如果其他處理器一直想讀取這個緩存行(馬上就能直到,因為一直在嗅探匯流排),獨占或已修改的緩存行必須要先回到共享狀態,如果是已經修改的緩存行,還要先將內容回寫到內存中。

    volatile變數的讀寫
    工作內存其實就是cpu緩存,當兩條線程同時操作主內存中的一個volatile變數時候,A線程寫了變數i,此時A線程發出lock指令,發出的lock指令鎖匯流排或者鎖緩存行,同時線程b的高速緩存中的緩存行內容失效,線程A想內存中回寫最新的i。當線程B讀取變數的時候,線程發現對應地址的緩存行被鎖了等待鎖釋放,鎖的一致性協議會保證它讀取到最新的值。

    ㈧ oracle 11g rac 哪個版本能裝在2012

    RAC
    在Grid Infrastructure安裝完以後,我們把注意力轉移到集群上的Oracle軟體的安裝上來。我們看到,Grid Infrasctructure提供了運行RAC的框架,包括集群通訊鏈接、節點分離、節點成員關系等服務。ASM是Oracle存儲資料庫的首選方式。RAC利用這些概念並擴展了需要的基本服務。
    安裝選項
    成功安裝了Grid Infrastructure/Clusterware以後,Oracle Universal Installer檢測到集群環境的建立,然後提供安裝整個集群上或是用戶指定其中幾個節點的RAC選項。使用集群檢驗工具cluvfy來為RDBMS的安裝檢測是否滿足先決條件是良好的做法。和安裝集群一樣,Oracle Universal Installer將首先在第一個節點上對軟體進行拷貝和鏈接,然後將Oracle主目錄push到指定的其他節點中。和Grid Infrastructure不同的是,Oracle RDBMS可以被安裝在共享文件系統上(例如OCFS2或ACFS上),在集群中增加新節點被簡化,因為不需要在新的節點上重新安裝軟體,打補丁同樣被簡化了--只有一個Oracle主目錄需要打補丁。但是補丁不能以rolling方式安裝,因此停機時間不可避免。
    在安裝過程中,Oracle Universal Installer將提醒管理員安裝或升級資料庫,或只安裝軟體。如果安裝的時候有新的版本發布,那麼僅僅安裝軟體,打補丁升級後再創建資料庫是比較好的做法。
    單實例和RAC資料庫
    RAC和單實例資料庫在很多重要方面都有所不同。
    在RAC中,一個資料庫在共享存儲中為多個伺服器上的實例所訪問。資料庫文件、在線redo文件、控制文件和伺服器參數文件(spfile)都必須共享。此外,閃回日誌、已歸檔的redo日誌、數據泵轉儲文件、和dataguard broker配置文件也可以共享,根據你的配置來決定(這是可選的,但還是強烈建議這么做)。在使用ASM的時候,你同樣可以在每個RAC的節點中找到一個本地的pfile文件,這個文件指向對應磁碟組中的spfile。另一個存儲在本地的文件是Oracle密碼文件。集群文件系統中的用戶常常把這些文件放在一個共享的位置,通過符號鏈接指向$ORACLE_HOME/dbs資料庫文件
    資料庫文件包含資料庫中的所有數據,包括表、索引、數據字典和經過編譯的PL/SQL代碼,不勝枚舉。在RAC中,每個數據文件都只有一個拷貝,位於共享存儲中,並為所有實例所訪問。Oracle默認不為數據文件提供鏡像,大部分用戶選擇在存儲層面來做冗餘,避免介質故障導致的數據丟失。在存儲陣列沒有這個功能時,可以使用Oracle ASM來提供冗餘。
    控制文件
    控制文件儲存資料庫的物理結構的相關信息,包括它們的狀態。如果你使用RMAN且沒有專門的RMAN catalog資料庫,控制文件中也可以儲存RMAN備份的信息。在單實例資料庫和RAC中,控制文件應該做鏡像以防止損壞或存儲故障。當同時使用ASM和閃回恢復區時,會自動做多路復用。默認情況下,Oracle在db_create_file_dest和db_recovery_file_dest指定的磁碟組中對控制文件做多路復用。這種情況下,若你使用spfile,control_files參數將自動更新。要知道控制文件會成為RAC中的一個爭用點,因為它們會被頻繁更新。因此不要對控制文件做過多的鏡像拷貝,而且應該把它們放置在高速存儲上。
    REDO和歸檔
    在RAC中,每個實例有它自己的聯機日誌文件,稱為線程(thread)。線程的信息可以在V$LOG和相關的視圖中查看。
    每個線程中你需要兩組redo日誌,而且若沒有使用ASM和閃回恢復區,你應該考慮手動對組中的成員做多路復用。由spfile負責實例和線程間的映射(通過初始化參數thread)。當添加一個新的實例到集群中時,就需要一個相應的redo線程,這可以使用兩種方式來做到:第一種,執行SQL語句alter database add logfile group x thread y; 第二種,在使用策略管理的資料庫(policy-managed)中,會自動創建。然後由Oracle來啟用。
    lgwr後台進程將redo buffer刷新到redo log中。online redo log需要放在高速存儲中,否則它可能會成為一個爭用的點,特別是在一個高頻率提交的系統中。通常對設計不合理的應用的優化是減少commit的頻率,並至少將redo log和控制文件移到高速存儲中,以減少一些性能瓶頸。在日誌切換頻繁的系統中,增加每個線程的重做日誌組數會有所幫助,它能給歸檔進程更多的時間來歸檔redo日誌。這種方法在歸檔進程需要將歸檔的redo傳送到standby資料庫中時也能獲益,但是,現在的大部分系統採用Log Network Service(LNSn)進程來非同步傳送redo給standby資料庫的Remote File Server(RFS)進程。在Oracle 10.2和11.1中,每個destination有一個LNS進程,到了11.2,LNSn進程被NSSn何NSAn後台進程所代替。NSSn進程被用來同步傳送redo,NSAn用來非同步傳送redo。redo log大小設置的原則是,日誌切換不會太頻繁(AWR和statspack能夠幫助定義一個合適的大小)。Oracle 11.2還允許管理員來選擇redo log的塊大小,現代存儲單元使用4kb扇區大小代替了原先的512b。
    當RAC中的一個實例發生故障,所有線程被合並來幫助建立恢復集,由伺服器監控進程來執行前滾或回滾操作。
    在lgwr進程將一個redo log寫滿以後,其中一個歸檔進程會將該文件拷貝到指定的目錄中。
    閃回恢復區在Oracle 10.1中引入,看是來是歸檔日誌的最佳存放位置。如果你沒有使用閃回恢復區,建議將歸檔日誌放在一個共享文件系統中,以便每個節點都可以訪問到。與單實例資料庫不同,RAC需要所有線程的歸檔日誌。當一個實例執行介質恢復時,你可以從它的alter日誌上看到,Oracle使用了每個線程的所有日誌文件。
    Undo表空間
    和redo線程類似,每個集群資料庫的實例由它自己的undo表空間。spfile中配置了實例和undo表空間之間的一對一映射關系。但這個映射並不代表該undo表空間就長期綁定在該實例上,所有的其他實例同樣可以訪問該undo表空間來創建塊的讀一致前鏡像。
    當添加一個實例到集群中時,需要添加新的undo表空間並映射到該實例,和redo log一樣。在policy-managed資料庫中,Oracle可以自己來做這件事。
    雖然還是可以使用手動的undo管理,但是強烈建議使用自動undo管理(AUM)。
    RAC資料庫的存儲選項
    管理員可以在如下的選項中選擇:
    ASM 這是Oracle的首選存儲選項,而且是RAC標准版中支持的唯一配置OCFS2
    裸設備 不推薦使用,不僅是因為被新版的linux內核棄用,在Oracle 11.2中同樣不支持網路文件系統(NFS)
    Red Hat Global File System 只在紅帽和Oracle Enterprise Linux中支持,可以用在閃回恢復區和資料庫文件上RAC實例
    一個RAC資料庫包含2個或更多的實例,一般每個實例都在不同的節點上,由一些共享內存結構和後台進程組成。
    每個實例都有自己的SGA,在實例啟動的時候分配。Oracle在10g中引入了自動共享內存管理(ASMM),在11g中引入了自動內存管理(AMM)。但是AMM與linux的大頁面不兼容,這對大內存的系統來說是個問題。
    Oracle需要同步訪問本地共享內存和整個集群。所有實例都能訪問其他實例的SGA。
    在RAC中Oracle內核對共享內存的保護措施和單實例中是一樣的,同樣使用了閂和鎖。閂是一個低級別、輕量級的串列裝置。請求閂的進程不會排隊,如果進程不能獲得閂,它就會進入spin狀態。spin的意思是,這個進程會進入一個緊密循環來預防被操作系統的調度程序從CPU中取下。如果一個進程長時間得不到閂,它會進入睡眠,在一個時間間隔後再次嘗試申請。閂是實例級別的,沒有集群范圍的閂。
    另一方面,鎖在更長的時間請求一次,比閂更為復雜。鎖可以是共享或獨占的,請求鎖的進程以先進先出(FIFO)的機制來等待,由隊列來控制鎖的訪問,這個隊列是集群范圍內的。
    緩存一致性的需求意味著鎖和閂在RAC中比單實例要更加復雜。和單實例中一樣,對buffer cache中資料庫的訪問和隊列必須在本地實例中管理,但是,遠程實例的訪問也需要管理。因為這個原因,Oracle使用全局資源目錄(GRD)和一些額外的後台進程。
    (Oracle將V$視圖加上實例標識組合起來形成GV$視圖,一個GV$視圖包含了集群中所有實例的動態性能視圖)全局資源目錄 (GRD)
    RAC中使用了一些附加的後台進程來做緩存間的同步——記住RAC使用cache fusion結構來模擬一個橫跨集群內所有節點的全局SGA。訪問buffer cache中的塊需要在讀一致和寫的訪問間進行協調,共享資源的隊列現在也是在集群全局上的。全局緩存服務(Global Cache Service GCS)用來對公共buffer cache的訪問,全局隊列服務(Global Enqueue Service GES)用來管理集群中的隊列。
    GCS和GES對應用而言都是透明的。內部使用的原結構就是先前提到的GRD,由GCS和GES進程來維護。GRD分布在集群的所有節點上,是SGA的一部分,這就是為什麼一個RAC資料庫的SGA比同等情況下的單實例資料庫要來得大。資源管理由GCS和GES來協商。特定的資源完全由一個實例來管理,這個實例就是resource master。但它並是不固定的,Oracle 9.2以後的版本實現了動態的資源管理(DRM),在9.2以前,資源的remastering只發生在實例故障、GRD重建的時候。新的版本中,如果Oracle檢測到一個resource master以外的實例在一個給定的時間間隔中對一個特定的資源的訪問過於頻繁,就會發生resource mastering。在這種情況下,該資源就會被remaster到其他節點上,也就是說,頻繁訪問該資源的另一個節點將成為resource master。很多用戶反饋了動態remastering的一些問題,當它過於頻繁發生的時候會造成一些不必要的開支。這種情況下,可以禁用DRM。
    (GRD還記錄了哪些資源由哪些實例來管理,當一個實例發生故障時,恢復起來將非常方便)下圖說明GCS如何與GES協同工作來維護GRD
    全局緩存服務(GCS)
    LMSn後台進程使用GCS在全局buffer cache中維護緩存的一致性,SGA中可以存在同一個數據塊的多份拷貝(當前版本只有一個),GCS對數據塊的狀態和位置進行跟蹤,並通過內部連接將塊傳輸到其他節點的實例中。
    全局隊列服務(GES)
    和GCS類似,GES工作在塊級別,管理集群中的全局隊列。根據經驗,如果一個操作沒有涉及在全局buffer cache中控制/移動數據塊,那麼很可能是經過了GES的處理。全局隊列服務負責所有的實例中的資源操作,比如對數據字典和庫緩存的訪問或事務的全局管理。它同樣可以檢測集群中的死鎖。它跟蹤多個實例同時訪問資源時Oracle隊列機制的狀態。全局隊列服務監控(LMON)和全局隊列服務後台進程(LMD)組成全局隊列服務的一部分。鎖進程LCK0負責無緩存方式的訪問,比如library和row cache請求。
    緩存融合(Cache Fusion)
    緩存融合是實例間數據傳送的最新演變。Oracle 8i中曾使用block ping的機制,作為替代,Oracle使用高速的內部連接來為所有節點間的讀寫轉移數據塊。
    實例間使用block ping方法來轉移數據塊代價是很昂貴的,它建議你將工作量與實例聯系在一起來使實例間的數據塊轉移達到最少。在Oracle並行伺服器(Oracle Parallel Server)中,當一個實例請求一個數據塊來進行修改,而這個數據塊當前正由別的實例所持有,它將發出一個信號給持有該塊的實例,使其將塊寫入到磁碟,再發回該塊已經可讀的信號。這種方法的通訊和對磁碟的讀寫操作的量很不盡如人意。
    緩存融合的塊轉移依賴於全局資源目錄,不需要超過3次跳躍(hop),這與安裝及節點的個數有關。很明顯,如果一個集群只有兩個節點,那麼有一個雙向的緩存轉移。如果多於2個節點,將跳躍數限制在3次是必要的。Oracle使用專用的等待事件來衡量涉及緩存的通訊,根據實際情況來決定做一個雙向或是三向的緩存轉移。
    當一個實例通過緩存融合來請求一個數據塊時,它首先與資源的master聯系來確定這個資源的當前狀態,如果這個資源沒有正在被使用,那麼它可以通過從本地磁碟讀取以獲得這個塊。如果這個資源正在被使用,那麼該資源master將把這個資源傳遞到發出請求的實例中。如果這個資源緊接著收到1個或多個實例的修改請求,將會把該資源添加進GRD,資源的master、請求者和持有者都可以不同,這種情況下最多需要三次跳躍來獲得這個塊。
    上面提到的雙向和三向的塊轉移與資源的管理方式有關。當資源的master持有被請求的資源,那麼對數據塊的請求就能馬上得到滿足並開始塊的傳輸,這就是雙向的通訊。在三向的情況中,請求者、master和持有者都不相同,那麼該資源master需要轉發這個請求,引發了新的跳躍。
    從剛才的討論中,你可以知道在全局buffer cache中對塊和它們影像間協調是不能低估的。在RAC資料庫中,緩存融合常常代表了最大的利益和最高的成本。好處是緩存融合理論上運行按比例增大,並可能取得近乎線性的擴展性。然而,緩存融合強加的額外工作量可能會在10%-20%的范圍內。
    讀一致性
    Oracle資料庫的主要特徵之一就是能同時提供不同視野下的數據,這個特徵叫做多版本讀一致。查詢是讀一致的,寫不會阻塞讀,反之亦然。當然,多版本讀一致對RAC一樣有效,但涉及到一點其他的工作。
    System Change Number(SCN)是一個Oracle的內部時間戳,對讀一致非常重要。如果本地實例請求一個塊的讀一致版本,它需要聯系這個塊的resource master來確定這個塊是否有相同SCN的版本,或者更新的版本存在於某個遠程實例的buffer cache中。如果這個塊存在,那麼resource master會發送請求給相應的遠程實例來轉發這個塊的讀一致版本給本地實例。如果遠程實例持有這個塊的請求時間SCN的版本,那麼它會馬上發送這個塊。如果遠程實例持有的是這個塊更新的版本,它將創建這個塊的拷貝(稱為前鏡像),並對這個拷貝應用回滾使其回到對應的SCN的狀態,然後將其通過內部連接發送。
    System Change Number(SCN)
    SCN是Oracle資料庫產生和使用的內部時間戳,資料庫中發生的所有事件都以SCN標記,事務也一樣。Oracle的讀一致嚴重依賴於SCN和undo表空間中的信息。SCN需要在集群中同步,RAC中用來使SCN在所有節點間通用的方案有兩個:broadcast-on-commit和Lamport。
    broadcast-on-commit是10.2以後的默認方案,它解決了Lamport方案的一個問題:在以前,這個默認方案是Lamport,它承諾了更好的擴展性,讓SCN像集群其他通訊一樣來傳播,但並不是在一個節點中commit後馬上發生。這在大部分情況下都能滿足要求,但是,Lamport方案有一個問題:一個節點的SCN相對另一個節點的SCN有延時是可能的,特別是在在消息傳送不活躍的時候。這種SCN的延時意味著在一個節點上提交的事務從另一個延時的實例上「看起來」會有點太新了。
    另一方面,broadcast-on-commit方案更加資源集中一點。LGWR進程在每次commit之後更新全局的SCN並將其廣播到所有的其他實例中。在RAC11.1中,初始化參數max_commit_propagation_delay允許資料庫管理員來修改默認的設定,這個參數在11.2中被移除。

    ㈨ 為何Redis用樂觀鎖,而MySQL資料庫卻沒有

    簡單來說,Redis使用樂觀鎖,相對於悲觀鎖,在實現中更加簡單,在某些場景中的性能也更好。Redis作為一個輕量級的、快速的緩存引擎,而不是一個全功能的關系型資料庫,既沒有使用悲觀鎖的必要,也難以承受使用悲觀鎖的成本。
    詳細來說,要深入到Redis和MySQL的事務處理機制。Redis關於事務的文檔見此:
    Transactions(事務)
    Redis對於事務只提供了非常有限的支持,其實更多地是試圖繞過問題。
    首先,Redis對於同一事務中的一組操作,而不是立即執行,而是放入一個queue中,當執行到EXEC時,再一起執行。事務執行是全局獨占的,也就是同一時間只有一個事務被執行,中途不能被其它事務打斷。Redis用這種最簡單的、也是性能最差的方式避免了race
    condition。
    其次,在Redis的事務中,如果有一個或多個操作失敗,其它操作仍然會成功,也就是說它根本沒有回滾機制。
    這種方式會帶來很多嚴重的問題,其中之一是,無法先讀取某個數值後再進行依賴這個值的操作,因為放在一個事務里會被在同一個瞬間執行,不放在同一個事務里又會導致race
    condition。解決方法是使用WATCH,它會監視一個或多個變數,如果變數的值在調用WATCH以後和事務提交之前被別的事務修改過了,整個事務都會失敗。這類似於操作系統中的CAS(Compare
    and
    Set)。我不知道WATCH具體是怎麼實現的,但是我推測它監控了指定變數的版本號。
    即使有了WATCH,Redis的事務也是受到嚴重限制的。第一,它沒有實現讀數據時的一致性,因為WATCH對於讀操作不起作用。第二,它不支持回滾。第三,在對同一變數存在大量並發寫操作時,性能會非常差,因為每次提交事務時,WATCH監控的變數都已經被修改了,導致事務將多次提交失敗。但是,Redis本來就是一個KV類型的緩存引擎,要處理的是大量讀少量寫的場景,對一致性也沒有要求。
    MySQL就完全不一樣了,作為一個典型的關系型資料庫,它需要完整地實現ACID,所以Redis的方式是解決不了它的問題的。
    MySQL中的MVCC機制(Oracle的也是),通過undo
    日誌來獲取某個行記錄的歷史快照,從而實現了所謂的讀一致性。它的目的是讀取某個時間點上的歷史數據(而不是可能已經被修改了的數據),而不是避免悲觀鎖的使用。嚴格地說這不能稱之為樂觀鎖,因為它既不Compare當前版本和歷史版本,也不進行Set。事實上,在讀取記錄的歷史快照時,當前記錄有可能(由於並發的寫操作)已經被加上獨占鎖。
    進一步的問題是:有沒有可能使用樂觀鎖來實現RDBMS中的寫一致性?有沒有可能使用樂觀鎖實現完整的ACID特性?
    回答是可以。例如,MS
    SQL
    SERVER的Hekaton引擎通過一套基於時間戳的多版本管理系統,實現了不使用了悲觀鎖的ACID。
    但是,這並不意味著樂觀鎖必然優於悲觀鎖。除了維護多版本的開銷以外,樂觀鎖無法避免的一個問題是,當多個寫操作試圖更新同一個對象時,只有第一個操作可以成功,其它的操作都會在Compare時失敗然後回滾,從而造成極大的性能問題。在這種情況下,樂觀鎖的性能會低於悲觀鎖。
    目前的趨勢似乎是,大規模的分布式資料庫更傾向於使用樂觀鎖來達到所謂的external
    consistency,因為基於傳統悲觀鎖的分布式鎖在集群大到一定程度以後(從幾百台擴展到成千上萬台時),性能開銷就大得無法接受了。Google的Spanner就是基於樂觀鎖。當然這完全是另外一個問題了。

    ㈩ 什麼是雲存儲技術

    雲存儲是在雲計算(cloud computing)概念上延伸和發展出來的一個新的概念,是指通過集群應用、網格技術或分布式文件系統等功能,將網路中大量各種不同類型的存儲設備通過應用軟體集合起來協同工作,共同對外提供數據存儲和業務訪問功能的一個系統。 當雲計算系統運算和處理的核心是大量數據的存儲和管理時,雲計算系統中就需要配置大量的存儲設備,那麼雲計算系統就轉變成為一個雲存儲系統,所以雲存儲是一個以數據存儲和管理為核心的雲計算系統。

    雲存儲的兩個層面

    雲存儲的兩個層面是作為雲計算支撐的存儲計算,主要涉及分布式存儲(如分布式文件系統、IPSAN、數據同步、復制)、數據存儲(如重復數據刪除、數據壓縮、數據編碼)和數據保護(如RAID、CDP、快照、備份與容災)等技術領域,如圖8-30所示,這在第6章中已有所介紹。和雲安全技術一樣,雲存儲技術也需要利用現有的所有存儲技術針對雲計算三層架構的各個環節採用適當的存儲技術,才能取得最佳效果,例如,對應不同需求,有時應該使用資料庫技術但有時卻應該使用LDAP技術,有些性能要求高的系統不能使用SAN或NAS,需直接使用基於RPC或Socket技術的並發文件系統,有些應用使用SAN成本太高等,這里不再做深入介紹。如圖8-31所示是一個採用NetApp FAS、思科 UCS和 VMWare vShpere 4技術打造的存儲系統,對上述兩種雲存儲技術和應用都有促進作用。雲存儲架構

    分為兩類:一種是通過服務來架構;另一種是通過軟體或硬體設備來架構。

    傳統的系統利用緊耦合對稱架構,這種架構的設計旨在解決HPC(高性能計算、超級運算)問題,現在其正在向外擴展成為雲存儲從而滿足快速呈現的市場需求。下一代架構已經採用了鬆弛耦合非對稱架構,集中元數據和控制操作,這種架構並不非常適合高性能HPC,但是這種設計旨在解決雲部署的大容量存儲需求。各種架構的摘要信息如下:

    緊耦合對稱(TCS)架構

    構建TCS系統是為了解決單一文件性能所面臨的挑戰,這種挑戰限制了傳統NAS系統的發展。HPC系統所具有的優勢迅速壓倒了存儲,因為它們需要的單一文件I/O操作要比單一設備的I/O操作多得多。業內對此的回應是創建利用TCS架構的產品,很多節點同時伴隨著分布式鎖管理(鎖定文件不同部分的寫操作)和緩存一致性功能。這種解決方案對於單文件吞吐量問題很有效,幾個不同行業的很多HPC客戶已經採用了這種解決方案。這種解決方案很先進,需要一定程度的技術經驗才能安裝和使用。

    鬆弛耦合非對稱(LCA)架構

    LCA系統採用不同的方法來向外擴展。它不是通過執行某個策略來使每個節點知道每個行動所執行的操作,而是利用一個數據路徑之外的中央元數據控制伺服器。集中控制提供了很多好處,允許進行新層次的擴展:

    ● 存儲節點可以將重點放在提供讀寫服務的要求上,而不需要來自網路節點的確認信息。

    ● 節點可以利用不同的商品硬體CPU和存儲配置,而且仍然在雲存儲中發揮作用。

    ● 用戶可以通過利用硬體性能或虛擬化實例來調整雲存儲。

    ● 消除節點之間共享的大量狀態開銷也可以消除用戶計算機互聯的需要,如光纖通道或infiniband,從而進一步降低成本。

    ● 異構硬體的混合和匹配使用戶能夠在需要的時候在當前經濟規模的基礎上擴大存儲,同時還能提供永久的數據可用性。

    ● 擁有集中元數據意味著,存儲節點可以旋轉地進行深層次應用程序歸檔,而且在控制節點上,元數據經常都是可用的。