分佈式文件與分佈式存儲系統學習總結(持續更新)

存儲系統知識

Write Ahead Log

  • 問題引入

存儲系統在運行過程中,每時每刻都在發生數據更新。如對文件數據的CRUD.

對於中心控制節點來說,這些都會涉及到metadata的更新操作。

爲了保持元數據和文件數據的狀態一致性,系統所有對數據的操作對應的元數據變更都應該要持久化到元數據db中。

那假如這個metadata db是在外存的,那麼是否意味着高頻的io操作?是否可以引入延時寫入的方法?

Write Ahead Log

核心意思:在把metadata的變更操作寫到持久穩定的db之前,會預寫入一個log中,然後再由另外的操作把log apply到外部持久的db中。

當系統要處理大量的事務操作的時候,WAL與實時同步db相比效率會更高。

WAL的日誌還可以在利於數據庫的事務回滾。

WAL執行細節

WAL不記錄metadata本身,而是記錄進行的操作的log
在這裏插入圖片描述
數據庫的操作記錄,首先會寫到內存的buffer中,當buffer滿或者人工觸發flush的時候,會把事務數據寫出到WAL的log中。

系統在每次完成一個操作的時候,同時會把改動應用到memory和WAL的buffer內,再由buffer 寫到外存的metadata db中。

當老的WAL被apply到元數據db的時候,可以用commitId來標識當前最新的事務。所以整個過程可以理解爲做一次checkpoint,即當前db的狀態+WAL = 新的db狀態

Write ahead log

分佈式存儲系統知識

分佈式存儲要解決的問題:

1.數據分佈
如何把數據分佈到多臺服務器才能夠保證數據分佈均勻?數據分佈到多臺服務器後,如何實現跨服務器的讀寫操作?

2.一致性
如何把數據的多個副本複製到多臺服務器並且保證一致性?

3.容錯
如何檢測服務器故障?如何自動把出現故障的服務器的數據和服務遷移到集羣中的其他服務器?

4.負載均衡
新增的服務器和集羣正常運行過程中如何實現自動負載均衡?數據遷移過程如何保證不影響已有事務?

5.事務與併發控制
如何實現分佈式事務?實現多版本併發控制?

6.壓縮與解壓縮
如何根據數據特點設計合理的壓縮算法?

分佈式存儲分類

  • 非結構化數據

  • 結構化數據

  • 半結構化數據
    介於非結構化數據和結構化數據之間,HTML文檔屬於半結構化數據。其與結構化數據最大的區別在於,半結構化數據模式結構內容混在一起

分佈式文件系統

存儲大量的圖片,照片,視頻等非結構化數據對象,叫做Blob(Big binary object data)

分佈式文件系統用於存儲Blob對象,塊存儲或者大文件存儲。

我們首先定義分佈式文件系統的基本存儲單元爲數據塊chunk

文件系統內按照chunk來組織數據,每個數據塊的大小大致相同。每個chunk可以包括多個Blob對象或者定長塊,一個大文件也可以拆分爲多個chunk。

這些chunk會分散到存儲的集羣中。

用戶對存儲數據的操作實際上會映射爲底層數據塊的操作。

分佈式鍵值系統

用於存儲關係簡單的半結構化數據,提供基於Primary Key的CRUD

分佈式表格系統

存儲較爲複雜的半結構化數據,支持掃描某個主鍵範圍,以表格爲單位組織數據,每個表格包括很多行,通過主鍵來標識其中一行。

分佈式數據庫

典型的系統包括MYSQL數據庫分片集羣。

Ceph

Kubernetes中pod數據的持久化可以利用Ceph

Ceph提供了對象存儲,塊存儲和CephFs文件系統存儲三個功能。

  • 對象存儲
    最簡單的Key-Value存儲,還有S3,Gluster

  • 塊存儲
    接口通常以QEMU Driver或者Kernel Module方式存在。

  • 文件存儲

支持POSIX接口,與傳統文件系統如Ext4同屬於一個類型。

Ceph架構

在虛擬化中,比較常用的是Ceph的塊設備存儲,Ceph集羣可以提供一個raw格式的塊存儲作爲虛擬機實例的硬盤

Ceph相比其他存儲優勢在於,可以充分利用存儲節點上的計算能力,存儲每一個數據的時候,都會通過計算得出這個數據存儲的位置,儘量把數據分佈均衡。

在這裏插入圖片描述

  • Ceph的核心組件
    Ceph OSD:
    Object Storage Device,主要功能是存儲,複製,平衡和恢復數據,一塊硬盤或者硬盤的一個分區對應一個OSD,由OSD來進行對硬盤存儲的管理。

架構實現:
1.物理磁盤驅動器
2.Linux文件系統(XFS,Ext4,BTRFS)
3.Ceph OSD

OSD還有一個Journal盤

寫數據到Ceph集羣的時候,先把數據寫到Journal盤中,每隔一段時間再把journal盤中的數據刷寫到文件系統中。

爲了使得讀寫時延更小,Journal盤一般採用SSD,這給予文件系統足夠的時間來合併寫入磁盤,可以說Journal盤就相當於一個緩存。

Ceph Monitor:
負責監視Ceph集羣,維護Ceph集羣的健康狀態,同時維護Ceph集羣中的MAP.

這些MAP是RADOS的數據結構,存儲着集羣中所有成員,關係,屬性等信息以及數據的轉發。當用戶需要存儲數據到Ceph集羣的時候,OSD首先需要通過Monitor來獲取最新的Map圖,然後根據Map圖和object id計算出數據最終的存儲位置。

Ceph MDS:

保存的是文件系統服務的元數據。對象存儲和塊存儲不需要這個服務。

底層架構是RADOS,作爲Ceph的核心,用戶數據的存儲最終是靠其進行

RADOS由OSD和Monitor組成
在這裏插入圖片描述
LIBRADOS: 操控RADOS的第三方庫
RADOSGW: 一套RESTFUL網關
RBD:通過Linux內核客戶端和QEMU/KVM驅動提供分佈式的塊設備
CEPH FS: 一個兼容POSIX的文件系統

Ceph如何保持數據均衡分佈?

對象存儲中,數據和object的關係:
用戶要把數據存儲到Ceph集羣的時候,存儲的數據會分割成多個object,每一個object都會有一個object id,object是Ceph存儲的最小單元。

object和pg的關係:一個pg包含了多個object,每一個object都會映射到某個特定的pg中。

pg與osd關係: pg需要通過映射到osd區存儲,一個pg可以映射到多個osd,其中一個副本爲主副本,其餘的都是從副本

pg與pgp關係
pgp個數關係到pg的分佈
一個pool可能包含多個pg,一個pg可能包含多個obj
在這裏插入圖片描述

Ceph可以使用CRUSH算法來根據存儲設備的權重來計算數據對象的分佈。

權重設計會根據磁盤的容量和讀寫速度來設置。

CRUSH是根據Cluster Map,數據分佈策略和一個隨機數來決定數據最終的存儲位置

ref

https://www.cnblogs.com/luohaixian/p/8087591.html

Linux文件系統

inode

文件存儲在硬盤上,硬盤的最小存儲單位叫做扇區,每個扇區會存儲512byte

操作系統在讀取硬盤的時候,不會一個個扇區讀取,而是會一次性連續讀取多個扇區,多個扇區組成一個block。也就是說讀取硬盤的時候是按照塊來讀的。

塊通常是8個sector組成一個block。

文件數據都存儲在block中,所以我們還必須要找到一個地方存儲文件的metadata,如文件的創建日期,大小,創建者等。

那麼存儲文件metadata的區域叫做inode,中文叫作"索引節點"

每一個文件都有一個對應的inode

inode內容

Size 文件的字節數
Uid 文件擁有者的User ID
Gid 文件的Group ID
Access 文件的讀、寫、執行權限
文件的時間戳,共有三個:
Change 指inode上一次變動的時間
Modify 指文件內容上一次變動的時間
Access 指文件上一次打開的時間
Links 鏈接數,即有多少文件名指向這個inode
Inode 文件數據block的位置
Blocks 塊數
IO Blocks 塊大小
Device 設備號碼

inode 大小

inode也會消耗硬盤空間,所以硬盤格式化的時候,操作系統會把硬盤分成兩個區域。一個是數據區,存放文件數據,另外一個是inode區,存放inode。

inode的數量在格式化的時候就已經給定了

一般每1KB或者2KB就會設置一個inode,那麼在一塊1GB的硬盤中,每個inode的節點大小爲128字節,每1KB就設置爲inode,那麼inode table大小就會達到128MB.

如果inode花光了,就無法再硬盤上創建新文件了。

inode號碼

操作系統怎麼識別不同的文件?
用inode號碼,linux是不使用文件名而是用inode號碼來識別文件的。文件名只是inode便於識別的別稱。

用戶通過文件名打開文件的步驟:

1.系統先找到這個文件名對應的inode號碼
2.通過inode號碼找到inode信息
3.根據inode信息找到文件數據所在的block,讀取數據

目錄文件

在linux中,目錄也是一種文件,打開目錄實際上就是打開文件。

目錄文件包含什麼呢?

包含一系列目錄項的列表,每個目錄項由兩部分組成:所包含文件的文件名,以及該文件名對應的inode號碼

硬鏈接

linux中多個文件可以同時指向一個inode,這意味着可以用不同的文件名訪問同樣的文件內容。

其中一個文件對內容進行修改,會影響到所有文件名。

刪除一個文件名,不會影響另外一個文件名的訪問。

inode信息中有一項叫做連接數,記錄着指向inode文件名的總數。

當inode==0的時候,表名沒有文件名指向這個inode,系統會回收這個inode號碼,以及其對應的block區域。

目錄文件中的"鏈接數",創建目錄的時候會在目錄產生".“和”…"兩個目錄項。

前者的inode就是當前目錄的inode,等同於當前目錄的hard link

"…“的inode就是當前目錄的父目錄的inode號碼,等同於父目錄的"hard link”

所以任何一個目錄的"hard link"總數,總是等於2+其子目錄總數

軟連接

文件A和文件B的inode號碼不一樣,但是讀取A的時候,系統會自動將訪問者導向文件B。

無論打開什麼文件,最終讀取的都是文件B,稱A爲文件B的軟連接或者符號鏈接。

因爲文件A指向的是文件B的文件名,而不是B的inode,B的連接數不會因此發生變化

ext4 extent

對於文件系統,每個文件都會對應一系列的磁盤塊。

那這個文件邏輯塊號和磁盤塊號的映射關係就存儲在inode中。

一個文件的邏輯塊號是連續的,磁盤塊號不一定連續。

ext4文件系統採用extent來保存文件邏輯塊號和磁盤塊號的關係

ext4中的一個inode可以直接存放4個extent.

邏輯塊號和磁盤塊號有點像虛擬地址和物理地址的關係

ext4怎麼把一個filename和一個inode綁定在一起?

  • inode存放文件元數據,沒有存放filename
  • 所以必然存在一個文件,保存着filename和inode之間的對應關係。
  • 這個對應關係保存在目錄文件的block中
  • 在這裏插入圖片描述
    但如果目錄層數太多,不可能對於每個路徑都要讀取對應目錄文件來找到是否有目錄文件。所以在內存中有DEntry目錄緩存,存放文件路徑和其對應數據信息的對應關係。(/home 和 文件名和inode號的表)

Linux VFS

  • superblock: 文件系統信息
  • 索引節點對象: inode 存儲着文件元數據
  • 目錄項對象 DEntry: 提供目錄緩存
  • 文件對象 File: 一個文件描述符對應一個打開的文件

文件的實現

文件是如何在存儲器上實現的?即研究外村分配方式與文件存儲空間的管理。

  • 外存分配方式

指的是如何爲文件分配磁盤塊?

兩種方式:靜態分配和動態分配

前者是在文件建立的時候,一次性分配所需的全部空間
後者是可以根據動態增長的文件長度進行分配,甚至可以一次分配一個物理塊。

常見的分配方法:

1.連續分配
優點是查找速度快,缺點就是容易產生碎片
預先分配空間的時候其實是要用戶事先知道空間的大小
在這裏插入圖片描述

2.鏈接分配
適用於用戶事先不知道文件的大小,則採用連接分配方式。

鏈接分配解決了連續分配的所有問題。採用鏈接分配,每個文件是磁盤塊的鏈表;磁盤塊可能會散佈在磁盤的任何地方。目錄包括文件第一塊和最後一塊的指針。例如,一個有5塊的文件可能從塊 9 開始,然而是塊 16、塊 1、塊 10,最後是塊 25(圖 2)。每塊都有下一塊的一個指針。用戶不能使用這些指針。因此,如果每塊有 512 字節,並且磁盤地址(指針)需要 4 字節,則用戶可以使用 508 字節。

在這裏插入圖片描述

缺點: 不能隨機訪問盤塊

3.索引分配

每個文件都有自己的索引塊,這是一個磁盤塊地址的數組。索引塊的第 i 個條目指向文件的第 i 個塊。目錄包含索引塊的地址(圖 4)。當查找和讀取第 i 個塊時,採用第 i 個索引塊條目的指針。
在這裏插入圖片描述

ref

http://c.biancheng.net/view/1302.html

磁盤調度算法

  • 先來先服務算法
    沒啥好說的

  • SSTF(最短尋道時間優先)算法
    選擇與當前磁頭所在的磁道距離最近的請求作爲下一次服務的對象
    磁盤移動臂的方向會隨時改變,可能會引起飢餓現象

  • 電梯調度掃描算法
    在磁頭前進方向上查找最短尋找時間的請求,只有在前進方向上沒有請求的時候,才調轉方向

  • 循環掃描算法
    規定磁頭單向移動,自裏向外,到了最外就重新從裏觸出發,對於每個磁道來說都是公平的

ref

inode介紹
ext4介紹

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章