遥测数据写入TimescaleDB指南

本指南详细阐述了如何配置和使用TimescaleDB来高效存储和管理遥测数据。特别针对使用4TB SATA硬盘作为数据存储介质的场景,提供了PostgreSQL参数的优化建议,以克服SATA硬盘的性能瓶颈。

1. TimescaleDB (PostgreSQL) 启动

TimescaleDB作为PostgreSQL的扩展,其启动方式与PostgreSQL相同。

  1. 确保TimescaleDB已正确安装并配置为PostgreSQL的扩展。
  2. 使用systemctl命令启动PostgreSQL服务:
sudo systemctl start postgresql

您也可以使用以下命令检查服务状态:

sudo systemctl status postgresql

2. PostgreSQL 配置优化 (针对SATA硬盘)

为了充分发挥4TB SATA硬盘的潜力,并缓解其I/O性能限制,需要对postgresql.conf进行关键调整。以下是基于提供的配置文档进行的详细说明。

重要提示: 修改配置文件后,务必重启PostgreSQL服务以使更改生效。

sudo systemctl restart postgresql

2.1 核心资源分配

内存是弥补SATA磁盘慢速的关键。通过增加内存分配,可以减少对慢速硬盘的读写次数。

2.2 磁盘 I/O 适配 (SATA 硬盘的重大调整)

这是针对SATA硬盘性能瓶颈进行优化的核心部分。

2.3 WAL 与 Checkpoint (混合存储优化的关键)

WAL(预写日志)和检查点(Checkpoint)的配置对写入性能和数据恢复至关重要,尤其是在SATA硬盘上。

2.4 并行与连接

这些参数控制了数据库的最大连接数和并行处理能力。

3. 数据库和用户设置

切换到PostgreSQL的默认用户postgres,然后创建数据库和专用的数据库用户,并授予必要的权限。

sudo -i -u postgres psql

-- 创建数据库
CREATE DATABASE test_db;

-- 创建用户并设置密码
CREATE USER user_test WITH PASSWORD 'your_secure_password'; -- 请替换 'your_secure_password' 为实际密码

-- 授予数据库连接权限
GRANT CONNECT ON DATABASE test_db TO user_test;

-- 授予数据库所有权限
GRANT ALL PRIVILEGES ON DATABASE test_db TO user_test;

-- 退出psql
\q

安全提示: 在生产环境中,应根据最小权限原则,仅授予用户所需的最低权限。

4. TimescaleDB 表结构、超表、压缩与索引

使用上述创建的用户登录到test_db数据库,然后创建遥测数据表、将其转换为TimescaleDB超表,并配置数据压缩和索引以优化存储和查询。

psql -U user_test -d test_db -h localhost

-- 创建TimescaleDB表结构
CREATE TABLE dms_data_gzdy (
    record_time TIMESTAMPTZ NOT NULL,  -- 使用TIMESTAMPTZ作为时间分区键
    station_name TEXT,
    feeder_gis_id TEXT,
    switch_name TEXT,
    switch_oid TEXT,
    switch_gis_id TEXT,
    switch_status INTEGER,
    switch_status_quality INTEGER,
    active_power DECIMAL(18,6),
    active_power_quality INTEGER,
    reactive_power DECIMAL(18,6),
    reactive_power_quality INTEGER,
    current_a DECIMAL(18,6),
    current_a_quality INTEGER,
    current_b DECIMAL(18,6),
    current_b_quality INTEGER,
    current_c DECIMAL(18,6),
    current_c_quality INTEGER,
    voltage_uab DECIMAL(18,6),
    voltage_uab_quality INTEGER,
    voltage_ubc DECIMAL(18,6),
    voltage_ubc_quality INTEGER,
    voltage_uca DECIMAL(18,6),
    voltage_uca_quality INTEGER,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    
    -- TimescaleDB需要时间列参与主键
    PRIMARY KEY (record_time, switch_oid)
);

-- 启用TimescaleDB扩展(如果尚未启用)并创建hypertable
CREATE EXTENSION IF NOT EXISTS timescaledb;
SELECT create_hypertable('dms_data_gzdy', 'record_time', chunk_time_interval => INTERVAL '1 day');


-- 设置压缩策略
ALTER TABLE dms_data_gzdy SET (
    timescaledb.compress,
    -- 按设备ID分组,查询特定设备时只读相关块
    timescaledb.compress_segmentby = 'switch_oid',
    -- 按时间排序,保持查询时的有序性
    timescaledb.compress_orderby = 'record_time ASC'
);

-- 添加3天后自动压缩策略
SELECT add_compression_policy('dms_data_gzdy', INTERVAL '3 days');

-- 创建优化查询的索引
CREATE INDEX idx_dms_switch_oid ON dms_data_gzdy (switch_oid, record_time);
CREATE INDEX idx_dms_feeder_gis_id ON dms_data_gzdy (feeder_gis_id, record_time);
CREATE INDEX idx_dms_station_name ON dms_data_gzdy (station_name, record_time);

-- 退出psql
\q

5. 数据导入策略

在数据导入方面,需要区分普通表和TimescaleDB超表。

6. ETL 脚本部署

efile.shetl.py 是将数据清洗后写入TimescaleDB的关键ETL脚本。它们需要部署到crontab中进行定时调度。

  1. 冷启动数据处理:

    在系统冷启动时,可能存在大量历史数据。为了避免一次性处理导致系统过载,建议预先将现有的E文件删除,等待新的调度推送的E文件上来,由ETL脚本逐步处理。

  2. 激活Python虚拟环境:

    etl.py脚本可能依赖特定的Python库,这些库通常安装在虚拟环境中。因此,在efile.sh脚本中,需要激活相应的虚拟环境。

    请在efile.sh脚本中增加以下一行,确保etl.py在正确的环境中运行:

    #!/bin/bash
    # ... 其他脚本内容 ...
    
    # 激活Python虚拟环境
    source /home/hello/tensorflow_project/tf_env/bin/activate
    
    # ... 调用 etl.py 脚本的命令 ...
    python /path/to/your/etl.py
    
    # ... 其他脚本内容 ...
    
  3. Crontab 部署:

    efile.shetl.py的执行命令添加到crontab中,设置合适的调度频率。

    crontab -e

    添加类似以下内容的行(例如,每5分钟执行一次):

    */5 * * * * /path/to/your/efile.sh >> /var/log/efile_etl.log 2>&1

    注意: 确保/path/to/your/efile.sh是脚本的完整路径,并且脚本具有执行权限(chmod +x efile.sh)。同时,检查日志文件路径是否可写。

7. API 部署

最后一步是部署新的API版本。

  1. 部署modperl目录下的API v1.1版本。
  2. 确保新的API版本能够正确连接到TimescaleDB并进行数据读写。
  3. 在确认v1.1版本稳定运行后,下线原有的v1.0版本。

遵循以上步骤,您将能够成功地将遥测数据高效地写入TimescaleDB,并通过优化配置充分利用SATA硬盘的存储能力。