A. 電腦經常出現"0x0002" 是什麼意思
軟體在內存中調試錯誤,發生異常
Google File System(簡稱GFS)是適用於大規模且可擴展的分布式文件系統,可以部署在廉價的商務伺服器上,在保證系統可靠性和可用 性的同時,大大降低了系統的成本。GFS的設計目標是高性能、高可靠、高可用性。
GFS把機器故障視為正常現象,可以很好地處理系統故障。GFS系統通常會部署在上百台甚至上千台廉價伺服器上,並會有相當多台廉價伺服器上部署GFS Client來訪問GFS服務,所以應用故障、操作系統bug、連接故障、網路故障、甚至機器供電故障都是經常發生的故障。GFS系統可以支持系統監控、故障檢測、故障容忍和自動恢復,提供了非常高的可靠性。其次,GFS系統中的文件一般都是大文件,且文件操作大部分場景下都是append而不是overwrite。一旦文件寫入完成後,大部分操作都是讀文件且是順序讀。
GFS提供了非標准(比如POSIX)的文件系統介面,支持 create、delete、open、close、read以及write。另外GFS支持snapshot和record append操作。snapshot可以以很低的代價創建文件或者目錄樹的拷貝,record append可以支持多個client並發地向同一個文件append data,同時還能保證每個client的append操作的原子性。
master記錄了文件系統的metadata,包括名字空間、許可權控制信息、文件到chunk的mapping以及chunk的分布。master也負責chunk的lease管理、無用chunk的垃圾回收、chunk遷移等。master定期與chunkserver通信,向chunkserver發送指令並搜集chunkserver的狀態。GFS client通過GFS的API與GFS系統通信(讀寫數據)。client向master請求獲取metadata,真正的讀寫數據是直接與chunkserver交互。client和chunkserver都不cache文件數據。因為大部分應用都是基於API來streaming read 大文件且系統的文件數據太多,所以client緩存文件數據沒有意義。chunkserver所在機器的Linux的buffer cache以及cache了頻繁訪問的數據,chunkserver也是沒有去cache文件數據的。
單點master大大簡化了系統設計,因為master知曉所有的meta信息,所以可以執行更加復雜的chunk位置分配和副本策略。但是,在讀寫數據時必須降低master的參與,以避免單點的master稱為系統瓶頸。client不會通過master來讀寫文件數據,但是client會向master發送查詢chunk位置分布的請求,然後client端緩存chunk的分布信息,然後直接向chunkserver讀寫數據。大致的讀過程如下:
1、client根據文件名、byte offset以及chunk size計算出要讀取的文件的chunk index
2、client通過文件名、chunk index向master查詢chunk的分布
3、master回復chunk handler以及副本分布
4、client 緩存chunk的meta信息,key由文件名和chunk index組成
5、client從chunk的分布信息中查找距離自己最新的chunkserver,並發送查詢請求。查詢請求中包括chunk hander以及byte range。後續對相同chunk的查詢不需要再次向master查詢meta信息,因為client已經緩存了meta信息。
chunk size是GFS系統的關鍵參數,通常設置為64MB,遠大於文件系統的block大小。每個chunk的副本都chunkserver所在機器上以Linux file存儲。之所為將chunk size定為64MB,主要有以下考慮:
1、可以減少client訪問master查詢meta信息的次數,降低master的訪問壓力。因為chunk size設計比較大,順序訪問一個超大文件時因為chunk數較少且client緩存了chunk meta信息,所以訪問master的次數就會降低。甚至,client可以緩存所有文件的chunk的meta信息,就算是隨機讀文件,master也不會成為系統性能瓶頸。
2、可以減少網路開銷,保持client與chunkserver的TCP連接,可以執行更多的chunk操作。
3、可以減少master上需要在內存中記錄的meta data數據量,降低master的內存佔用。
size大的缺點是:小文件包含很少的chunk,甚至只有一個。這樣的話,在多個client高並發查詢該小文件時對應的chunk會成為熱點。實際上,這種情況在GFS系統中很少發生,因為大部分client的操作都是順序讀大文件。但是,考慮以下場景,我們部署一個服務的二進制文件到GFS系統中,然後數百台的伺服器同時查詢二進制文件並啟動服務,此時該二進制文件副本所在的chunkserver立馬就會成為查詢瓶頸。當然,可以通過增加副本數和分散伺服器的查詢時間來解決這種場景下的問題。
master主要存儲三種類型的metadata:file和chunk的名字空間,file到chunk的mapping信息以及chunk的副本分布。所有的metadata都在master的內存中存儲。前兩種meta信息可以持久化存儲,將操作日誌存儲在master的本地磁碟以及將備份日誌存儲在遠端機器上。master不持久化存儲chunk的副本分布信息,而是通過與chunkserver交互來獲取chunkserver上的chunk信息。
4.1 in-memory data structure
meta信息在內存中,所有master的操作很快。另外,master可以高效地定期在後台scan所有的meta數據,來執行垃圾回收、副本修復、均衡等。metadata都記錄在內存中,所以GFS系統會比較關注chunk的數量以及master的可用內存量。但是在實際場景下,這不是問題。每個64MB的chunk的metadata小於64位元組,大部分的chunk都是滿負荷存儲的,除了文件最後一個chunk的空間是沒有完全被佔用。由於文件的名字空間採用了前綴壓縮的方式存儲,單個文件的meta信息也是小於64位元組。如果需要擴大系統規模的話,可以很簡單地通過增大master的內存就可以了。相比於系統的高可靠、高性能和簡潔性,增加內存是很最小的代價了。
4.2 chunk 分布
並沒有持久化存儲chunk的副本分布信息,而是在master啟動時向chunkserver查詢其chunk信息,然後通過heartbeat來持續更新master的副本分布信息,以與chunkserver數據保持一致。GFS起初設計時嘗試將chunk的分布信息持久化存儲在master端,隨後發現通過master啟動時拉取然後通過heartbeat同步chunk信息的方式更簡單。因為,當chunkserver加入、退出、名字改變、重啟等行為經常發生,這會導致維護master的chunk meta數據的正確性是非常困難的。從另一個角度考慮就是,只有chunkserver匯報的chunk信息才是集群中最真實的chunk分布,因為master不需要自己維護一個chunk分布狀態,只需要以chunkserver的狀態匯報為准即可。
4.3 操作日誌
日誌記錄了GFS集群數據更改的歷史記錄。操作日誌對GFS來說是至關重要的,因為它不僅是metadata的持久化記錄,還記錄了並發操作的時序。因為操作日誌很重要,所以必須可靠地存儲。在metadata的change沒有持久化之前,client是不能看到的數據的更改。當client修改數據時,操作記錄需要保存在多個遠端機器上,而且只有當操作記錄持久化存儲在本地和遠端以後,才會回復client數據更改成功。
可以通過回放操作日誌來恢復文件系統。為了減少系統啟動時replay的時間,必須縮減回放的日誌量。master可以定期存儲metadata的checkpoint,master重啟時可以從checkpoint載入metadata,然後回放checkpoint之後的少量日誌即可。
1、client向master查詢chunk的primary所在的chunkserver以及其他副本的分布,如果沒有primary的花,master會選擇一個作為該chunk的primary
2、master回復client primary和其他副本的分布信息。client會cache返回的metadata
3、client將數據發送所有的副本。client可以以任意順序執行。每個chunkserser都會在內存的LRUbuffer中記錄數據。
4、當所有的副本都返回已經接收數據成功後,client會向primary發送一個寫請求。primary會為每一個數據更改的請求附加一個序列號,數據更改是按照序列號的順序執行的。
5、primary將數據更改同步到其他副本中,副本也是按照序列號執行數據更改操作。
6、primary接收到其他副本回復的數據操作完成
7、primary返回client結果。期間發生的所有錯誤都會報給client。
GFS集群一般都會有上百台的chunkserver,分布在多個機架上。chunkserver也會接收來自本機架或者其他機架的上百個client的查詢請求。不同機架的伺服器通信可能會途徑一個或者多個交換機轉發。chunk的副本分布選擇策略主要目的是盡量提高數據的可靠性和可用性,同時最大化地充分利用網路帶寬。所以,僅僅將副本跨機器部署是不夠的。GFS將副本是跨機架部署的,這樣可以保證在一個機架被損壞或者下線時,chunk至少會有副本是可用的。
chunk的副本在下列情況下會被創建:創建chunk、副本修復、rebalance。當master創建chunk時,會選擇存儲該chunk副本的chunkserver。主要考慮以下幾點:
1、新副本所在chunkserver的磁碟利用率低於系統的平均水平
2、限制每個chunkserver最近一段時間創建chunk的數量
3、每個chunk的所有副本不能都在一個機架
chunk的副本數少於一定數量是,master會復制一個副本。這可能發生在chunkserver宕機或者chunkserver匯報自己的副本損壞或者chunkserver所在機器的磁碟損壞等等。每個chunk 復制任務都有優先順序,按照優先順序由高到低子master中排隊等待執行。master還會定期掃描當前副本的分布情況,一旦發現磁碟使用量或者機器負載不均衡,就會發起負載均衡操作。無論是chunk創建、chunk復制還是負載均衡,選擇chunk副本的位置的策略都是相同的,並且需要限制副本修復和均衡的速度,否則會影響系統的正常讀寫服務。
Google的成功表明單master的設計師可行的。這不僅簡化了系統,而且能夠較好地實現一致性,給予性能考慮,GFS提出了「記錄至少原子性追加一次」的一致性模型。通過租約的方式將每個chunk的修改授權到chunkserver從而減少了master的負載,通過流水線的方式復制多個副本以減少延時。master維護的元數據很多,需要設計高效的數據結構,且要保證佔用內存小和支持快照操作。支持COW的B樹可以滿足需求,但是實現確實相當復雜。
C. /proc文件系統的作用
proc 文件系統
在Linux中有額外的機制可以為內核和內核模塊將信息發送給進程-- /proc
文件系統。最初設計的目的是允許更方便的對進程信息進行訪問(因此得名),現在它被每一個有有趣的東西報告的內核使用,例如/proc/moles
有模塊的列表/proc/meminfo 有內存使用的統計表。
使用proc 文件系統的方法和使用設備驅動程序非常相似--創建一個/proc
文件需要的所有信息的結構,包括任何處理函數的指針(在我們的例子中只有一個,當某人試圖從/proc
文件讀時調用的那一個)。然後,init_mole 在內核中登記該結構而cleanup_mole 注銷它。
我們使用proc_register_dynamic(這是在2.0 版中的情況,在2.2 版中如果我們將節點設置為0系統將自動為我們做到)
的原因是我們不想預先決定我們的文件的節點數字,而是為防止沖突而由內核決定它。通常的文件系統存在於磁碟上而不是內存中(/proc
在內存中),在這中情況下,節點數是是指向文件的索引節點所在的磁碟位置的指針。節點包含文件的信息(例如文件的存取許可權)和指向磁碟位置或文件數據可以
被找到的幾個位置的指針。
因為當文件被打開或關閉的時候不能得到調用,所以在這個模塊中沒有地方放置MOD_INC_USE_COUNT
和MOD_DEC_USE_COUNT,並且,如果文件被打開隨後模塊被移除,我們沒有辦法避免後果。在下一章我們會看到一個艱難的但更靈活的可以處理
/proc文件的實現方式,它也可以讓我們防止那個問題。
Linux 內核提供了一種通過/proc 文件系統,在運行時訪問內核內部數據結構、改變內核設置的機制。盡管在各種硬體平台上的Linux
系統的/proc 文件系統的基本概念都是相同的,但本文只討論基於intel x86 架構的Linux /proc 文件系統。
_________________ _________________ _________________
/proc --- 一個虛擬文件系統
/proc 文件系統是一種內核和內核模塊用來向進程(process)
發送信息的機制(所以叫做/proc)。這個偽文件系統讓你可以和內核內部數據結構進行交互,獲取 有關進程的有用信息,在運行中(on the
fly) 改變設置(通過改變內核參數)。 與其他文件系統不同,/proc 存在於內存之中而不是硬碟上。如果你察看文件/proc/mounts
(和mount 命令一樣列出所有已經載入的文件系統),你會看到其中 一行是這樣的:
grep proc /proc/mounts
/proc /proc proc rw 0 0
/proc 由內核控制,沒有承載/proc 的設備。因為/proc
主要存放由內核控制的狀態信息,所以大部分這些信息的邏輯位置位於內核控制的內存。對/proc 進行一次'ls -l' 可以看到大部分文件都是0
位元組大的;不過察看這些文件的時候,確實可以看到一些信息。這怎麼可能?這是因為/proc
文件系統和其他常規的文件系統一樣把自己注冊到虛擬文件系統層(VFS) 了。然而,直到當VFS 調用它,請求文件、目錄的i-node
的時候,/proc 文件系統才根據內核中的信息建立相應的文件和目錄。
載入proc 文件系統
如果系統中還沒有載入proc 文件系統,可以通過如下命令載入proc 文件系統:
mount -t proc proc /proc
上述命令將成功載入你的proc 文件系統。
proc 文件系統可以被用於收集有用的關於系統和運行中的內核的信息。下面是一些重要的文件:
* /proc/cpuinfo - CPU 的信息(型號, 家族, 緩存大小等)
* /proc/meminfo - 物理內存、交換空間等的信息
* /proc/mounts - 已載入的文件系統的列表
* /proc/devices - 可用設備的列表
* /proc/filesystems - 被支持的文件系統
* /proc/moles - 已載入的模塊
* /proc/version - 內核版本
* /proc/cmdline - 系統啟動時輸入的內核命令行參數
proc 中的文件遠不止上面列出的這么多。想要進一步了解的讀者可以對/proc
的每一個文件都'more'一下或讀參考文獻[1]獲取更多的有關/proc
目錄中的文件的信息。我建議使用'more'而不是'cat',除非你知道這個文件很小,因為有些文件(比如kcore) 可能會非常長。
通過/proc 與內核交互
上面討論的大部分/proc 的文件是只讀的。而實際上/proc 文件系統通過/proc 中可讀寫的文件提供了對內核的交互機制。寫這些文件可以改變內核的狀態,因而要慎重改動這些文件。/proc/sys 目錄存放所有可讀寫的文件的目錄,可以被用於改變內核行為。
/proc/sys/kernel - 這個目錄包含反通用內核行為的信息。/proc/sys/kernel/{domainname, hostname} 存放著機器/網路的域名和主機名。這些文件可以用於修改這些名字。
$ hostname
machinename.domainname.com
$ cat /proc/sys/kernel/domainname
domainname.com
$ cat /proc/sys/kernel/hostname
machinename
$ echo "new-machinename" > /proc/sys/kernel/hostname
$ hostname
new-machinename.domainname.com
這樣,通過修改/proc 文件系統中的文件,我們可以修改主機名。很多其他可配置的文件存在於/proc/sys/kernel/。這里不可能列出所有這些文件,讀者可以自己去這個目錄查看以得到更多細節信息。
另一個可配置的目錄是/proc/sys/net。這個目錄中的文件可以用於修改機器/網路的網路屬性。比如,簡單修改一個文件,你可以在網路上癮藏匿的計算機。
$ echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
這將在網路上癮藏你的機器,因為它不響應icmp_echo。主機將不會響應其他主機發出的ping 查詢。
$ ping machinename.domainname.com
no answer from machinename.domainname.com
要改回預設設置,只要
$ echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all
/proc/sys 下還有許多其它可以用於改變內核屬性。讀者可以通過參考文獻[1], [2] 獲取更多信息。
結論
/proc 文件系統提供了一個基於文件的Linux 內部介面。它可以用於確定系統的各種不同設備和進程的狀態。對他們進行配置。因而,理解和應用有關這個文件系統的知識是理解你的Linux 系統的關鍵。