成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

1.5億用戶、萬億數據,爆款社交平臺的兩次大型數據庫遷移

開發 前端
技術人員都希望,現行數據庫能夠滿足不斷增長的存儲需求,同時保持較低的維護需求??上КF實往往事與愿違—— Discord 使用的 Cassandra 集群出現嚴重的性能問題,技術人員耗費越來越多的精力,致力于維護數據庫,而非改進性能。

2017年,Discord 在技術博客中提到,由于 RAM 中無法再容納數據和索引,延遲開始變得不可預測,急速增長的數據存儲亟待遷移。他們希冀找到一款可擴展、容錯且維護成本相對較低的數據庫,以實現存儲數十億條消息的目標,最終完成了從 MongoDB 到 Cassandra 的遷移。

技術人員都希望,現行數據庫能夠滿足不斷增長的存儲需求,同時保持較低的維護需求??上КF實往往事與愿違—— Discord 使用的 Cassandra 集群出現嚴重的性能問題,技術人員耗費越來越多的精力,致力于維護數據庫,而非改進性能。

時隔六年,Discord 消息存儲再面臨性能挑戰,于是將數據庫遷移至 ScyllaDB。

這兩次數據庫遷移原因幾何?Discord 如何選型?遷移過程中問題又將如何解決?

讓我們一同在下文中尋找答案。

2017:從MongoDB到Cassandra

Discord 的增長速度和用戶生成的內容數量超出了我們的預期,用戶越多,聊天信息也就越多。2016年7月,平臺消息量已達4000萬條,12月增至1億條,而截至這篇文章發布(2017年1月)時,信息量已超過1.2億條。

我們很早就決定永久存儲所有聊天記錄,以便用戶隨時返回查看,并在任何設備上使用他們的數據。而這些龐大數據的增長速度及規模都在持續攀升,并且需要隨時保持可用。

這一點如何做到?我們的回答是遷移至 Cassandra 數據庫。

1.Discord 最初版本

2015年初,Discord 的最初版本在不到兩個月的時間成功創建。在當時情況下,MongoDB 是快速迭代的最佳數據庫之一。Discord 的所有內容都存儲在單個 MongoDB 集群中,這是有意為之,但同時我們也做好一切后續規劃,以便將所有數據輕松地遷移到新數據庫(我們確信不會使用 MongoDB 分片,因為它使用復雜,且穩定性不佳)。

實際上,這是我們公司文化的一部分:快速構建以驗證產品功能,但始終為更強大的解決方案留有后路。

消息存儲在 MongoDB 集合中,使用 channel_id 和 created_at 的單一復合索引。2015 年 11 月左右,存儲消息數量達到 1 億條,此時,預期問題發生了:RAM 無法再容納數據和索引,延遲開始變得不可控,是時候遷移到更合適的數據庫了。

2.選擇合適的數據庫

選擇新數據庫之前,必須了解我們的讀/寫模式,以及我們目前解決方案出現問題的原因。

  • 我們的讀取極其隨機,讀寫比例大約為 50/50。
  • 管理語音聊天的重型 Discord 服務器幾乎不發送任何消息,這意味著它們每隔幾天只發送一兩條消息,這種服務器在一年內發送的信息幾乎不到 1000 條。問題是,雖然信息量很小,但卻增加了向用戶提供數據的難度。只要向用戶返回 50 條信息,就會在磁盤上產生許多隨機尋道,導致磁盤緩存被驅逐。
  • 管理文字私聊的重型 Discord 服務器發送的信息數量相當可觀,每年可輕松達到 10 萬至 100 萬條,請求數據通常都是最新的。問題是,由于這些服務器通常只有不到 100 名成員,因此請求數據的速度很低,磁盤緩存中也不太可能具備這些數據。
  • 大型公共聊天 Discord 服務器會發送大量信息,其中,成千上萬的成員每天發送數千條信息,每年可發送數百萬條信息。它們幾乎總是在請求最近一小時內發送的信息,并且請求頻率很高。因此,數據通常都在磁盤緩存中。
  • 在接下來的一年里,我們將為用戶提供更多隨機讀取數據的方式:查看過去 30 天內的提及消息,并跳轉到歷史記錄的對應內容,查看并跳轉到標記消息,以及全文搜索。以上這些功能都意味著更多的隨機讀??!

隨后,我們來定義下需求:

  • 線性可擴展性:不希望以后重新考慮解決方案或手動重新分揀數據。
  • 自動故障轉移:我們不希望被夜間打擾,因此系統出現問題時,要盡可能讓 Discord 自動修復。
  • 低維護:一旦配置完畢,它就能正常工作。我們只需在數據增長時添加更多節點即可。
  • 經證明可行:我們喜歡嘗試新技術,但不能太新。
  • 可預測性:當 API 的響應時間95%超過 80ms 時無需警報,我們也不想在 Redis 或 Memcached 中緩存消息。
  • 不使用 blob 存儲:如果不斷對 blob 存儲數據進行反序列化并新增數據,那么每秒寫入數千條消息的速度將大打折扣。
  • 開源:將命運掌握在自己手里,不依賴第三方公司。

Cassandra 是唯一能滿足所有要求的數據庫。添加節點即可擴展,同時添加過程中可以容忍節點丟失,不會對應用程序產生任何影響。Netflix 和蘋果等大公司已部署使用了數千個 Cassandra 節點。相關數據連續存儲在磁盤上,這樣減少了數據訪問尋址次數,并且數據便于在集群中分布。Cassandra 由 DataStax 支持,但仍然是開源的,由社區驅動。

既然做出了選擇,我們就需要證明它確實可行。

3.數據建模

如何向新手介紹 Cassandra?最好的方式就是將其描述為一個 KKV 存儲器,它的主鍵由兩個 K 組成。

第一個 K 是分區鍵,用于確定數據所在的節點以及在磁盤上的位置。分區中包含多行記錄,每行記錄由第二個 K(即聚類鍵)確定。聚類鍵既是分區內的主鍵,也是行的排序方式,可以將分區看作有序字典。這些屬性結合在一起,即可實現非常強大的數據建模。

前文提到, MongoDB 使用 channel_id 和 created_at 索引信息, 因為所有查詢都在頻道(channel)中進行,所以channel_id 被設為分區鍵,但 created_at 并不是一個很好的聚類鍵,因為不同消息的創建時間可能相同。

好在Discord 的所有 ID都是雪花算法(可按時間排序),因此我們可以用它們來代替created_at。由此主鍵變成了(channel_id,message_id),其中 message_id 是雪花算法。這意味著加載頻道時,可以告知 Cassandra 掃描消息的準確范圍。

下面是消息表的簡化模式(省略了約 10 列)。

CREATE TABLE messages (
  channel_id bigint,
  message_id bigint,
  author_id bigint,
  content text,
  PRIMARY KEY (channel_id, message_id)
) WITH CLUSTERING ORDER BY (message_id DESC);

Cassandra 的 schema 與關系數據庫的模式有很大差別,Cassandra 的 schema 更改成本相較更低,而且不會對性能造成任何臨時性影響,因此,我們獲得了 blob 存儲和關系型存儲的最佳效果。

當我們開始將現有信息導入 Cassandra 時,日志立刻出現告警,提醒分區的大小超過了 100MB。這是怎么回事?Cassandra 宣稱可以單個分區可支持 2GB!顯然,理論性能并不意味著實際應用效果。

在壓縮、集群擴展等操作過程中,大分區會給 Cassandra 帶來很大的 GC 壓力。同時,大分區還意味著其中的數據無法分布在集群中。由于 Discord 頻道(channel)將存在數年,且持續增長擴大,所以必須限制分區的大小。

我們決定按時間分類信息,參考Discord 上最大頻道,確定如果在一個桶中存儲約 10 天的消息,就可以輕松地將容量控制在 100MB 以下。桶必須從消息 ID 或時間戳中歸并。

DISCORD_EPOCH = 1420070400000
BUCKET_SIZE = 1000 * 60 * 60 * 24 * 10




def make_bucket(snowflake):
   if snowflake is None:
       timestamp = int(time.time() * 1000) - DISCORD_EPOCH
   else:
       # When a Snowflake is created it contains the number of
       # seconds since the DISCORD_EPOCH.
       timestamp = snowflake_id >> 22
   return int(timestamp / BUCKET_SIZE)
  
  
def make_buckets(start_id, end_id=None):
   return range(make_bucket(start_id), make_bucket(end_id) + 1)

Cassandra 分區鍵可復合,因此新主鍵變成了((channel_id, bucket), message_id)。

CREATE TABLE messages (
   channel_id bigint,
   bucket int,
   message_id bigint,
   author_id bigint,
   content text,
   PRIMARY KEY ((channel_id, bucket), message_id)
) WITH CLUSTERING ORDER BY (message_id DESC);

查詢通道中最近的消息,需要生成一個從當前時間到 channel_id 的桶范圍(它也是雪花算法,必須比第一條消息更早)。然后,按順序查詢分區,直到收集到足夠多的信息。

這種方法的缺點是,不活躍的 Discord 頻道需要查詢多個分區才能收集到足夠多的信息。不過該方法在實踐中證明可行,因為對于活躍的 Discord 頻道來說,通常在第一個分區中就能找到足夠的消息,且這種情況占多數。

將消息導入 Cassandra 的過程非常順利,我們已做好了遷移到生產環境的準備。

4.驚險的啟動

將一個新系統引入生產環境總是令人恐懼的,因此最好在不影響用戶的情況下進行測試。我們將代碼設置為 MongoDB 和 Cassandra 的雙重讀/寫。

啟動后,我們的錯誤(bug)跟蹤器立即收到錯誤信息,提示稱 author_id 為空(null)。怎么回事?這是一個必填字段!

讓我們先一起回顧下問題產生的背景。

5.最終一致性

Cassandra 是 AP 數據庫,這意味著它犧牲了強一致性以換取可用性,而這正是我們想要的。在 Cassandra 中,“先讀后寫”是一種反模式(讀取比寫入成本更高),因此,即使只訪問某些列,在 Cassandra 上本質也會成為一個更新插入操作。你也可以向任何節點寫入數據,它將根據每一列的情況,使用“last write wins”的策略自動解決沖突。這對我們有什么影響?

編輯/刪除 race condition 的例子編輯/刪除 race condition 的例子

以上動圖例子中,在一個用戶編輯消息的同時,另一個用戶刪除了同一條消息。由于 Cassandra 寫入時執行更新插入操作,因此我們最終發現記錄中只有主鍵和文本外,缺少其余數據。

有兩種可能解決方案處理這個問題:

  • 編輯信息時,寫回整條信息。這有可能找回已刪除的信息,但也增加并發寫入其他列時發生沖突的機會。
  • 找出已損壞的信息并從數據庫中刪除。

我們采用了第二種方法,即選擇一個必填列(本例中為 author_id),如果該列為空,則刪除該消息。

解決這個問題時,我們注意到我們的寫入效率非常低。由于 Cassandra 被設計為最終一致性,因此它執行刪除操作時不會立即刪除數據,必須將刪除復制到其他節點。即使其他節點暫時不可用,也要執行刪除操作。

Cassandra 將刪除作為一種名為“墓碑”的寫入形式來處理。在讀取時,它會跳過遇到的墓碑。墓碑的存活時間可配置(默認為 10 天),過期后會在壓縮過程中被永久刪除。

刪除列和將空值(null)寫入列完全是一回事。它們都會生成墓碑。由于 Cassandra 中的所有寫入都是更新插入,這意味著即使第一次寫入空值也會生成墓碑。實際上,我們的整個消息模式包含 16 個列,但平均每條消息長度僅有 4 個值。這導致插入新一行數據時,大部分時間都在無緣無故地向 Cassandra 寫入 12 個墓碑。

解決這個問題的辦法很簡單:只向 Cassandra 寫入非空值。

6.性能

眾所周知,Cassandra 的寫入速度比讀取速度快,我們的觀察結果也是如此:寫入速度低于1毫秒,讀取速度低于 5 毫秒。無論訪問什么數據,觀察結果都一致,并且性能在一周的測試中始終如一。意料之中,我們得到了所期望的數據庫。

通過 Datadog 查看讀寫延遲通過 Datadog 查看讀寫延遲

快速、一致的讀取性能可以通過以下例子表現:在數百萬條信息的頻道中跳轉到一年前的某條消息。

跳轉到一年前的聊天記錄跳轉到一年前的聊天記錄

7.巨大的意外

一切都很順利,我們將 Cassandra 切換為主數據庫,并在一周內淘汰掉 MongoDB 。Cassandra 完美地運行了約 6 個月,直到有一天變得反應遲鈍。

我們注意到 Cassandra 持續出現 10 秒鐘的 GC 全停頓("stop-the-world "GC),但原因未知。我們開始定位問題,發現加載 Discord 頻道需要 20 秒。一個名為“Puzzles & Dragons Subreddit”的公共 Discord 服務器是罪魁禍首。由于它是一個開放的服務器,我們加入進去一探原因。

令人驚訝的是,頻道里只有一條信息。同時我們發現,他們使用我們的 API 刪除了數百萬條信息,只在頻道中留下了 1 條信息。

上文(談及最終一致性時)提到過, Cassandra 是如何使用墓碑處理刪除操作。當用戶加載該頻道時,即使只有一條消息,Cassandra 也必須掃描數以百萬計的消息墓碑(產生垃圾的速度比 JVM 收集垃圾的速度更快)。

我們通過以下方法解決了這個問題:

  • 因為我們每晚都會在消息集群上運行 Cassandra 修復(反熵進程),所以將墓碑的生命周期從 10 天縮短到 2 天。
  • 修改查詢代碼,以跟蹤空桶,并在未來避免在頻道中出現空桶。這意味著,如果用戶再次進行此查詢,即使是最壞的情況下,Cassandra 也只能掃描最近的數據桶。

8.未來發展規劃

目前正在運行一個復制系數為 3 的 12 節點集群,并將根據意外所需繼續添加新的 Cassandra 節點,我們相信在很長一段時間內這個集群可以持續高效運行。

但隨著 Discord 的不斷發展,在遙遠的未來,有可能每天需要存儲數十億條消息。Netflix 和蘋果公司運行著數百個節點的集群,因此我們知道這個階段不用過多顧慮。不過,我們還是準備了一些未雨綢繆的計劃。

1)近期計劃

  • 將我們的消息集群從 Cassandra 2 升級到 Cassandra 3。Cassandra 3 有一種新的存儲格式,可將存儲大小減少 50% 以上。
  • 新版本的 Cassandra 更善于在單個節點上處理更多數據。我們目前在每個節點上存儲近 1TB 的壓縮數據。我們相信,只要將其提升到 2TB,就能安全地減少集群中的節點數量。

2)長期計劃

  • 探索使用 C++ 編寫的 Cassandra 兼容數據庫 Scylla 。在正常運行期間,我們的 Cassandra 節點占用的 CPU 并不多,但在非高峰時段,當我們運行修復(一個反熵進程)時,CPU 占用就非常高。同時,在上一次修復后,修復持續時間和寫入的數據量也會增加。Scylla 宣稱能大大縮短修復時間。
  • 建立一個系統,將未使用的頻道歸檔到谷歌云存儲的文件中,并按需加載回來。其實我們不希望這樣做,所以這一計劃未必會落實。

9.結論

盡管經歷“巨大的意外”,但我們的切換過程一直很順利。每日信息總量從 1 億多條增加到 1.2 億多條,也一直保持著良好的性能與穩定性。

由于這個項目的成功,我們已經將其余的實時生產數據轉移到 Cassandra,并且也取得了成功。

2023:從Cassandra到 ScyllaDB

2023年,Discord 使用的 Cassandra 集群出現嚴重的性能問題,技術人員耗費越來越多的精力,致力于維護數據庫,而非改進性能。

時隔六年,Discord 消息存儲再面臨性能挑戰,存儲遷移刻不容緩。

1.Cassandra的存儲痛點

Discord 將信息存儲在名為 cassandra-messages 的數據庫中。顧名思義,它運行 Cassandra 以存儲信息。2017年,Discord 運行12個 Cassandra 節點,存儲數十億條信息。

截至2022年初,以上系統擁有177個節點和數萬億條消息,Cassandra 出現了嚴重的性能問題。由于不可預測的數據庫延遲等問題,技術團隊必須隨時保持聯系,減少運維操作,避免增加系統運行成本。

痛點從何產生?讓我們來看以下這條消息。

CREATE TABLE messages (
   channel_id bigint,
   bucket int,
   message_id bigint,
   author_id bigint,
   content text,
   PRIMARY KEY ((channel_id, bucket), message_id)
) WITH CLUSTERING ORDER BY (message_id DESC);

以上 CQL 語句是消息模式的最小版本。Discord 使用的每個 ID 都通過Snowflake 生成,因此可按時間排序。根據消息發送的通道以及一個存儲桶(一個靜態時間窗口)來劃分消息。這種分區意味著,在 Cassandra 中,給定通道和存儲桶的所有消息都將存儲在一起,并跨三個節點(或設置的任何復制系數)進行復制。

在 Cassandra 中,讀取比寫入的成本高。寫入操作被附加到提交日志中,并寫入名為內存表(memtable)的內存結構中,最終被刷新到磁盤。然而,讀取需要查詢內存表(memtable)和可能的多個磁盤文件(SSTable),操作成本相當高。

用戶與服務器交互時,大量并發讀取使分區出現熱點,一般將其稱為“熱分區”。一旦數據集的規模與這些訪問模式結合,導致 Cassandra 集群出現問題。

熱分區經常導致整個數據庫集群延遲。通道與存儲桶組合接收大量流量,隨著節點服務流量越發吃力,節點延遲就越發嚴重。

由于節點速度無法跟上,對該節點的其他查詢受到影響。由于我們使用仲裁一致性級別執行讀寫操作,因此服務于熱分區的節點的所有查詢都會影響,延遲增加,從而對最終用戶產生更廣泛的影響。

集群維護任務也經常引起麻煩。我們很容易在壓縮上落后,Cassandra 會壓縮磁盤上的SSTable以獲得更高的性能讀取。這樣一來,我們的讀取成本不僅會更高,并且由于節點試圖壓縮,還會產生級聯延遲。

我們經常執行一種被稱為“八卦舞蹈”的操作,即停止一個節點的輪換,讓它在不占用流量的情況下進行壓縮,將其重新加入輪換,從 Cassandra 獲取切換提示,然后重復這個操作,直至壓縮積壓的信息被清空。由于 GC 暫停會導致顯著的延遲峰值,我們還花了大量時間調優 JVM 的垃圾收集器和堆設置。

2.架構遷移

消息集群并非唯一的 Cassandra 數據庫,我們還具備其他幾個集群,每個集群都表現出類似的缺點(雖然可能沒有那么嚴重)。

ScyllaDB 引起了我們的興趣,這是一個用 C++ 編寫的與 Cassandra 兼容的數據庫。它承諾提供更好的性能、更快的修復、通過核分片架構實現更強的工作負載隔離,以及無垃圾回收,聽起來相當吸引人。

當然ScyllaDB也存在不足之處,由于采用 C++ 編譯而不是 Java,所以它沒有垃圾收集器。過去,我們的團隊在 Cassandra 上的垃圾收集器上遇到許多問題,包括影響延遲的 GC 暫停、一直到超長的連續 GC 暫停,以至于操作員必須手動重新啟動,問題節點才能恢復健康狀態。這些問題導致技術團隊必須隨叫隨到,同時,這些問題也是影響消息集群穩定性問題的根源。

在對 ScyllaDB 進行試驗,并觀察到測試中的改進成效后,我們決定遷移所有數據庫。雖然這項決定本身可以用一篇博客來介紹,但簡而言之,截至2020年,我們已經將所有數據庫遷移到 ScyllaDB,除了一個數據庫—— cassandra-messages 。

為什么我們還未開始遷移?首先,集群規模巨大,包括數以萬億計的消息和近200個節點,任何遷移操作都非常復雜。此外,我們希望調整新數據庫時,其性能達到最佳狀態。我們還想在生產環境中積累使用 ScyllaDB 的更多經驗,了解其缺陷。

針對我們的用例,還改進了 ScyllaDB 的性能。我們在測試中發現,反向查詢的性能不足以滿足需求。以與表排序相反的順序進行數據庫掃描時,例如按升序掃描消息時,則執行反向查詢。ScyllaDB 團隊優先對其進行改進,實現了高性能的反向查詢,清除了我們遷移計劃中的“最后一個數據庫”的障礙。

我們擔心,在系統上添加新數據庫不太可能有翻天覆地的性能改進,“熱分區”的問題依然存在于 ScyllaDB ,因此,我們寄希望于投資改進數據庫上游系統,以助于數據庫屏蔽和提升數據庫性能。

3.使用數據服務提供數據

針對 Cassandra ,我們遇到了熱分區的難題,分給特定分區的高流量會引起無限并發,進而導致級聯延遲,延長后續查詢時間。如果能夠控制熱分區的并發流量,就可保護數據庫免于重負。

為了完成這項任務,我們編寫了所謂的數據服務——位于 API 單體和數據庫集群之間的中介服務。編寫數據服務時,我們選擇了一種在 Discord 應用越發廣泛的語言:Rust!它能在保障安全性的前提下,提供可與 C/ C++ 媲美的高速度。

Rust 的主要優勢之一是無懼并發——該語言使編寫安全并發代碼變得容易。它的庫也非常適合完成我們的其他工作,Tokio生態系統是構建異步I/O系統的監視基礎,并且該語言也對 Cassandra 和 ScyllaDB 提供驅動程序支持。

此外,Rust 編譯器提供的幫助、清晰的錯誤消息、語言結構以及對安全性的重視,編寫代碼變得很有趣。Rust 程序一旦通過編譯,就可以運行,這讓我們很滿意。最重要的是,我們用Rust 進行重寫(meme/模因信譽非常重要)。

我們的數據服務位于 API 和 ScyllaDB 集群之間。每個數據庫查詢大約包含一個gRPC 端點,并且故意不包含業務邏輯。數據服務一大特點是請求合并,如果多個用戶同時請求同一行,我們將只查詢一次數據庫。首個發出請求的用戶會觸發數據服務中的工作任務,后續請求將檢查該任務是否存在并訂閱它,該工作任務將查詢數據庫并將該行返回給所有訂閱者。

這就是 Rust 的強大之處:它使編寫安全的并發代碼變得輕松。

讓我們想象一下,大型服務器有一條@所有人的重要公告:用戶將打開應用程序并閱讀消息,向數據庫發送大量流量。以往,這可能會導致熱分區,并且可能需要工程師隨時保持待機,以幫助系統恢復。數據服務能夠顯著減少數據庫的流量峰值。

第二個神奇之處在于數據服務的上游。為實現更有效的合并,我們實現了一致的基于哈希的數據服務路由,為每個數據服務請求提供路由鍵。對消息來說,這是一個通道ID,因此對同一通道的所有請求都將轉到服務的同一實例,這種路由方式有助于進一步減少數據庫的負載。

這些改進頗有助益,但并未解決所有問題。,但它們并不能解決我們所有的問題。Cassandra集群上仍然存在熱分區和延遲增加,只是不那么頻繁了,這為我們贏得了一些時間,以便準備最優ScyllaDB集群并執行遷移。

4.大規模數據遷移

我們的遷移需求非常簡單:在不停機的情況下遷移數萬億條消息,并快速完成。正如上文所述,雖然 Cassandra 的情況有所改善,但還常常出現問題。

第一步很簡單:使用超級磁盤存儲拓撲配置一個新的 ScyllaDB 集群。

使用本地 SSD 提高速度,并利用 RAID 將數據鏡像到持久磁盤,由此我們同時獲得了連接本地磁盤的速度和持久磁盤的持久性。集群建立后,就可以開始向其遷移數據了。

我們的初版遷移技術旨在快速獲取價值。我們將開始使用全新的 ScyllaDB 集群來處理新數據,在切換時間內遷移歷史數據。這項操作增加了復雜性,但每個大型項目都無法避免額外的復雜性,對吧?

然后,向 Cassandra 和 ScyllaDB 雙重寫入新數據,并同時開始準備 ScyllaDB 的 Spark 遷移器。這需要大量調整,一旦設置完成,我們預計三個月能夠完成遷移。

這個時間期限讓我們并不滿意,因為我們希望更快獲取價值。所以,我們組織了一場團隊會議,集思廣益,思考如何增速——我們已經編寫了一個快速和高性能的數據庫,可以對其進行拓展。因而我們選擇參與了一些模因驅動工程,用Rust重寫數據遷移器。

某一天的下午,我們擴展了數據服務庫以便執行大規模數據遷移。它從數據庫讀取令牌范圍,通過 SQLite 在本地檢查,然后將它們送入 ScyllaDB 。連接改進后的新遷移器后,我們重新預估工期:9天!如果可以這么迅速地遷移數據,就可以放棄基于時間的復雜方式,一次性切換所有數據。

啟動遷移器并讓其保持運行,以每秒320萬的速度遷移信息。幾天后,遷移進度達到100%,但我們意識到它停留在99.9999%的完成度。遷移器在讀取數據的最后幾個令牌范圍時超時了,因為它們包含了 Cassandra 中未壓縮過的巨大墓碑范圍。我們將這個令牌范圍壓實,幾秒鐘后,遷移完成!

執行自動數據驗證,即通過向兩個數據庫發送一小部分讀取數據并比較結果,一切看起來都很好。在全生產流量的情況下,集群表現良好,而 Cassandra 卻遭受越來越頻繁的延遲問題。我們團隊聚集在現場,打開開關使 ScyllaDB 成為主數據庫。

5.數據庫遷移效果

Discord 在2022年5月切換了消息數據庫,遷移效果如何?

運行的177個 Cassandra 節點減少到72個 ScyllaDB 節點,每個 ScyllaDB 節點有9tb的磁盤空間,高于每個 Cassandra 節點平均 4tb 的磁盤空間。

我們的尾部延遲也大大改善了。例如,在 Cassandra 上獲取歷史消息的p99在40-125ms之間,ScyllaDB 的p99延遲在15ms之間,消息插入性能從 Cassandra 上的5-70ms p99上升到 ScyllaDB 上穩定的5ms p99。

2022年底,全球觀眾都在收看世界杯。技術人員發現,Discord 的監控圖表可以展示決賽的進球情況。這為技術團隊提供了一個在會議期間觀看足球比賽的借口——不是“在會議期間看足球比賽”,而是“主動監控系統性能”。

以上的信息發送數量圖,描繪了世界杯決賽的精彩發展,圖中的每個峰值分別代表比賽中的重要節點。

1. 梅西罰進點球,阿根廷1比0領先。

2. 阿根廷再次得分,以2比0領先。

3. 中場休息。當用戶談論比賽時,會持續15分鐘。

4. 姆巴佩為法國隊進球,90秒后再次進球將比分扳平!

5. 規則結束了,這場重要的比賽將進入加時賽。

6. 在加時賽的前半段沒有太多的事情發生,但我們到了中場休息,用戶開始聊天。

7. 梅西再次得分,阿根廷隊領先!

8. 姆巴佩反擊將比分扳平!

9. 加時賽結束了,我們要進點球了!

  1. 在整個點球大戰中,興奮和壓力不斷增加,直到法國隊失誤,而阿根廷隊沒有!阿根廷贏了!

每秒合并消息數每秒合并消息數

世界各地的人們都在觀看這場激動人心的比賽,與此同時,Discord 使用基于 rust 的數據服務和 ScyllaDB ,不費吹灰之力便承擔了比賽產生的巨大流量,同時為用戶提供交流平臺。

參考資料

  • HOW DISCORD STORES BILLIONS OF MESSAGEShttps://discord.com/blog/how-discord-stores-billions-of-messages
  • HOW DISCORD STORES TRILLIONS OF MESSAGEShttps://discord.com/blog/how-discord-stores-trillions-of-messages

作者丨Stanislav Vishnevskiy & Bo Ingram

編譯丨onehunnit

責任編輯:武曉燕 來源: dbaplus社群
相關推薦

2020-12-01 15:12:49

字節跳動數據庫數據

2009-03-23 09:05:01

2011-03-11 08:53:06

DB2Oracle

2019-03-05 10:16:54

數據分區表SQLserver

2020-06-08 10:41:13

云計算數據工具

2020-03-05 10:36:12

云計算數據庫云平臺

2020-10-23 09:38:41

數據分庫分表數據遷移

2025-01-14 16:12:54

2020-02-28 18:27:37

運維管理微盟

2010-09-25 15:42:26

數據庫集群Facebook

2011-05-11 10:26:36

MySQL數據庫無縫遷移

2020-08-20 07:53:14

安全數據泄露數據

2011-04-12 10:59:46

Oracle數據庫

2011-09-23 09:09:38

數據庫遷移

2020-08-13 07:42:15

數據庫Flyway代碼

2017-11-22 09:20:41

數據庫在線數據遷移Subscriptio

2010-08-25 14:32:49

DB2數據庫遷移

2011-05-17 11:09:30

大型數據庫

2009-03-19 09:44:07

SQL Server數據庫遷移數據庫

2011-04-29 14:30:23

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产91久久久久久 | 久久黄色| 国产91精品网站 | 日韩精品一区二区三区四区视频 | 97精品视频在线 | 羞羞涩涩在线观看 | 久久久久久成人 | 久久尤物免费一区二区三区 | 一级黄色毛片免费 | 一区二区高清 | 国产一区二区视频在线观看 | 中文字幕电影在线观看 | 日韩av手机在线观看 | 国产一区中文字幕 | 红桃视频一区二区三区免费 | 精品av| jav成人av免费播放 | 精品视频在线免费观看 | 亚洲欧美日韩系列 | 久久中文字幕电影 | 中文字幕精品一区二区三区精品 | 91视频大全 | 日韩快播电影 | 成人免费视频网站在线观看 | 亚洲一区二区三区免费观看 | 日韩欧美在线观看视频 | 亚洲欧美日本在线 | 婷婷色婷婷 | 亚洲国产精品激情在线观看 | 夜夜操操操 | av网址在线播放 | 久久久亚洲一区 | 中文字幕精品一区 | 精品一区二区三区在线视频 | 亚洲一区二区在线视频 | 日韩一区二区免费视频 | 日本超碰在线 | 国产一区久久 | 欧美中文字幕一区二区 | 中国一级大毛片 | 亚洲视频一区在线观看 |