Frage Wie weise ich einem Linux-Prozess eine "Speicher-Priorität" zu?


Ich laufe auf einem kleinen OpenWRT-Router, wo Swapping aufgrund der begrenzten verfügbaren RAM (32 MB) nicht vermieden werden kann.

Meistens macht der Router nichts anderes, aber von Zeit zu Zeit wird auf eine Postgresql-Datenbank zugegriffen, die auch auf dem Router läuft. Aufgrund des ständig laufenden Updates ist Postgresql komplett ausgelagert und die ersten paar Zugriffe haben eine sehr hohe Latenz, was schlecht ist, da es sich um ein interaktiv genutztes System handelt.

Ich habe bereits einen schönen Wert von -15 für Postgres und +15 für Tor zugewiesen, aber es scheint die Speicherverwaltung nicht sehr zu beeinträchtigen. Swappiness = 1 global zu setzen ändert auch nichts, da Swapping nicht vermieden werden kann, und weil postgresql die meiste Zeit nicht läuft, wird es trotzdem ausgelagert.

Gibt es irgendeinen Weg wie eine Speicherpriorität zu einem Linux-Prozess? Ich habe mir die cgroup-spezifische Swappiness angeschaut, aber die einzige Beschreibung, die ich fand, war, dass sie den Entscheidungsseiten-Cache vs Swap betrifft.

Was ich suche, ist ein Parameter, der dem Linux-Kernel sagt, dass er postgresql nicht so aggressiv austauscht wie die anderen Prozesse (aber ich möchte den gesamten Prozess nicht mockern). Oder würde swappiness = 80 systemweit und swapiness = 1 für postgresql postgresql im Speicher belassen und alles andere bei Bedarf austauschen?


5
2017-08-20 12:25


Ursprung


Antworten:


Genaugenommen können Sie unter Linux nicht verhindern, dass ein Prozess ausgetauscht wird. Sie können vermeiden, dass Sie das Ganze komplett verwenden swapoff -a (und Hinzufügen von etwas RAM), aber dies kann das System zu Instabilität führen.

Aber in diesem Fall leistet Linux gute Arbeit: ein Prozess, der "von Zeit zu Zeit" verwendet wird Muss ausgelagert werden, egal wie viel freier RAM man hat. Vielleicht verwenden Sie eine falsche Konfiguration. Kannst du Postgres auf einen anderen Host legen, vielleicht mit einer schnelleren Festplatte?

BTW: Wenn Sie das Auslagern von Postgres-Prozess in Ihrer aktuellen Konfiguration verhindern wollen, denke ich, dass Sie versuchen können, etwas wie ein Keep Alive zu verwenden: Lassen Sie ein Deamon (oder ein einfaches Bash-Skript) periodisch eine Abfrage senden, um das zu lassen System sehen, dass der Prozess aktiv ist.

I.E. Sie können etwas tun wie:

#!/bin/bash
DBHOST=localhost
DBPORT=5432
DBNAME=theDBname
DBUSER=theUserName
THEQUERY="SELECT 1"

psql -h $DBHOST -p $DBPORT -d $DBNAME -U $DBUSER  -c "$THEQUERY"

Und lassen Sie den Cron es jede Minute oder so nennen.

Wenn Sie etwas anspruchsvolleres wollen, können Sie einen Daemon erstellen, um eine "echte" Abfrage zu senden und die Ergebnisse zwischenzuspeichern, so dass Postgres ausgetauscht werden können, während Sie bereits zwischengespeicherte Ergebnisse haben.


3
2017-08-20 13:08



Ich denke, dass Sie PostgreSQL konfigurieren sollten, um weniger Speicher zu verwenden. Es verwendet viel Speicher, um die Leistung zu verbessern, aber in Ihrem Fall funktioniert es nicht. Die Standardkonfiguration für Ihre OpenWRT PostgreSQL-Installation reduziert vermutlich bereits den Speicherbedarf der Festplatte gegenüber ihren massiven Standardeinstellungen, aber es sieht so aus, als müssten Sie noch weiter gehen.

Das PostgreSQL-Dokumentation listet eine Reihe von Optionen auf, die sich auf die Ressourcennutzung auswirken.

Die anderen Vorschläge von StefanoF und Basile Starynkevitch, entweder den PostgreSQL-Server auf einen anderen Rechner zu verschieben oder effizientere Datenbanken wie sqlite zu verwenden, sind die besseren Lösungen, als zu versuchen, die Auslagerungsleistung von absolut schrecklich zu nur schrecklich zu verbessern.


2
2017-08-20 15:17



Sie könnten verwenden mlock (2) und wahrscheinlicher Madvise (2) in Ihrem Programm (wahrscheinlich Postgresql).

Ich glaube jedoch, dass Postgresql (oder Mysql) für ein 32 MB RAM-System zu groß ist. Hast du darüber nachgedacht? SQLite ? Es ist ein Bibliothek (kein Server), den Sie in Ihre Anwendung einbinden könnten, und damit können Sie SQL- "Anfragen" in einer lokalen SQLite-Datei (die als Datenbank fungiert) ausführen. Natürlich müssen Sie Ihre Anwendung möglicherweise in der Lage sein, über das Internet zu interagieren (z. B. mit FASTCGI oder mit einer HTTP - Server - Bibliothek wie z libonion).

Vielleicht Ionische (1) könnte relevant sein (aber ich denke nicht).


1
2017-08-20 14:37