OwnCloud: Performance-Tuning für OwnCloud 9.x

Im folgenden habe ich die wichtigsten Tipps und Tricks zusammen getragen, die OwnCloud 9.x auch auf schwacher Hardware zum Rennen bringen. Mein Fokus liegt dabei auf dem Cubietruck bzw. Raspberry PI1/2/3. Die Liste ist selbstverständlich unvollständig – ich freue mich immer über Ergänzungen und Korrekturen in den Kommentaren. OwnCloud 9.x ist noch recht jung und noch nicht lange auf meinem Server. Ich werde die Liste in den nächsten Wochen weiter pflegen und auf neuere OwnCloud-Versionen erweitern. Ich habe dazu meine Anleitung für das Performance-Tuning von OwnCloud 8.x dupliziert und von allen Hinweisen für ältere OwnCloud-Versionen befreit um die Lesbarkeit zu erhöhen. Aktuell sind die Tipps hier auch auf Nextcloud 10 und 11 übertragbar. Ich werde in der nächsten Zeit einen weiteren Artikel zu den Besonderheiten von Nextcloud veröffentlichen, sobald meine Tests mit Nextcloud abgeschlossen sind.

Beginnen wir mit den Standard-Tipps, die man selbstverständlich schon umgesetzt haben sollte. Ich führe sie hier nur kurz als „Merkzettel“ auf.

0. Standard-Tipps

  • Cron verwenden. Damit die Hintergrundaufgaben nicht bei jedem Seitenaufruf ausgeführt werden müssen, ist es extrem empfehlenswert diese via Cronjob ausführen zu lassen:
    # crontab -u www-data -e
    
    */15 * * * * php -f /var/www/owncloud/cron.php > /dev/null 2>&1
    
  • Eine zu MySQL kompatible Datenbank verwenden – ich empfehle MariaDB
  • PHP-FPM >7.0.4 mit OpCache und einen Memory-Cache verwenden (siehe unten auch der Hinweis auf APCu)
  • Nginx verwenden

1. OwnCloud-Konfiguration config.php

Die folgenden Einstellungen sollten in der config.php der OwnCloud-Installation vorgenommen werden.

Journal der Activities-App

Falls die Activities-App eingesetzt wird, das Journal nicht endlos anwachsen lassen:

'activity_expire_days' => 90,

Wenn der Cron-Job läuft, wird das Journal der vorgenommenen Aktivitäten auf den angegebenen Zeitraum gekürzt. Bei sehr lange laufenden Installationen kann das Journal recht groß werden und so viel Speicherplatz verschwenden.

Memory-Caching aktivieren

OwnCloud stellt mehrere Backends für das Caching von Daten bereit. Aktuell sind dies:

  • \OC\Memcache\APC Alternative PHP Cache backend
  • \OC\Memcache\APCu APC user backend
  • \OC\Memcache\ArrayCache In-memory array-based backend (nicht empfohlen)
  • \OC\Memcache\Memcached Memcached backend
  • \OC\Memcache\Redis Redis backend
  • \OC\Memcache\XCache XCache backend

Ich bevorzuge und empfehle für OwnCloud wegen der einfachen Installation und Wartung das APCu-Backend. Nicht nur Gentoo, sondern so ziemlich jeden Distribution bringt APCu von Hause aus mit. APCu wird aktiviert via:

'memcache.local' => '\OC\Memcache\APCu',

Memory-Caching Für das File-Locking aktivieren (<PHP7)

In OwnCloud 8.2 wurde die File-Locking-App entfernt und voll auf das so genannte Transactional-File-Locking umgestellt. Standardmäßig verwendet OwnCloud die Datenbank für das Sichern der File-Locks, was je nach Anbindung und Geschwindigkeit der Datenbank zu einem spührbaren Geschwindigkeitsverlust der gesamten OwnCloud-Installation führen kann. Ich empfehle ab OwnCloud 8.2, das Redis-Backend als Memory-Cache zu nutzen. Leider steht pecl-redis für PHP7 noch nicht zur Verfügung. In der config.php sind dafür die folgenden Zeilen einzufügen:

'memcache.local' =&amp;gt; '\OC\Memcache\APCu',
'memcache.locking' =&amp;gt; '\OC\Memcache\Redis',
'redis' =&amp;gt; array(
     'host' =&amp;gt; '/var/run/redis/redis.sock',
     'port' =&amp;gt; 0,
      ),

Ich empfehle hier aus Gründen der Sicherheit und der Performance auf den Unix-Socket zu setzen und keinen weiteren Port zu exponieren. Meine /etc/redis.conf habe ich weitestgehend unmodifiziert gelassen und nur diese Zeilen eingefügt bzw. verändert:

port 0
unixsocket /var/run/redis/redis.sock                                                                                                                                                         
unixsocketperm 770

Die Socket-Datei gehört dabei dem Benutzer „redis“ und der Gruppe „nginx“ (bei mir, kann aber je nach System auch „www“ o.ä. sein). Auf meinem Gentoo-System wird dies in der Datei /etc/conf.d/redis konfiguriert:

# Redis user.                                                                                                                                                                                
REDIS_USER="redis"                                                                                                                                                                           
# Redis group.                                                                                                                                                                               
REDIS_GROUP="nginx"                                                                                                                                                                          

2. allgemeine Systemoptimierungen

Bei DynDNS-Domainnamen externen Hostnamen in Hosts-Datei eintragen

Für den Zugriff auf die OwnCloud über den (externen) Namen der Webseite, der z.B. bei DynDNS-Domains, wird sehr viel Zeit verbraucht, weil für die Namensauflösung der DNS des Gateways und über diesen der DNS des DynDNS-Anbieters verwendet wird. Wenn der externe Name in die /etc/hosts-Datei eingetragen wird, fällt die komplette Namensauflösung weg.

TMP-FS

Um das Erstellen und Verwalten von Session in OwnCloud zu beschleunigen, sollte das TMP-Dateisystem auf einem schnellen Medium wie einer SSD oder gar auf einer RAM-Disk liegen, was via /etc/fstab so erreicht werden kann:

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

XDG-Cache-Verzeichnis in die RAM-Disk legen

Viele von der OwnCloud verwendeten Tools wie z.B. Imagemagick nutzen die Environment-Variable XDG_CACHE_HOME um ihre Caches abzulegen. Damit diese nicht auf einem (potentiell) langsamen Speichermedium erstellt werden müssen, sollte man dies in die RAM-Disk legen:

export XDG_CACHE_HOME="/dev/shm/.cache"

Einen modernen Kernel (ab Kernel 4.x) verwenden

Moderne Kernels – gerade für den Cubietruck – bieten zahlreiche Performance-Optimierungen am Netzwerk-Stack, an den Dateisystemen und bei der Lastverteilung auf die CPUs. Auf meiner Kernel-Seite für den Cubietruck stelle ich die jeweils aktuellen Kernels als binäres Image zur Verfügung – sie sind als Drop-In-Replacement für den leider noch zu oft verwendeten Android-Kernel 3.4 gedacht. Die Linux-Kernels ab 4.8 haben hier insbesondere zugelegt. Die mittlere Antwortzeit beim Abruf der Kalender-Seite ließ sich nur durch den Tausch des Kernels um etwa 10% verbessern.

Ein modernes/performantes Dateisystem verwenden

Wenn auf dem System ein hinreichend aktueller Kernel läuft (also ein >4.x Kernel), lohnt es sich die OwnCloud-Dateien und die Datenbank auf einem BTRFS formatierten Datenträger abzulegen. In meinem System liegt die OwnCloud auf einer WD-Red 2.5″ Festplatte am SATA-Port des Cubietrucks. Der Wechsel auf BRTFS verkürzte die Antwortzeit (ohne Caching) um etwa 30%. Für den Cubietruck sollte auf jeden Fall ein Mainline-Kernel genutzt werden, denn in den von den Android-Builds portierten 3.4.x Kernels ist BTRFS noch nicht hinreichend stabil und performant. Meine Kernel-Builds für den Cubietruck stelle ich auf dieser Seite zur Verfügung.
Wer seine Cloud von einem Flash-Speicher aus betreibt sollte einmal einen Blick auf F2FS werfen. Dieses geht mit den oft eher langsamen sequentiellen Leseraten von SD-Karten besser um und schont die CPU bei Zugriffen. Wer auf eine SSD am SATA-Anschluss zurückgreifen kann, braucht sich über das Dateisystem nur wenig Gedanken zu machen und liegt mit BTRFS oder EXT4 auf der sicheren Seite.

Ein wichtiger Aspekt ist bei EXT4 noch anpassungswürdig. Das Schreiben des Zeitstempels für lesende Zugriffe auf die Datei sollte auf Servern mit Magnetfestplatte oder SD-Karte deaktiviert werden. Dazu wird in die Mount-Parameter die Option „noatime“ aufgenommen. Exemplarisch sieht das in der /etc/fstab so aus:


/dev/sda2  /  ext4  noatime  0 1

Latenzoptimierung des Ondemand-Schedulers

Der Ondemand-Scheduler des Kernels ist für die Regelung der Taktfrequenzen des Hauptprozessors zuständig. Gerade auf dem Cubietruck ist dieser jedoch für hohe Latenzen beim Laden von Webseiten verantwortlich, weil er zu spät den Takt erhöht. Bei den 3.4er-Kernels steht der wesentlich besser funktionierende „interactive“-Scheduler zur Verfügung, bei den Mainline-Kernels jedoch nicht. Die Performance lässt sich hier durch eine geeignete Parametrisierung des ondemand-Schedulers verbessern. Ich lade die Einstellungen über die (anzulegende) Datei /etc/local.d/ondemand_tuning.start:

#!/bin/sh                                                                                                                                                                                    
echo ondemand &amp;gt; /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo 1008000 &amp;gt; /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
echo 408000 &amp;gt; /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
echo 25 &amp;gt; /sys/devices/system/cpu/cpufreq/ondemand/up_threshold
echo 10 &amp;gt; /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor
echo 1 &amp;gt; /sys/devices/system/cpu/cpufreq/ondemand/io_is_busy

Wichtig hier ist insbesondere auch die Limitierung der minimalen Taktfrequenz auf 408MHz – wird eine geringere Frequenz gewählt, dauert das Aufwachen bzw. der Wechsel in den Idle-Zustand deutlich länger.

weitere Latenzoptimierungen

Auch die Art und Weise wie der Kernel neu erstellte Prozesse auf die Kerne verteilt, hat einen großen Einfluss auf die Responsivität des Servers. Eine auf Desktop-Systemen sehr nützliche Einstellung ist die Auto-Gruppierung des Scheduler. Hier werden normalerweise Prozesse je nach TTY gruppiert um die gefühlte Performance auf einem interaktiven System zu verbessern. Allerdings verhindert dies auch die Migration von erzeugten Kind-Prozessen auf andere CPUs, was auf einem Server mit einem sehr, sehr lange laufenden Daemon kontraproduktiv ist. Autogrouping wird in der /etc/sysctl.conf deaktiviert:

kernel.sched_autogroup_enabled = 0

PHP den Zugriff auf /dev/urandom gestatten

Während /dev/random bei unzureichender Menge von Zufallszahlen blockiert, liefert /dev/urandom immer eine Antwort – auch wenn diese evtl. aus Pseudo-Zufallszahlen besteht, was aber gerade im Umfeld der OwnCloud keinen große Rolle spielen sollte. Man sollte hier sowohl die Zugriffsrechte überprüfen, als auch ob der Zugriff evtl. durch ein konfiguriertes „open_basedir“ in der php.ini evtl. unmöglich ist.

Netzwerk-Optimierungen

Wenn die OwnCloud auf einem System mit leistungsschwacher CPU läuft, sollte man sich überlegen, SYN-Cookies zu deaktivieren. Diese sind zwar ein gutes Mittel um Denial-Of-Service-Attacken abzuwehren, jedoch gilt dies nicht für leistungsschwache Systeme, da hier viel Rechenleistung für die Berechnungen der SYN-Cookies benötigt wird. Ein SYN-Flood-Angriff würde zwar scheitern, jedoch würde dem System dennoch die Puste ausgehen, was den Angriff letztendlich doch gelingen lässt. Die Einstellung ändert man in der Datei /etc/sysctl.conf, die dann für leistungsschwache Systeme so aussieht:

net.ipv4.tcp_syncookies = 0

Auf potenterer Hardware im Sinne der CPU-Leistung sieht dies jedoch genau andersherum aus. Hier sollten SYN-Cookies aktiviert werden und sogar die Anzahl der überwachten Sockets und die Tiefe des Backlogs erhöht werden:

net.ipv4.tcp_syncookies = 1
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 2048

3. Webserver (Nginx)

Alle folgenden Tuning-Tipps beziehen sich auf Nginx und werden in der nginx.conf-Datei vorgenommen. Gerade auf leistungsschwachen Systemen wie den gängigen ARM-Boards (Raspberry-PI, Cubietruck, Banana-PI) ist die Leistung des Crypto-Subsystemes recht schwach – besonders im Vergleich mit modernen Intel-Prozessoren mit AES-NI-Erweiterungen. Eine wichtige Tuningmaßnahme ist daher, die teuren SSL-Session-Setups zu minimieren.

SSL session reuse

Im Nginx sollte auf jeden Fall die Wiederverwertung von SSL Sessions und Session-Tickets aktiviert werden. Dies führt zu einer merklich kürzeren Latenz beim Laden der OwnCloud-Webseiten und erleichtert die „tägliche“ Arbeit mit den jeweiligen OwnCloud-Apps.

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_ticket_key /etc/ssl/ssl_session_ticket.key;
ssl_session_tickets on;

SPDY-Protokoll bzw. HTTP/2 aktivieren

Nginx ab der Version 1.9.5 im Mainline-Branch unterstützt nun HTTP/2 das als direkter Nachfolger von SPDY gesehen werden kann. Alle wichtigen Browser unterstützen nun auch HTTP/2, daher sollte dieses Protokoll vorgezogen werden. HTTP/2 kann die Zugriffe auf die OwnCloud-Instanz teilweise erheblich beschleunigen.

listen 6443 ssl http2 default deferred;

Steht HTTP/2 nicht zur Verfügung, kann das SPDY-Protokoll verwendet werden. In älteren Versionen (7.x) gab es hier einige Einschränkungen und Fehler, mit OwnCloud 9.x sollten diese nicht mehr auftreten. SPDY wird in der nginx.conf konfiguriert. Hier muss SPDY in die „listen“-Zeile der unterstützten Protokolle aufgenommen werden und die Fähigkeit via Header annonciert werden:

listen 6443 ssl spdy default deferred;

# RSP: add google spdy support --&amp;gt; http://nginx.org/en/docs/http/ngx_http_spdy_module.html#spdy_headers_comp
# http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_buffer_size
add_header Alternate-Protocol &amp;nbsp;6443:npn-spdy/3;
spdy_headers_comp 6;
ssl_buffer_size 4k;

Weitere Nginx-Optimierungen

Bei der OwnCloud werden oft viele kleine nacheinanderfolgende Anfragen gestellt – dies gilt besonders für die Kontakte-App. Ein erhöhtes Keepalive/Keepalive-Timeout behält die Sitzung länger offen um nacheinander folgende Anfragen nicht auszubremsen. Die Option „multi_accept“ veranlasst dagegen, den Arbeitsprozess neue Verbindungen anzunehmen bevor die aktuelle Anfrage zu Ende gebracht wird, was sich sehr positiv auf die Latenz auswirken kann.

Im produktiven Einsatz benötigen wir keine Informationen darüber, wann und welche Seiten bzw. Elemente aufgerufen wurden. Damit können wir das Zugriffs-Log deaktivieren und den Druck auf das Dateisystem senken.

Die vorgeschlagenen Änderungen in der nginx.conf sehen so aus:

events { 
...
multi_accept on;
...
}

http {
...
keepalive_requests 100000;
keepalive_timeout 75 20;
access_log off;
...}

6 Antworten auf „OwnCloud: Performance-Tuning für OwnCloud 9.x“

  1. Hallo Herr Sperling. Nach langem Überlegen habe ich mich nun endlich entschlossen eine Owncloud auf meinem Cubietruck zu betreiben. Ihre Artikel finde ich als Anmerkung sehr gelungen, wenn auch nicht immer ganz verständlich da ich mit Linux noch nicht so konform bin.
    Jedoch hätte ich eine Frage zum Dateisystem BTRFS. Aktuell läuft alles von einer 16GB SD Karte. Durch den Anschluss einer 2,5″ Festplatte besteht nun die Überlegung Root auf die HDD auszulagern. So wie Sie es beschrieben haben, liegt Owncloud und die DB auf einer BTRFS Partition. Dies betrifft aber nur diese (Owncloud+DB) und nicht Root, oder?
    Da ich gerne noch eine SWAP hätte und diese nach meinen Recherchen nur mit Modifikationen mit BTRFS möglich sind stellt mein aktueller Wissensstand dies hier dar:

    SD Karte: Boot
    Partition 1: ext4 (Root)
    Partition 2: Swap
    Partition 3: BTRFS (Owncloud, Maria DB) Würde etwas dagegen sprechen nginx auch darauf laufen zu lassen?

    Ist diese Annahme korrekt?

    1. Danke für das Feedback. Wenn Sie konkrete Anregungen haben, an welchen Stellen mehr Erklärung nötig ist, kann ich diese gerne hier und dort noch einpflegen. Jeder, der von meinem Blog profitieren kann, sollte dies auch tun können, wenn es an ein paar Extrahinweisen hängt, helfe ich gerne weiter.
      Zu den Fragen: Also prinzipiell kann man auch für die Root-Partition jedes beliebige Dateisystem verwenden, nur die Boot-Partition sollte entweder VFAT oder EXT2 formatiert sein, damit der UBoot-Bootloader den Kernel findet. BTRFS ist auch als Dateisystem für die Root-Partition sinnvoll, weil gegenüber EXT4 der Zugriff auf die vielen, kleinen Bibliotheksdateien erheblich schneller geht und die On-Disk-Kompression viel Platz spart. Die Probleme mit BTRFS und Swap betreffen nur Swap-Dateien im Dateisystem. Swap-Partitionen sind davon nicht betroffen.

      Mein Partitionsschema sieht folgendermaßen aus:
      SD Karte: Boot
      HDD-Partition 1: Boot
      HDD-Partition 2: Root (mit der OwnCloud-Instanz unter /var/www bzw. dem Web-Root vom nginx)
      HDD-Partition 3: Swap
      HDD-Partition 4: Home mit Maria-DB und den OwnCloud-Daten

      Die Festplatte trägt bei mir auch noch eine Boot-Partition, weil abzusehen ist, dass der UBoot in naher Zukunft direkt von der (eSATA-)Platte den Kernel starten kann. Das spart den Umweg über die SD-Karten, die dann entfallen kann.
      Es spricht absolut nichts dagegen so viel wie möglich sowohl auf die Festplatte, als auch auf ein BTRFS-Volumen auszulagern.

      Ich hoffe, das bringt ein wenig Licht ins Dunkel.

      Viele Grüße,
      Robert

  2. Hallo,
    eine Frage:

    „Im Nginx sollte auf jeden Fall die Wiederverwertung von SSL Sessions… “ wo bitte in welcher Datei füge ich das darauf folgende ein?

    Ich versuche nach dieser Anleitung die Zeilen in mein System zu kopieren, aber hier fehlt der Hinweis, wo das sein soll. In der Nginx.conf fand ich nichts,,,

    DANKE für nen Tipp

    1. Ich habe mal den Kommentar in die richtige Sektion verschoben – er gehört nicht als Kommentar unter mein Impressum. Die Antwort auf die Frage steht direkt unter der Erklärung:

      ssl_session_cache shared:SSL:10m;
      ssl_session_timeout 10m;

      Die Änderungen gehören natürlich in die nginx.conf, in die „server“-Sektion. Ich kann das ja noch einmal im Beitrag hervorheben.

  3. Hallo!

    Ein sehr interessanter Artikel und offensichtlich professionell. Sind diese Tuning-Tipps auch auch den Banana Pi anwendbar und wenn ja, dann alle?
    Betreibe den Banana Pi mit der SD-Karte, auf der bananian installiert ist, als Massenspeicher dient eine SATA-HDD.

    Beste Grüße

    1. Danke für die Blumen 😉 Der Banana Pi – also die erste Version – ist bis auf die geringere Speicherausstattung fast baugleich mit dem Cubietruck, damit sind die Tipps natürlich auch dort verwendbar. Prinzipiell gebe ich mir Mühe, dass die Tipps bis hin zu größeren Maschinen skalieren. Eine meiner NextClouds läuft auf einem Quad-Core Atom und auch dort kann man Geschwindigkeitsverbesserungen erzielen, auch wenn der jeweilige Effekt unterschiedlich stark ist.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

elf − sieben =