這是看了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 技巧:
-
批量插入
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 -
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) 性能都伸縮了不少. 數據中心非要這種方式的收集方法.
-
控制數據增長
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 等監控後臺的圖表展現上.
-
分區
所有細節的表由hq_metric_data_xh_ys 表示,每兩個表代表一天,一共9天,
所有的數據歸檔壓縮之後直接truncate ,而不是delete (這是針對mysql 5.1 之前沒有partition 的功能而做,不知道以後會不會針對mysql 5.1 之後出個特別版), 應用程序上會自動計算應該insert 那個表,每個時間段該取那個表的數據. 所以insert 的表不會跟select 表和truncate 的表有衝突,3種表都自己做自己的工作.
truncate 和 delete 的好處也有提到,這種partition 的設計還是要好好學學.
-
索引的選擇
選用InnoDB 是因爲其基於主鍵的cluster index (和oracle 的IOT 一樣), 優點就是select 更快,insert 也更快,索引佔的磁盤也更少. 由於它全部都是基於時間點的順序加入的,所以其cluster index, leaf index, data 都是基於同一個順序在磁盤上訪問,所以即使它不需要事務和鎖,InnoDB 還是其最佳選擇.
-
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 , 我花了幾天時間還是隻能理解個大概)
-
ID 生成策略
ID都是從10001開始生成,爲hard-code 的ID 保留10000個空位,不使用auto-increment , 使用myisam 類型的hq_sequence 表來表示sequence ,
- 後面還有幾個關於hibernate id 生成策略,建議性能參數和統計值,以及服務器建議配置等,不一一介紹了.
參考資料:
-
http://www.scribd.com/doc/2909846/Scaling-MySQL-A-Case-Study-of-Hyperic-HQ
scribd 上的文檔大部分可以下載,也可以在線觀看,很好的文檔分享站點.