Raspberry Pi Schreiboperationen minimieren

Aus Laub-Home Wiki

Der Raspberry Pi verwendet als Festplatte eine SD-Karte von der er bootet und im Normalfall auch das gesamte System samt Services und Applikationen darauf läuft. Eine SD Karte ist leider nicht für unendliches Beschreiben ausgerichtet. Wieviele Schreiboperationen diese aushält ist leider nicht vorhersagbar, das einzige was man voraussagen kann ist, das sie irgendwann nicht mehr funktionieren wird. Deshalb sollte man sich von Anfang an Gedanken darüber machen, wie man Schreiboperationen auf dem Raspberry Pi minimiert. Ich habe hier ein paar Dinge gesammelt. Man kann mittels iotop sehen, welche Prozesse, wieviel lesen und schreiben. Am besten startet man an dieser Stelle und schaut welche Applikationen Schreibzugriffe ausführen.

Wer schreibt auf die SD-Karte

Mit dem kleinen Tool iotop können wir herausfinden, welche Prozess gerade auf die SD Karte zugreifen, lesend wie schreibend. Interessant ist welche Prozesse schreiben, wie oft und wieviel. Also einfach installieren und starten, man sollte es ein paar Minuten gestartet lassen, damit man sehen kann, was alles auf der SD-Karte passiert.

apt install iotop -y
iotop -oPak
iotop -bktoqqq

oder mit iostat:

apt install sysstat -y
iostat -dzp 5

/tmp als tmpfs mounten

Mit der folgenden Zeile in der /etc/fstab mounten wir /tmp als tmpfs, also als ramdrive. So reduzieren wir hier ein wenig die Zugriffe auf die SD Karte.

/etc/fstab

tmpfs /tmp tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777,size=128M 0 0

Pi OS ab Bookworm: Systemd-Journald im Ram halten

Bookworm kommt standardmäßig mit systemd-journald, als Jogging daemon. Sylog, rsyslog und Konsorten können aber auch nachinstalliert werden, sollte hier Bedarf sein. Der Vorteil von dem neuen Logging ist, das man es direkt per Konfiguration einrichten kann, die Logs nur im Ram zu halten und somit keine Schreib/Lese Operationen auf der SD Karte zu generieren. Nachteil, die Logs sind nach einem Reboot weg.

Wir editieren hierfür die /etc/systemd/journald.conf und setzen die folgenden Parameter:

/etc/systemd/journald.conf

Storage=volatile
RuntimeMaxUse=512M
RuntimeKeepFree=150M

Das bewirkt zunächst das aktivieren des RAM Loggings und begrenzt den gesamt nutzbaren Speicher auf 512MB, oder sorgt dafür das mindestens noch 150MB freibleiben sollen. Die Logs werden dann nach /var/run/log/journal geschrieben, welches ein tmpfs mit einer maximalen Größe ist.

Pi OS Buster: Rsyslog logging reduzieren

Achtung: Ab Pi OS Bookworm kümmert sich journald um das Logging, welches ein deutlich besseres handling hat und vor allem den RAM nutzt.

Wir reduzieren die Syslog Tätigkeiten auf ein minimum. Es werden nur noch zwei files geschrieben, auth.log und syslog. Cron Messages exkludieren wir aus dem syslog.

Dafür kann man die folgende Datei editieren:

/etc/rsyslog.conf

#
# First some standard log files.  Log by facility.
#
auth,authpriv.*                 /var/log/auth.log
#*.*;auth,authpriv.none         -/var/log/syslog
*.*;cron,auth,authpriv.none             -/var/log/syslog
#cron.*                         /var/log/cron.log
#daemon.*                       -/var/log/daemon.log
#kern.*                         -/var/log/kern.log
#lpr.*                          -/var/log/lpr.log
#mail.*                         -/var/log/mail.log
#user.*                         -/var/log/user.log

#
# Logging for the mail system.  Split it up so that
# it is easy to write scripts to parse these files.
#
#mail.info                      -/var/log/mail.info
#mail.warn                      -/var/log/mail.warn
#mail.err                       /var/log/mail.err

#
# Some "catch-all" log files.
#
#*.=debug;\
#       auth,authpriv.none;\
#       news.none;mail.none     -/var/log/debug
#*.=info;*.=notice;*.=warn;\
#       auth,authpriv.none;\
#       cron,daemon.none;\
#       mail,news.none          -/var/log/messages

#
# Emergencies are sent to everybody logged in.
#
#*.emerg                                :omusrmsg:*

oder das Ganze via sed Befehle ändern:

sed -i 's/^*.*;auth,authpriv.none/*.*;cron,auth,authpriv.none/g' /etc/rsyslog.conf
sed -i 's/^mail./#mail./g' /etc/rsyslog.conf
sed -i 's/^daemon./#daemon./g' /etc/rsyslog.conf
sed -i 's/^kern./#kern./g' /etc/rsyslog.conf
sed -i 's/^lpr./#lpr./g' /etc/rsyslog.conf
sed -i 's/^user./#user./g' /etc/rsyslog.conf
sed -i 's/^*.=/#*.=/g' /etc/rsyslog.conf
sed -i 's/^\t/#\t/g' /etc/rsyslog.conf

Nun können wir noch eine Blockliste erstellen die noch ein wenig mehr "Spam" aus dem Logging hält, dafür einfach die folgende Datei anlegen: /etc/rsyslog.d/01-blocklist.conf

# Docker Messages
if $msg contains "run-docker-runtime" and $msg contains ".mount: Succeeded." then {
    stop
}
if $msg contains "var-lib-docker-containers" and $msg contains ".mount: Succeeded." then {
    stop
}
if $msg contains "var-lib-docker-overlay2" and $msg contains ".mount: Succeeded." then {
    stop
}

# Cronjob-Spam umleiten
if $msg contains "pam_unix(cron:session):" then {
    stop
}
# SSH Login ohne String
if $msg contains "Did not receive identification string from" then {
    stop
}
# rngd stop logging
if $msg contains "stats:" then {
    stop
}
# rngd stop logging
if $programname == "rngd" then {
    stop
}

zu guter letzt starten wir den rsyslog daemon neu:

systemctl restart rsyslog.service

Swap File deaktivieren

So ist es möglich das swap file und somit das gesamte swapping des Systems zu deaktivieren. Bei einem Pi 4 mit 4GB Ram sollte das zu keinem Problem führen:

systemctl disable dphys-swapfile
systemctl stop dphys-swapfile

Xorg Logfile

Xorg legt unter /home/home/username/.local/share/xorg/ ein Logfile Namens Xorg.0.log an. Dieses legt man am besten auch in ein tmpfs

/etc/fstab

tmpfs /home/pi/.local/share/xorg/  tmpfs   noatime,nodev,nosuid,size=10M  0       0

Pi-hole

Pi-hole schreit standardmäßig mehrere Logfiles und vor allem alle queries in eine Datenbank. Dies kann man wie folgt deaktivieren:

als erstes fügen wir die folgende Zeile der pihole-FTL.conf hinzu.

data/pihole/conf/pihole-FTL.conf

MAXDBDAYS=0

dies deaktiviert die Query Datenbank nun legen wir noch mittels Docker Volume mount die Logfiles nach /dev/null um:

...
    volumes:
      ...
      - /dev/null:/var/log/pihole.log:ro
      - /dev/null:/var/log/pihole-FTL.log:ro
      - /dev/null:/var/log/lighthttpd:ro
...

nun deployed wir das compose Projekt neu:

cd /opt/pihole
docker-compose up -d

openHAB

Bei openHAB kann man die LogLevels konfigurieren um so das Logging zu reduzieren. Wie das geht findet ihr hier:

Mosquitto MQTT Broker

Um den Mosquitto MQTT Broker ruhig zu stellen muss man lediglich das Logging und den persistence Mode deaktivieren. Hierfür muss man die mosquitto.conf entsprechend anpassen:

data/mosquitto/conf/mosquitto.conf

persistence false
log_dest none

dann zum Aktivieren Mosquitto durchstarten.

Chromium Browser

Chromium ist ein richtiger IO Fresser. Gerade weil er ständig ins Cache Directory schreibt und auch in sein Profile Directory. Diese beiden Ordner verbannen wir als erstes in den RAM. Deshalb mounten wir die beiden Ordner als tmpfs. Hier gehe ich vom pi User und dessen Home Verzeichnis aus.

/etc/fstab

tmpfs /home/pi/.cache   tmpfs   noatime,nodev,nosuid,size=100M  0       0
tmpfs /home/pi/.config/chromium/ tmpfs   noatime,nodev,nosuid,size=100M  0       0

Nun müssen wir noch dafür sorgen das Chromium den Cache minimiert nutzt. Dafür nutzen wir die folgenden Optionen:

--aggressive-cache-discard --disable-sync-preferences --process-per-site --disable-quic --enable-fast-unload --enable-tcp-fast-open --disk-cache-size=10000000 --media-cache-size=5000000

Diese tragen wir in ein Konfigurationsdatei ein: /etc/chromium-browser/customizations/00-rpi-vars

CHROMIUM_FLAGS="--disable-quic --enable-fast-unload --enable-tcp-fast-open --disk-cache-size=10000000 --media-cache-size=5000000"

Mehr Infos zu chromium findet ihr hier:

Fail2ban

Logging kann man auf ERROR stellen wenn alles konfiguriert ist und läuft. Ebenfalls kann man die Datenbank in den Ram legen, das spart ebenfalls Zugriffe auf die Festplatte / SD Karte. Nach einem Reboot ist dieses allerdings leer. Zum Konfigurieren einfach folgende Datei mit folgendem Inhalt anlegen.

/etc/fail2ban/fail2ban.d/001-fail2ban.conf

[Definition]
loglevel = ERROR
dbfile = :memory:

zum Aktivieren einfach den daemon Neustarten:

systemctl restart fail2ban.service

Overlay File System

Sollte man zum Beispiel eine Raspberry Pi nur dafür verwenden, Daten einzulesen und diese zum Beispiel an einen MQTT Broker zu schicken, kann man die gesamte SD-Karte nach dem Setup read-only schalten. Die funktioniert beim Raspberry Pi ganz einfach über raspi-config. Hier kann man einfach unter

4 Performance Options --> P3 Overlay File System

das overlay File System aktivieren oder mit den folgenden Befehlen:

raspi-config nonint enable_bootro
raspi-config nonint enable_overlayfs
reboot

Rückgängig machen wir das Ganze mit

raspi-config nonint disable_overlayfs
reboot
# after reboot
raspi-config nonint disable_bootro
reboot