完美的群晖独立硬盘休眠,打造真正静音的NAS

2,340 阅读8分钟

本文探讨在SSD和HDD组成的混合Nas中实现硬盘独立休眠,用哪块盘就只唤醒哪块,访问SSD不影响机械盘休眠,实现真正的静音!

先科普下群晖的分区方式

在群晖的默认分区中,所有盘都会划分出两个额外的分区, 以/dev/sata1为例 第一个/dev/sata1p1分区,8G,作为系统分区 第二个/dev/sata1p2分区,2G,作为swap分区 第三个/dev/sata1p3分区,用户自己的存储分区

所有盘位的P1分区加入/dev/md0组成Raid1,用作rootfs 所有盘位的P2分区加入/dev/md1组成Raid1,用作swap 其他分区用于用户自己组建存储池

在这个机制下,群晖的默认休眠机制非常保守和拉跨,一旦有任何硬盘活动,所有盘立刻全部唤醒,唤醒时还要等一会才能进系统,非常不爽。即使仅访问固态盘数据,机械盘也会不时咔咔响,无法独立休眠,希捷银河企业盘那个炒豆子的声音,你懂的。。

我的解决思路如下:

  • 将常用热数据存放在ssd,不常用的数据放到hdd
  • 让操作系统仅活动在ssd上,将机械盘踢出系统Raid阵列
  • 弃用群晖的硬盘休眠,使用Linux的硬盘休眠实现独立硬盘休眠
  • 跟机械盘的定时任务,例如SMART,快照等,降低频度,安排集中的时段执行

我在用的是DS423+,4盘位

  • 1号和2号盘位:Intel S3510固态
  • 3号和4号盘位:希捷银河
  • M2位置:西数SN850X

在上述思路下,我对我的Nas做了以下调整

1号固态盘位存储套件及常用热数据:

  • 所有套件(除Docker外)
  • homes (Drive套件使用)
  • photo (照片)
  • 其他常用文件夹

如果套件已经安装在其他盘的,可以用
github.com/007revad/Sy…
这个脚本将套件转移到固态盘上

2号固态盘位作为下载盘:

  • download (下载)

3号机械盘作为影音盘:

  • music
  • video
  • tv
  • 其他不太常用的

4号机械盘位作为备份盘:

  • homes、photo、套件及其他数据用hyperbackup定时备份

M2盘位:

Docker套件及容器数据,SN850x有DRAM缓存,4K性能好,适合跑docker

群晖默认M2只能用做缓存,只有群晖自己的m2盘可以用作存储池
第三方m2可以用
github.com/007revad/Sy…
将你的M2型号加入白名单,就可以创建存储池了。

以下操作需要一定的linux基础,新手操作前务必对重要数据做好备份!!!
以下操作需要一定的linux基础,新手操作前务必对重要数据做好备份!!!
以下操作需要一定的linux基础,新手操作前务必对重要数据做好备份!!!

ssh到nas,切换至root用户

ssh username@nas-ip
sudo -i

1. 首先找到各硬盘所对于的设备标识符

fdisk -l /dev/sata3
fdisk -l /dev/sata4
fdisk -l /dev/sata1
fdisk -l /dev/sata2

Pasted image 20250206114618.png 我这里 sata3 sata4是固态盘,sata1 sata2是机械盘

2. 将机械盘踢出系统Raid阵列,让系统仅运行在固态上

先执行cat /proc/mdstat查看系统raid的状态,以及raid组成

Pasted image 20250206120303.png

然后分离机械盘,盘符根据实际情况调整

mdadm /dev/md0 --fail /dev/sata2p1
mdadm /dev/md0 --remove /dev/sata2p1
mdadm /dev/md0 --fail /dev/sata1p1
mdadm /dev/md0 --remove /dev/sata1p1

mdadm /dev/md1 --fail /dev/sata2p2
mdadm /dev/md1 --remove /dev/sata2p2
mdadm /dev/md1 --fail /dev/sata1p2
mdadm /dev/md1 --remove /dev/sata1p2

此时系统会弹出警告系统分区降级,可以无视,正常使用没有问题
如果你和我一样是强迫症患者,无法接受有系统警告,可以进行如下操作

mdadm --grow /dev/md0 --raid-devices=2
mdadm /dev/md0 --add /dev/sata2p1
mdadm /dev/md0 --add /dev/sata1p1

mdadm --grow /dev/md1 --raid-devices=2
mdadm /dev/md1 --add /dev/sata2p2
mdadm /dev/md1 --add /dev/sata1p2

此操作的目的是将原有的raid数量从4减少到2,并将两块机械盘加入raid作为热备盘,以免群晖检测不到机械盘上的系统分区和swap分区给警告

再次执行cat /proc/mdstat发现sata1和sata2上多了一个S标识(Spare),其主要功能是在raid的磁盘发生故障的时候自动替换掉故障磁盘,正常状态下这俩不活动 Pasted image 20250206120303.png 这时候系统警告消失,进入下一步

3. 弃用群晖的硬盘休眠,启用Linux的硬盘休眠实现独立硬盘休眠

进行群晖网页控制面板->硬件与电源->硬盘休眠, 将休眠时间改成无
启用Linux的硬盘休眠

hdparm -S 120 /dev/sata2
hdparm -S 120 /dev/sata1

SSD不要设置休眠,保证系统的快速响应

注意:后面的参数在1-240之间的时候,单位是5秒,从5秒至20分钟
在241和251之间的时候,减去240乘以30分钟,也就是30分钟至5.5小时
上面的120的意思是120*5=600秒,闲置10分钟后进入休眠状态
根据自己的需要设置合适的休眠时长

最后在控制面板->任务计计划->新增->触发的任务,在开机的时候以root身份执行上命令

4.监控休眠状态,找出无故唤醒的元凶

在技术支持中心->技术支持服务中,启用硬盘休眠调试模式

Pasted image 20250206132757.png

硬盘活动日志记录在 /var/log/hibermation.log/var/log/hibermationFull.log中,这个日志会滚动压缩,你可能需要在压缩包中找到特定时间点的日志

将以下代码保存为hddmon.sh,一定要存在固态盘上

#!/bin/bash

# Configuration
LOG_FILE="/tmp/hddmon.log"
STATE_FILE="/tmp/hddmon.txt"
DRIVES=("/dev/sata1" "/dev/sata2" "/dev/sata4")

# Ensure files exist
touch "$LOG_FILE" "$STATE_FILE"

log() {
    echo "$(date '+%m-%d %H:%M') $1" >> "$LOG_FILE"
    if [[ -n "$LOG_SERVER" ]]; then
        logger -n "$LOG_SERVER" --udp -p cron.info --tag "常规" "$1"
    fi
}

# Get drive states using a single hdparm command
drive_states=$(hdparm -C "${DRIVES[@]}" | awk '
    /^\/dev\// { device = $1 }
    /drive state is:/ {
        gsub(/:$/, "", device)
        print device ":" $NF
    }
')

# Process each drive state
changes=()
while IFS=: read -r device state; do
    if [[ -z "$device" ]]; then
        continue
    fi

    # Compare with previous state
    prev_state=$(grep -s "^$device:" "$STATE_FILE" | cut -d: -f2)

    if [[ "$prev_state" != "$state" ]]; then
        changes+=("$device: $state;")
        # Update or add state to temp file
        sed -i "\#$device#d" "$STATE_FILE"
        echo "$device:$state" >> "$STATE_FILE"
    fi
done <<< "$drive_states"

# Log changes if any
if [[ ${#changes[@]} -gt 0 ]]; then
    log "${changes[*]}"
fi


在控制面板->任务计划->新增->计划的任务,以root身份每分钟定时执行上述脚本

此脚本会监控硬盘的休眠状态,并在状态变更后记录到/tmp/hddmon.log
cat /tmp/hddmon.log查看休眠日志

Pasted image 20250206132625.png

将休眠的日志记录到群晖的日志中心中: 打开群晖 日志中心->接收日志-新增 新增一个日志服务器,日志格式选IETF格式

WX20250207-131116@2x.png

然后就能在日志中心中直接看到硬盘休眠和唤醒的日志记录了,跟内置的休眠功能一样,是不是很完美~

WX20250207-132512@2x.png

如果发现中某个时间点无故唤醒,就去hibermation.log中去找原因,作出相应的调整

5.调整索引服务配置和日志的目录位置

经过上述调整后,查日志发现synoelasticd进程会经常唤醒硬盘,禁用SynoFinder服务后休眠就会恢复正常。

注:Universal Search无法从套件中心停止,需要通过命令 sudo synopkg stop SynoFinder 来停用

这是群晖的文件索引服务,如果需要使用Drive,不要停用,用下文的方法可以解决

检查 /var/packages/SynoFinder/etc/var/packages/SynoFinder/var 这两个位置的软连接,如果不是在volume1 上,需要用以下命令将这两个文件夹挪到固态上

Pasted image 20250206135133.png

mv /volumeX/\@SynoFinder-etc-volume /volume1
mv /volumeX/\@SynoFinder-log /volume1

cd /var/packages/SynoFinder/etc
ln -sf /volume1/\@SynoFinder-etc-volume etc-volume

cd /var/packages/SynoFinder/var
ln -sf /volume1/\@SynoFinder-log log      

然后有个天坑,重启后这个修改又会恢复原样!

原因:群晖偷懒了,在服务重启、存储池创建、销毁、上线、离线等事件中,不论这俩文件夹是否受影响,都会直接简单粗暴的重建这两个文件夹,跑到机械盘上就无法休眠了 解决方法如下:

vim /var/packages/SynoFinder/scripts/start-stop-status
vim /var/packages/SynoFinder/target/scripts/syno_finder_fileindex_volume_create.sh
vim /var/packages/SynoFinder/target/scripts/syno_finder_fileindex_volume_delete.sh
vim /var/packages/SynoFinder/target/scripts/syno_finder_fileindex_volume_offline.sh
vim /var/packages/SynoFinder/target/scripts/syno_finder_fileindex_volume_online.sh

在这五个文件中,注释掉update_log_locationupdate_etc_location所在的两行

Pasted image 20250206140227.png

#${TOOL_DIR}/fileindex -a update_log_location -j ""

/usr/syno/bin/synosystemctl start pkg-SynoFinder-synoelasticd.service
${TOOL_DIR}/updater
# FIXME: restarting is bad, achieve settings reloading with socket command
#${TOOL_DIR}/fileindex -a update_etc_location -j ""11202421

到这里,硬盘应该已经可以正常独立休眠了,每天大约会唤醒1-2次,如果你还有强迫症,请进行后续的进一步优化

5. 调整唤醒硬盘的定时任务

经过几天的监控,有几个任务会唤醒硬盘

  • 内置的定时任务builtin-libhwcontrol-disk_daily_routine每天晚上12点整硬盘会准时唤醒,进行硬盘smart检查,调整到每周进行一次。
vim /usr/syno/share/synocron.d/libhwcontrol.conf

Pasted image 20250206142026.png

从"0 0 * * *"每天0:00执行,改成"0 10 * * 0"每周日10:00执行

  • 内置定时任务builtin-libsynostorage-syno_disk_db_update每天更新硬盘兼容性数据库,并进行兼容性检查,这个每月一次就够,完全禁掉也OK
vim /usr/syno/share/synocron.d/libsynostorage.conf

Pasted image 20250206141801.png

这里从daily改成monthly,每月一次

重启群晖的定时服务

systemctl restart synocrond

到这里基本上就OK了,白裙黑裙通用,可以做到不去访问机械盘上的数据,机械盘就不会唤醒,,静音凉快又节能~
发现异常唤醒就检查下日志,大概率是定时任务的原因

此方案最好使用两块ssd来实现,一块ssd理论上也是可以的,只是mdadm --grow命令需要加上force选项。
这样的话操作系统将失去Raid保护,一旦主SSD挂了,就得重新装系统了,不过重装系统不会影响p3分区的,并不会丢失重要用户数据

群晖可以通过sysfs的方式来控制硬盘指示灯

各指示灯sys路径如下

1号硬盘绿灯(/dev/sata3)  /sys/class/leds/syno_led0
1号硬盘橙灯(/dev/sata3)  /sys/class/leds/syno_led1
2号硬盘绿灯(/dev/sata4)  /sys/class/leds/syno_led2
2号硬盘橙灯(/dev/sata4)  /sys/class/leds/syno_led3
3号硬盘绿灯(/dev/sata1)  /sys/class/leds/syno_led4
3号硬盘橙灯(/dev/sata1)  /sys/class/leds/syno_led4
4号硬盘绿灯(/dev/sata2)  /sys/class/leds/syno_led6
4号硬盘橙灯(/dev/sata2)  /sys/class/leds/syno_led7

例如我想要控制4号盘位硬盘灯 强制灭灯,用root执行  echo 0 > /sys/class/leds/syno_led6/brightness

恢复默认,用root执行  echo syno_led6_ledstring > /sys/class/leds/syno_led6/trigger

由系统通过事件来接管硬盘指示灯

把这个整合到上面的定时脚本, 就可以控制某个硬盘唤醒的时候亮灯,休眠的时候熄灯
哪个在休眠哪个在干活更直观了。。
至此日志中心的休眠日志和指示灯都有了,完美替代系统休眠~~

最后重要的事情说3遍:

勤备份!勤备份!勤备份!

重要数据遵循3-2-1原则,硬盘有价数据无价!

ssd上的数据定期备份到机械盘,机械盘坏了还能开盘,ssd坏了数据没有任何修复可能,重要数据定期用cloudsync加密备份到百度云等云盘(以免云盘的审查机制误伤你的文件)

探索不易,原创不易,各位欢迎各位大佬讨论指点,转载请注明原作者和出处!