溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何解決DynamoDB的問題

發(fā)布時間:2021-12-23 15:12:29 來源:億速云 閱讀:164 作者:柒染 欄目:數據庫

如何解決DynamoDB的問題,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

DynamoDB 是 Amazon 基于《 Dynamo: Amazon’s Highly Available Key-value Store 》實現的  NoSQL 數據庫服務。它可以滿足數據庫無縫的擴展,可以保證數據的持久性以及高可用性。開發(fā)人員不必費心關注 DynamoDB  的維護、擴展、性能等一系列問題,它由 Amazon 完全托管,開發(fā)人員可以將更多的精力放到架構和業(yè)務層面上。

下面主要介紹作者所在團隊在具體業(yè)務中所遇到的挑戰(zhàn),基于這些挑戰(zhàn)為何最終選型使用 Amazon  DynamoDB,在實踐中遇到了哪些問題以及又是如何解決的。文中不會詳細討論 Amazon DynamoDB 的技術細節(jié),也不會涵蓋 Amazon  DynamoDB 的全部特性。

背景與挑戰(zhàn)

TalkingData 移動廣告效果監(jiān)測產品(TalkingData Ad  Tracking)作為廣告主與媒體之間的一個廣告投放監(jiān)測平臺,每天需要接收大量的推廣樣本信息和實際效果信息,并最終將實際的效果歸因到推廣樣本上。

舉個例子,我們通過手機某新聞類 APP  瀏覽信息,會在信息流中看到穿插的廣告,廣告可能是文字形式、圖片形式、視頻形式的,而不管是哪種形式的廣告它們都是可以和用戶交互的。

如果廣告推送比較精準,剛好是用戶感興趣的內容,用戶可能會去點擊這個廣告來了解更多的信息。一旦點擊了廣告,監(jiān)測平臺會收到這一次用戶觸發(fā)的點擊事件,我們將這個點擊事件攜帶的所有信息稱為樣本信息,其中可能包含點擊的廣告來源、點擊廣告的時間等等。通常,點擊了廣告后會引導用戶進行相關操作,比如下載廣告推薦的  APP,當用戶下載并打開 APP 后,移動廣告監(jiān)測平臺會收到這個 APP 發(fā)來的效果信息。到此為止,對于廣告投放來說就算做一次成功轉化。

如何解決DynamoDB的問題

DynamoDB實踐:當數據量巨大而不可預知,如何保證高可用與實時性?

移動廣告監(jiān)測平臺需要接收源源不斷的樣本信息和效果信息,并反復、不停的實時處理一次又一次轉化。對于監(jiān)測平臺來講,它的責任重大,不能多記錄,也不能少記錄,如果轉化數據記多了廣告主需要多付廣告費給媒體,記少了媒體會有虧損。這樣就為平臺帶來了幾大挑戰(zhàn):

  • 數據量大:有的媒體為了利益最大化可能會采取非正常手段制造假的樣本,產生“虛假流量”,所以廣告監(jiān)測平臺除了會收到真實用戶樣本外,也會收到大量造假的樣本,影響正常的監(jiān)測和歸因。在最“瘋狂”的時候,我們的平臺會在一天內收到  40 億 + 的點擊樣本事件請求。要知道,這些點擊樣本事件是要保留下來作為后續(xù)效果歸因用的,而且樣本有效期大不相同,從最短 12 小時到最長 90  天不等。

  • 數據量不可預知:對于廣告主的大推、應用商店競價排名等一系列的推廣,會導致突發(fā)大量樣本數據流入。面對這些流量不可預知的情況,我們仍要保證系統(tǒng)的正確、穩(wěn)定、實時。

  • 實時處理:廣告主依賴廣告監(jiān)測平臺實時處理的結果來調整廣告推廣策略。因此廣告監(jiān)測平臺需要支持數據實時處理,才能為廣告主更快的優(yōu)化推廣策略提供有力支撐。與此同時,廣告監(jiān)測平臺的處理結果也要實時回傳給媒體方以及廣告主。可以看到,準確性和實時性是系統(tǒng)必須要滿足的基本條件。

  • 樣本存儲:我們的業(yè)務最核心的功能就是歸因,我們要明確例如用戶下載打開 APP 的這個轉化效果是由哪一個推廣活動樣本帶來的——也就是上圖中的第 7  步,當用戶安裝 APP 后,監(jiān)測平臺要對應找到第 1  步中樣本所在推廣活動,這個是一個查詢匹配的過程。對于龐大的歸因樣本數據,有效期又各不相同,我們應該怎樣存儲樣本才能讓系統(tǒng)快速歸因,不影響實時結果,這也是一個很大的挑戰(zhàn)。

最初形態(tài)

在 2017 年 6 月前我們的業(yè)務處理服務部署在機房,使用 Redis Version 2.8 存儲所有樣本數據。Redis  使用多節(jié)點分區(qū),每個分區(qū)以主從方式部署。在最開始我們 Redis  部署了多個節(jié)點,分成多個分區(qū),每個分區(qū)一主一從。剛開始這種方式還沒有出現什么問題,但隨著用戶設置的樣本有效期加長、監(jiān)測樣本增多,當時的節(jié)點數量逐漸已經不夠支撐業(yè)務存儲量級了。如果用戶監(jiān)測推廣量一旦暴增,我們系統(tǒng)存儲將面臨崩潰,業(yè)務也會癱瘓。于是我們進行了第一次擴容。

由于之前的部署方式我們只能將 Redis 的多個節(jié)點翻倍擴容,這一切都需要人為手動操作,并且在此期間我們想盡各種辦法來保護用戶的樣本數據。

如何解決DynamoDB的問題

DynamoDB實踐:當數據量巨大而不可預知,如何保證高可用與實時性?

這種部署方式隨著監(jiān)測量的增長以及用戶設定有效期變長會越來越不堪重負,當出現不可預知的突發(fā)量時就會產生嚴重的后果。而且,手動擴容的方式容易出錯,及時性低,成本也是翻倍的增長。在當時由于機器資源有限,不僅  Redis 需要擴容,廣告監(jiān)測平臺的一系列服務和集群也需要進行擴容。

化解挑戰(zhàn)

經過討論和評估,我們決定將樣本處理等服務遷移到云端處理,同時對存儲方式重新選型為 Amazon  DynamoDB,它能夠滿足我們的絕大部分業(yè)務需求。經過結構調整后系統(tǒng)大概是下圖的樣子:

如何解決DynamoDB的問題

DynamoDB實踐:當數據量巨大而不可預知,如何保證高可用與實時性?

  • 應對數據量大且不可預知:我們的平臺需要接受推廣監(jiān)測連接請求,并進行持久化用于后續(xù)的數據歸因處理。理論上來說系統(tǒng)進來多少廣告監(jiān)測數據請求,DynamoDB  就能存多少數據,只需要一張表就可以存儲任意數量級的數據。不用關心 DynamoDB 擴容問題,在系統(tǒng)運行時我們感知不到存儲正在擴容。這也是 Amazon  官方宣稱的完全托管、無縫擴展。

  • 高可用:Amazon DynamoDB 作為存儲服務提供了極高的可用性,對于寫入 DynamoDB 的全部數據都會存儲到固態(tài)硬盤中,并且自動同步到 AWS  多個可用區(qū),以達到數據的高可用。這些工作同樣完全由 Amazon DynamoDB 服務托管,使用者可以將精力放到業(yè)務架構及編碼上。

  • 實時處理:Amazon DynamoDB 提供了極高的吞吐性能,并且支持按秒維度配置任意級別的吞吐量。對于寫多讀少的應用可以將每秒寫入數據的數量調整成  1000 甚至更高,將每秒讀取的數量降低到 10 甚至更少。吞吐量支持使用者任意設定,在設定吞吐量時除了可以隨時在 Web 管理后臺調整外,還可以通過  DynamoDB 提供的客戶端動態(tài)調整。比如系統(tǒng)在運行時寫入能力不足了,我們可以選擇到 Web 管理后臺手動上調或在代碼中通過調用客戶端 API  的方式實現自動上調。使用客戶端動態(tài)調整的方式會讓系統(tǒng)具備較高的收縮能力,同時還可以保證數據的實時處理,系統(tǒng)數據流量變高了就動態(tài)調整上去,數據流量變低了再動態(tài)調整下來。相比手動調整來看,動態(tài)調整的方式更為靈活?;谝陨蠋c,我們認為  Amazon DynamoDB 可以很輕松的支撐系統(tǒng)的核心業(yè)務能力。對于業(yè)務側需要做的就是,整理好業(yè)務邏輯把數據寫到 DynamoDB 就可以了,剩下的就交給  DynamoDB 去做。

此外還有:

  • TTL:我們利用了 Amazon DynamoDB 提供的 TTL 特性管理那些有生命周期的數據。TTL  是對表中要過期的數據設置特定時間戳的一種機制,一旦時間戳過期 DynamoDB 在后臺會刪除過期的數據,類似于 Redis 中的 TTL 概念。借助 TTL  的能力,我們減少了很多業(yè)務上不必要的邏輯判定,同時還降低了因存儲量帶來的成本。

  • 流:在我們的業(yè)務中沒有啟用流來捕獲表的動作,但我們認為 DynamoDB 流是一個非常好的特性,當存儲在 DynamoDB  表中的數據發(fā)生變更(新增、修改、刪除)時,通知到相關的服務 / 程序。比如我們修改了一條記錄的某個字段,DynamoDB  可以捕獲到這個字段的變更,并將變更前后的結果編寫成一條流記錄。

實踐出真知

我們在使用一些開源框架或服務時總會遇到一些“坑”,這些“坑”其實也可以理解為沒有很好的理解和應對它們的一些使用規(guī)則。DynamoDB  和所有服務一樣,也有著它自己的使用規(guī)則。在這里主要分享我們在實際使用過程中遇到的問題以及解決辦法。

數據偏移

在 DynamoDB  中創(chuàng)建表時需要指定表的主鍵,這主要為了數據的唯一性、能夠快速索引、增加并行度。主鍵有兩種類型,「單獨使用分區(qū)鍵」作為主鍵和「使用分區(qū)鍵 +  排序鍵」作為主鍵,后者可以理解為組合主鍵(索引),它由兩個字段唯一確定 / 檢索一條數據。DynamoDB  底層根據主鍵的值對數據進行分區(qū)存儲,這樣可以負載均衡,減輕單獨分區(qū)壓力,同時 DynamoDB 也會對主鍵值嘗試做“合理的”分區(qū)。

在開始我們沒有對主鍵值做任何處理,因為 DynamoDB  會將分區(qū)鍵值作為內部散列函數的輸入,其輸出會決定數據存儲到具體的分區(qū)。但隨著運行,我們發(fā)現數據開始出現寫入偏移了,而且非常嚴重,帶來的后果就是導致  DynamoDB 表的讀寫性能下降,具體原因在后面會做詳細討論。發(fā)現這類問題之后,我們考慮了兩種解決辦法:

如何解決DynamoDB的問題

所以我們選擇了第二種方法,調整業(yè)務代碼,在寫入時將主鍵值做哈希,查詢時將主鍵條件做哈希進行查詢。

自動擴容潛規(guī)則

在解決了數據偏移之后讀 / 寫性能恢復了,但是運行了一段時間之后讀寫性能卻再次下降。查詢了數據寫入并不偏移,當時我們將寫入性能提升到了 6 萬 +/  秒,但沒起到任何作用,實際寫入速度也就在 2 萬 +/ 秒。最后發(fā)現是我們的分區(qū)數量太多了,DynamoDB 在后臺自動維護的分區(qū)數量已經達到了 200+  個,嚴重影響了 DynamoDB 表的讀寫性能。

DynamoDB 自動擴容、支持用戶任意設定的吞吐量,這些都是基于它的兩個自動擴容規(guī)則:單分區(qū)大小限制和讀寫性能限制。

單分區(qū)大小限制

DynamoDB 會自動維護數據存儲分區(qū),但每個分區(qū)大小上限為 10GB,一旦超過該限制會導致 DynamoDB  拆分區(qū)。這也正是數據偏移帶來的影響,當數據嚴重偏移時,DynamoDB 會默默為你的偏移分區(qū)拆分區(qū)。我們可以根據下面的公式計算分區(qū)數量:

數據總大小 / 10GB 再向上取整 = 分區(qū)總數

比如表里數據總量為 15GB,15 / 10 = 1.5,向上取整 = 2,分區(qū)數為 2,如果數據不偏移均勻分配的話兩個分區(qū)每個存儲 7.5GB  數據。

讀寫性能限制

DynamoDB 為什么要拆分區(qū)呢?因為它要保證用戶預設的讀 / 寫性能。怎么保證呢?依靠將每個分區(qū)數據控制在 10G  以內。另一個條件就是當分區(qū)不能滿足預設吞吐量時,DynamoDB 也會將分區(qū)進行擴充。DynamoDB 對于每個分區(qū)讀寫容量定義如下:

寫入容量單位:寫入容量單位(WCU:write capacity units),以每條數據最大 1KB 計算,最大每秒寫入 1000 條。

讀取容量單位:讀取容量單位(RCU:read capacity units),以每條數據最大 4KB 計算,最大每秒讀取 3000 條。

也就是說,一個分區(qū)的最大寫入容量單位和讀取容量單位是固定的,超過了分區(qū)最大容量單位就會拆分區(qū)。因此我們可以根據下面的公式計算分區(qū)數量:

(預設讀容量 /3000)+(預設寫容量 /1000)再向上取整 = 分區(qū)總數

比如預設的讀取容量為 500,寫入容量為 5000,(500 / 3000) + (5000 / 1000) = 5.1,再向上取整 = 6,分區(qū)數為  6。

需要注意的是,對于單分區(qū)超過 10G 拆分后的新分區(qū)是共享原分區(qū)讀寫容量的,并不是每個表單獨的讀寫容量。

因為預設的讀寫容量決定了分區(qū)數量,但由于單分區(qū)數據量達到上限而拆出兩個新的分區(qū)。

所以當數據偏移嚴重時,讀寫性能會急劇下降。

冷熱數據

產生上面的問題是由于我們一開始是單表操作。這樣就算數據不偏移,但隨著時間推移數據量越來越多,自然拆出的分區(qū)也越來越多。

因此,我們根據業(yè)務做了合理的拆表、設定了冷熱數據表。這樣做有兩大好處:

提升性能:這一點根據上面的規(guī)則顯而易見,熱表中數據量不會持續(xù)無限增長,因此分區(qū)也穩(wěn)定在一定數量級內,保證了讀寫性能。

降低成本:無謂的為單表增加讀寫性能不僅效果不明顯,而且費用也會急劇增高,使用成本的增加對于誰都是無法接受的。DynamoDB  存儲也是需要成本的,所以可以將冷表數據存儲到 S3 或其他持久化服務中,將 DynamoDB 的表刪除,也是降低成本的一種方式。

表限制

表對于數據的大小以及數量并沒有限制,可以無限制的往一張表里寫入數據。但對于 AWS 的一個賬戶,每個 DynamoDB 使用區(qū)域的限制為 256  張表。對于一個公司來說,如果共用同一個賬號的話可能會存在創(chuàng)建表受限的風險。所以如果啟用了冷熱表策略,除了刪冷表降低成本外,也是對 256  張表限制的一種解決辦法。

屬性名長度

上面提到了寫入單位每條數據最大 1KB、讀取單位每條最大 4KB  的限制。單條數據的大小除了字段值占用字節(jié)外,屬性名也會占用字節(jié),因此在保證可讀性的前提下應盡量縮減表中的屬性名。

DynamoDB 的使用也是存在成本的,主要體現在寫入和讀取的費用。我們自己研發(fā)了一套按照實際流量實時調整讀、寫上限的策略。隨著發(fā)展 DynamoDB  也推出了 Auto Scaling 功能,它實現了自定義策略動態(tài)調整寫入與讀取上限的能力,對于開發(fā)者來說又可以省去了不少研發(fā)精力。目前我們也有部分業(yè)務使用了  Auto Scaling 功能,但由于該功能的限制,實際使用上動態(tài)調整的實時性略顯欠缺。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI