hyperic mysql scaling 案例學習(數據庫優化)

這是看了Sun 的communityone 上一篇介紹hyperic 在mysql 上scaling 的介紹寫的筆記.

hyperic 是一個在大型數據中心用作服務器管理和監控的軟件,Hyperic HQ 提供中心服務器來收集多臺主機的狀態和性能指標,並且在一箇中心界面上管理…… 其他的好處看後面的參考資料
Hyperic 默認是支持三種數據庫mysql,oracle,postgresql.

後面會用到的幾個hyperic 內的術語:
Servers:  一臺主機上一個特定的應用類型,比如mysql 服務,jboss 服務.
Services: 對應一個服務裏面具體的某一個類型,比如mysql 裏面的cpu 消耗,內存消耗,每個表的磁盤消耗.
Metrics: 每一個Services 一個時間點收集上來的數據,比如10:40 cpu 的消耗是60%.
Metrics data points(數據點): 一個時間點的某一個services 的具體數值, 比如上面的60%.

一種標準中等規模的度量數據:
遠程管理300臺主機,2100 Servers,21000 Services , 46萬metric, 每分鐘收集2萬metric (平均值), 每天就是2千8百萬數據點 (這個數據比較保守,性能收集間隔可以大一些.所以實際支持主機還可以多很多)

Hyperic Mysql 版本Scaling 技巧:

  1. 批量插入

    INSERT INTO TABLE (a,b,c) values (0, 0,0), (1,1,1),(2,2,2),(3,3,3),…,…

    減少和數據庫來回次數,注意設置mysql 參數max_allowed_packet
    其他可選的提高插入速度的方法Set unique_checks=0, insert, set unique_checks=1 .
    Set foreign_key_checks=0, insert, set foreign_key_checks=1

  2. Batch Aggregate Inserter

    實際的數據點的數據一般很少看到,真正給監控人員看到的都是聚合後的數據(用線性圖展現出來的)

    HQ agent 將收集到的聚合數據發送給HQ Server , 然後Server 並不馬上保存這些數據,而server將幾百個agent 的各種service 數據都放在queue 裏面,然後批量插入.

    好處就是減少插入語句次數和connection 數. 減少CPU 消耗和服務器負載.調優之後的配置一般能達到700 agent . 3個workers , 每次批量插入BatchSize:2000 ,  QueueSize :4,000,000 , 每分鐘可以插入2.2M 數據點. (還算是很保守的)

    這個技巧我覺得最厲害,這跟它表的結構也有關係, 它表儲存原始數據都是三個列(time,measurement_id,value), 所以任何監控類型數據都可以存在這個表,所以它把數據放在queue 裏面,然後批量的2000個才插入一次, 每次queue 裏面總有幾百萬的數據,但是連接數卻總能控制在個位數下,如果幾百個agent 每種metric 都要從數據連接池裏面取連接,而且還是永久性的連接,最少需要上千甚至上萬個connection, 使用這種queue + batch 的方式,只有幾個connection , 數據庫跟hyperic server 服務器(它用的jboss) 性能都伸縮了不少. 數據中心非要這種方式的收集方法.

  3. 控制數據增長

    hyperic 監控的主機越多,service 越多,每分鐘收集的數據量也就越多,控制詳細數據和聚合數據的大小對於磁盤消耗顯得很重要. 對於每個數據點收集是在hq_metric_data_xh_ys ,  一共有18個這樣的表只保存2天的詳細數據,每個表只保存一個小時的詳細數據,然後循環,每個小時進行一次數據壓縮,壓縮的表已經不會進行insert 操作了,把數據壓縮之後保存在eam_measurement_data_1h 中 (5列 $MEASUREMENT_ID , $TIMESTAMP , $VALUE , $MIN , $MAX ) , 每個小時只有一條數據(簡單認爲縮小了60倍吧),這種每個小時的數據保存14天,然後再把數據壓縮到6個小時保存一條數據放在MEASUREMENT_DATA_6H 表中,保存31天,表結構完全一樣,最後保存到MEASUREMENT_DATA_1D 表中,一天只保存一條數據.這個表你想保存多少年都可以了. 按照一臺主機監控800臺服務器上的16,000個metric 來看,一天也就16,000條數據,多少年都不成問題了.

    由於裏面每個表的功能基本都是獨立,一層一層的級別關係,所以進行很多操作的時候都沒有鎖,實時收集數據的表只有insert 操作,刪除的表都是直接truncate 掉,壓縮的表一個小時才做一次,用戶查看的都是一個小時幾個點的數據,而你又很容易看到幾個月甚至幾年的綜合數據,比如像是可用性,CPU ,磁盤使用. 每種應用都找到自己的特殊表來用. 性能,負載,容量,歷史數據都得到了很好的保存。 這個想法主要來自RRDtool ,一個主要用來時間系列的畫圖框架,主要用在nagios, cacti 等監控後臺的圖表展現上.

  4. 分區

    所有細節的表由hq_metric_data_xh_ys 表示,每兩個表代表一天,一共9天,

    所有的數據歸檔壓縮之後直接truncate ,而不是delete (這是針對mysql 5.1 之前沒有partition 的功能而做,不知道以後會不會針對mysql 5.1 之後出個特別版), 應用程序上會自動計算應該insert 那個表,每個時間段該取那個表的數據. 所以insert 的表不會跟select 表和truncate 的表有衝突,3種表都自己做自己的工作.

    truncate 和 delete 的好處也有提到,這種partition 的設計還是要好好學學.

  5. 索引的選擇

    選用InnoDB 是因爲其基於主鍵的cluster index (和oracle 的IOT 一樣), 優點就是select 更快,insert 也更快,索引佔的磁盤也更少. 由於它全部都是基於時間點的順序加入的,所以其cluster index, leaf index, data 都是基於同一個順序在磁盤上訪問,所以即使它不需要事務和鎖,InnoDB 還是其最佳選擇.

  6. SQL 的選擇

    由於mysql 的view 不能夠把子查詢的sql 執行計劃和外層的查詢計劃統一來計算,所以數據過濾操作要放在裏面,外面再把表連接起來, 像是select xxx from (select *** from innertable1 union innertable2) as bigtable  where bigtable.xxx <??? 這種sql 執行起來就很慢, 而hyperic 要通過程序計算從那些表取數據,然後在外層連接起來. 像是這樣

    SELECT begin AS timestamp, AVG(value) AS value, MAX(value) AS peak, MIN(value) AS low
    FROM
    (SELECT 1207631340000 + (2880000 * i) AS begin FROM EAM_NUMBERS WHERE i < 60) n,
    (SELECT * FROM HQ_METRIC_DATA_2D_1S
    WHERE timestamp between 1207767600000 and 1207804140000 AND
    measurement_id = 600332 UNION ALL
    SELECT * FROM HQ_METRIC_DATA_2D_0S
    WHERE timestamp between 1207724400000 and 1207767599999 AND
    measurement_id = 600332 UNION ALL
    SELECT * FROM HQ_METRIC_DATA_1D_1S
    WHERE timestamp between 1207681200000 and 1207724399999 AND
    measurement_id = 600332 UNION ALL
    SELECT * FROM HQ_METRIC_DATA_1D_0S
    WHERE timestamp between 1207638000000 and 1207681199999 AND
    measurement_id = 600332 UNION ALL
    SELECT * FROM HQ_METRIC_DATA_0D_1S
    WHERE timestamp between 1207631340000 and 1207637999999 AND
    measurement_id = 600332) EAM_MEASUREMENT_DATA
    WHERE timestamp BETWEEN begin AND begin + 2879999 AND measurement_id = 600332
    GROUP BY begin ORDER BY begin;

    不用管裏面多複雜,簡單來說就是裏面要儘量多過濾數據(過濾條件都是程序通過時間計算的),外層得到最少的值纔開始group 和order . (它從最差性能的sql -> 中等性能的sql -> 程序配合的最好性能的sql , 我花了幾天時間還是隻能理解個大概)

  7. ID 生成策略

    ID都是從10001開始生成,爲hard-code 的ID 保留10000個空位,不使用auto-increment , 使用myisam 類型的hq_sequence 表來表示sequence , 

  8. 後面還有幾個關於hibernate id 生成策略,建議性能參數和統計值,以及服務器建議配置等,不一一介紹了.
<p 整個hyperic ="" 在體系架構,編程特性和數據庫設計上都設計的很高級,有很多功能是因爲數據庫特性限制而設計的,但同時也儘量發揮了每種數據庫的最大特性,尤其是程序和數據庫結合的設計提升性能很多,看得出特爲數據中心的管理方式做了很多優化.<="" p="" style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px; color: rgb(85, 85, 85); font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 17px; ">

參考資料:

  1. http://www.scribd.com/doc/2909846/Scaling-MySQL-A-Case-Study-of-Hyperic-HQ

    scribd 上的文檔大部分可以下載,也可以在線觀看,很好的文檔分享站點.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章