① 關於磁碟冗餘陣列
獨立磁碟冗餘陣列(Rendant Array of Independent Disks,RAID;在台灣一般俗稱:磁碟陣列)的基本思想就是把多個相對便宜的小磁碟組合起來,成為一個磁碟組, 使性能達到甚至超過一個價格昂貴、容量巨大的磁碟。根據選擇的版本不同,RAID比單盤有以下一個或多個方面的益處:增強數據整合度,增強容錯功能,增加吞吐量或容量。另外,磁碟組對於計算機來說, 看起來就像一個單獨的磁碟或邏輯存儲單元。分為RAID-1,RAID-10,RAID-3,RAID-30,RAID-5,RAID-50。
圍繞RAID的基本想法就是把多個便宜的小磁碟組合到一起,成為一個磁碟組式的邏輯硬碟,因此,操作系統僅把它們看作一個單一的邏輯存儲單元或磁碟。通過這種手段使邏輯硬碟的性能達到或超過一個容量巨大、價格昂貴的磁碟。RAID常被用在伺服器計算機上,並且常使用完全相同的硬碟作為組合。由於硬碟價格的不斷下降與和RAID功能更加有效地與主板整合,它也成為了高級最終用戶的一個選擇,特別是需要大量存儲的工作,如:視頻與音頻製作。
利用如磁碟條紋化 (RAID 0) 和 磁碟鏡像 (RAID 1) 的技巧,把數據分布到各個磁碟上,來達到亢余性、低延遲、讀寫的高帶寬、硬碟毀壞後的最大可恢復性。
採用 RAID 的主要原因是:
1、增強了速度
2、擴容了存儲能力(以及更多的便利)
3、可高效恢復磁碟
有兩種可以實現RAID的方法:硬RAID和軟RAID。
最初的RAID分成了不同的等級,每種等級都有其理論上的優缺點。這些年來,出現了對於RAID觀念不同的應用。
參考http://ke..com/view/1247528.htm
② 什麼是資料庫中的數據冗餘如何消除數據冗餘
數據冗餘指數據之間的重復,也可以說是同一數據存儲在不同數據文件中的現象。可以說增加數據的獨立性和減少數據冗餘為企業范圍信息資源管理和大規模信息系統獲得成功的前提條件。
數據冗餘會妨礙資料庫中數據的完整性(integrality),也會造成存貯空間的浪費。盡可能地降低數據冗餘度,是資料庫設計的主要目標之一。關系模式的規范化理淪(以下稱NF理論)的主要思想之一就是最小冗餘原則,即規范化的關系模式在某種意義上應該冗餘度最小。
但是,NF理論沒有標準的概念可用,按等價原則,在有或沒有泛關系假設(universal relation assumption)等不同前提下,冗餘的定義可能有好幾種。
數據的應用中為了某種目的採取數據冗餘方式。
1、重復存儲或傳輸數據以防止數據的丟失。
2、對數據進行冗餘性的編碼來防止數據的丟失、錯誤,並提供對錯誤數據進行反變換得到原始數據的功能。
3、為簡化流程所造成額數據冗餘。
4、為加快處理過程而將同一數據在不同地點存放。
5、為方便處理而使同一信息在不同地點有不同的表現形式。
6、大量數據的索引,一般在資料庫中經常使用。
7、方法類的信息冗餘。
8、為了完備性而配備的冗餘數據。
9、規則性的冗餘。根據法律、制度、規則等約束進行的。
10、為達到其他目的所進行的冗餘。
③ 數據冗餘的類型有哪些
數據的應用中為了某種目的採取數據冗餘方式。
1、重復存儲或傳輸數據以防止數據的丟失。
2、對數據進行冗餘性的編碼來防止數據的丟失、錯誤,並提供對錯誤數據進行反變換得到原始數據的功能。
3、為簡化流程所造成額數據冗餘。例如向多個目的發送同樣的信息、在多個地點存放同樣的信息,而不對數據進行分析而減少工作量。
4、為加快處理過程而將同一數據在不同地點存放。例如並行處理同一信息的不同內容,或用不同方法處理同一信息等。
5、為方便處理而使同一信息在不同地點有不同的表現形式。例如一本書的不同語言的版本。
6、大量數據的索引,一般在資料庫中經常使用。其目的類似第4點。
7、方法類的信息冗餘:比如每個司機都要記住同一城春拍市的基本交通信息;大量個人鉛野電腦都安裝類似的操作系統或軟體。
8、為了完備性而配備的冗餘數據。例如字典里的字很多,但我們只查詢其中很少的一些字。軟體功能很多,但我們只扒激羨使用其中一部分。
9、規則性的冗餘。根據法律、制度、規則等約束進行的。例如合同中大量的模式化的內容。
10、為達到其他目的所進行的冗餘。例如重復信息以達到被重視等等。
④ 增加數據冗餘,避免連接查詢,這樣好嗎
本文首先討論了基於第三範式的燃褲資料庫表的基本設計,著重論述了建立主鍵和索引的策略和方案,然後從資料庫表的擴展設計和庫表對象的放置等角度概述了資料庫管理系統的優化方案。
關鍵詞: 優化(Optimizing) 第三範式(3NF) 冗餘數據(Rendant Data) 索引(Index) 數據分割(Data Partitioning) 對象放置(Object Placement)
1 引言
資料庫優化的目標無非是避免磁碟I/O瓶頸、減少CPU利用率和減少資源競爭。為了便於讀者閱讀和理解,筆者參閱了Sybase、Informix和Oracle等大型資料庫系統參考資料,基於多年的工程實踐經驗,從基本表設計、擴展設計和資料庫表對象放置等角度進行討論,著重討論了如何避免磁碟I/O瓶頸和減少資源競爭,相信讀者會一目瞭然。
2 基於第三範式的基本表設計
在基於表驅動的信息管皮含簡理系統(MIS)中,基本表的設計規范是第三範式(3NF)。第三範式的基本特徵是非主鍵屬性只依賴於主鍵屬性。基於第三範式的資料庫表設計具有很多優點:一是消除了冗餘數據,節省了磁碟存儲空間;二是有良好的數據完整性限制,即基於主外鍵的參照完整限制和基於主鍵的實體完整性限制,這使得數據容易維護,也容易移植和更新;三老猛是數據的可逆性好,在做連接(Join)查詢或者合並表時不遺漏、也不重復;四是因消除了冗餘數據(冗餘列),在查詢(Select)時每個數據頁存的數據行就多,這樣就有效地減少了邏輯I/O,每個Cash存的頁面就多,也減少物理I/O;五是對大多數事務(Transaction)而言,運行性能好;六是物理設計(Physical Design)的機動性較大,能滿足日益增長的用戶需求。
在基本表設計中,表的主鍵、外鍵、索引設計佔有非常重要的地位,但系統設計人員往往只注重於滿足用戶要求,而沒有從系統優化的高度來認識和重視它們。實際上,它們與系統的運行性能密切相關。現在從系統資料庫優化角度討論這些基本概念及其重要意義:
(1)主鍵(Primary Key):主鍵被用於復雜的SQL語句時,頻繁地在數據訪問中被用到。一個表只有一個主鍵。主鍵應該有固定值(不能為Null或預設值,要有相對穩定性),不含代碼信息,易訪問。把常用(眾所周知)的列作為主鍵才有意義。短主鍵最佳(小於25bytes),主鍵的長短影響索引的大小,索引的大小影響索引頁的大小,從而影響磁碟I/O。主鍵分為自然主鍵和人為主鍵。自然主鍵由實體的屬性構成,自然主鍵可以是復合性的,在形成復合主鍵時,主鍵列不能太多,復合主鍵使得Join*作復雜化、也增加了外鍵表的大小。人為主鍵是,在沒有合適的自然屬性鍵、或自然屬性復雜或靈敏度高時,人為形成的。人為主鍵一般是整型值(滿足最小化要求),沒有實際意義,也略微增加了表的大小;但減少了把它作為外鍵的表的大小。
(2)外鍵(Foreign Key):外鍵的作用是建立關系型資料庫中表之間的關系(參照完整性),主鍵只能從獨立的實體遷移到非獨立的實體,成為後者的一個屬性,被稱為外鍵。
(3)索引(Index):利用索引優化系統性能是顯而易見的,對所有常用於查詢中的Where子句的列和所有用於排序的列創建索引,可以避免整表掃描或訪問,在不改變表的物理結構的情況下,直接訪問特定的數據列,這樣減少數據存取時間;利用索引可以優化或排除耗時的分類*作;把數據分散到不同的頁面上,就分散了插入的數據;主鍵自動建立了唯一索引,因此唯一索引也能確保數據的唯一性(即實體完整性);索引碼越小,定位就越直接;新建的索引效能最好,因此定期更新索引非常必要。索引也有代價:有空間開銷,建立它也要花費時間,在進行Insert、Delete和Update*作時,也有維護代價。索引有兩種:聚族索引和非聚族索引。一個表只能有一個聚族索引,可有多個非聚族索引。使用聚族索引查詢數據要比使用非聚族索引快。在建索引前,應利用資料庫系統函數估算索引的大小。
① 聚族索引(Clustered Index):聚族索引的數據頁按物理有序儲存,佔用空間小。選擇策略是,被用於Where子句的列:包括范圍查詢、模糊查詢或高度重復的列(連續磁碟掃描);被用於連接Join*作的列;被用於Order by和Group by子句的列。聚族索引不利於插入*作,另外沒有必要用主鍵建聚族索引。
② 非聚族索引(Nonclustered Index):與聚族索引相比,佔用空間大,而且效率低。選擇策略是,被用於Where子句的列:包括范圍查詢、模糊查詢(在沒有聚族索引時)、主鍵或外鍵列、點(指針類)或小范圍(返回的結果域小於整表數據的20%)查詢;被用於連接Join*作的列、主鍵列(范圍查詢);被用於Order by和Group by子句的列;需要被覆蓋的列。對只讀表建多個非聚族索引有利。索引也有其弊端,一是創建索引要耗費時間,二是索引要佔有大量磁碟空間,三是增加了維護代價(在修改帶索引的數據列時索引會減緩修改速度)。那麼,在哪種情況下不建索引呢?對於小表(數據小於5頁)、小到中表(不直接訪問單行數據或結果集不用排序)、單值域(返回值密集)、索引列值太長(大於20bitys)、容易變化的列、高度重復的列、Null值列,對沒有被用於Where子語句和Join查詢的列都不能建索引。另外,對主要用於數據錄入的,盡可能少建索引。當然,也要防止建立無效索引,當Where語句中多於5個條件時,維護索引的開銷大於索引的效益,這時,建立臨時表存儲有關數據更有效。
批量導入數據時的注意事項:在實際應用中,大批量的計算(如電信話單計費)用C語言程序做,這種基於主外鍵關系數據計算而得的批量數據(文本文件),可利用系統的自身功能函數(如Sybase的BCP命令)快速批量導入,在導入資料庫表時,可先刪除相應庫表的索引,這有利於加快導入速度,減少導入時間。在導入後再重建索引以便優化查詢。
(4)鎖:鎖是並行處理的重要機制,能保持數據並發的一致性,即按事務進行處理;系統利用鎖,保證數據完整性。因此,我們避免不了死鎖,但在設計時可以充分考慮如何避免長事務,減少排它鎖時間,減少在事務中與用戶的交互,杜絕讓用戶控制事務的長短;要避免批量數據同時執行,尤其是耗時並用到相同的數據表。鎖的徵用:一個表同時只能有一個排它鎖,一個用戶用時,其它用戶在等待。若用戶數增加,則Server的性能下降,出現「假死」現象。如何避免死鎖呢?從頁級鎖到行級鎖,減少了鎖徵用;給小表增加無效記錄,從頁級鎖到行級鎖沒有影響,若在同一頁內競爭有影響,可選擇合適的聚族索引把數據分配到不同的頁面;創建冗餘表;保持事務簡短;同一批處理應該沒有網路交互。
(5)查詢優化規則:在訪問資料庫表的數據(Access Data)時,要盡可能避免排序(Sort)、連接(Join)和相關子查詢*作。經驗告訴我們,在優化查詢時,必須做到:
① 盡可能少的行;
② 避免排序或為盡可能少的行排序,若要做大量數據排序,最好將相關數據放在臨時表中*作;用簡單的鍵(列)排序,如整型或短字元串排序;
③ 避免表內的相關子查詢;
④ 避免在Where子句中使用復雜的表達式或非起始的子字元串、用長字元串連接;
⑤ 在Where子句中多使用「與」(And)連接,少使用「或」(Or)連接;
⑥ 利用臨時資料庫。在查詢多表、有多個連接、查詢復雜、數據要過濾時,可以建臨時表(索引)以減少I/O。但缺點是增加了空間開銷。
除非每個列都有索引支持,否則在有連接的查詢時分別找出兩個動態索引,放在工作表中重新排序。
3 基本表擴展設計
基於第三範式設計的庫表雖然有其優越性(見本文第一部分),然而在實際應用中有時不利於系統運行性能的優化:如需要部分數據時而要掃描整表,許多過程同時競爭同一數據,反復用相同行計算相同的結果,過程從多表獲取數據時引發大量的連接*作,當數據來源於多表時的連接*作;這都消耗了磁碟I/O和CPU時間。
尤其在遇到下列情形時,我們要對基本表進行擴展設計:許多過程要頻繁訪問一個表、子集數據訪問、重復計算和冗餘數據,有時用戶要求一些過程優先或低的響應時間。
如何避免這些不利因素呢?根據訪問的頻繁程度對相關表進行分割處理、存儲冗餘數據、存儲衍生列、合並相關表處理,這些都是克服這些不利因素和優化系統運行的有效途徑。
3.1 分割表或儲存冗餘數據
分割表分為水平分割表和垂直分割表兩種。分割表增加了維護數據完整性的代價。
水平分割表:一種是當多個過程頻繁訪問數據表的不同行時,水平分割表,並消除新表中的冗餘數據列;若個別過程要訪問整個數據,則要用連接*作,這也無妨分割表;典型案例是電信話單按月分割存放。另一種是當主要過程要重復訪問部分行時,最好將被重復訪問的這些行單獨形成子集表(冗餘儲存),這在不考慮磁碟空間開銷時顯得十分重要;但在分割表以後,增加了維護難度,要用觸發器立即更新、或存儲過程或應用代碼批量更新,這也會增加額外的磁碟I/O開銷。
垂直分割表(不破壞第三範式),一種是當多個過程頻繁訪問表的不同列時,可將表垂直分成幾個表,減少磁碟I/O(每行的數據列少,每頁存的數據行就多,相應佔用的頁就少),更新時不必考慮鎖,沒有冗餘數據。缺點是要在插入或刪除數據時要考慮數據的完整性,用存儲過程維護。另一種是當主要過程反復訪問部分列時,最好將這部分被頻繁訪問的列數據單獨存為一個子集表(冗餘儲存),這在不考慮磁碟空間開銷時顯得十分重要;但這增加了重疊列的維護難度,要用觸發器立即更新、或存儲過程或應用代碼批量更新,這也會增加額外的磁碟I/O開銷。垂直分割表可以達到最大化利用Cache的目的。
總之,為主要過程分割表的方法適用於:各個過程需要表的不聯結的子集,各個過程需要表的子集,訪問頻率高的主要過程不需要整表。在主要的、頻繁訪問的主表需要表的子集而其它主要頻繁訪問的過程需要整表時則產生冗餘子集表。
注意,在分割表以後,要考慮重新建立索引。
3.2 存儲衍生數據
對一些要做大量重復性計算的過程而言,若重復計算過程得到的結果相同(源列數據穩定,因此計算結果也不變),或計算牽扯多行數據需額外的磁碟I/O開銷,或計算復雜需要大量的CPU時間,就考慮存儲計算結果(冗餘儲存)。現予以分類說明:
若在一行內重復計算,就在表內增加列存儲結果。但若參與計算的列被更新時,必須要用觸發器更新這個新列。
若對表按類進行重復計算,就增加新表(一般而言,存放類和結果兩列就可以了)存儲相關結果。但若參與計算的列被更新時,就必須要用觸發器立即更新、或存儲過程或應用代碼批量更新這個新表。
若對多行進行重復性計算(如排名次),就在表內增加列存儲結果。但若參與計算的列被更新時,必須要用觸發器或存儲過程更新這個新列。
總之,存儲冗餘數據有利於加快訪問速度;但違反了第三範式,這會增加維護數據完整性的代價,必須用觸發器立即更新、或存儲過程或應用代碼批量更新,以維護數據的完整性。
3.3 消除昂貴結合
對於頻繁同時訪問多表的一些主要過程,考慮在主表內存儲冗餘數據,即存儲冗餘列或衍生列(它不依賴於主鍵),但破壞了第三範式,也增加了維護難度。在源表的相關列發生變化時,必須要用觸發器或存儲過程更新這個冗餘列。當主要過程總同時訪問兩個表時可以合並表,這樣可以減少磁碟I/O*作,但破壞了第三範式,也增加了維護難度。對父子表和1:1關系表合並方法不同:合並父子表後,產生冗餘表;合並1:1關系表後,在表內產生冗餘數據。
4 資料庫對象的放置策略
資料庫對象的放置策略是均勻地把數據分布在系統的磁碟中,平衡I/O訪問,避免I/O瓶頸。
⑴ 訪問分散到不同的磁碟,即使用戶數據盡可能跨越多個設備,多個I/O運轉,避免I/O競爭,克服訪問瓶頸;分別放置隨機訪問和連續訪問數據。
⑵ 分離系統資料庫I/O和應用資料庫I/O。把系統審計表和臨時庫表放在不忙的磁碟上。
⑶ 把事務日誌放在單獨的磁碟上,減少磁碟I/O開銷,這還有利於在障礙後恢復,提高了系統的安全性。
⑷ 把頻繁訪問的「活性」表放在不同的磁碟上;把頻繁用的表、頻繁做Join*作的表分別放在單獨的磁碟上,甚至把把頻繁訪問的表的欄位放在不同的磁碟上,把訪問分散到不同的磁碟上,避免I/O爭奪;
⑸ 利用段分離頻繁訪問的表及其索引(非聚族的)、分離文本和圖像數據。段的目的是平衡I/O,避免瓶頸,增加吞吐量,實現並行掃描,提高並發度,最大化磁碟的吞吐量。利用邏輯段功能,分別放置「活性」表及其非聚族索引以平衡I/O。當然最好利用系統的默認段。另外,利用段可以使備份和恢復數據更加靈活,使系統授權更加靈活。
⑤ 什麼是數據冗餘
數據冗餘是指數據之間的重復,也可以說是同一數據存儲在不同數據文件中的現象。可以說增加數據的獨立性和減少數據冗餘是企業范圍信息資源管理和大規模信息系統獲得成功的前提條件。
是傳輸消息所用數據位的數目與消息中所包含的實際信息的數據位的數目的差值。數據壓縮是一種用來消除不需要的冗餘的方法,校驗和是在經過有限信道容量的雜訊信道中通信,為了進行錯誤校正而增加冗餘的方法。
⑥ 監控硬碟存儲冗餘要求
監控硬碟存儲要求:對於一款監控硬碟而言,處理高效讀寫並非簡單的事情,對外既要保證錄像畫面無損,高效的編解碼協議、傳輸協議和數據封裝協議,滿足高幀率、高像素的前端設備的採用。
是全面支持智能視頻分析技術,滿足監控系統多路並發的數據採集、存儲、分析與輸出。
安全可靠的數據保護技術,滿足數據時代下的數據加密與安全需求。
⑦ 磁碟存儲冗餘是什麼意思
通過多重備份來增加系統的可靠性!
冗餘系統配件主要有:
電源:高端伺服器產品中普遍採用雙電源系統,這兩個電源是負載均衡的,即在系統工作時它們都為系統提供電力,當一個電源出現故障時,另一個電源就承擔所有的負載。有些伺服器系統實現了DC的冗餘,另一些伺服器產品如Micron公司的NetFRAME 9000實現了AC、DC的全冗餘。
存儲子系統:存儲子系統是整個伺服器系統中最容易發生故障的地方。以下幾種方法可以實現該子系統的冗餘。
磁碟鏡像:將相同的數據分別寫入兩個磁碟中:
磁碟雙聯:為鏡像磁碟增加了一個I/O控制器,就形成了磁碟雙聯,使匯流排爭用情況得到改善;
RAID:廉價冗餘磁碟陣列(Rendant array of inexpensive disks)的縮寫。顧名思義,它由幾個磁碟組成,通過一個控制器協調運動機制使單個數據流依次寫入這幾個磁碟中。RAID3系統由5個磁碟構成,其中4個磁碟存儲數據,1個磁碟存儲校驗信息。如果一個磁碟發生故障,可以在線更換故障盤,並通過另3個磁碟和校驗盤重新創建新盤上的數據。RAID5將校驗信息分布在5個磁碟上,這樣可更換任一磁碟,其餘與RAID3相同。
I/O卡:對伺服器來說,主要指網卡和硬碟控制卡的冗餘。網卡冗餘是在伺服器中插上雙網卡。冗餘網卡技術原為大型機及中型機上的技術,現在也逐漸被PC伺服器所擁有。PC伺服器如Micron公司的NetFRAME9200最多實現4個網卡的冗餘,這4個網卡各承擔25%的網路流量。康柏公司的所有ProSignia/Proliant伺服器都具有容錯冗餘雙網卡。
PCI匯流排:代表Micron公司最高技術水平的產品NetFRAME 9200採用三重對等PCI技術,優化PCI匯流排的帶寬,提升硬碟、網卡等高速設備的數據傳輸速度。
CPU:系統中主處理器並不會經常出現故障,但對稱多處理器(SMP)能讓多個CPU分擔工作以提供某種程度的容錯。
⑧ 硬碟數據錯誤循環冗餘檢查怎麼解決
數據錯誤循環冗餘檢查說明這個盤的文件系統結構損壞了。在平時如果數據不重要,那麼可以直接格式化就能用了。但是有的時候裡面的數據很重要,那麼就必須先恢復出數據再格式化,具體操作步驟如下:
1、首先我們下載並解壓數據恢復軟體運行後,直接雙擊需要恢復的分區,接著右擊軟體圖標選擇《以管理員身份運行》。
⑨ hadoop中存儲文件系統hdfs的冗餘機制是怎麼進行的有什麼特點
可以只用一行代碼來運行MapRece作業:JobClient.runJon(conf),Job作業運行時參與的四個實體:
1.JobClient 寫代碼,配置作業,提交作業。
2.JobTracker:初始化作業,分配作業,協調作業運行。這是一個java程序,主類是JobTracker。
3.TaskTracker:運行作業劃分後的任務,即分配數據分配上執行Map或Rece任務。
4.HDFS:保存作業數據、配置信息等,保存作業結果。
Map/Rece 作業總體執行流程:
代碼編寫 ----> 作業配置 ---->作業提交---->Map任務分配和執行---->處理中間結果----> Rece任務分配與執行----> 輸出結果
而對於每個作業的執行,又包含:
輸入准備---->任務執行---->輸出結果
作業提交JobClient:
JobClient的runJob方法產生一個Jobclient實例並調用其submitJob方法,然後runJob開始循環嗎,並在循環中調用getTaskCompetionEvents方法,獲得TaskCompletionEvent實例,每秒輪詢作業進度(後面有介紹進度和狀態更新),把進度寫到控制台,作業完成後顯示作業計數器,若失敗,則把錯誤記錄到控制台。
submitJob方法作業提交的過程:
1.向JobTracker請求一個新的JobId。
2.檢查作業相關路徑,如果路徑不正確就會返回錯誤。
3.計算作業輸入分片及其劃分信息。
4.將作業運行需要的資源(jar文件、配置文件等)復制到Shared HDFS,並
復制多個副本(參數控制,默認值為10)供tasktracker訪問,也會將計算的分片復制到HDFS。
5.調用JobTracker對象的submitJob()方法來真正提交作業,告訴JobTracker作業准備執行。
作業的初始化JobTracker:
JobTracker收到submitJob方法調用後,會把調用放入到一個內部隊列,由作業調度器(Job scheler)進行調度並對其初始化。Job初始化即創建一個作業對象。
當作業被調度後,JobTracker會創建一個代表這個作業的JobInProgress對象,並將任務和記錄信息封裝在這個對象中,以便跟蹤任務狀態和進程。
初始化過程就是JobInProgress對象的initTasks方法進行初始化的。
初始化步驟:
1.從HDFS中讀取作業對應的job.split信息,為後面的初始化做好准備。
2.創建並初始化map和rece任務。根據數據分片信息中的個數確定map task的個數,然後為每個map task生成一個TaskInProgress對象來處理數據分片,先將其放入nonRunningMapCache,以便JobTracker分配任務的時候使用。接下來根據JobConf中的mapred.rece.tasks屬性利用setNumReceTasks()方法設置rece task的數量,然後同map task創建方式。
3.最後就是創建兩個初始化task,進行map和rece的初始化。
任務的分配JobTracker:
消息傳遞HeartBeat: tasktracker運行一個簡單循環定期發送心跳(heartbeat)給JobTracker。由心跳告知JobTracker自己是否存活,同時作為消息通道傳遞其它信息(請求新task)。作為心跳的一部分,tasktracker會指明自己是否已准備好運行新的任務,如果是,jobtracker會分配它一個任務。
分配任務所屬於的作業:在Jobtracker分配任務前需先確定任務所在的作業。後面會介紹到各種作業調度演算法,默認是一個FIFO的作業調度。
分配Map和Rece任務:tasktracker有固定數量的任務槽,一個tasktracker可以同時運行多個Map和Rece任務,但其准確的數量由tasktracker的核的數量和內存大小決定。默認調度器會先填滿Map任務槽,再填Rece任務槽。jobtracker會選擇距離離分片文件最近的tasktracker,最理想情況下,任務是數據本地化(data-local)的,當然也可以是機架本地化(rack-local),如果不是本地化的,那麼他們就需要從其他機架上檢索數據。Rece任務分配很簡單,jobtracker會簡單的從待運行的rece任務列表中選取下一個來執行,不用考慮數據本地化。
任務的執行TaskTracker:
TaskTracker收到新任務後,就要在本地運行任務了,運行任務的第一步就是通過localizedJob將任務本地化所需要的注入配置、數據、程序等信息進行本地化。
1.本地化數據:從共享文件系統將job.split 、job.jar (在分布式緩存中)復制本地,將job配置信息寫入job.xml。
2.新建本地工作目錄:tasktracker會加壓job.jar文件到本工作目錄。
3.調用launchTaskForJob方法發布任務(其中會新建TaskRunner實例運行任務),如果是Map任務就啟用MapTaskRunner,對於Rece就是ReceTaskRunner。
在這之後,TaskRunner會啟用一個新的JVM來運行每個Map/Rece任務,防止程序原因而導致tasktracker崩潰,但不同任務間重用JVM還是可以的,後續會講到任務JVM重用。
對於單個Map,任務執行的簡單流程是:
1.分配任務執行參數
2.在Child臨時文件中添加map任務信息(Child是運行Map和Rece任務的主進程)
3.配置log文件夾,配置map任務的通信和輸出參數
4.讀取input split,生成RecordReader讀取數據
5.為Map生成MapRunnable,依次從RecordReader中接收數據,並調用Map函數進行處理。
6.最後將map函數的輸出調用collect收集到MapOutputBuffer(參數控制其大小)中。
Streaming和Pipes:
Streaming和Pipes都運行特殊的Map和Rece任務,目的是運行用戶提供的可執行程序並與之通信。
Streaming:使用標准輸入輸出Streaming與進程進行通信。
Pipes:用來監聽套接字,會發送一個埠號給C++程序,兩者便可建立鏈接。
進度和狀態更新:
一個作業和它的任務都有狀態(status),其中包括:運行成功失敗狀態、Map/Rece進度、作業計數器值、狀態消息。
狀態消息與客戶端的通信:
1.對於Map任務Progress的追蹤:progress是已經處理完的輸入所佔的比例。
2.對於Rece:稍復雜,rece任務分三個階段(每個階段佔1/3),復制、排序和Rece處理,若rece已執行一半的輸入的話,那麼任務進度便是1/3+1/3+1/6=5/6。
3.任務計數器:任務有一組計數器,負責對任務運行各個事件進行計數。
4.任務進度報告:如果任務報告了進度,便會設置一個標記以表明狀態將被發送到tasktracker。有一個獨立線程每隔三秒檢查一次此標記,如果已設置,則告知tasktracker當前狀態。
5.tasktracker進度報告:tasktracker會每隔5秒(這個心跳是由集群大小決定,集群越大時間會越長)發送heartbeat到jobtracker,並且tasktracker運行的所有狀態都會在調用中被發送到jobtracker。
6.jobtracker合並各任務報告:產生一個表明所有運行作業機器所含任務狀態的全局視圖。
前面提到的JobClient就是通過每秒查詢JobTracker來接收最新狀態,而且客戶端JobClient的getJob方法可以得到一個RunningJob的實例,其包含了作業的所以狀態信息。
作業的完成:
當jobtracker收到作業最後一個任務已完成的通知後,便把作業狀態設置成成功。JobClient查詢狀態時,便知道任務已成功完成,於是JobClient列印一條消息告知用戶,然後從runJob方法返回。
如果jobtracker有相應設置,也會發送一個Http作業通知給客戶端,希望收到回調指令的客戶端可以通過job.end.notification.url屬性來進行設置。
jobtracker情況作業的工作狀態,指示tasktracker也清空作業的工作狀態,如刪除中間輸出。
失敗
實際情況下,用戶的代碼存在軟體錯誤進程會崩潰,機器也會產生故障,但Hadoop能很好的應對這些故障並完成作業。
1.任務失敗
子任務異常:如Map/Rece任務中的用戶代碼拋出異常,子任務JVM進程會在退出前向父進程tasktracker發送錯誤報告,錯誤被記錄用戶日誌。tasktracker會將此次task attempt標記為tailed,並釋放這個任務槽運行另外一個任務。
子進程JVM突然退出:可能由於JVM bug導致用戶代碼造成的某些特殊原因導致JVM退出,這種情況下,tasktracker會注意到進程已經退出,並將此次嘗試標記為failed。
任務掛起:一旦tasktracker注意一段時間沒有收到進度更新,便會將任務標記為failed,JVM子進程將被自動殺死。任務失敗間隔時間通常為10分鍾,可以以作業或者集群為基礎設置過期時間,參數為mapred.task.timeout。注意:如果參數值設置為0,則掛起的任務永遠不會釋放掉它的任務槽,隨著時間的推移會降低整個集群的效率。
任務失敗嘗試次數:jobtracker得知一個tasktracker失敗後,它會重新調度該任務執行,當然,jobtracker會嘗試避免重新調度失敗過的tasktracker任務。如果一個任務嘗試次數超過4次,它將不再被重試。這個值是可以設置的,對於Map任務,參數是mapred.map.max.attempts,對於rece任務,則由mapred.rece.max.attempts屬性控制。如果次數超過限制,整個作業都會失敗。當然,有時我們不希望少數幾個任務失敗就終止運行的整個作業,因為即使有些任務失敗,作業的一些結果可能還是有用的,這種情況下,可以為作業設置在不觸發作業失敗情況下的允許任務失敗的最大百分比,Map任務和Rece任務可以獨立控制,參數為mapred.max.map.failures.percent 和mapred.max.rece.failures.percent。
任務嘗試中止(kill):任務終止和任務失敗不同,task attempt可以中止是因為他是一個推測副本或因為它所處的tasktracker失敗,導致jobtracker將它上面的所有task attempt標記為killed。被終止的task attempt不會被計入任務運行嘗試次數,因為嘗試中止並不是任務的錯。
2.tasktracker失敗
tasktracker由於崩潰或者運行過慢而失敗,他將停止向jobtracker發送心跳(或很少發送心跳)。jobtracker注意已停止發送心跳的tasktracker(過期時間由參數mapred.tasktracker.expiry.interval設置,單位毫秒),並將它從等待調度的tasktracker池中移除。如果是未完成的作業,jobtracker會安排次tasktracker上已經運行成功的Map任務重新運行,因為此時rece任務已無法訪問(中間輸出存放在失敗的tasktracker的本地文件系統上)。
即使tasktracker沒有失敗,也有可能被jobtracker列入黑名單。如果tasktracker上面的失敗任務數量遠遠高於集群的平均失敗任務次數,他就會被列入黑名單,被列入黑名單的tasktracker可以通過重啟從jobtracker黑名單中移除。
3.jobtracker失敗
老版本的JobTracker失敗屬於單點故障,這種情況下作業註定失敗。
作業調度:
早期作業調度FIFO:按作業提交順序先進先出。可以設置優先順序,通過設置mapred.job.priority屬性或者JobClient的setJobPriority()方法制定優先順序(優先順序別:VERY_HIGH,HIGH,NORMAL,LOW,VERY_LOW)。注意FIFO調度演算法不支持搶占(preemption),所以高優先順序作業仍然會被那些已經開始的長時間運行的低優先順序作業所阻塞。
Fair Scheler:目標是讓每個用戶公平地共享集群能力。當集群存在很多作業時,空閑的任務槽會以」讓每個用戶共享集群「的方式進行分配。默認每個用戶都有自己的作業池。FairScheler支持搶占,所以,如果一個池在特定的一段時間未得到公平地資源共享,它會終止池中得到過多的資源任務,以便把任務槽讓給資源不足的池。FairScheler是一個後續模塊,使用它需要將其jar文件放在Hadoop的類路徑下。可以通過參數map.red.jobtracker.taskScheler屬性配置(值為org.apache.hadoop.mapred.FairScheler)
Capacity Scheler:
集群由很多隊列組成,每個隊列都有一個分配能力,這一點與FairScheler類似,只不過在每個隊列內部,作業根據FIFO方式進行調度。本質上說,Capacity Scheler允許用戶或組織為每個用戶模擬一個獨立使用FIFO的集群。
shuffle和排序:
MapRece確保每個Recer的輸入都是按鍵排序的。系統執行排序的過程-將map輸出作為輸入傳給recer的過程稱為shuffle。shuffle屬於不斷被優化和改進的代碼庫的一部分,從許多方面來看,shuffle是MapRece的心臟。
整個shuffle的流程應該是這樣:
map結果劃分partition 排序sort 分割spill 合並同一劃分 合並同一劃分 合並結果排序 rece處理 輸出
Map端:
寫入緩沖區:Map函數的輸出,是由collector處理的,它並不是簡單的將結果寫到磁碟。它利用緩沖的方式寫到內存,並處於效率的考慮進行預排序。每個map都有一個環形的內存緩沖區,用於任務輸出,默認緩沖區大小為100MB(由參數io.sort.mb調整),一旦緩沖區內容達到閾值(默認0.8),後台進程邊開始把內容寫到磁碟(spill),在寫磁碟過程中,map輸出繼續被寫到緩沖區,但如果緩沖區被填滿,map會阻塞知道寫磁碟過程完成。寫磁碟將按照輪詢方式寫到mapred.local.dir屬性制定的作業特定子目錄中。
寫出緩沖區:collect將緩沖區的內容寫出時,會調用sortAndSpill函數,這個函數作用主要是創建spill文件,按照key值對數據進行排序,按照劃分將數據寫入文件,如果配置了combiner類,會先調用combineAndSpill函數再寫文件。sortAndSpill每被調用一次,就會寫一個spill文件。
合並所有Map的spill文件:TaskTracker會在每個map任務結束後對所有map產生的spill文件進行merge,merge規則是根據分區將各個spill文件中數據同一分區中的數據合並在一起,並寫入到一個已分區且排序的map輸出文件中。待唯一的已分區且已排序的map輸出文件寫入最後一條記錄後,map端的shuffle階段就結束了。
在寫磁碟前,線程首先根據數據最終要傳遞到的recer把數據劃分成響應的分區(partition),在每個分區中,後台線程按鍵進行內排序,如果有一個combiner,它會在排序後的輸出上運行。
內存達到溢出寫的閾值時,就會新建一個溢出寫文件,因為map任務完成其最後一個輸出記錄之後,會有幾個溢出寫文件。在任務完成前,溢出寫文件會被合並成一個已分區且已排序的輸出文件。配置屬性io.sort.facor控制一次最多能合並多少流,默認值是10。
如果已經指定combiner,並且寫次數至少為3(通過min.mum.spills.for.combine設置)時,則combiner就會在輸出文件寫到磁碟之前運行。運行combiner的意義在於使map輸出更緊湊,捨得寫到本地磁碟和傳給recer的數據更少。
寫磁碟時壓縮:寫磁碟時壓縮會讓寫的速度更快,節約磁碟空間,並且減少傳給recer的數據量。默認情況下,輸出是不壓縮的,但可以通過設置mapred.compress.map.output值為true,就可以啟用壓縮。使用的壓縮庫是由mapred.map.output.compression.codec制定。
recer獲得文件分區的工作線程:recer通過http方式得到輸出文件的分區,用於文件分區的工作線程數量由tracker.http.threads屬性指定,此設置針對的是每個tasktracker,而不是每個map任務槽。默認值為40,在大型集群上此值可以根據需要而增加。
Rece端:
復制階段:rece會定期向JobTracker獲取map的輸出位置,一旦拿到輸出位置,rece就會從對應的TaskTracker上復制map輸出到本地(如果map輸出很小,則會被復制到TaskTracker節點的內存中,否則會被讓如磁碟),而不會等到所有map任務結束(當然這個也有參數控制)。
合並階段:從各個TaskTracker上復制的map輸出文件(無論在磁碟還是內存)進行整合,並維持數據原來的順序。
Rece階段:從合並的文件中順序拿出一條數據進行rece函數處理,然後將結果輸出到本地HDFS。
Map的輸出文件位於運行map任務的tasktracker的本地磁碟,現在,tasktracker要為分區文件運行rece任務。每個任務完成時間可能不同,但是只要有一個任務完成,rece任務就開始復制其輸出,這就是rece任務的復制階段( phase)。rece任務有少量復制線程,因此能夠並行取得map輸出。默認值是5個線程,可以通過mapred.rece.parallel.copies屬性設置。
Recer如何得知從哪個tasktracker獲得map輸出:map任務完成後會通知其父tasktracker狀態已更新,tasktracker進而通知(通過heart beat)jobtracker。因此,JobTracker就知道map輸出和tasktracker之間的映射關系,recer中的一個線程定期詢問jobtracker以便獲知map輸出位置。由於recer有可能失敗,因此tasktracker並沒有在第一個recer檢索到map輸出時就立即從磁碟上刪除它們,相反他會等待jobtracker告示它可以刪除map輸出時才刪除,這是作業完成後最後執行的。
如果map輸出很小,則會被直接復制到rece tasktracker的內存緩沖區(大小由mapred.job.shuffle.input.buffer.percent控制,占堆空間的百分比),否則,map輸出被復制到磁碟。一旦內存緩沖區達到閾值大小(由mapred.iob.shuffle.merge.percent)
或達到map輸出閾值大小(mapred.inmem.threadhold),則合並後溢出寫到磁碟中。
隨著磁碟上副本增多,後台線程會將他們合並為更大的、排好序的文件。注意:為了合並,壓縮的map輸出必須在內存中被解壓縮。
排序階段:復制階段完成後,rece任務會進入排序階段,更確切的說是合並階段,這個階段將合並map輸出,維持其順序排列。合並是循環進行的,由合並因子決定每次合並的輸出文件數量。但讓有可能會產生中間文件。
rece階段:在最後rece階段,會直接把排序好的文件輸入rece函數,不會對中間文件進行再合並,最後的合並即可來自內存,也可來自磁碟。此階段的輸出會直接寫到文件系統,一般為hdfs。
細節:這里合並是並非平均合並,比如有40個文件,合並因子為10,我們並不是每趟合並10個,合並四趟。而是第一趟合並4個,後三趟合並10,在最後一趟中4個已合並的文件和餘下6個未合並會直接並入rece。
⑩ 資料庫中數據冗餘會產生什麼問題
數據冗餘的缺點:
1、存儲空間的浪費。
2、數據交互和資料庫訪問執行效率降低。
但適當的數據冗餘又能加快查詢。數據冗餘究竟是好是壞還是要根據自己所做的項目進行合理的取捨。
當同一數據塊存儲在兩個或多個單獨的位置時, 就會發生數據冗餘。假設創建了一個資料庫來存儲銷售記錄, 並在每個銷售的記錄中輸入客戶地址。但是,有多個銷售到同一客戶,因此同一地址被多次輸入。重復輸入的地址是冗餘數據。
(10)存儲冗餘62模式擴展閱讀
一定的冗餘可以提升性能
1、空間換時間
有一張字典表 city 其中有 id 和 cityName 兩個欄位,有一張業務表,其中有 id 、cityId、XXX、XXX…欄位。如果查詢業務表的話,就必須 join 一下 city 字典表,如果業務表很大很大,那麼就會查詢的很慢,這個時候我們就可以使用冗餘來解決這個問題。
直接將業務表中的 cityId 更換成 cityName,這樣我們在查詢業務表的時候就不需要去 join 那一張 city 的字典表了。這樣的方式顯然是不符合我們資料庫設計的範式的,但是這樣的冗餘或許很有必要。
2、查詢某一個狀態值數據
業務表中有一個欄位 status 用來存儲提交和未提交,假設這張表中未提交的數據相對於提交的數據是很少的,當用戶查詢所有未提交的數據的時候,就需要在全部的數據,然後篩選出未同意的數據。如果這張業務表非常的龐大,那麼這樣的查詢的效率就非常的慢。
這個時候我們就可以把這張業務表中的未同意的數據冗餘到一張新表中,這樣用戶查詢未提交的數據的時候就可以直接在這張未提交的表中查詢,查詢速度提交很多。