TrueNAS SCALE - 硬盘休眠

概要

众所周知,NAS 中硬盘是耗电的主要来源,那么有什么办法能够降低功耗呢?

答案是肯定的,现在市面上常见的 NAS 系统都有提供硬盘休眠功能,接下来我将以 TrueNAS Scale为例,分享一下我的设置的方法、如何检测是否生效以及遇到的坑。

设置方法

官方文档:https://www.truenas.com/docs/scale/24.04/scaleuireference/storage/disksscreen/#power-management-settings

Storage → Disks → Edit → Power Management
image

参数说明:

  • HDD Standby:硬盘在几分钟未活动后进入休眠状态(Alaways On 永不休眠)
  • Advanced Power Management:我这边选择的是 Level 1, 直接让硬盘停转,以最低功耗运行;

检测是否生效

shell 脚本

编写脚本用于定时检测硬盘状态,主要是通过 hdparm -C /dev/sda 这个命令来判断硬盘当前状态

  • standby:代表硬盘进入休眠状态

  • active/idle:代表硬盘处于活跃/空闲状态,未休眠

  • disk_monitor.sh

    #!/bin/bash
    
    LOG_DIR="/root/disk_monitor"
    mkdir -p $LOG_DIR
    
    STATS_FILE="$LOG_DIR/spindown_stats.txt"
    DEBUG_FILE="$LOG_DIR/spindown_debug.log"
    
    DISKS=("/dev/sda" "/dev/sdb")
    declare -A last_state
    declare -A standby_count
    declare -A active_count
    
    # 初始化状态为 unknown
    for disk in "${DISKS[@]}"; do
        last_state[$disk]="unknown"
        standby_count[$disk]=0
        active_count[$disk]=0
    done
    
    # 添加调试函数
    debug_log() {
        echo "$(date '+%Y-%m-%d %H:%M:%S'): $1" >> $DEBUG_FILE
    }
    
    # 更新统计信息的函数
    update_stats() {
        local current_time="$1"
        local today=$(date '+%Y-%m-%d')
        
        echo "=== 统计信息 ($current_time) ===" > $STATS_FILE
        echo "今日日期: $today" >> $STATS_FILE
        echo "监控开始时间: $(head -n 1 $DEBUG_FILE 2>/dev/null | cut -d':' -f1 || echo $current_time)" >> $STATS_FILE
        echo "" >> $STATS_FILE
        
        for disk in "${DISKS[@]}"; do
            disk_name=$(basename $disk)
            echo "硬盘 $disk_name:" >> $STATS_FILE
            echo "- 进入休眠次数: ${standby_count[$disk]}" >> $STATS_FILE
            echo "- 唤醒次数: ${active_count[$disk]}" >> $STATS_FILE
            echo "" >> $STATS_FILE
        done
    }
    
    while true; do
        current_time=$(date '+%Y-%m-%d %H:%M:%S')
        
        for disk in "${DISKS[@]}"; do
            disk_name=$(basename $disk)
            current_state=$(hdparm -C $disk 2>/dev/null | grep "drive state" | awk '{print $NF}')
            
            # 添加调试信息
            debug_log "硬盘: $disk_name"
            debug_log "当前状态: $current_state"
            debug_log "上次状态: ${last_state[$disk]}"
            
            if [ "${last_state[$disk]}" != "$current_state" ]; then
                debug_log "状态发生变化"
                if [ "$current_state" = "standby" ]; then
                    ((standby_count[$disk]++))
                    debug_log "$disk_name 进入休眠,计数: ${standby_count[$disk]}"
                elif [ "$current_state" = "active/idle" ]; then
                    ((active_count[$disk]++))
                    debug_log "$disk_name 被唤醒,计数: ${active_count[$disk]}"
                fi
                
                # 更新状态前记录
                debug_log "更新状态: ${last_state[$disk]} -> $current_state"
                last_state[$disk]=$current_state
                # 更新状态后验证
                debug_log "更新后的状态: ${last_state[$disk]}"
                
                update_stats "$current_time"
            else
                debug_log "状态未变化"
            fi
            
            debug_log "-------------------"
        done
        
        # 日志轮转(保持最近7天的日志)
        find $LOG_DIR -name "spindown_debug.log.*" -mtime +7 -delete 2>/dev/null
        if [ $(stat -c%s "$DEBUG_FILE" 2>/dev/null) -gt 1048576 ]; then  # 1MB
            mv $DEBUG_FILE "$DEBUG_FILE.$(date '+%Y%m%d')"
        fi
        
        sleep 300  # 每5分钟检查一次
    done
    

使用 tmux: TrueNAS SCALE 已经预装了 tmux,你可以使用它来管理会话。tmux 的功能与 screen 类似。

  • 启动 tmux 会话 & 运行脚本:

    tmux new -s disk_monitor
    chmod 777 ./disk_monitor.sh
    ./disk_monitor.sh
    
  • 分离会话:

    *# 按 Ctrl+B 然后按 D*
    
  • 列出会话:

    tmux ls
    
  • 重新连接到会话:

    tmux attach -t disk_monitor
    

查看统计信息

# 统计信息
cat /root/disk_monitor/spindown_stats.txt
# debug日志
cat /root/disk_monitor/spindown_debug.log 

image

遇到的问题

硬盘被周期性唤醒

通过观察日志 & 功耗可以发现,NAS 在待机状态下,硬盘频繁的被唤醒;仔细观察日志发现,硬盘有规律的被唤醒,30min/次。

这样频繁的唤醒对机械硬盘是很不好的,如果硬盘坏了最后节省的电费还没有一块硬盘和数据来的值钱,于是我立即展开排查。

image
image

这样的有规律的一般是后台有定时任务在执行导致的,经过一顿排查,发现系统并没有定时任务会去读写 sda & sdb 这两块硬盘;最后在系统日志中发现了猫腻:

root@truenas[~/disk_monitor]# cat /var/log/syslog | grep "smartd"
Dec  3 00:23:10 truenas smartd[2631]: Device: /dev/sda [SAT], SMART Usage Attribute: 190 Airflow_Temperature_Cel changed from 71 to 74
Dec  3 00:23:10 truenas smartd[2631]: Device: /dev/sda [SAT], SMART Usage Attribute: 194 Temperature_Celsius changed from 29 to 26
Dec  3 00:53:11 truenas smartd[2631]: Device: /dev/sda [SAT], SMART Usage Attribute: 190 Airflow_Temperature_Cel changed from 74 to 75
Dec  3 00:53:11 truenas smartd[2631]: Device: /dev/sda [SAT], SMART Usage Attribute: 194 Temperature_Celsius changed from 26 to 25
Dec  3 01:22:55 truenas smartd[2631]: Device: /dev/sdb [SAT], SMART Usage Attribute: 194 Temperature_Celsius changed from 240 to 250

smartd 每隔半小时会去检测硬盘的温度变化,这个操作会导致硬盘被唤醒;

于是我直接将 smartd 服务给关闭, 果不其然硬盘不再被周期性唤醒。

# 停止服务
systemctl stop smartd

# 禁用服务
systemctl disable smartd

# 检查状态
systemctl status smartd

Help: HDD Standby
Minutes of inactivity before the drive enters standby mode. Temperature monitoring is disabled for standby disks.

官方在硬盘休眠的帮助说到,在硬盘休眠时,温度监控是被禁用的,不确定为什么它还是会执行。

我尝试禁用特定硬盘的 S.M.A.R.T. ,但看起来它还是会被定期执行,我怀疑是: System Settings → Services → S.M.A.R.T.这边开启的原因。大家又遇到同样的问题可以尝试将 Power Mode 修改为非 Never 试看看。

参考:https://www.truenas.com/docs/scale/scaleuireference/systemsettings/services/smartservicesscreen/

image
image

总结

经过一番折腾,终于搞定了 TrueNAS Scale 下硬盘休眠,大家可以根据自己的需求设置硬盘休眠的策略;另外在设置好后,一定要注意观察硬盘是否有频繁被唤醒的情况,如果存在则需要及时排查原因,避免频繁的启停最终导致硬盘损坏,得不偿失!

若文中有描述不准确的地方还请各位指出,大家什么有问题或建议也可以在评论区里一起讨论~

8 个赞

感谢大佬分享

1 个赞

谢谢大帅哥捧场 :partying_face:

我有两块hdd硬盘
一个很正常 10分钟就休眠
另一个hc550 很奇怪,永远都是 active/idle 状态
手动设置一下休眠时间 hdparm -S 120 /dev/sdd
对第一个hdd正常,对hc550就无效
手动强制休眠
sudo hdparm -Y /dev/sdd 没用,一触发,硬盘就先暂停然后立马又开始运行
能听到明显的硬盘启停的声音

如果有明显启停的声音,那大概率是存在对硬盘的读/写请求的。
你可以这个命令看看是否有读写请求:

iostat -x /dev/sdd 1

我文中提到定时温度监控导致的磁盘被唤醒,是没有硬盘启停的声音。
另外你这个硬盘是否有作为 Application 数据存储盘 / 系统数据集(见截图)被使用呢?
image

谢谢回复,我不是trueNAS 我是直接pve当nas用的…
启停声音是执行hdparm -Y /dev/sdd才有,其他时候没有

至于数据读写,至少持续读写是没有的,普通hdd和hc550这两个其实使用条件完全一致,就是hc550没法休眠 . 问了卖家说是企业盘特性,但它有时候又能出现 standard,不是说永远不会出现,
不过现在就这一块盘无法休眠,也就懒得管了