AWS的大數據分析 — Part2 資料儲存
我們在Part 1提到AWS的大數據分析中會分為四個資料的收集,處理,儲存與分析。在收集,處理,分析階段都必需要從儲存的地方提取資料才能接下來後續的作業。
本篇我們將介紹AWS不同的儲存服務,像是 S3, DynamoDB, DocumentDB, Neptune, TimeStream, FXs fir windows, FSx for Lustre與 Storage Gateway。每一項的儲存服務都適用在不同的場景中。
下圖展示AWS不同的儲存服務適合的的應用。至於下圖中的General Storage我們只會介紹S3的部分。 EBS(像是VM掛載的HHD)與EFS(AWS提供的NAS服務)則不會討論,因為我們的焦點在於如何使用AWS的儲存服務來實現數據分析。
AWS S3(Simple Storage Service)
這是一個AWS提供的Web service,S3提供了 console與API的方式來讓我們與S3的服務互動。簡單的來說我們在S3的儲存中止會看到兩種東西,一個叫做bucket,我們可以把它看成是電腦中的資料夾(不過技術上不是只是使用邏輯看起來會是)。另一個則是object,我們真正把檔案放上S3的名稱。當然在bucket中我們可以再create類似子資料夾的目錄(不過技術上也不是這樣)。
甚麼是Bucket?
buckets的名稱必須具又全世界的唯一性,因為我們取的bucket 名稱後,S3會在這個名稱帶上網址。而每個bucket的範圍是region level。Bucket的命名規則是
- 沒有英文大寫, ˊˇ有小寫
- 沒有 underscore 的 這個 _ 符號
- 字數可以從3–63個字元
- 名字的開頭可以是英文或數字
- 命名的方式不可以用IP address的格式,像是192.168.1.1
甚麼是Object?
就是我們放上去的各類型檔案。每一個Object都會有一個稱為key,也就是這個Object的Full path。像是
<我們的bucket name>/my_file.txt
<我們的bucket name>/my_folder/sub_folder/mt_file.mp3
每一個單一Object(也就是我們放上的檔案)最高可以到5TB的szie。不過建議當我們要用網路上傳大於5GB的檔案時可以用multi-part upload的方式,這是一個用AWS提供的工具上傳時,它會把檔案分成多個部分同時上傳。不管哪個部分檔案先到S3,最後S3會在把所有的部分檔案組合起來。這麼做可以加快上傳速度。每個Object都會有metadata(key-value pairs),而我們也可以對Object貼上Tag來作為其他識別管理。而S3上的Object也可以有版本,意思是如果我們對同一個檔案再上傳一次(不論檔案內容有沒有不一樣),S3都可以幫我們保留上一個檔案版本。
S3的資料一致性模式
S3提供了對Object的 PUTs, GETs, HEADs, DELETEs等操作,但因此基於這些操作我們在S3上的Object的資料一致性會呈現不同的狀況(S3是一種分散式的儲存服務)。
PUTs 操作+ 新的Object,這種是 read-after-write consistency。所有人讀取的都是同一個檔案版本。
HEAD或GET Key name(通常是object有存在),S3提供的就會是read-after-write的最終一致性。
如果是用PUTs來overwrite object或是DELETEs,S3提供也是最終一致性。
若是Update 單一個Key,在S3這是屬於atomic,也因此當我們update單一的key的同時若有其他人來讀取資料,就可能會讀到舊的檔案。
為什麼會有以上這種現象呢?因為S3在底層是一種分散式架構,意思是當我們對S3做一些檔案操作時底層的storage需要時間將資料複製到其他實體的storage。所以造成了若對檔案replace 或delete之後又要立即再讀取該檔案的話,S3可能就會回傳一個舊的檔案,具體取決於變動傳播的狀態。以下會有幾種狀況發生:
List-after-Write 如果我們在放上一個Object(就是檔案),"立刻"要在S3 list key(也就是看到該檔案的列表)。但我們可能有時會看不到該檔案的列表,需要到整個檔案狀態的傳播完成。
Reads-after-write 當我們取代或更新一個object並立刻嘗試讀取它,如果傳播狀態還沒穩定時我們可能就會讀取到這個檔案。
Reads-after-deletes 當我們刪除一個object並立刻嘗試讀取它,如果傳播狀態還沒穩定時我們可能就會讀取到這個檔案。
List-after-deletes 當我們刪除一個object並立刻嘗試list它,如果傳播狀態還沒穩定時我們可能就會list到這個檔案。
S3 storage 的級別
S3 storage依據不同的使用狀況會有不同的使用級別,會分這麼多級別最重要就是費用的問題。你越不想分得哪麼清楚使用S3的服務費用就會越多,相反的你分得越清楚使用狀況費用就會降低。以下為S3的sotrage 級別
- S3 Standard-General Purpose
- S3 Standard- Infrequent Access (IA)
- S3 One Zone- Infrequent Access
- S3 Intelligent Tiering
- S3 Glacier
- S3 Glacier Deep Archive
除了最大的費用問題外,使用這些不同級別的S3 storage還有會影響到資料的Durability / Availability 。
S3 Standard-General Purpose
這是預設的使用級別,資料存放在這個級別的Durability是99.999999999%(資料會同時存在於AWS region的三個AZ中)。11個九的durability意味著要65萬九千年我們才會損失一個檔案,並提供 99.99%(per year)的availability。這種級別的storage適合放Production會用到的資料。
S3 Standard- Infrequent Access (IA)
顧名思義就是我們不會經常用的的檔案,但是要取得時是很快的。但意味著放在這裡的檔案我們的對data 的access cost會比general purpose還要高,但儲存費用低於General purpose。它的data durability的等級與general purpose 一樣是11個9,並橫跨三個AZ。Availability是 99.9%。這種級別的storage適合放Backup或Disaster recovery會用到的資料。
S3 One Zone- Infrequent Access
Durability一樣是11個9,但因為資料只存放在一個Zone,所以Availability只有99.5%。但它提供的效能與前面兩種一樣都是low latency and high performance。費用基本上會比 Standard-IA便宜個20%。這種級別的storage適合放你可以重製的資料,意思是這個級別的資料損失了也沒有甚麼關係。
S3 Intelligent Tiering
這種算是懶人用的或是組織對資料的週期管理沒有Policy的,又想省錢的就可以用這種。這個服務會根據資料的使用狀況自動移動資料到便宜或貴的storage。Durability與General Purpose級別是一樣的,Availability則是99.9%。
S3 Glacier
這是檔案需要長期歸檔的使用級別。若讀者跟我一樣是IT的老鳥可以想成我們以前在傳統機房用的磁帶,備份完成後要叫快遞拿到特殊的倉庫存放的哪種服務。這個服務通常是為了法規法令或組織業務的要求長期存放的(可能一放要放10年的哪種)。提供的Durability一樣是11個九,但儲存費用便宜很多(每GB是0.004 USD)。但相對的要資料取出來就要收你比較多的錢了,而且取出資料的時間需要等待。
在Glacier有兩個術語概念,一個是Archive另一個是Vault。Archive是Glacier裡最基本的單位(你可以把它看成是一個個的磁帶),可以是任何類型的檔案。每一個Archive 都會有一個unique ID與optional description。
另一個是Vault,這是一個為archive製作出來的容器。我們可以把它想成地端機房磁帶的防潮箱,通常這樣的分類是依專案,任務或部門來分別的。
S3 Glacier Deep Archive
這種歸檔服務儲存費用又比Glacier在便宜。但資料取出的時間就比Glacier更久。
S3 Glacier有三種取資料的選擇
- 加急式 :1–5分鐘
- 標準: 3–5小時
- 大批量(bulk): 5–12小時
資料在這至少要放90天
S3 Glacier deep archive有兩種取資料的選擇
- 標準: 12小時
- 大批量(bulk): 48小時
資料在這至少要放180天
下圖為我們的資料存取頻率來決定我們應該放在哪種級別的S3 storage
另外根據不同級別的比較表如下
另外我們剛剛提到,若組織對資料的生命週期管理已經有良好的政策與規則,我們可以使用S3的 lifecycle configuration根據組織的政策與規則自動的移動這些資料到不同級別的storage。
在S3 lifecycle Rules中有兩種動作,一個是transition actions另一個是Expirtion action。 transition是根據規則將資料移動到不同級別的storage,expiration則是根據到期的時間刪除資料。像是刪除放了365天後的資料或黨的舊版本。
而S3的檔案版本功能預設是沒有開啟的,通常在production環境中開啟它會是一個好的作法,防止有人不小心的刪除或修改到檔案讓我們可以回復回來。版本功能的啟用會是在Bucket level。
S3 Replication(複製)
AWS S3提供了以bucket level為基礎的data replication。 要起用replication功能bucket的版本功能必須要被啟動。這個replication可以在同一個AWS region(SRR-same region replication)或不同的Region(CRR- Cross region replication),可以是同一個AWS account或是不同account。這個replication的資料是非同步(asynchronous)的方式。
複製檔案(object)時會一起把object的metadata一起複製過去,且可以複製到不同的storage級別,有可以在replication過程中變更ownership。通常會使用到CRR通常是法規法令的要求或是在不同的國家或區域對access同樣的資料要求同等的低延遲。而使用SRR則是因將logs aggregate到單一個bucket中以進行更簡單的處理,或是為了測試環境所需要的資料replicate一份出來。
S3的存取效能
AWS可以根據存取的需求自動擴展資料的存取需求的(提供的延遲性會在100–200ms之間),但是要根據一些規則才可以,不然會有hot partition的狀況發生。也就是資料的存取全都集中在同一個partition。
S3提供給我們的資料存取操作在一個Bucket中的每一個prefix(就是檔案路徑)的每秒鐘會有至少 3,500次 PUT/COPY/POST/DELETE與 5,500次的 GET/HEAD。而prefix的數量則是沒有限制, 例如我們有以下四個prefix
bucket1/folder1/sub1/file
bucket1/folder3/sub3/file
bucket1/2/file
bucket1/4/file
在同一個bucket下有四個prefix,所以如果我們讀取資料(GET/HEAD)在這四個prefix是平均的話我們就可以有 5,500 x4 = 22,000request(每秒)get/head資料的能力。
S3的Partitioning, 壓縮, 與檔案格式
之前我們提到S3提供高效能的存取與較低存取費用,最主要的技術是靠partitioning,壓縮與選擇最佳的檔案格式。最佳的檔案格式應該是可以被壓縮的,這樣儲存空間才會佔比較小,並且這樣做實質上也會增加在進行資料分析的查詢效能(例如用Athena查詢在S3裡的資料)。在S3中儲存的最佳格式的檔案是Apache Parquet(我們當然也可以存放CSV,JSON等其他任何的檔案在S3中),這是一個用來設計查詢大量資料的壓縮的columnar storage 格式。當我們要對在S3裡的資料做查詢(Query)時會有兩種費用產生。
- 掃描資料的大小
- 掃描的資料量
與以raw format存儲的資料相比,columnar 壓縮格式允許分析查詢掃描更少量的資料,從而提高性能並降低總體成本。
對資料進行partition對效能和成本有類似的影響,因為通過對資料進行partition,我們可以限制每次查詢掃描的資料量,從而提高效能並降低成本。 雖然我們可以使用任何column來對資料進行partition,但基於資料和時間進行partition通常是一種好的做法,這會產生多個等級的partition。 例如,我們可以將信用卡交易存儲在S3中,並且我們可以基於年、月、日和小時進行partition。 這種partition模式將改進在特定時間變量上過濾資料的查詢,從而減少掃描的資料並提高性能。 測試顯示,這可以使查詢速度提高 70%,掃描成本降低 90%。
壓縮提供了類似的效能提升,因為要掃描的資料較少,因此 S3 和分析工具之間產生的網路流量也較少,從而也降低了總體成本。然而,選擇可拆分的壓縮格式很重要,因為拆分檔案允許execution engine通過使用多個讀取器拆分檔案的讀取,進而增加查詢的整體parallelism。不可拆分的檔案會對查詢效能產生負面影響,因為只有一個讀取器可以讀取資料,而其他讀取器則處於閒置狀態。這是分佈式運算中最常見的問題之一,其中worker之間的工作負載不均勻且嚴重傾斜,並影響系統的整體效能。下表列出了最常見的壓縮演算法、它們支援的壓縮比、壓縮過程中算法的速度以及它們的最佳使用。例如,Gzip 是一種非常常用的壓縮方式,它最適合raw存儲,因為它具有很高的壓縮率;然而,由於其不可分割的性質,它不適合平行處理。
加速上傳至S3
AWS提供了以下兩種方式(使用網路)加速我們檔案的上傳,若覺得還是不夠快可以使用AWS的Snowball系列。
Multi-Part upload
這是將檔案拆分成小的檔案同時傳送至S3,檔案本身有100MB以上就可以拆分了,若是5G以上就一定要強制拆分。
S3 Transfer Acceleration
簡單來說就是將檔案傳送到離你最近的AWS Edge location,然後AWS會用自己的專線送回Bucket,這個方式也能跟Multi-Part upload搭配加速傳送
DynamoDB
這是AWS的全託管式,具高可用(HA — replication across 3 AZ)的NoSQL DB服務。可以承受大規模工作負仔的分散式DB。每秒百萬次的request,每次request可以存取萬億(trillions)的row。
Data Type
DynamoDB的table支援不同屬性資料型態,主要分為三種: scalar, document, 與Set
Scalar Data Types
它呈現的是一個value(exactly one value)。scalar type會有number, string, binary, Boolean跟null。下表為每個data type的詳細說明。
Document Data Types
這種呈現的是一種具nested attributes的複雜結構 — 像是我們常看到的JSON結構資料。document type有兩種: list與map。雖然DynamoDB可以支援這種的資料型態,在這種資料形態裡的數字(number)就不會像scalar中的Number有其限制。唯一的限制就是DynamoDB的每一個Item最多只能有400KB。
attribute value不可以是empty set(string set, number set, binary set),但 empty list 與 maps是允許的。下表為每個data type的詳細說明。
Set Types
這裡呈現的其實是多個scalar values,所以才說是一個Set。 set types有 string set, number set, 與binary set。同一個Set裡的Value屬性需要一樣不可以混不一樣屬性的value。這裡跟document type一樣 number的長度沒有限制,並限制在一個Item不能大於400KB。在Set裡的value都是要unique的。set中value的順序不保留; 因此,我們的Application不得依賴於set中元素的任何特定順序。empty sets是不支援的。以下是一個string set, number set, binary set的範例
[“A”,”B”,”C”]
[123,456,78,999]
[“U3Vubnk=”, “UmFpbnk=”, “U25vd3k=”]
DynamoDB的核心觀念
Tables/items/attributes/partition keys and sort key為DynamoDB的四個核心概念。
Tables 這跟一般其他的DB概念差不多,是一群資料的集合(collection)。一樣是將資料存在table裡,並包含了很多個items.
Items 概念像是一個row,一個 tuple或是關聯式DB中的records,items是一組多個屬性,這些屬性(attributes)在tables中的其他items中是唯一可識別的。
Attributes 每個item可能都會有一個以上的屬性。attribute類似關聯式DB中的field or column概念,attribute可以有null。
Partition Keys and Sort Keys 在Item中的第一個屬性是partition keys。從效能角度來看,partition keys非常重要,因為它被用作內部hash function的input,其output決定了這個item在 DynamoDB infrastructure上的物理存儲位置。 item中的第二個屬性是sort keys,它是選用的,用於按sort keys/values順序對資料進行排序。 具有相似partition keys的items存儲在一起以提高效能。 如果兩個items具有相同的partition keys/values,則它們需要具有不同的sort keys/values。
所以parition keys 或 (partition keys + sort keys)這兩種都可以是我們DynamoDB table的Primary keys.
下圖為單獨使用partition keys當作我們的primary keys,在partition keys中的每一個item都是unique。partition keys必須要是diverse,資料才能有效的分佈。
Partition keys + sort keys ,資料是被partition keys給群組起來的。而sort keys就像是range key。例如我們如果經常查詢的資料是依據user id + game id就可以這樣設計(如下圖範例)
secondary index是一種資料結構,它包含來自table的屬性subset和支援Query operation的alternative key。我們可以使用 Query 從index中檢索資料,這類似於對table使用 Query。一個table可以有多個secondary index,這使我們的應用程式可以存取許多不同的query patterns。每個secondary index都與一個table相關聯,從中取得資料。這稱為index 的base table。創建index時,我們可以為index定義一個alternative key(partition keys與sort keys)。還可以定義要從base table project或複製到index 中的attributes。 DynamoDB 將這些attributes與base table中的primary key屬性一起復製到index中。然後,我們可以像query或scane table一樣query 或scan index。
每個secondary index都由 DynamoDB 自動維護。當我們在base table中添加、修改或刪除Item時,該table上的任何index也會update以反映這些更改。
DynamoDB支援兩種型態的 secondary index:
Local Secondary Index(LSI)
LSI 是與base table具有相同partition keys但sort keys不同的index。 LSI中的是"本地"的,因為LSI的每個partition都限定為具有相同partition key/value的base table partition。 任何一個partition key/value的indexed items的總量不能超過 10 GB。 LSI與為被index的table提供的throughput相同。 每個table最多可以定義五個LSI。LSI在create table就要決定要不要使用。下圖為一個具LSI的table範例
Global Secondary Index(GSI)
GSI 是一個帶有partition keys和sort keys的index(其實在DynamoDB裡它也是個table),可以與base table上的keys和sort keys不同。 GSI被認為是“全域的”,因為對index的Query可以跨越base table中的所有資料,跨越所有partition。 GSI沒有像LSI那樣的大小限制,它有自己的provisioned 的read/write throughput,與原始table分開。可以在table create後對其新增或修改。最多可以為每個table定義 20 個GSI,所以我們可以根據我們會經常Query的attribute(也可以視作欄位conlumn)。以下為一個使用不同的attribute作為partition key來建立index。
甚麼是Partition
Partition是DynamoDB存放資料的地方。所謂的partition是table的存儲分配,底層是SSD硬碟,並在 AWS region內的多個AZ之間自動複製。DynamoDB會完全進行partition的管理,我們不需要知道如何管理partition,只要知道如何選擇/設計良好的partition keys與 sort keys。DynamoDB使用hash keys(使用partition key來hash產生的),並根據資料的大小與已經provision的throughput總量來自動畫分partition。
DynamoDB的 Read/Write Capacity
DynamoDB提供對table的大量資料的讀取能力(Read and Write)並提供兩種對資料的read/write模式: on-demand(彈性變動) 與provisioned(fixed capacity)。
On-Demand Capacity Mode
簡單的說就是我們對Application的需求搞不清楚要多少資源時,DynamoDB就提供我們要多少就給多少的data read/write能力(幾個ms 的latency)。這個模式在create table後也可以事後調整,調整時不須需要變動Application任何東西。所以算是懶人用的。在這邊我們不需要特別計算read/write的能力,DynamoDB會掌控一切,但費用可能會很高(因為我們懶得去計算)。
在這模式下的read / write,DynamoDB把它定義為 Read Request Unit與 Write Request Unit。雖然在這模式是自動的,但是沒有算好的話你的AWS帳單可能會爆掉
Read Request Unit
每個request的Read 資料的大小最大是4KB,如果超過4KB就要額外一次的read request。所以我們的計算我們的資料到底需要多少次的request的因素如下
- Item size
- Read type(Eventually consistent 與 strongly consistent)
舉例,我們有一個Item 的Size是 8KB,我們可能需要的read request如下
- 如果strongly consistent read需要兩次的read request
- 如果是eventually consistent read只需要一次read request
- 如果是transactional read需求要四次的read request
Write Request Unit
每次寫入資料的大小最高是1KB,所以如同read 一樣,Iteam資料寫入超過1KB就需要額外的 write request次數。寫入的資料是1KB的話
- Standard write只要一次的write
- transactional write就要兩次
所以拿剛剛8KB的範例要寫入資料的話,standard wriet就要8次write request, transactional write就要16次write request。
On-Demand模式下Dynamodb都會假設你的Application traffic會是兩倍來應對。例如我們的Apllication traffic介於10,000 strongly consistent reads per second 到20,000 strongly consistent reads per second 之間,哪麼DynamoDB就會為我們準備 40,000 strongly consistent reads per second的capacity。如果最高曾來到40,000,DynamoDB就會為我們準備80,000的capacity。
哪為什麼不選彈性的on-demand而有人會選擇provisioned(fixed capacity)呢?除了provisioned可以控制費用不要花太兇,另一個原因在於 "throttling”。因為剛剛講到DynamoDB會為我們準備之前peak time的兩倍的量,但是是在30分鐘的時間區間內,意思是如果Application traffice在30分鐘內是超過兩倍的話,哪DynamoDB就會會進行節流(throttling)。有些Application無法處理這種狀況。
Provisioned Capacity Mode
這跟on-demand mode不一樣,這是固定的資料讀寫的capacity。這表示我們對自己Application讀寫需求是很明確的,並且這麼做也能節省費用。在這個模式下DynamoDB對其table read/write的單位分別是 RCU(Read Capacity Unit)與WCU(Write Capacity Unit)。
Read Capacity Unit(RCU)
因為這是需要先計算好我們Application所需的read能力,所以考慮的因素如下
- Item size
- Type of read(Eventually consistent, strongly consistent, transactional read)
read capacity與On-demand 一樣每次最大是4KB, 所以讀取4KB所需的read request是
- 每秒一次的strongly consistent read
- 每秒兩次的eventually consistent read
- Transactional read requests需要兩個RCU才能實現每秒一次read 4KB資料
RCU計算範例
舉例一 : 每秒 10 次strongly consistent reads,每次 4 KB的. 這樣要多少RCU呢? 10 * 4KB/ 4KB = 10RCU
舉例二: 每秒 16次eventually consistent reads,每次 12KB的. 這樣要多少RCU呢? (16/2) * (12/4)= 24 RCU
舉例三: 每秒 10次strongly consistent reads,每次 7KB的. 這樣要多少RCU呢? 10 * 7KB / 4 = 20 RCU (其中 7/4無條件進位)
DynamoDB的Read consistency
DynamoDB提供的是region level的服務。也就是DynamoDB中的資料會同時存在一個region的多個AZ中。而這樣就會有資料複寫的問題存在,資料的最終一致性通常會在低於一秒內在所有的AZ中完成複寫。也因為這種資料的寫入延遲,DynamoDB提供了兩種資料一致性的模式,Eventually consistent reads與 strongly consistent reads。
eventually consistent reads我們上面提到因為要等資料複寫完成(約一秒內)如果在這個模式下我們是write-after-read,我們會get到未預期的錯誤,因為底層的data replication還沒跑完。所以read-after-write會有錯誤的狀況發生。但是好處Eventually consistent reads以可能以過時的資料為代價而得到最大throughput。
Strongly Consistent Read: 如果是這種模式做write-after-read就會得到正確的值。在Strongly Consistent Read的情況下,DynamoDB 會返回對最新資料的回應,並反映所有先前成功操作的update。 Strongly Consistent Read的問題在於,如果存在網路延遲或中斷,並且我們無法從global secondary index(GSI)進行Strongly Consistent Read,則該read可能不可用。 GetItem、Query、Scan等read operation提供了ConsistentRead參數,可以設置為true,保證DynamoDB在操作過程中使用Strongly Consistent Read。
Write Capac 10ity Unit(WCU)
這邊一樣是每次write 資料的大小是1KB。而若要達成transactional write request(一次寫入1KB)則需要兩個WCU。
哪當如果我們Application的RCU/WCU超過我們當初的設定呢?這時我們跟on-demand mode一樣會遭遇到節流(throttling)。我們會get到一個an HTTP 400 (Bad Request | ProvisionedThrougputExceededException)的error code。這時我們就需要進行retry的機制。不過如果我們有使用AWS SDK的話,這個retry機制已經寫在裡面了,我們的Application不用處理這一個邏輯。
WCU計算範例(標準的write)
舉例一 : 我們每秒寫入 10個object,每個object 2 KB,這樣需要多少WCU呢? 2* 10 = 20 WCU
舉例二 : 我們每秒寫入 6 個object,每個object 4.6 KB,這樣需要多少WCU呢? 6* 5= 30 WCU(4.6要無條件進位)
舉例三 : ,我們每分鐘寫入 120個object,每個object 2KB這樣需要多少WCU呢? 120/60 * 2= 4 WCU
DynamoDB的Auto Scaling與Reserved Capacity
我們可以選擇使用 DynamoDB 的auto scaling來管理table 和global secondary index(gsi) 的throughput容量。 我們可以定義RCU/WCU的範圍(upper-lower),或該範圍內的目標利用率百分比。 隨著工作負載的增加,DynamoDB Auto Scaling 會嘗試維持我們的目標利用率。
AutoScaling可幫助我們獲得預先配置容量的優勢,同時還能在流量突然激增時進行擴展,以避免應用Application受到限制。 如果我們使用 AWS console創建table或GSI,則預設情況下會啟用 DynamoDB Auto Scaling。
根據前面介紹的RCU與WCU還有甚麼是partition。我們舉以下個圖示範例。每個partition的capacity是固定的(10GB大小,3000 RCU,1000 WCU)。而計算公式如下
- By capacity: (Total RCU / 3000) + (Ttoal WCU /1000)
- By size: Total size / 10GB
- Total partitions = Ceiling(MAX(Capacity, Size))
假設我們的table需要 6,000 RCU與 2,400 WCU但服務的資料一開始不到10GB。根據上面的公式會得到三個partitions(如下圖)
Global Tables
DynamoDB Global tables是一種機制,我們可以通過該機制構建完全託管的多區域和multi-master DB,不用自己搞。 在構建Global tables時,我們指定tables用在那些AWS region, DynamoDB 管理在所選region中創建相同tables,然後在它們之間複製資料。 Global tables的一個很好的使用案例是當我們的全球客戶群分佈在多個地理區域(例如,美國、歐洲、中東和亞太地區)時。 選項之一是在每個region中創建三個單獨的table,然後手動跨region複製資料。 這很累也容易出錯,而且設置和配置也很複雜。 一個更懶的選擇是使用 DynamoDB 創建一個Global tables,選擇我們想要創建這些table的region,然後讓 DynamoDB 管理跨這些region複製資料的工作。
DynamoDB Accelerator(DAX)
說白話就是DynamoDB的in-memory cache,而資料的Read/Write都可以透過DAX。DAX主要解決問題
- 減少read/query data的回應時間(microseconds)
- 解決Hot key 的問題(主要針對read負載很重的服務),從而減少所需要的RCU並達到節費的功能。
資料在DAX的TTL預設是5分鐘,當然也可以更改。DAX的cluster最多可以到10個node並分散在多個AZ中以達HA的目的。
DynamoDB Streams
這是一個針對資料在DynamoDB異動的即時記錄,以時間序列的方式來記錄Item的異動(Create/Update/Delete),這些異動的change log都會被放在stream中24小時(與primary keys一起被寫入)。在這裡我們可以查閱一個Item變動之前與之後的樣子。這個服務的資料寫入是非同步式的所以不會對DynamoDB造成效能影響。
這個stream裡的log可以被其他的Application給讀取而能有下一步的回應。例如使用Lambda,當有新的使用者註冊資料寫入(create Item)到DynamoDB時送出歡迎信件。也可以用它來非同步的對兩個不同region的DynamoDB table作資料同步。
DynamoDB Streams- Kinesis Adapter
AWS建議使用 Amazon Kinesis Adapter 利用來自 DynamoDB streams的資料。 DynamoDB streams 的 API 類似於real time processing的 Kinesis Data Streams(我們在part 1中有介紹)。 在這兩個服務中,data streams由shards組成,shards實際上是streams records的容器。 兩個服務的 API 都包含以下內容:
- ListStremas
- DescribeStream
- GetShards
- GetShardIterator
我們的Application可以使用KCL(Kinesis Client Library)與Kinesis adapter互動,參考下圖
DynamoDB 的TTL(Time to Live)
意旨資料在DynamoDB存活的時間,時間到之後就會被自動刪除(如果我們有啟用這項功能的話)。刪除時不會使用到WCU/RCU,而且這是一個由DynamoDB自行運作的background task。主要是不要讓我們經過長時間的運作資料一直增長,進而節省費用。DynamoDB通常會刪除48小時候的items,這也會一更新GSI與LSI。但我們可以使用DynamoDB streams把資料recovery回來。
DynamoDB的使用場景
DynamoDB經常用在以下場景中
- Mobile apps
- Gaming
- Digital ad serving
- Live voting
- Audience interaction for live events
- Sensor networks
- Log ingestion
- Access control for web based content
- Metadata storage for Amazon S3 objects
- Ecommerce shopping carts
- Web session management
但還是有一些不適合的使用場景
- 取與既有的Application搭配RDBMS
- join或複雜的transactions
- 儲存BLOB(Binary Large Object)檔案,這類檔案要放S3但metadata可以放DynamoDB。
- 需要低 I/O rate的大量資料存取(要用S3)
AWS DocumentDB
為何需要DocumentDB呢?這與AWS的理念有關,因為不同的使用場景就要使用不同的工具來解決。如果你手上只有鐵鎚哪你看甚麼問題都像是釘子。下表為不同的資料類型使用不同的型式的資料褲來解決。
DocumentDB非常適合儲存 raw data是JSON格式的資料。而JSON本身是一種半結構化的資料型態,而這種型態資料是關聯式資料庫無法處裡的。JSON document model是自然的map到Application data中,每一個document都可以有著獨立於其他document data的結構。我們可以對document中的任何key進行index,並在整個資料集上運行臨時aggregation和分析。
如我們知道一些關聯式資料庫概念,每一個row都有著相同數量的attribute(就是columns),然而非關聯式資料庫在每一個Item(row)有著不同數量的attributes(columns)。讓我們來看一個情境是適合DocumentDB而非RDBMS。
我們在一個遊戲公司工作,我們已經有了基本的使用者資料的table,然後公司現在要上線一個新遊戲fast。我們想要追蹤在這個遊戲中每一個使用者的狀態,我們這時有兩個選擇,DocumentDB與RDBMS。如果我們用RDBMS並使其資料正規化,我們就會得到兩個tables(如下圖)
這樣的方式適合公司只有一個遊戲,但如果遊戲隨著時間過去越來越來需要上線呢?這時的"資料正規化"對我們要追蹤使用者每個遊戲的狀態會對系統效能造成莫大的負擔,而且在Application layer要維護的代價會越來越高。
而使用DocumentDB,我們只要加一個狀態的屬性就可以了。不需要額外的新增table也不用有一堆的join table,在Application layer的維護也相對簡單。
AWS DocumentDB概觀
這是一個與MongoDB相容的全託管的服務。以下是一些主要的功能:
- 在幾個millisecond 的latency內處理百萬個requests
- 與其他AWS服務高度整合
- 如果原來我們在使用MongoDB,要轉到AWS DocumentDB。我們的Application完全部用做任何code的更動。
在使用AWS DocumentDB時我們不需要先劃定我們需要多少容量,它是用多少算多少,可以從10GB到64TB。如果需要大量的”read” 資料的operation,DocumentDB提供最多15個replica instance。由於這些replicas 都使用同一個storage,我們可以最少的代價在這些replicas nodes間的資料同步。所以replica lag time只會有幾個millisecond而已。AWS DocumentDB提供了 read/write的cluster endpoint與 讀取資料的 reader endpoint,所以我們可以將資料做讀寫分離的設計。因為endpoint的設計所以我們的Application 不用去理會replicas node的增減。新增replicas可以在一分鐘之內完成。我們也可以針對cluster的compute/memory做scale up/down的動作,而這些都只要在幾分鐘內就可以完成。
在Cluster內的監控與管理都是自動化的,亦即如果instance有問題的話,DocumentDB會自動換掉有問題的instance。而DocumentDB是把 DB process與DB cache分開的,所以在instance restart過程中我們的資料不會受到任何影響。
AWS DocumentDB也提供point-in-time recovery(PITR)的功能,亦即我們可以restore cluster的資料到保留期內的任何一秒(最多為最後 5 分鐘)。而這些保留期的資料可以被backup到S3中,最多保留15天。backup的方式是automatic incremental,並且不會影響到cluster的整體效能。
AWS Document DB的架構
下圖為AWS DocumentDB的架構圖。其cluster可以從零個到16個 instance。所有的write operation都必需要透過 primary instance,而 read 可以透過primary或是 read replicas。AWS DocumentDB的instance必須運行在VPC內。
AWS DocumentDB的架構是把 storage與compute分開。在每一個 storage layer,DocumentDB會把資料replica成六份(橫跨多個AZ)來達到fault tolerance與redundancy。
AWS DocumentDB interface
我們有以下方式來操作DocumentDB
- AWS management console
- AWS CLI
- Mongo shell: 連結我們的DocumentDB cluster對其進行 documents的 create/read/update/delete
- MongoDB Drivers
圖形資料庫與AWS Neptune
我們知道關聯式DB的tables是由rows與columns所組成的。其主要目的是儲存資料而非儲存資料之間的關係。在關聯式DB中的資料間的關係是由primary keys and foreign keys所定義的。這施加了諸如參照完整性之類的限制,這不僅在將資料寫入 RDBMS 時很複雜,而且在通過在多個tables之間連接資料來檢索資料時也面臨複雜的挑戰。例如我們在一間航空公司的資料庫,有一個table是 airline passengers(客戶)與另一個table 是trip(客戶的旅程)
Passengers:
Id, Name, Age, Country, PassportNo
Trips:
Id, OriginAirport, DestinationAirport, PassengerId, timestamp
假如我們要知道那些旅客從 DXB(Dubai)到SFO(San Francisco)的話,我們必須join這兩個table才能知道結果。哪如果我們要知道那些旅客從DXB(Dubai)中轉SFO(San Francisco)最後到LHR(London Heathrow)的話,這個SQL語法會再更複雜一些。挑戰在於,關聯式DB是為存儲資料而構建的,不包含資料之間固定關係的概念。
而圖形資料庫使用的是圖行結構進行語義查詢,通過nodes、edges和properties來表示和存儲資料。 該系統的一個關鍵概念是圖型,它將DB中的data item與nodes和edge的集合相關聯。
Nodes代表的是entities(資料本身)與edges代表的是entities之間的關係,而這些關係會被儲存起來與資料本身在一起的。所以當讀取資料時只要一次的operation就可以取得所有相關的資料。
DocumentDB比起關聯式DB的使用場景的優勢有: 社交網路,推薦系統引擎,詐欺偵測 — 當我們要查詢資料與資料資間的關係時都可以很快速的查詢到。如果使用關聯式資料庫要達到這些功能的話,使用的SQL語法的nested queries於複雜的joins會是DBA的一大挑戰。況且過多的joins也會嚴重的增加系統的負擔。
AWS Neptune 概觀
這是AWS提供的全托管式圖形DB。 Neptune engine可以儲存10億個以上的資料之間的關係並提供milliseconds latency的資料查詢。資料的查詢語法支援了Apache TinkerPop, Gremlin, W3C’s SPARQL。
Neptune提供HA架構(含read replicas),point-in-time recovery, 持續備份到S3中,資料的replications是橫跨多個AZ。
Neptune的使用場景
以下為Neptune適合的使用場景
- 詐欺偵測 — 識別信用卡的不正常使用或欺詐賬戶。
- 推薦系統引擎 — 產品推薦,社交推薦(你可能認識的朋友)。
- 知識圖譜 — 構建複雜的知識圖以推薦與當前興趣相似的其他有興趣項目。
- 生命科學 — 疾病和基因相互作用的模型建立。
Storage Gateway
這多用在我們的地端機房與AWS服務同時運作並交換之間的資料,就是混和雲的模式。
混和式的storage需求
我們通常會將儲存需求放到Cloud的原因不外乎可能有著以下的效益
- 通過能夠根據需要即時擴展和縮減資源,可以獲得更高的敏捷性。
- 通過提供各種服務來在雲端平台上處理地端機房的資料,包括機器學習和大規模分析,可以加快創新速度。
- 通過使用靈活的pay-as-you-go模型,減少了過度購買地端設備的需要,並提供了根據資料的使用情況和價值在不同存儲層之間移動資料的能力,從而降低了資料存儲成本。
我們將資料移動到雲端看起來是合乎邏輯的選擇,但有些程式服務在當下可能因為種種原因無法立即跟著資料從地端移動過去。這就造成了地端的程式需要與雲端的資料互通。
我們在之前介紹過將資料移動到AWS的一些服務,像是 multipart PUTs到S3, AWS Snowball系列。而sotrage gateway則是雲端中的資料必須與地端的程式互通的服務。
通常我們在地端Application與雲端的storage一起協同作業會遭遇到以下幾個議題:
- Protocol : Application與storage應該用甚麼樣的協定溝通
- Applications: 地端的程式通常需要low latency的與storage 連結
- management : 通常我們都會希望即使將資料放在cloud的storage中管理的方式也不要差異太大
- networking: 雲端與地端的網路能夠高度整合在一起並具有足夠的韌性來應付網路的任何狀況
AWS Storage Gateway
這是AWS提供的混和雲服務,主要是透過這個服務讓我們地端的Application使用向S3, S3 Glacier, S3 Glacier Deep, EBS, 等儲存服務。AWS storage gateway提供以下針對地端的Applications的主要效益:
- 能夠使用多種協定來溝通,例如NFS, SMB
- AWS storage gateway可以使用local cache的功能來加速經常會被"讀取"的資料。
- 優化地端與AWS之間的網路已加速資料傳輸
- 高度整合我們的地端Application並簡化我們的管理與監控
AWS Storage Gateway提供三種型態的解決方案: file, volume, and type。
File Gateway
這種服務可以讓我們用 NFS(network file system)與SMB(server message block)的協定讓Application與S3 storage來連結傳輸檔案。AWS提供一個VM image(gateway appliance)作為file gateway,這個VM image可以用在Vmware or Hyper-v。這個gateway appliance除了具有data cache的功能外,還能用 parallel streaming的方式優化管理地端與雲端之間的storage traffic。 File gateway可以與以下其他AWS服務整合:
- IAM — for access control
- KMS — 資料加密
- CloudWatch — for monmitoring
- AuditTrial — for稽核
這個服務對S3是非同步式的update。在S3內的加密方式採用SSE-S3,傳輸過程採https加密。這個gatweay appliance對AWS S3會使用 multipart parallel資料上傳與 byte-range 下載來優化地端與AWS之間的network traffic。下圖為我們可以使用storage gateway的部署方式。
Volume Gateway
AWS會提供iSCSI協定的device讓地端的application可以掛載成本地端的硬碟。AWS提供兩種型態: cached and stored。
Cached Volumes
這個方式為全部的資料都會在S3中,但是地端的storage appliance會扮演S3 data cahce的角色(但SLA會比較差),所以提供的是low latency讓Application來存取資料。local cache的大小可以從 1TB到32TB。每個gateway最多可以設定到最高32個volumes。所以單一的storage appliance 最大就提供 1024TB(1PB)的大小。不過也要你地端的storage可以提供這個storage appliance(VM)有這麼大的容量。
Stored Volumes
前一個說的cached volume提供了對地端application高速的資料存取,但有其資料大小的極限(1PB,如果你的資料量真的有哪麼大)。stored volumes是將 資料全部存放在storage appliance中,S3只是這個stored appliance 的非同步資料備份點(point-in-time snapshot)。這個方式有個好處,資料備份到S3是省錢的。
AWS EFS(Elastic File System)
AWS提供的全托管式的NFS服務(NFS v4.1)。這服務可以AWS 的Services與地端的resource來使用。提供的大小最多可以到petabytes的等級容量,而且可以我們依我們再上面的檔案的增減自動的成長或shrinking容量大小。
AWS EFS提供兩種等級的EFS: Standard storage class(EFS standard) and Infrequent Access storage class(EFS IA)。
EFS IA提供的是兼具效能與成本的非經常性檔案存取的storage。我們可以啟用EFS的lifecycle management功能來根據對data的policy來移動資料到EFS IA中。
這兩種級別的storage從邏輯上的設定可以是同一個 file system namespace,在這個file system namespace中我們可以定義兩個不同級別的storage各占的比例是多少。
AWS EFS與其他地端的storage的NFS服務差不多,有著讓大量的VM(在AWS上是EC2)大量同時存取的效能。所以如果我們們在地端有NFS storagte,我們就可以無痛的轉移到AWS EFS上使用。
AWS EFS的服務是region levle的,意味著其服務是橫跨多個AZ的。而mount point是提供在VPC內的,所以如果我們要讓地端的resource使用的話,要嘛是Direct connect要不然就是VPN的方式也可以用VPC peer的方式讓另一個VPC裡的服務來存取。
AWS EFS提供兩種的file system performance :
- General Purpose mode (GP mode, 預設的,大部份的場景使用)
- Max I/O(用在是 scale-out workloads)
這兩種效能的取捨在於 lower metadata latency vs. operations per second limit。 GP 模式提供 EFS 能夠實現的 lower metadata latency,而Max I/O 模式不受任何 IO 限制並提供最高級別的aggregate throughput。
AWS EF也提供了兩種 system performance:
- Bursting throughput Mode(預設): throughput與file system的大小成線性關係,並允許定期突發超過標準數量。這個適合大部分的使用場景。
- Provisioned Throughput Mode: 這是提供固定量的throughput。如果我們的Application的read/write需要持續性的大量讀寫。
AWS EFS的使用場景可以參考下圖
AWS EFS 的Security Model
在這裡AWS EFS提供多個level的資料保護
Layer 1: VPC security,用Network ACL在網路層來保護network access
Layer2:使用標準的POSIx permission來控制誰可以存取那些檔案或目錄
Layer 3: AWS IAM 通過鎖定對 EFS 的administrative access來提供額外的安全層。
Layer 4: 我們可以在EFS的file system中實行加密,這個加密功能必需在create file system時就要決定。
Layer 5:在EFS跟client端之間的資料傳輸進行加密(使用的是TSL 1.2)。
AWS FSx for Lustre
如果EFS還是無法滿足我們的需求呢?比如我們有一堆EC2的VM,每個VM的CPU core可以處理每秒高達 100GB的read呢?這通常會是 grid-computing架構或某些大數據分析的需求所產生的。下圖為有這種需求的狀況使用有的兩種解法
在上圖中我們看到我們看到選項一是將資料copy到EBS的本地端處裡,選項二是copy資料自行建置的shared file system。
上面兩種選項都需要file system。當我們要讀取大量的資料又要求是low latency時,我們可以直接用S3,但是會接到AWS爆掉的帳單。所以我們需要一個file interface來讓我們可以處理這樣的需求。
這種 shared file system會有兩種需求
- POSIX interface
- throughput 與 IOPS是High level的
這樣的解決方案就是平行分散式檔案系統 — Lustre。我們當然可以自建,但就需要人力來維護。所以AWS提供了 FSx的託管服務。