背景

在家用树莓派3B做小型NAS以及frp跳板机,半年左右树莓派SD卡就会损坏。

总共损坏过三次。近一年前终于忍受不了,详细找了原因解决了问题,希望后面的人不要踩坑。

原因

分析和查找资料后,认为问题基本是因为SD卡反复读写导致的卡损坏。

选择适的存储介质

有条件使用EMMC时使用EMMC(需要工业级的CM3/CM3+);

无条件时采用长寿命的高耐用的监控用SD卡。

文件系统配置

尽量使用Ext4文件系统,至少在Ext3以上,因为它们有日志功能,能降低文件系统损坏的风险。

Ext4文件系统具有日志功能,以及Barrier,快速系统检查功能,详见文件系统进化但是Ext4仍然可能造成文件丢失。

更改文件系统日志模式data=journal,会有更高的可靠性,损失一部分系统性能。

1234nano /boot/cmdline.txt添加rootflags=data=journal

值得注意的是默认提交metadata时间是五秒:

也就是说,5秒内的工作有可能丢失;但因为日志系统存在,文件系统正常不会损坏。

修改/boot/cmdline.txt

123nano /boot/cmdline.txt添加fsck.repair=yes

最后的cmdline.txt文件:

1dwc_otg.lpm_enable=0 root=PARTUUID=0cb3856c-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait rootflags=data=journal

关闭SWAP分区

SWAP分区是Linux用作虚拟内存的分区磁盘,Raspberry CM3/3B中使用的内存有1GB之大,不需要使用SWAP分区。

1234567891011121314# 切换到root帐号sudo su# 使用systemd关闭swap分区systemctl disable dphys-swapfilesystemctl stop dphys-swapfilesystemctl status dphys-swapfile# 查看内存使用情况,swap内为0free -mh total used free shared buff/cache availableMem: 875M 27M 779M 11M 67M 786MSwap: 0B 0B 0B

关闭系统日志转发

RASPBIAN系统日志由三部分组成:

systemd-journald

此服务收集内核、进程stdout、stderr的消息,并写入/run下的临时文件,/run/log是tmpfs,不会使用磁盘IO。

可调整其存储策略以及占用限制。

在此调整ForwardToSyslog=no,关闭持久化转发,这样会降低IO,但是损失很久之前的log信息。

12345678910111213141516171819202122232425262728293031323334nano /etc/systemd/journald.conf[Journal]#Storage=auto#Compress=yes#Seal=yes#SplitMode=uid#SyncIntervalSec=5m#RateLimitIntervalSec=30s#RateLimitBurst=1000SystemMaxUse=100MSystemKeepFree=1GSystemMaxFileSize=20MSystemMaxFiles=100RuntimeMaxUse=100MRuntimeKeepFree=1GRuntimeMaxFileSize=20MRuntimeMaxFiles=100MaxRetentionSec=3dayMaxFileSec=3dayForwardToSyslog=no#ForwardToKMsg=no#ForwardToConsole=no#ForwardToWall=yes#TTYPath=/dev/console#MaxLevelStore=debug#MaxLevelSyslog=debug#MaxLevelKMsg=notice#MaxLevelConsole=info#MaxLevelWall=emerg# 然后重启日志服务systemctl restart systemd-journald

rsyslog

这部分文件存在/var/log下,是磁盘数据,会占用磁盘空间和IO资源。

因为我们已经关闭了systemd-journald向rsyslog的转发功能,不需要再调整rsyslog的配置。

配置文件:

1nano /etc/rsyslog.conf

rsyslog可以通过配置,设置过滤规则,转发规则,文件名等规则。

logrotate

这个服务是日志轮转功能,将rsyslog存下的日志文件定期轮转,可以不用动。

配置文件:

12345678910111213141516171819202122232425262728293031323334nano /etc/logrotate.conf# see "man logrotate" for details# rotate log files weeklydaily# keep 4 weeks worth of backlogsrotate 4# create new (empty) log files after rotating old onescreate# uncomment this if you want your log files compressedcompress# packages drop log rotation information into this directoryinclude /etc/logrotate.d# no packages own wtmp, or btmp -- we'll rotate them here/var/log/wtmp { missingok monthly create 0664 root utmp rotate 1}/var/log/btmp { missingok monthly create 0660 root utmp rotate 1}# system-specific logs may be configured here

REDIS等中间件的持久化配置

中间件会定期向磁盘写入文件,以保证数据持久化,可关闭此功能,将save段全部注释:

123456789nano /etc/redis/redis.conf...# save 900 1# save 300 10# save 60 10000...

应用log配置

自定义的应用程序尽量采用向stdout和stderr流写入数据的方式存储log,使用systemd-journald控制log流转,而不是自定义log文件。

写在最后

最后上个图