本文探讨在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
我这里 sata3 sata4是固态盘,sata1 sata2是机械盘
2. 将机械盘踢出系统Raid阵列,让系统仅运行在固态上
先执行cat /proc/mdstat查看系统raid的状态,以及raid组成
然后分离机械盘,盘符根据实际情况调整
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的磁盘发生故障的时候自动替换掉故障磁盘,正常状态下这俩不活动
这时候系统警告消失,进入下一步
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.监控休眠状态,找出无故唤醒的元凶
在技术支持中心->技术支持服务中,启用硬盘休眠调试模式
硬盘活动日志记录在 /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查看休眠日志
将休眠的日志记录到群晖的日志中心中:
打开群晖 日志中心->接收日志-新增 新增一个日志服务器,日志格式选IETF格式
然后就能在日志中心中直接看到硬盘休眠和唤醒的日志记录了,跟内置的休眠功能一样,是不是很完美~
如果发现中某个时间点无故唤醒,就去hibermation.log中去找原因,作出相应的调整
5.调整索引服务配置和日志的目录位置
经过上述调整后,查日志发现synoelasticd进程会经常唤醒硬盘,禁用SynoFinder服务后休眠就会恢复正常。
注:Universal Search无法从套件中心停止,需要通过命令 sudo synopkg stop SynoFinder 来停用
这是群晖的文件索引服务,如果需要使用Drive,不要停用,用下文的方法可以解决
检查
/var/packages/SynoFinder/etc和/var/packages/SynoFinder/var
这两个位置的软连接,如果不是在volume1 上,需要用以下命令将这两个文件夹挪到固态上
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_location和update_etc_location所在的两行
#${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
从"0 0 * * *"每天0:00执行,改成"0 10 * * 0"每周日10:00执行
- 内置定时任务
builtin-libsynostorage-syno_disk_db_update每天更新硬盘兼容性数据库,并进行兼容性检查,这个每月一次就够,完全禁掉也OK
vim /usr/syno/share/synocron.d/libsynostorage.conf
这里从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加密备份到百度云等云盘(以免云盘的审查机制误伤你的文件)