随着時間推移,資料庫中資料量會越來越大,如果把查詢分析都挂到資料庫上,有可能會影響到生産系統的正常運作。是以,一般都會将生産資料庫中不再變動的資料定期移出到另一個分析資料庫中,由分析資料庫來承擔查詢分析的壓力。
不過,我們知道,檔案系統比資料庫有更好的IO性能,對于不再變動的曆史資料,使用檔案還可以采用更靈活的壓縮技術。這樣,如果我們把移出的資料存儲到檔案中,隻要有好的計算引擎(比如集算器),那麼基于檔案計算将獲得比分析資料庫更好的性能,而曆史資料常常巨大,性能提升很有意義。
要實作這種結構,需要定期把曆史資料從生産資料庫中導出到檔案,這看起來也沒什麼難的,導出是很正常的資料庫操作。
如果是冷導出,那确實沒什麼。所謂冷導出,是指在資料導出過程中,基于檔案的查詢分析系統會暫停使用,等導出完畢後再繼續使用。比如在每天夜間沒有查詢工作的時候進行,把導出的新曆史資料追加到原來的檔案之後就可以了,有需要建索引的情況也可以同時維護好。
但是如果是熱導出,情況就不一樣了。所謂熱導出,是指查詢分析系統永不停機,随時需要能響應請求。而資料導出本身也需要時間,在導出的過程之中仍然可能有查詢請求進來。但是,這種有特殊格式的檔案在追加和維護(索引)過程中,經常是不可用的,這時候就不能在導出資料的同時還響應查詢請求了。
采用資料庫卻沒有這個問題。原因是資料庫擁有事務一緻性的能力,在資料寫入(導出對于目标資料庫來講是寫入)過程中,資料庫仍然可以應對查詢請求,并且不會使尚未完全寫入的資料參與查詢。不過,如果每批資料量寫入太多時,也會給目标資料庫造成較大的負擔,資料庫復原機制的成本并不低。
那麼,我們怎麼能夠即享受到檔案的高性能,又支援不停機的熱導出呢?
一個簡單的辦法是把資料檔案拆細。比如,假如資料是每天導出,那麼就可以每天儲存一個檔案,每次導出時形成新檔案,在導出過程中原有的檔案不變,可以繼續使用。新的一天的檔案導出維護完成後,在某個時刻才開始啟用。比如每天0點開始導出前一天資料,假定一小時内能全部完成,則可以約定淩晨1點起啟用新檔案資料(即1點以後的查詢将開始使用這個新檔案)。這樣的壞處是檔案系統中積累過多碎檔案,對管理造成麻煩,而且每次查詢時都可能要涉及多個檔案,運算代碼不好寫而且性能也會受到影響。
在資料庫一緻性能力的支援下,再配合備份檔案,我們還是可以實作将資料熱導出成單一檔案。
準備工作:● 将資料檔案複制成相同的兩份:A份和B份,平時查詢使用A份;
● 在(生産)資料庫中建立表X,用于記錄目前查詢正在使用的資料檔案是A份還是B份,以及目前正在執行的查詢。
查詢響應過程:● 從X中讀出目前使用哪個資料檔案,并在X中寫入一條記錄表示目前查詢開始,需要生成一個唯一碼,同時記錄該查詢基于哪個資料檔案;
● 使用相應的資料檔案進行查詢計算并獲得傳回資料後;
● 将步驟1中寫入的記錄删除(用生成的唯一碼),表示查詢已經結束。
導出過程:● 開始導出資料時,此時X中記錄的目前使用檔案為A,将這個值改為B,後續出現的查詢将基于B進行;
● 等待X中基于A的查詢全部結束,即X中不再有關于A的查詢記錄,此時A已不再被任何查詢使用了;
● 現在可以導出資料追加到檔案A,完成A的維護工作;
● 将X中記錄的目前使用檔案改為A,再有的查詢将轉回基于A進行;
● 等待X中基于B的查詢全部結束;
● 将A追加的資料也同時追加給B(這時隻要讀A,不會影響A上的運算),完成B的維護工作,B進入可用狀态,導出結束。
基本原理是在導出資料過程中使用另一個檔案,完成導出後再換回來去維護備份檔案。期間要考慮到查詢的并發性,借助資料庫的一緻性確定不會發生寫入和查詢在同一個時刻針對同一檔案進行。并發讀寫導緻的錯誤,不是刻意或大規模使用時很難測試出來,在設計時要特别小心。
許多機構期望資料庫系統能支援T+0全量實時查詢,在資料量很大時一般隻能進行資料庫擴容了(包括上述分庫手段也需要擴容資料倉庫),成本高昂。如果采用檔案系統和生産資料庫混合運算,就可以實作低成本高性能的T+0查詢了,而熱導出機制則是這個方案的基礎(需要進行簡單改造,在X表中記錄檔案中資料的截止時刻,超過此時刻的查詢請求将轉給生産資料庫去執行)。
不過,這個過程确實有些複雜,實作起來還是很麻煩,我們在乾學院上放一個以T+0查詢為目标而實作的熱導出例程(http://c.raqsoft.com.cn/article/1541494770016)另外,在新的集算器倉庫版也将支援這一機制,直接向組表追加資料就可以了,集算器會自動處理熱導出中的問題。當然,集算器不能依賴有資料庫,它會自己實作一緻性效果。
原文釋出時間為:2018-11-6
本文作者:蔣步星
本文來自雲栖社群合作夥伴“
資料蔣堂”,了解相關資訊可以關注“
”。