DevOps 技術:資料庫變更管理
資料庫變更通常是執行部署時風險和延遲的主要來源。DevOps 研究和評估 (DORA) 調查了在實現持續交付過程中與資料庫相關的最佳做法,同時提高了軟體交付性能和可用性。
DORA 的研究發現,將資料庫工作集成到軟體交付流程中有助於持續交付。但是,作為實現持續交付的一部分,您的團隊如何改進資料庫交付?一些做法可以預測性能結果。
DORA 發現包含資料庫訴訟或調查的良好通信和綜合配置管理。在持續交付方面表現出色的團隊將資料庫變更作為腳本存儲在版本控制中,並以與管理生產應用變更相同的方式來管理這些變更。此外,當對應用的變更需要變更資料庫時,這些團隊會與負責生產資料庫的人員討論這些變更,並確保工程團隊能夠清楚了解待處理的資料庫變更進度。
如果團隊遵循這些做法,資料庫變更不會拖慢它們的速度,或在執行代碼部署時出現問題。
如何實現資料庫變更管理
實現高效的資料庫變更管理有兩個方面:文化和技術。本部分將討論這兩種方法。
建立有效的資料庫變更通信
研究顯示,當團隊與負責管理生產資料庫的人員討論變更,並且當團隊每個人了解待處理的資料庫變更進度時,團隊表現最佳。
由於幾個原因,與生產資料庫管理員 (DBA) 討論建議的變更很重要。首先,這些專家可以就如何取得最佳結果提出建議,並指出諸如性能問題之類的潛在問題。(與開發者工作站相比,生產系統中的許多操作具有非常不同的性能特徵)。通過這次討論,DBA 可以深入了解上遊正在發生的事情,從而幫助他們更好地為即將發生的變更帶來的影響做準備。
確保每個人都了解變更進度也很重要,因此包括 DBA 在內的團隊可以了解即將發生的變更、其測試狀態,以及各種生產資料庫和非生產共享資料庫發生了哪些架構變更。您可以通過以下方式提高可見性:
將所有資料庫架構變更以及架構所屬的應用代碼一起保留在版本控制中;使用工具記錄對環境進行了哪些變更及其結果。這些做法還可確保所有變更具有規範真實來源,使變更歷史記錄易於訪問以用於審核。
將所有資料庫架構變更視為遷移
版本控制資料庫變更的廣泛模式是捕獲所有變更作為遷移腳本保留在版本控制中,如下圖所示。每個遷移腳本都有唯一的序列號,以便您知道應用遷移的順序。
然後確保每個資料庫實例都有一個表,記錄針對該特定實例運行的遷移。通過這種方式,您可以對資料庫架構進行版本控制,因此,您可以使用工具來應用遷移腳本,將資料庫轉換為您想要的架構版本。工具示例包括:
遷移 (Go)alembic (Python)Active Record Migrations (Ruby on Rails)dbup (.NET)Entity Framework Migrations (.NET)Laravel Migrations (PHP)Flyway (platform-independent)Liquibase (platform-independent)您還可以使用遷移來創建空資料庫架構以進行開發和測試。
如下圖所示,每個資料庫實例都有一個表,記錄您針對該實例運行的遷移。然後,您可以使用工具或腳本自動執行更新,該工具或腳本會執行尚未應用到資料庫實例的遷移,並在每個遷移成功完成後更新遷移表。
您可以用與管理應用變更相同的方式來管理資料庫變更:通過使用版本控制作為其真實來源的自動化過程。
零停機時間資料庫變更
許多組織會在資料庫架構變更時安排服務停機時間,因為需要與應用部署協調,或在執行此類變更的過程中資料庫表鎖定。持續交付旨在消除部署的停機時間,因此以下是在不停機的情況下進行資料庫架構變更的一些策略:
使用在線架構遷移框架,例如 gh-ost 或 pt-online-schema-change。這些工具會為您要變更的每個表創建一個「ghost」副本,遷移空副本,然後從原始表中逐步複製數據,包括遷移期間發生的任何更新。此過程完成後,它們會用「ghost」替換原始表。某些資料庫,例如 Cloud Spanner,可以在零停機時間的情況下執行架構更新。使用並行更改模式分離資料庫變更和應用變更。在此模式中,您永遠不會更改現有資料庫對象。相反,您可以在舊結構的基礎上添加新的結構。例如,考慮將「地址」列變更為兩列:address_1 和 address_2。您可以添加新列,但保留舊列,而不用刪除舊列並添加新列,並同時發布應用的新版本。您可以在部署應用之前執行此操作。然後,該應用的新版本可以查找新列並從中讀取(如果存在且不為 null),否則從舊列中讀取。然後,應用可以寫入新列和舊列、延遲遷移數據,並允許應用回滾,而無需資料庫回滾。通過這種方式,應用部署與資料庫變更分離,資料庫變更通常可以在不引起停機的情況下進行,因為它不涉及遷移數據。為了降低部署難度,我們在應用中權衡了一些額外的複雜性。或者,您可以使用資料庫觸發器來使新列和舊列中的數據保持同步。設計和實現數據分區和歸檔策略。遷移時間長的一個主要原因是具有大量行的資料庫表。請確保您的應用設計為允許對數據進行分區和歸檔,以避免表變得太大。其中一個例子是為每個季度創建一個表的多個實例,例如,如果沒有 survey_answers表,您可能有 survey_answers_2020Q1、survey_answers_2020Q2,依此類推。確保應用的設計和架構審核包括驗證應用的數據分區/歸檔策略。使用事件溯源架構。在事件溯源架構中,不是讓資料庫存儲應用的當前狀態,而是以事件日誌的形式將其變更存儲其狀態,稱為命令。因此,當客戶更改其地址時,該應用會發出一個存儲在資料庫中的地址變更命令,而不是在表中更新客戶詳情。這就是資料庫事務日誌和版本控制的工作方式,也是分布式系統中的常見模式。在事件溯源架構中,事件可排入隊列,從而允許在事件排隊時進行資料庫遷移。遷移完成後,隊列中的事件可以刷新到資料庫中。有些資料庫能夠在架構遷移運行時對查詢進行排隊,如果遷移完成得足夠快,這會很有效。使用 NoSQL 解決方案。有些 NoSQL 資料庫(例如 Firestore 和 Cloud BigTable)不受架構變更造成的停機時間問題的影響。Firestore 等文檔資料庫具有隱式架構,這意味著架構在應用層(而不是資料庫層)進行管理。但是,使用 NoSQL 資料庫時也存在與其相關的權衡:它並非適用於每個應用。除了消除計劃停機時間之外,您還需要避免計劃外停機時間。請確保針對類似生產的數據集(已清理任何個人信息或機密信息)測試每個架構變更,以確保應用在遷移期間和遷移後的行為符合預期。一些組織每天都會創建生產資料庫的清理版本以用於此目的。如果您使用的資料庫管理系統在生產環境中具有多個節點,請確保您正在針對具有至少兩個節點的實例進行測試,以捕獲分布式系統問題。
實施資料庫變更管理的常見誤區
在實現本文所述的關鍵做法時,需要注意一些常見問題。
許多組織都處於非常孤立的狀態。DBA 通常在自己的單獨團隊中工作,該團隊使用自己的流程來管理變更。當軟體交付團隊在沒有諮詢 DBA 團隊的情況下實現管理資料庫變更的新流程時,他們可能會在使用新流程對 DBA 團隊管理的資料庫進行變更時遇到阻力。這樣可以顯著減少遷移到新流程的優勢。
第一步是與他們一起討論如何實現本文所述的目標。讓他們接受任何建議的流程和技術變更是很重要的。為此,最好的辦法是詢問他們所遇到的問題,了解本文介紹的建議如何幫助他們解決這些問題,並提供解決方案。理想情況下,交付團隊和 DBA 可以找到一個互相接受的解決方案。
另一個問題通常會加劇這種障礙:多個應用共用同一資料庫架構的情況。這意味著在一個應用上工作的團隊不能在不影響其他應用的情況下變更架構。這要求採用一個解決方案來管理共享資料庫架構的所有應用的資料庫變更。在這種情況下,實現版本控制的自助服務機制部署資料庫變更是可行的,甚至更加有益。不過,這需要仔細規劃和發布。
最後,同時實現基於遷移的資料庫變更管理和零停機時間部署可能涉及重大架構變更。在估算實現這些做法所需的工作量時,應考慮這一點。
如何衡量資料庫變更管理
有效的資料庫變更管理系統的目標是,資料庫變更不會減慢部署的速度或造成問題。值得衡量的是,資料庫變更中失敗變更的百分比是一個促成因素,以及與資料庫變更相關的工作在多大程度上有助於從版本控制到發布的整個交貨期。
如果資料庫變更需要計劃停機時間,這也是一個重要的考慮因素。要衡量計劃停機時間的經濟影響,請考慮停機時間所產生的潛在經濟損失,以及為執行部署而支付員工在非正常工作時間工作的工資成本。在工作時間以外進行部署也可能會導致團隊倦怠。這些影響可用於證明實現本文檔中討論的零停機時間部署解決方案所需的工作。
在衡量自動化水平時,請考慮使用完全自動化流程以按鈕式進行資料庫變更的比例。目標是以這種方式完成 100% 的資料庫變更。(轉自DevOps