D1 現在處於公開測試階段,主題是「規模」:憑藉每個資料庫更高的儲存限制_和_建立更多資料庫的能力,我們正在為開發人員解鎖在 D1 上建立生產規模應用程式的能力。擁有現有付費 Workers 方案的所有無需採取任何動作即可受益:我們已將其追溯套用至所有現有的 D1 資料庫。
如果您錯過了 Developer Week 期間的上一次 D1 更新、變更記錄中的大量更新,或者只是 D1 的新內容:請繼續閱讀。
提醒我:D1?資料庫?
D1 是我們的原生無伺服器資料庫,我們在去年 11 月推出了 Alpha 版:對 Workers KV、Durable Objects 和 R2 的可查詢資料庫補充。
當我們開始建立 D1 時,我們確定了一些事情:它需要速度快,能夠非常輕鬆地建立資料庫,並且需要基於 SQL。
最後一點至關重要,這樣開發人員就可以:a) 無需學習另一種自訂查詢語言;b) 讓現有查詢建置、ORM(物件關係對應程式)庫和其他工具以最小的努力更輕鬆地連接到 D1。由此,我們看到大量專案為 D1 建立了支援:從 Drizzle ORM 和 Kysely 中對 D1 的支援,到 T4 App(一個使用 D1 作為其資料庫的完整堆疊工具包)。
我們也知道,D1 不可能是從 Workers 查詢資料庫的唯一方法:對於擁有現有資料庫和數千行 SQL 或現有 ORM 程式碼的團隊來說,遷移到 D1 並不能在一個下午之內完成。對於這些團隊,我們建立了 Hyperdrive,讓您可以連接到現有資料庫並讓它們具有全球化的感覺。我們認為這為團隊提供了靈活性:將 D1 和 Workers 結合起來用於全球分散式應用程式,並使用 Hyperdrive 來查詢傳統雲端中無法一夜之間擺脫的資料庫。
更多更大的資料庫
這是整個 Alpha 測試期間數千名 D1 使用者提出的最大要求:不僅要有更多的資料庫,還要有_更大的_資料庫。
Workers 付費方案的開發人員現在可以將每個資料庫擴展至 2GB,並建立 50,000 個資料庫(之前分別為 500MB 和 10 個)。是的,您沒有看錯:每個帳戶 50,000 個資料庫。這解鎖了大量每個使用者一個資料庫的用例,並實現了客戶之間的真正隔離,這是傳統關係型資料庫部署所無法做到的。
我們將在未來幾週和幾個月內繼續努力解鎖更大的資料庫:使用 D1 Beta 測試版的開發人員將看到 D1 公用變更記錄中發佈的這些限制自動增加。
兩位數 GB 資料庫的最大障礙之一是效能:我們希望確保資料庫能夠快速載入並準備就緒_——_數秒(或更長時間)的冷啟動是不可接受的。如果一個 10GB 或 20GB 的資料庫需要 15 秒才能回答查詢,那麼使用起來會非常令人沮喪。
Workers 免費方案的使用者將永遠保留 10 個 500MB 資料庫(變更記錄):我們希望為更多開發人員提供更多空間,讓他們在正式訂購 D1 和 Workers 之前進行充分試驗。
推出 Time Travel
Time Travel 可讓您將資料庫回滾到特定時間點:具體來說,是過去 30 天內的任何分鐘。每個 D1 資料庫預設啟用此功能,不再需要任何費用,並且不會計入您的儲存限制。
對於那些一直關注此功能的人:我們最初在今年早些時候宣佈推出 Time Travel,並在 7 月向所有 D1 使用者開放。它的核心功能非常簡單:Time Travel 在 D1 中引入了「書籤」的概念。書籤代表資料庫在特定時間點的狀態,實際上是一個僅附加的記錄。Time Travel 可以獲取時間戳記並將其轉換為書籤,或直接獲取書籤:讓您可以還原到該點。更秒的是:還原之後,您仍然可以返回現狀。
我們認為最好用一個範例來說明 Time Travel,因此讓我們對資料庫進行變更:一個資料庫包含一個訂單表格,用於儲存我們電子商務商店的每個訂單:
好的,太好了。現在,如果我們想要變更一組特定的訂單:變更地址或貨運公司,該怎麼辦?
# To illustrate: we have 89,185 unique addresses in our order database.
➜ wrangler d1 execute northwind --command "SELECT count(distinct ShipAddress) FROM [Order]"
┌──────────┐
│ count(*) │
├──────────┤
│ 89185 │
└──────────┘
等等,我們犯了很多人以前都犯過的錯誤:我們忘記了 UPDATE 查詢中的 WHERE 子句。我們沒有更新特定的訂單 ID,而是更新了表格中每個訂單的送貨地址。
# I think we might be forgetting something here...
➜ wrangler d1 execute northwind --command "UPDATE [Order] SET ShipAddress = 'Av. Veracruz 38, Roma Nte., Cuauhtémoc, 06700 Ciudad de México, CDMX, Mexico'
恐慌開始了。在此之前我們記得先做了備份嗎?那是多久以前的事了?我們開啟時間點恢復了嗎?當時它似乎很貴…
# Every order is now going to a wine bar in Mexico City.
➜ wrangler d1 execute northwind --command "SELECT count(distinct ShipAddress) FROM [Order]"
┌──────────┐
│ count(*) │
├──────────┤
│ 1 │
└──────────┘
沒關係。我們用的是 D1。我們可以使用 Time Travel。預設情況下它是打開的:讓我們修復這個問題,回到幾分鐘前。
讓我們檢查一下它是否有效:
# Let's go back in time.
➜ wrangler d1 time-travel restore northwind --timestamp="2023-09-23T14:20:00Z"
🚧 Restoring database northwind from bookmark 0000000b-00000002-00004ca7-9f3dba64bda132e1c1706a4b9d44c3c9
✔ OK to proceed (y/N) … yes
⚡️ Time travel in progress...
✅ Database dash-db restored back to bookmark 00000000-00000004-00004ca7-97a8857d35583887de16219c766c0785
↩️ To undo this operation, you can restore to the previous bookmark: 00000013-ffffffff-00004ca7-90b029f26ab5bd88843c55c87b26f497
我們認為,當您擁有許多較小的資料庫時,Time Travel 會變得更加強大:任何還原操作的弊端都會進一步減少,並且僅限於單一使用者或租用戶。
# Phew. We're good.
➜ wrangler d1 execute northwind --command "SELECT count(distinct ShipAddress) FROM [Order]"
┌──────────┐
│ count(*) │
├──────────┤
│ 89185 │
└──────────┘
這還只是 Time Travel 的開始:我們不僅在努力支援復原資料庫,還支援從現有資料庫中派生資料庫和複寫現有資料庫。如果您可以使用單一命令派生資料庫和/或針對真實資料測試遷移和結構描述變更,則可以消除過去使用資料庫所帶來的許多傳統挑戰的風險。
基於行的定價
早在 5 月份,我們就宣佈了 D1 的定價,並針對我們在免費方案和付費方案中包含的內容收到了許多正面回饋。8 月份,我們發佈了一個新的基於行的模型,取代了先前的位元組單位,這使得預測和量化使用量變得更加容易。具體來說,我們改為使用行,是因為這樣更容易推理:如果您正在寫入一行,那麼它是 1KB 還是 1MB 並不重要。如果您的讀取查詢使用索引欄進行篩選,您不僅會看到效能優勢,還會節省成本。
以下是 D1 的定價——幾乎所有內容都保持不變,還提供了按行收費的額外好處:
D1 的定價——您可以在 D1 的公開文件中找到更多詳細資訊。
和以前一樣,D1 不會針對「資料庫小時數」、資料庫數量或時間點復原 (Time Travel) 收取費用,您只需要查詢 D1 並為您的讀取、寫入和儲存付費,這就夠了。
我們相信,這不僅使 D1 更具成本效益,而且還可以更輕鬆地管理多個資料庫以隔離客戶資料或生產與暫存:我們不關心您查詢_哪個_資料庫。您可以按照自己喜歡的方式管理資料,分離客戶資料,並避免落入「基於計費的架構」陷阱,這種架構僅圍繞收費方式進行構建,即使這對您的團隊來說並不直觀或合理。
為了更容易瞭解給定查詢的費用_以及_何時使用索引最佳化查詢,D1 還傳回查詢讀取或寫入(或兩者)的行數,以便您可以瞭解它的金錢和時間成本。
例如,以下查詢根據日期篩選訂單:
上面的未索引查詢掃描了 16,800 行。即使我們不對其進行最佳化,D1 每月免費包含 250 億次查詢,這意味著我們可以在整個月內進行該查詢 140 萬次,而不必擔心額外成本。
SELECT * FROM [Order] WHERE ShippedDate > '2016-01-22'"
[
{
"results": [],
"success": true,
"meta": {
"duration": 5.032,
"size_after": 33067008,
"rows_read": 16818,
"rows_written": 0
}
}
]
但我們可以透過索引做得更好:
建立索引後,讓我們看看我們的查詢現在需要讀取多少行:
CREATE INDEX IF NOT EXISTS idx_orders_date ON [Order](ShippedDate)
在 ShippedDate 欄上使用索引的相同查詢僅讀取 417 行:不僅速度更快(持續時間以毫秒為單位!),而且成本更低。使用 5 美元的 Workers 方案,我們可以每月執行此查詢 5900 萬次,超出此次數才需要額外付費。
SELECT * FROM [Order] WHERE ShippedDate > '2016-01-22'"
[
{
"results": [],
"success": true,
"meta": {
"duration": 3.793,
"size_after": 33067008,
"rows_read": 417,
"rows_written": 0
}
}
]
D1 也透過 Cloudflare 儀表板和我們的 GraphQL 分析 API 公開行計數,這樣,您不僅可以在調整效能時查看每個查詢,還可以分解所有資料庫中的查詢模式。
D1 for Platforms
在整個 D1 的 Alpha 測試階段,我們合作的團隊和其他一些團隊都對 D1 的水平擴展能力感到興奮:能夠為每個客戶(或使用者!)部署一個資料庫,以將資料儲存在離團隊更近的位置_,同時_更強有力地將該資料與其他使用者隔離。
在 Workers for Platforms 上構建下一個重要產品的團隊(將其視為「功能即服務,即服務」)可以使用 D1 為每個使用者部署一個資料庫,從而使客戶資料彼此嚴格分離。
例如,作為 D1 的早期採用者之一,RONIN 正在建立一個邊緣優先的內容和資料平台,為每個客戶提供一個專用的 D1 資料庫,這允許客戶將資料放置在更靠近使用者的位置,並讓客戶之間的查詢互相隔離。
RONIN 使用 D1 for Platforms 在邊緣提供自動無限可擴展性,而不是啟動並管理無數的傳統資料庫執行個體。這使得 RONIN 能夠專注於為您的內容提供直覺的編輯體驗。
談到啟用「D1 for Platforms」,我們從一開始就從幾個方面考慮了這一點:
除了 D1 支援每個帳戶 50,000 個資料庫之外,還為 Workers for Platforms 使用者支援超過 100,000 個資料庫——其實並沒有限制,但如果我們直接說「無限制」,您可能不會相信。
D1 的定價——您無需為每個資料庫或「閒置資料庫」付費。如果您擁有許多使用者,有的使用者每秒數千個查詢,有的 10 分鐘才有 1-2 個查詢,您無需為流量較少的資料庫上的「資料庫小時數」支付更多費用,也無需針對整個使用者群體中的峰值工作負載來進行規劃。
能夠透過 D1 的 HTTP API 以程式設計方式設定更多資料庫_,且無需重新部署即可將_它們附加到您的 Worker 上。也沒有「佈建」延遲:建立了資料庫,就立即可供您或您的使用者查詢。
詳細的每個資料庫分析,以便您可以瞭解哪些資料庫正在使用中以及如何透過 D1 的 GraphQL 分析 API 查詢它們。
如果您正在 Workers 之上構建下一個大型平台並希望大規模使用 D1(無論您是否參與 Workers Launchpad 計畫),請與我們聯絡。
D1 的後續計畫是什麼?
**我們設定了一個明確的目標:我們希望在明年初(2024 年第一季)使 D1 對於生產使用案例「普遍可用」(GA)。**儘管您已經可以在無需等候清單或核准流程的情況下使用 D1,但我們知道 GA 標籤對許多人來說是資料庫的一個重要標籤(我們也是如此)。
從現在到 GA 之前,我們會努力研究 D1 願景的一些真正關鍵部分,並持續專注於可靠性和效能。
這個願景中尚未實現的一個重大部分是全域讀取複寫,我們在今年早些時候寫到過這一點。重要的是,複寫將是免費的,不會增加您的儲存消耗,並且仍將實現工作階段一致性(閱讀您所寫)。D1 的部分使命是讓資料更接近使用者所在地,我們很期待能夠實現這一目標。
我們也正在努力擴展 Time Travel(D1 的內建時間點復原功能),以便您可以即時從特定時間點分支和/或複製資料庫。
我們還將逐步開放每個資料庫儲存的限制,為每個帳戶解鎖更多儲存空間,以及您在今年剩餘時間內可以建立的資料庫數量,因此請密切關注 D1 變更記錄(或您的收件匣)。
同時,如果您尚未使用 D1,您可以立即開始使用,造訪 D1 的開發人員文件來激發一些想法,或加入我們 Developer Discord 上的 #d1-beta 頻道,與其他 D1 開發人員和我們的產品工程團隊進行交流。