Google栽樹, 后人乘涼---OpenStack滾動升級漫談(OpenStack rolling upgrade)


    2010年, 美國的雲計算公司 Rackspace 想重寫他們的雲平台代碼, 並打算開源他們的技術和代碼; 與此同時, NASA(美國航空航天局)下屬的 Anso Lab 實驗室發布了他們的 Beta 版的雲計算平台代碼;

    Rackspace 想和 NASA 共同成立一個開源的雲計算平台項目;

    2010年7月, 在奧斯丁, Rackspace 和 NASA 一起創建了 OpenStack 項目, 之后在波特蘭的世界開源大會上, OpenStack 被正式宣布;

 

    開源之后, 大部分公司都選擇了 OpenStack 作為自己的雲計算平台, 國內使用 OpenStack 的公司有 騰訊, 阿里, 百度, 華為, 中國移動等等;

    根據 Galera 的用戶案例里面的描述, 中國移動使用 OpenStack 和 Galera Cluster  在生產環境上部署了 1000 多個節點; 

    Galera 是一家位於芬蘭赫爾辛基的小公司, 他們的產品可以用下面一張圖來介紹;

 

 

 

    基於 OpenStack 被大量使用, OpenStack 版本升級成為需要考慮的事, 不能影響生產環境, 要做到 0 停機時間;

    OpenStack 實現了自己的滾動升級策略, 主要的思路是;

        1. 表結構變更兼容: N 和 N+1 版本的服務同時支持 N+1 版本的一個中間狀態的表結構, 如下;

        2. RPC 調用兼容: 類似表結構, RPC調用也做了兼容;

        3. 服務之間的調用兼容: 服務之間的 restful 調用通過版本號控制, http://restful-api/v2,  http://restful-api/v3;

 

    這里舉例說下第1點---表結構變更的支持:

        假如有一張表, 有3個屬性:

            用戶名,

            特長,

            性別;

       N版本插入了這樣一條數據:

            用戶名: 吳藝凡,

            特長: 牙簽,

            性別: 男;

        N+1 版本想刪除屬性 "性別", 流程大概是這樣的;

        1. N+1 的 expand 階段不刪除列, 但是服務不會再操作 "性別" 這一列;

            這個時候 N 版本仍舊可以對表進行增刪改查操作;

        2. 逐步下線 N 版本的服務, 上線 N+1 版本的服務;

        3. 變更表為 contract 階段, 這個時候刪除 "性別" 列;

        如果場景不是刪除列而是增加列, 則 N+1 版本的服務在 contract 階段會用兩種方法填充新列:

            1. 服務在訪問表時觸發對列數據的填充;

            2. 執行 contract 遷移的時候對列數據填充;

    上面就是簡單的表結構變更流程;

    OpenStack 的滾動升級策略大概是從 Newton 版本開始的, 時間是在 2016年;

 

    離開 OpenStack, 我們講一下 Google;

    2013年, Google 的分布式數據庫 F1 取得成功, Google 發布了幾篇關於分布式數據庫的論文; 論述了 F1 的原理;

    后來的很多分布式數據庫都是以 Google 的論文作為基礎開發出來的;

    Google的其中一篇論文講述了數據庫升級時, 表結構變更的場景:

    "Online, Asynchronous Schema Change in F1" --- F1 中的在線, 異步表結構變更;

    Google論文原文鏈接: http://static.googleusercontent.com/media/research.google.com/zh-CN//pubs/archive/41376.pdf

    因為某種原因打不開, 您可以自行搜索一下 PDF 版;

    Google F1 的背景就不講了, 它是一個 分布式數據庫, 解決傳統 MySQL 和 Oracle 的問題; 這里稍微講一下為什么需要在線表結構變更:

        傳統數據庫在表結構變更時, 操作期間數據庫無法提供服務; 

        即使有很多服務做熱備, 但是數據庫升級時服務不能訪問數據庫, 所以服務不可用;

        Google 的論文可以保證在表結構變更期間, 服務仍然可以訪問數據庫; 

    以增加表字段為例, 大體上講講這篇論文:

    如果要增加一個主鍵列, 列狀態需要有如下的狀態變更流程:

    absent --> delete only --> write only --(db reorg)--> public

    不存在 --> 只能被刪 --> 只能被寫 --重組數據--> 公共狀態

    這里的狀態在論文的中 3.1 節有定義: 3.1 Schema elements and states;

    比如: 一個 delete-only 的表或列, 不能被讀, 只能被刪, 一個 delete-only 的索引, 只能被刪或者更新, 並且更新操作只能刪除索引對應的鍵值對, 而不能創建;

            A delete-only table, column, or index
            cannot have their key–value pairs read by user transactions
            and
            1. if E is a table or column, it can be modified only by
            delete operations.
            2. if E is an index, it is modified only by delete and update
            operations. Moreover, update operations can delete
            key–value pairs corresponding to updated index keys,
            but they cannot create any new ones.

 

    下面是增刪改表結構的流程, 其中紅框部分是增加表字段的流程; 參見論文中的 Figure 3;

        

    對於主鍵, 是上面提到的: absent --> delete only --> write only --(db reorg)--> public;

    對於可選字段, 流程簡單一點 absent --> delete only --(db reorg)--> public;

    除了狀態約束, 還加入了新的約束: lease(租期);

    兩個相鄰的租期之間的操作是相容的;

    以增加可選列為例; 

    absent --> delete only --(db reorg)--> public;

        1. 計算節點1 在 t1 時間點同步到的列狀態為absent;

        2. t1+1 時間點列狀態變為 delete only;

        3. 計算節點2 的租期在 t1+2 過期, 它重新同步表狀態, 獲取的列的狀態為 delete only;

        4. 計算節點2 在 t1+3 時間點執行SQL: insert xxx into xxx, 新增加的列的狀態為 delete only, 所以這列不會進入數據;

        5. 計算節點1 在 t1+4 時間點 執行SQL: delete xxx from xxx, 它緩存的列狀態為absent, 新列對它不可見, 它不需要刪除新列的數據;

    這個場景的關鍵點是 delete only 狀態, 他可以保證 absent 狀態的計算節點的操作不會留下orphan data(孤兒數據);

    兩個相鄰的租期的計算節點的操作, 對於對方是兼容的;

        

    如果一個計算節點無法在租期過后重新同步表狀態怎么辦? 論文沒提到, 其實很簡單, 把這個計算節點殺掉就可以了;

 

    我們再回頭看看剛才 OpenStack 的滾動升級策略, 和 Google 的 這篇論文很像; 只是 OpenStack 把這種思想用在了業務服務的層面上;

 

    完;

    

    

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM