Im folgenden habe ich die wichtigsten Tipps und Tricks zusammen getragen, die OwnCloud 8.x auch auf schwacher Hardware zum Rennen bringen. Dieser Artikel bezieht sich ausschließlich auf OwnCloud 8.x, zu OwnCloud 9.x bitte hier weiterlesen. Mein Fokus liegt dabei auf dem Cubietruck bzw. Raspberry PI2. Die Liste ist selbstverständlich unvollständig – ich freue mich immer über Ergänzungen und Korrekturen in den Kommentaren. Ich werde die Liste in den nächsten Wochen weiter pflegen und auf neuere OwnCloud-Versionen erweitern.
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 extem 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 >5.6 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',
Leider funktioniert selbst mit OwnCloud 8.2.3 noch nicht das zu PHP7 passende APCu-Backend (Version 5.1.2). Um dieses dennoch nutzen zu können muss di1717e Datei „lib/private/memcache/apcu.php“ durch die auf Git-Hub veröffentlichten Version ersetzt werden.
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' => '\OC\Memcache\APCu', 'memcache.locking' => '\OC\Memcache\Redis', 'redis' => array( 'host' => '/var/run/redis/redis.sock', 'port' => 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"
Asset-Pipelining aktivieren
OwnCloud kann die vielen CSS und Javascript in der OwnCloud-Installation zusammengefasst und komprimiert ausliefern, was sehr viel Zeit beim Laden der Seite spart. Dazu werden die Dateien im Vorhinein zusammengefasst und im Assets-Verzeichnis der OwnCloud-Installation abgelegt. Dazu muss der Webserver Schreibrechte für das Verzeichnis „assets“ in der OwnCloud-Installation besitzen. Diese muss ggf. zuvor noch erzeugt werden.
'asset-pipeline.enabled' => true,
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
BTRFS als 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.
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 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor echo 1008000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq echo 408000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq echo 25 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold echo 10 > /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor echo 1 > /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
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-Coockies 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
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 bei 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
Das SPDY-Protokoll ist eine Ergänzung des HTTP-Protokolls und kann die Zugriffe auf die OwnCloud-Instanz teilweise erheblich beschleunigen. In älteren Versionen (7.x) gab es hier einige Einschränkungen und Fehler, mit OwnCloud 8.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 --> 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 6443:npn-spdy/3; spdy_headers_comp 6; ssl_buffer_size 4k;
Update: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. Die Vorgehensweise ist ähnlich dem vom SPDY, jedoch muss man sich hier nicht um das Anfügen von alternativ-Protokoll-Headern kümmern:
listen 6443 ssl http2 default deferred;
Statische Webseiten direkt via Nginx ausliefern (bis OwnCloud 8.1.x)
Web-Content, der sich nicht ändert, sollte so möglich nicht via PHP ausgeliefert werden, sondern direkt via Nginx verteilt werden. Wie dies zu realisieren ist, habe ich ausführlich hier beschrieben. Dies funktioniert leider mehr mit OwnCloud >=8.2, denn die Unterstützung für XSendFile wurde mit dieser Version entfernt. Darum an dieser Stelle nur die einzufügenden Code-Zeilen für die nginx.conf mit OwnCloud bis Version 8.2:
location ~ \.php(?:$|/) { # ... fastcgi_param MOD_X_ACCEL_REDIRECT_ENABLED on; fastcgi_param MOD_X_ACCEL_REDIRECT_PREFIX /xaccel; # ... }
Nach der PHP-Sektion wird eine weitere Sektion angelegt, die alle mit dem Präfix gekennzeichneten Dateien als intern auszuliefern markiert:
location ^~ /xaccel { internal; alias /; }
Statische Inhalte bereits vorkomprimiert direkt ausliefern (bis OwnCloud 8.1.x)
HTML-Seiten und andere gut komprimierbare Inhalte in komprimierter Form auszuliefern, spart Bandbreite und erhöht die Performance… üblicherweise. Leider gilt dieser Grundsatz nicht für schwache Hardware wie Embedded-ARM-Boards wie den Cubietruck, Raspberry-PI oder Banana-PI. Hier ist es sinnvoll die auszuliefernden Dateien bereits komprimiert auf der Platte abzulegen und so die Prozessorleistung nicht für die Kompression zu verschwenden. Static-GZIP wird in der nginx.conf folgendermaßen aktiviert:
# RSP: Support serving pre-compressed static files, disallow on-demand compression to reduce CPU load gzip off; gzip_vary off; gzip_comp_level 1; gzip_static on; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css application/json application/x-javascript text/xml text/x-js application/xml+rss text/javascript image/svg+xml application/atom+xml application/xml; gzip_proxied expired no-cache no-store private auth; gzip_disable "MSIE [1-6]\.(?!.*SV1)";
Nun muss man die entsprechenden Dateien nur noch auf der Fesplatte komprimiert ablegen. Dazu finden man so manche auf find & Co. basierende Skripte, die via Cron-Job das WWW-Verzeichnis durchstöbern und alle in Frage kommenden Dateien komprimieren. Aus meiner Sicht ist dies nicht günstig, weil die Dateien zum einen vom unkomprimierten Original abweichen können und zum anderen nicht direkt nach dem Erzeugen der Datei zur Verfügung stehen. Ich empfehle die Dateien via inotify bei der Erzeugung bzw. beim Modifizieren neu zu komprimieren. Dazu dient dieses im Hintergrund laufende BASH-Skript:
#!/bin/bash inotifywait -m -q -e CREATE -e MODIFY -e MOVED_TO -e DELETE -e MOVED_FROM -r "/var/www/localhost/htdocs/" -c --excludei '\.(jpg|png|gif|ico|log|sql|zip|gz|pdf|php|swf|ttf|eot|woff|)$' | while read file do file=( ${file//,/ } ) pathname=${file[0]} action=${file[1]} filename=${file[2]} if [[ $filename =~ \.(html|css|js|xml|json|sfw)$ ]]; then if [[ $action == @(DELETE|MOVED_FROM) ]]; then rm -f $pathname$filename.gz elif [[ $action == @(CREATE|MODIFY|MOVED_TO) ]]; then gzip -f -c -9 $pathname$filename > $pathname$filename.gz fi fi done
Danke für die Tuning Tipps, hat meine Cloud um einiges beschleunigt! 🙂
LG Bernd
Prima. Danke für das Feedback!
Hello there, I think your site could possibly be having web browser compatibility
issues. Whenever I look at your website in Safari, it looks
fine however, if opening in IE, it’s got some overlapping
issues. I just wanted to provide you with a quick heads up!
Apart from that, wonderful blog!
That’s strange – I’ve tries a recent version of IE and MS Edge without any issues. Which version of IE did you use?
Hi there, Ӏ enjoy reading throᥙgh youг article.
I like to write a little commеnt to support you.
whoah this blog is magnificent i like reading your posts.
Stay up the great work! You understand, a lot of persons are
searching around for this information, you can help them greatly.
Wow, this post is nice, my sister is analyzing these thingѕ, thеrefore I am going to convey her.
I don’t even know the way I ended up here, but I thought this publish used to be great.
I don’t recognise who you might be but certainly you are going to a famous blogger when you aren’t already.
Cheers!
Hello just wanted to give you a brief heads uup and let youu know a few of the pictures aren’t loading properly.
I’m not sure why but I think its a linking issue. I’ve tried it in two different web browsers and both show the same
results.