RAID-Synchronisation unter Ubuntu beschleunigen

Wenn ein Ubuntu-Server mit einem Software-RAID betrieben wird, so kann der Status des RAIDs über den Befehl:

cat /proc/mdstat

eingesehen werden. Eine entsprechende Ausgabe könnte dann wie folgt aussehen:

Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10] 
md1 : active raid1 sda2[0] sdb2[1]
      11714556864 blocks super 1.2 [2/2] [UU]
      bitmap: 6/88 pages [24KB], 65536KB chunk

md0 : active raid1 sda1[0] sdb1[1]
      4189184 blocks super 1.2 [2/2] [UU]
      
unused devices: <none>

Wird ein RAID neu aufgebaut bzw. synchronisiert sieht die Ausgabe etwas ausführlicher aus:

Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10] 
md1 : active raid1 sda2[0] sdb2[1]
      11714556864 blocks super 1.2 [2/2] [UU]
      [==================>..]  resync = 94.6% (11088768000/11714556864) finish=153.3min speed=67991K/sec
      bitmap: 12/88 pages [48KB], 65536KB chunk

md0 : active raid1 sda1[0] sdb1[1]
      4189184 blocks super 1.2 [2/2] [UU]
      
unused devices: <none>

Die Synchronisation kann unter anderem über die Variable speed_limit_max gesteuert werden. Der Standardwert für dieses Limit liegt bei 200000. Wird dieser Wert höher gesetzt:

echo 1250000 > /proc/sys/dev/raid/speed_limit_max

kann die Synchronisation mehr Ressourcen nutzen und läuft somit schneller. Das bedeutet natürlich auch, dass das System im Allgemeinen stärker ausgelastet wird. Nach einem Neustart wird der geänderte Wert wieder auf seinen ursprünglichen Wert gesetzt.

Node.js unter Ubuntu 22.04 installieren

Wenn Node.js unter der aktuellen Ubuntu-LTS Version 22.04 installiert werden soll, so kann hierfür apt benutzt werden:

apt install nodejs

Das Problem an dieser Version aus den offiziellen Paketquellen ist, das sie ziemlich veraltet ist und mittlerweile meist neuere Node.js Versionen benötigt werden. Der gängige Weg wäre es nun die aktuelle LTS-Version von Node.js über den Befehl:

curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
apt install -y nodejs

zu installieren. Allerdings schlägt dies mangels eines für Ubuntu 22.04 hinterlegtem Paket mit folgender Meldung fehl:

Your distribution, identified as „jammy“, is not currently supported, please contact NodeSource at https://github.com/nodesource/distributions/issues if you think this is incorrect or would like your distribution to be considered for support

Hier kann sich beholfen werden, indem das Paket manuell heruntergeladen und installiert wird, um die Prüfung zu umgehen:

wget https://deb.nodesource.com/node_16.x/pool/main/n/nodejs/nodejs_16.9.1-deb-1nodesource1_amd64.deb
apt install ./nodejs_16.9.1-deb-1nodesource1_amd64.deb

Sobald die Pakete für Ubuntu 22.04 (Jammy) unter Nodesource bereitstehen kann das Setup-Skript wieder genutzt werden, um die Pakete aktuell zu halten. Alternativ kann Node.js auch über Snap installiert werden:

snap install node --classic

Dabei wird die aktuelle 18er-Version von Node.js installiert.

Fehlende Nextcloud-Indicies erzeugen

Unter Umständen kann es bei einer Nextcloud-Installation dazu kommen, das nach einem Update folgende Meldung im Backend angezeigt wird:

In der Datenbank fehlen einige Indizes. Auf Grund der Tatsache, dass das Hinzufügen von Indizes in großen Tabellen einige Zeit in Anspruch nehmen kann, wurden diese nicht automatisch erzeugt. Durch das Ausführen von „occ db:add-missing-indices“ können die fehlenden Indizes manuell hinzugefügt werden, während die Instanz weiter läuft. Nachdem die Indizes hinzugefügt wurden, sind Anfragen auf die Tabellen normalerweise schneller.

Fehlender Index „direct_edit_timestamp“ in der Tabelle „oc_direct_edit“.

Fehlende Indices können unter anderem zu Performanceeinbußen führen, sodass die Indices erstellt werden sollten. Möglich ist dies mit dem Tool occ, welches in der Nextcloud-Installation vorhanden ist. Dieses sollte im Ordner der Nextcloud-Installation ausgeführt werden:

sudo -u www-data php occ db:add-missing-indices

Anschließend findet eine Überprüfung der Indices statt:

Check indices of the share table.
Check indices of the filecache table.
Check indices of the twofactor_providers table.
Check indices of the login_flow_v2 table.
Check indices of the whats_new table.
Check indices of the cards table.
Check indices of the cards_properties table.
Check indices of the calendarobjects_props table.
Check indices of the schedulingobjects table.
Check indices of the oc_properties table.
Check indices of the oc_jobs table.
Check indices of the oc_direct_edit table.
Adding direct_edit_timestamp index to the oc_direct_edit table, this can take some time...
oc_direct_edit table updated successfully.

Fehlende Indices werden hierbei automatisch angelegt und damit eventuellen Performanceeinbußen vorgebeugt.

Lautstärke für Alexa Lautsprecher-Gruppen einstellen

Alexa bzw. mehrere Alexa-Geräte können als Multiroom-Beschallung genutzt werden. Dazu werden sogenannte Lautsprecher-Gruppen in der Alexa-App eingerichtet.

‎Amazon Alexa
Preis: Kostenlos+
Amazon Alexa
Preis: Kostenlos

Die Lautstärke der einzelnen Geräte kann individuell geregelt werden. So führt der Befehl:

Alexa, Lautstärke 4

dazu das die Lautstärke des Gerätes auf einer Skala von 1 bis 10 auf die Lautstärke 4 gestellt wird. Alternativ können die Befehle Alexa, leiser und Alexa, lauter genutzt werden.

Alexa ist aktiv

Neben dieser Möglichkeit der Einstellung der einzelnen Geräte können auch alle Geräte einer Lautsprecher-Gruppe gemeinsam auf eine neue Lautstärke gestellt werden. Dazu dient der Befehl:

Alexa, Lautstärke Überall auf 4

Damit wird die Lautstärke aller Geräte der Gruppe Überall auf vier gestellt. Die Anfrage kann auch variiert werden, solange das Wort Lautstärke, der Wert und der Name der Gruppe in der Anfrage vorkommt. Diese Funktionalität ist vor allem dann praktisch, wenn eine größere Anzahl an Alexa-Geräten genutzt wird.

Klassenname für Logger unter Java automatisch ermitteln

Vor einiger Zeit schrieb ich einen Artikel darüber, wie der Klassenname für einen Logger ermittelt werden kann. Im Endergebnis sah die damalige Lösung, unter Nutzung der Simple Logging Facade for Java kurz SLF4J, wie folgt aus:

Logger log = LoggerFactory.getLogger(new Exception().fillInStackTrace().getStackTrace()[0].getClassName());

Damit wird der gesamte Stacktrace zusammengesammelt und entsprechend der Klassenname extrahiert. Das Problem an dieser Variante ist das der gesamte Stack dafür ausgewertet wird und für jede Nutzung eines Logs eine relativ unintuitive und lange Zeile von A nach B kopiert werden muss. Anders sieht es mit folgender Lösung aus:

package net.seeseekey.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Utility class to get logger
 */
public final class Logging {

    private Logging() {
    }

    public static Logger getLogger() {

        StackWalker.StackFrame frame = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
                .walk(stream -> stream.skip(1)
                        .findFirst()
                        .orElse(null));

        if (frame == null) {
            return LoggerFactory.getLogger("Common");
        }

        return LoggerFactory.getLogger(frame.getClassName());
    }
}

Bei dieser Utility-Klasse wird der entsprechende Klassenname dynamisch über einen StackWalker ermittelt. Zurückgegeben wird hierbei der Klassenname des Aufrufers. Konnte kein Klassenname ermittelt werden, so wird stattdessen ein Logger mit dem Namen Common zurückgegeben. Damit kann der eigentliche Logger nun wie folgt angelegt werden:

Logger log = Logging.getLogger();

Der StackWalker ist ab Java 9 verfügbar und kann somit in neueren Projekten problemlos genutzt werden. Im Gegensatz zu den bisherigen Methoden Teile des Stacktrace zu erhalten, ist der StackWalker aus Performancesicht zu bevorzugen. Definiert wurde diese API in der JEP 259.