01
引言
隨著用戶的增長、業務的發展,大型企業用戶的業務系統的數據量越來越大,超大數據表的性能問題成為阻礙業務功能實現的一大障礙。其中,流水錶作為最常見的一類超大表,是企業級用戶經常碰到的性能瓶頸。
本文就以流水類的超大表,探討基於SequoiaDB巨杉資料庫存儲的超大表進行的性能調優。SequoiaDB 巨杉資料庫,作為新一代 OLTP 的分布式資料庫,被廣泛使用於海量數據存儲與高並發操作場景中。對於海量數據的存儲和高並發操作,分布式資料庫相較於傳統資料庫有著天然的優勢,合理利用SequoiaDB巨杉資料庫多種特性,輕鬆解決超大表的性能問題。
02
數據存儲規劃很重要
對於流水類超大表,前期的數據存儲規劃尤為重要,合理的數據存儲規劃能有效利用資料庫集群硬體資源,提供更高性能、更高效率的數據服務。
1. 集群規模評估與硬體配置搭配
在資料庫集群規劃伊始,需要通過調研資料庫集群支撐應用規模、系統定位和業務長期發展規划進行摸底,用以評估集群規模以及各伺服器的CPU、內存、硬碟、網卡的合理搭配。
精準的評估一個資料庫集群規模,是一個宏大且複雜的綜合工程,需要有的業務需求評估數據加以支持。通常情況下,由於業務需求變化快、業務增長普遍高於預期,小集群規劃可以按照業務調研信息的1.5~2倍進行評估,大集群規劃可以按1~1.5倍進行評估。
集群規模需要通過業務規模、數據存儲規模、最大流水錶3年數據規模,三類信息進行評估。業務規模評估需要從業務訪問量、資料庫各類操作比例、操作時間分布等進行調研,最終得出各類操作的交易TPS和操作並發度數據。
數據存儲規模主要對流水類數據進行評估,從存量數據、3年增量數據預估、數據吞吐規模等信息進行調研,最終得出集群數據存儲大小、數據吞吐量,並結合交易TPS估算出磁碟IOPS。基礎信息表的數據規模對集群規模評估影響小,作為一個參考信息只需要出整體規模上評估即可,例如,集群需存儲1000張基礎表,平均每張0.1GB,整體需要100GB,這個量級在上百TB的集群規模裡可以忽略不計。
具體操作上,可以先敲定集群存儲大小,在根據IOPS和數據吞吐情況平衡使用磁碟還是固態硬碟,每個硬碟的大小,一臺伺服器掛載幾個硬碟等等,根據TPS、操作類型比例和並發度來配置CPU和內存。一般情況下,建議CPU內存比為1:8,單個硬碟在1.5~3T的容量為主,單個盤容量越大越容易出現IO性能瓶頸,網絡帶寬根據集群大小和集群吞吐量可選擇使用千兆網或萬兆網絡。
2. 流水錶怎麼建會更好
流水類數據通常包含兩個維度特徵:業務時間維度和業務主鍵維度。對於流水錶最普遍的就是創建多維分區表(如圖1),先在主表集合通過把不同業務日期的數據切分到不同的子表集合中,以此確保單個集合數據量不至於過大;然後,在子表集合通過業務主鍵將數據打散到集群的各個數據節點中,單集合在單節點上的數據量最好在百萬數據量級以內。另外,通過業務日期進行多維度分區,可以非常簡單的實現集群橫向擴容。
需要注意的是,在設計流水錶集合空間時,最好按年或按月創建集合空間,這樣當數據超過數據保存周期時可以快速備份、刪除並釋放存儲空間。
3. 再合理的規劃也無法一勞永逸
再合理的數據存儲規劃,在急劇增長的數據和千變萬化的業務需求面前,都顯得那麼無能為力,數據的增長總會超出預期,性能瓶頸總有發生的那天。這個時候,就需要針對具體性能問題進行性能優化。
03
硬體資源性能瓶頸分析
集群硬體資源的使用情況,是分析性能瓶頸的一個重要依據,通過硬體資源使用情況的變化,可以直觀確定發生變化時集群應該發生了業務變更或者操作變更,從變化中梳理出一條分析思路。
1. 集群硬體資源監控數據是基礎
集群伺服器各硬體資源的日常性能監控很重要,通過日常的監控數據,可以了解集群性能的波動情況。
nmon監控軟體是是一款很出名的開源的系統性能監控工具,用於監控AIX\linux系統的資源消耗信息,並能把結果輸出到文件中,然後通過nmon_analyser工具產生數據文件與圖形化結果。如圖2是nmon的運行主界面,網際網路上有許多關於nmon工具的安裝、實時監控、數據採集、分析報表生成等一整套教程,感興趣的小夥伴可以了解一下。
2. 集群硬體資源使用情況多維度分析
硬體資源使用情況分析,分為實時監控分析和監控報表數據分析,兩者需要需要結合使用。
對於常態化的性能問題,先使用實時監控獲取具體進程使用的各硬體資源的情況,再結合報表分析將監控的時間長度拉長,找到出現性能變化的起點,看這種性能變化是否是周期性的、隨機性的或是漸變的,結合此時點前後的生產變更情況以及相關數據操作動作來定位問題。
對於已發生暫時沒有重現的性能問題,先通過監控報表分析手段,分析性能問題發生時點前後的硬體資源變化,再將監控的時間長度拉長,嘗試找出資源變化的規律,然後通過應用日誌、資料庫日誌和生產變更情況,找出引發性能問題的操作。最後,嘗試重新執行相關操作,並進行實時性能監控,驗證相關問題猜想。
從硬體資源監控中找出性能變化的內在邏輯是問題分析的關鍵所在,掌握硬體資源的變化規律就初步掌握了集群的性能情況,也是進行性能調優的第一步。
04
資料庫集群業務情況與操作分析
掌握了解硬體資源性能情況是性能優化的第一步,還需要結合集群業務情況與各類操作比例與時間分布,才能進一步精確的定位性能問題。
1. 業務情況摸底
業務情況摸底一般通過業務訪問監控接口持續獲取業務訪問情況,並結合業務邏輯分析需要執行的資料庫操作,獲得業務TPS、並發度、數據操作類型分布、數據吞吐量等信息,以此評估資料庫集群壓力。
2. 數據分布情況分析
數據分布不均導致的性能問題是一個非常常見的問題,流水類超大表出現數據分布不均主要是由於業務主鍵欄位隨機性弱,無法很好的進行哈希打散,可使用其他隨機性較強的欄位代替,或者結合數據特點使用範圍分區也是一個可以嘗試的方法。
如何確定數據是否均勻分布?首先,通過查看主表集合的編目信息,檢查業務日期切分是否均衡;然後,查看每個子表集合的編目信息,檢查數據是否根據業務主鍵打散到所在數據域的各個節點;最後,抽查2~3張子表集合,檢查子表集合在每個節點的數據量是否相當均衡。
3. 訪問計劃分析
通過query.explain({ Detail : true, Run : true })可獲取查詢的詳細訪問計劃。通過分析數據操作語句的訪問計劃,可以掌握該數據操作的涉及到哪些子表集合,每個子表集合的每個節點的訪問計劃情況,包括訪問計劃的掃描方式、索引使用情況,數據情況,資源使用情況等信息。
4. 查詢監控與全表掃描檢測
通過抓取資料庫集群會話快照db.snapshot(SDB_SNAP_SESSIONS),可以捕獲每個查詢的數據操作詳細信息,包括會話狀態、線程信息、索引數據信息、數據操作記錄數、操作耗時、資源使用情況等等信息。
可通過不斷抓取會話快照信息,監控會話快照信息中的"LastOpInfo"欄位是否包含"tbscan"字樣,來檢測數據操作中是否存在全表掃描的情況。
05
性能優化指引
流水類超大表的性能優化,一般遵循從操作到軟體再到硬體,由簡到繁的一個優化思路,優化前需要充分了解軟硬體情況,例如數據操作情況、資料庫配置、系統性能情況等等。
1. 適量創建高效索引
索引是一種提高數據訪問效率的特殊對象。恰當的使用索引可提高數據檢索效率,但索引使用不當反而會降低數據檢索速度,嚴重的還會造成資料庫整體服務性能下降。
利用索引對流水類超大表進行性能調優,是最為經濟、簡單、高效的一種方式。那麼,如何恰到好處的創建索引,即能提高數據操作效率,又不會對資料庫服務性能造成影響?
首先,需要了解索引的可供調優參考的部分特性,以及相關性能開銷成本。
部分相關特性:
使用二分查找,可快速定位數據,平均複雜度是O(logN)。索引數據信息大小遠小於表數據大小,索引數據可長時間緩存在內存。使用B樹結構,三層的B樹可以表示上百萬的數據,通過索引檢索數據可減少磁碟I/O次數,數據欄位越小索引效率越好。I/O的次數取決於B樹的高度H,假設當前數據表的數據為N,每個磁碟塊的數據項的數量是M,則有:H=log(M+1)N,當數據量N一定的情況下,M越大,H越小;而M=磁碟塊大小/數據項大小,磁碟塊大小也就是一個數據頁的大小,是固定的,如果數據項佔的空間越小,數據項的數量越多,樹的高度也就越低。這也就是為什麼每個數據項,即索引欄位要儘量的小,比如int佔4個字節,要比bigint的8個字節小一半。這也是為什麼B樹要求把真實數據放在葉子節點內而不是內層節點內,一旦放到內層節點內,磁碟塊的數據項會大幅度的下降,導致樹層級的增高。當數據項為1時,B樹會退化成線性表。
索引具有最左匹配特性,創建複合索引要根據數據重複率和查詢使用的欄位情況進行創建。B樹的數據項是複合性數據結構,按照從左到右的順序來建立搜索樹的,例如:當(小張,22,女)這樣的數據來檢索的時候,B樹會優先比較name來確定下一步的搜索方向,如果name相同再依次比較age和gender,最後得到檢索的數據。但是,當(22,女)這樣沒有name的數據來的時候,B樹就不知道下一步該查哪個節點,因為建立搜索樹的時候,name就是第一個比較因子,必須根據name來搜索才知道下一步去哪裡查詢。比如,當(小張,男)這樣的數據來檢索時,B樹就可以根據name來指定搜索方向,但下一欄位age缺失,所以只能把名字是「小張」的所有數據都找到,然後再匹配性別是「男」的數據了。索引數據是有序的,支持順、逆排序,合理利用可優化查詢排序和分組效率。數據重複率越低索引使用效率越高。
相關性能開銷:
對數據操作都需要額外對索引進行維護,索引越多維護性能開銷越大。創建索引需要排序,需要額外存儲空間,會獲取表鎖,創建時會消耗大量內存、CPU。一次數據查詢操作,至少產生2次IO操作,一次查詢索引數據,一次訪問表數據。一次數據插入操作,至少產生1+n(n為索引個數)次IO操作,當索引當葉結點過滿時會觸髮結點遞歸分裂時,IO操作會劇增。一次數據刪除操作,至少產生3+n(n為索引個數)次IO操作,當索引當葉結點過空時會觸髮結點遞歸合併時,IO操作會劇增。一次數據更新操作,如果更新欄位不是索引欄位,則產生3次IO操作,如果更新欄位為索引欄位,則產生3+n(n為索引個數)次IO操作,且索引結點的分裂與合併均有可能發生(變長數據類型欄位)。
掌握了索引相關特性和性能開銷,結合流水類超大表的特點,通過評估確定數據插入、更新和查詢操作的比例,調研更新欄位與查詢欄位是否有重合等信息,以此來確定是否需要創建索引,創建哪些索引。
一般來說,流水類超大表都需要創建流水主鍵索引,以確保流水數據唯一性。其他的索引創建需要可根據更新、查詢條件、數據規模等信息進行評估,通常創建2~3個索引效率性能比較為理想。如果數據查詢操作為主,可酌情增加索引數量。對於多個欄位組成的查詢條件,可根據條件欄位的重複率情況創建複合索引;對於有數據排序、數據分組的欄位,可按排序分組欄位創建複合索引。
2. 優化查詢語句
對於流水類超大表的查詢優化,有兩個基本原則:一是通過索引調優,強制數據查詢走指定索引,二是通過限制查詢的業務日期範圍,減少查詢檢索的數據規模。
索引調優可以結合本文 「適量創建高效索引」章節所述合理創建索引,並通過查看執行計劃確保查詢走索引。
合理的利用巨杉資料庫主子表的特點,在查詢時確定查詢數據的業務日期維度,可以極大的減少檢索數據規模,減少節省資料庫集群資源,舉個例子:應用需要通過流水號(主鍵)查詢該流水號對應的流水數據,該流水號記有業務日期信息。通常情況下,簡單的使用流水號就可以準確快速的查詢到該條流水,但對於一個流水類超大表來說,可能存放著十年幾十年的流水數據,數據可能存儲在上百張子表中,如果單單使用流水號查詢,那麼資料庫就需要對每個子表進行一次索引檢索,最後只會有一張表檢索到數據,但如果把流水號中的業務日期截取出來作為一個查詢條件,那麼資料庫就可以通過主表的業務日期分區信息定位到該流水數據所在的子表,資料庫僅會對該子表進行索引檢索。
另外,對於對大範圍業務日期查詢,且需要分頁處理的,可每次查詢一個業務日期分區,分多次完成查詢。對於查詢數據結果集很大的查詢,通常使用分頁查詢,單頁數據量在數百以內為佳。
總的來說,查詢語句的調優沒有一套固定標準的操作方法,它是一個循序漸進的過程,只有通過不斷的測試、優化、再測試、再優化,在不斷迭代中逐步提高查詢效率。
3. 調整數據切分粒度
流水類超大表什麼時候需要調整數據切分粒度,可能是本節內容的最大挑戰,需要綜合考慮集群硬體資源使用情況、查詢優化情況,子表單節點數據大小、索引大小等等一系列問題。
從硬體資源使用角度考慮,硬碟使用率在70%以下,超過70%可以考慮直接進行集群擴容,在集群CPU、內存基本保持在60%以下,只有IOPS居高不下,且IO讀緊張IO寫正常,查詢業務TPS遠低於IOPS,此現象說明1次查詢會產生非常多的IO讀;從查詢優化情況看,已無全表掃描的查詢,查詢語句已做了足夠的優化,但查詢依然無法滿足需求;以單子表單個節點的數據規模進行評估,數據規模需要控制在百萬級別,單條數據記錄的欄位數與數據長度對數據檢索也有影響,特別是數據更新操作,數據欄位越多、數據長度越長更新效率越低;評估查詢語句中的業務日期範圍,查詢越精確,切分粒度的調整彈性就越大;另外,根據創建的索引的欄位類型以及實際索引大小,評估索引是否可以完全緩存至內存,儘可能將數據切分粒度調整至索引數據可完全緩存至內存。
實際上,調整流水類超大表的數據切分粒度,就是提高數據並發度,減少單子表在單節點的索引數據規模,使得整個索引數據可以常駐內存,最大程度減少IO開銷,故而,調整數據切分粒度會增加內存、CPU資源的消耗。
如何調整數據切分粒度是需要探討的另一個問題,對於按本文介紹的主子表建表規則創建流水類超大表,很簡單的就可以完成調整動作,只需要將主表的每個業務日期區間,拆分成多個切分區間,即一個子表數據拆分成多個子表。關鍵的問題是,拆成多少個子表合理,一般建議一個子表拆分成2~3個子表較為合理,不過,最可靠的方式是——模擬生產測試。
4. 升級短板硬體
伺服器停機升級短板硬體,對於天然具備容災高可用特性的巨杉資料庫來說,是一件不能再簡單的事情,只需將需要升級的伺服器的資料庫主節點切換到其他伺服器,就可以停掉資料庫服務然後進行停機升級;如果是替換硬碟,在重啟完成新硬碟掛載並創建相應數據目錄後,重啟資料庫服務後,資料庫會自動同步數據。
通過硬體資源的性能瓶頸分析,可以很清晰的看出硬體資源瓶頸,可根據業務需要酌情升級短板硬體,如添加內存條,將磁碟替換成固態硬碟,甚至可直接將整臺伺服器置換掉。
5. 集群擴容
當資料庫集群存儲空間不足,或者上述優化手段都不能很好的解決性能瓶頸問題時,可以著手進行集群擴容。
在集群擴容時,需要根據現有集群情況加以調整優化,例如,原有數據域有3臺伺服器,由於增量數據劇增,後續規劃的數據域就需要6臺或者更多伺服器。又例如,新伺服器參照舊伺服器的硬體資源使用情況,需要調整硬體配置,降低空閒的配置要求,提升短板硬體資源的配置等等。由於有了一個現成的參考對象,集群擴容的規模評估和硬體配置評估就可以簡單很多。
對於流水類超大表的集群擴容操作是非常簡單的,只需在安裝好巨杉資料庫軟體的伺服器按規範新增數據節點,將新增節點添加進原有集群並作為一個新的數據域,然後將後續業務日期的子表集合創建在新的數據域,再將子表集合按規範掛載到主表集合上,到此為止已經完成了集群擴容的所有步驟。如下圖所示,當數據域1各類硬體資源不夠使用,可新增一個數據域2存儲2030年以後的流水數據。
06
總結
流水類超大表的性能優化,是一個持續迭代的過程,需要建立在對資料庫集群的業務層、數據層、硬體資源層有充分的了解的基礎上,依次對硬體資源分析、集群操作分析與檢測、業務分析,完成對性能問題的定位。
同時,對於巨杉資料庫的用戶,在處理超大表優化問題時,可以合理利用 SequoiaDB 巨杉資料庫多維分區特性和簡易的橫向擴展機制,輕鬆解決超大表的性能問題,面對超大表的性能優化再也不用愁~