首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

RRDTool 數據導入 MySQL 實戰:Python 自動化腳本與長期存儲架構

     編輯:MySQL 綜合教學

Ganglia 等監控系統採用 RRD (Round Robin Database) 循環覆蓋存儲,無法長期保留高精度數據。本文提供完整 Python 自動化方案,定時將 RRD 數據增量導入 MySQL,實現長期保留與多維分析。

一、RRD 特性與導入必要性

特性RRDMySQL
存儲模式循環覆蓋 (固定大小)增量增長
精度保留高精度短期、低精度長期全精度永久保留
查詢靈活性僅支援 RRDtool 查詢SQL 任意聚合、JOIN、窗口函數
適用場景實時監控圖表趨勢分析、審計、機器學習特徵

導入策略:Cron 定時 (如每 5 分鐘) 執行 Python 腳本,增量讀取 RRD 最新數據,UPSERT 寫入 MySQL。

二、環境準備

pip install mysqlclient rrdtool  # 或 pip install pymysql rrdtool-python

RRD 檔案路徑 (Ganglia 預設):/var/lib/ganglia/rrds/{cluster}/{host}/{metric}.rrd

三、初始化腳本:自動建庫建表

import os, MySQLdb, string, rrdtool

ROOT = "/var/lib/ganglia/rrds/hap-clu"
MAP_DOT = str.maketrans('.', '_')
MAP_DASH = str.maketrans('-', '_')

conn = MySQLdb.connect(host='localhost', user='root', passwd='123456')
cursor = conn.cursor()

for host_dir in os.listdir(ROOT):
    db_name = host_dir.translate(MAP_DOT).translate(MAP_DASH)
    cursor.execute(f"CREATE DATABASE IF NOT EXISTS `{db_name}`")
    conn.select_db(db_name)
    
    host_path = os.path.join(ROOT, host_dir)
    for rrd_file in os.listdir(host_path):
        table_name = rrd_file[:-4].translate(MAP_DOT)  # 去 .rrd
        if db_name == "__SummaryInfo__":
            cursor.execute(f"""
                CREATE TABLE IF NOT EXISTS `{table_name}` (
                    time_id INT NOT NULL PRIMARY KEY,
                    value VARCHAR(30),
                    num VARCHAR(30)
                ) ENGINE=InnoDB
            """)
        else:
            cursor.execute(f"""
                CREATE TABLE IF NOT EXISTS `{table_name}` (
                    time_id INT NOT NULL PRIMARY KEY,
                    value VARCHAR(30)
                ) ENGINE=INNODB
            """)
    conn.commit()
    print(f"DB: {db_name} created.")
cursor.close()

關鍵點:

  • 库名/表名轉換:MySQL 禁止 . -,用 str.maketrans 替換為 _
  • SummaryInfo 表多一個 num 欄位
  • 每日重跑初始化,自動適配新增節點/指標

四、增量導入腳本:核心邏輯

import os, MySQLdb, string, rrdtool

ROOT = "/var/lib/ganglia/rrds/hap-clu"
MAP_DOT = str.maketrans('.', '_')
MAP_DASH = str.maketrans('-', '_')

conn = MySQLdb.connect(host='localhost', user='root', passwd='123456')
cursor = conn.cursor()

for host_dir in os.listdir(ROOT):
    db_name = host_dir.translate(MAP_DOT).translate(MAP_DASH)
    conn.select_db(db_name)
    host_path = os.path.join(ROOT, host_dir)
    os.chdir(host_path)
    
    for rrd_file in os.listdir(host_path):
        table_name = rrd_file[:-4].translate(MAP_DOT)
        # 讀取所有 AVERAGE 值
        data = rrdtool.fetch(rrd_file, "AVERAGE")
        start_time, end_time, step = data[0]
        values = data[2]  # list of (value,) or (value, num)
        
        batch = []
        for i, row in enumerate(values):
            timestamp = start_time + i * step
            if row[0] is None:
                continue
            if db_name == "__SummaryInfo__":
                batch.append((timestamp, str(row[0]), str(row[1])))
            else:
                batch.append((timestamp, str(row[0])))
        
        # 批量 UPSERT (主鍵衝突忽略)
        if batch:
            if db_name == "__SummaryInfo__":
                sql = f"INSERT IGNORE INTO `{table_name}` (time_id, value, num) VALUES (%s, %s, %s)"
            else:
                sql = f"INSERT IGNORE INTO `{table_name}` (time_id, value) VALUES (%s, %s)"
            cursor.executemany(sql, batch)
    
    conn.commit()
    print(f"UPDATED DB: {db_name}")
cursor.close()

五、關鍵優化細節

  1. 批量提交:executemany + 單次 commit,避免逐行提交極慢
  2. 主鍵去重:time_id 為 Unix 時間戳主鍵,INSERT IGNORE 自動跳過重複
  3. 頻率高於 RRD 步長:Cron 每 5 分鐘跑,RRD 步長 15 秒,確保無數據丟失
  4. 大表性能:單表年增長 ~200 萬行,建議按月分表或用 TimescaleDB/ClickHouse

六、Cron 部署

# /etc/cron.d/rrd2mysql
# 每 5 分鐘執行,先初始化再導入
*/5 * * * * root /usr/bin/python3 /opt/scripts/rrd_init.py
*/5 * * * * root /usr/bin/python3 /opt/scripts/rrd_import.py

七、架構演進建議

階段方案優勢
初期MySQL + Python Cron零依賴、開發快、SQL 靈活
中期MySQL 分表 + 定時歸檔單表控制在 500 萬行
成熟期TimescaleDB / ClickHouse / Apache IoTDB原生時序優化、壓縮率高、聚合快

RRD 到 MySQL 的橋樑,讓監控數據從「看圖」進化為「做分析」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved