Prozesse auf Linux-Server parallelisieren, CPU-Maximierung

Hallo zusammen,

ich bin mir nicht sicher, ob dieses Thema hier rein gehört, aber eventuell hat jemand einen Tip für mich?
Ich habe eine Menge an Berechnungen durchzuführen, die auf einen Linux-Server ausgelagert werden. Anfangs war der CPU damit komplett ausgelastet, weshalb zusätzliche Kerne an die DB zugewiesen wurden. Jetzt liegt die CPU-Auslastung auf dem Server bei maximal 12 %, egal wie viele Berechnungen gleichzeitig von meinem Rechner geschickt werden. Kann ich einstellen (und wenn ja wo), dass der komplette CPU von einem User benutzt werden kann? Gibt es außerdem die Möglichkeit parallel mehrere Prozesse, die von einem Rechner angeordnet werden, durchführen zu lassen?

(Ich bin der einzige, der Zugang auf die Datenbank hat, sodass ich damit niemanden blockiere wenn der CPU ausgelastet ist.)

Vielen Dank und einen schönen Abend

PostgreSQL nutzt je Verbindung eine CPU. Mehr nicht. Wenn Du Dinge parallel laufen lassen willst, mußt Du also mehrere Connections aufmachen und das so verteilen.

Ich kenne nun ja nicht Deine Anwendung und was da genau abläuft. Mir kommt aber pl/proxy in den Sinn, damit kannst Du Sharding betreiben - also Daten auf mehrere DB’s verteilen. Diese können ja durchaus auf derselben Kiste laufen. Und in Abfragen kannst Du dann solche Tabellen, die physisch in unterschiedlichen Datenbanken liegen, parallel abfragen. Zum Schluß kommt dann quasi ein UNION ALL. Das Konzept ist recht cool. Aber wie gesagt, um das als Lösung zu nutzen müßten mehr Details bekannt sein.

Das ist schon mal hilfreich, danke! Ich habe folgendes SQL-Skript:

===============================================
DROP TABLE IF EXISTS public.lines;
CREATE TABLE public.lines(
kuppelpunkt char (50),
FOREIGN KEY (kuppelpunkt) REFERENCES kuppelpunkte (point_id),
wandpunkt char (40),
FOREIGN KEY (wandpunkt) REFERENCES wandpunkte (wand_pk),
weight double precision,
weight_svf double precision,
wand BIGINT

);

SELECT AddGeometryColumn(‘public’, ‘lines’, ‘geom’, 0, ‘GEOMETRY’, 3, true);
INSERT INTO public.lines
SELECT
kuppelpunkte.point_id,
wandpunkte.wand_pk,
kuppelpunkte.weight_diff,
kuppelpunkte.flaechenanteil,
wandpunkte.wall,
ST_MakeLine(wandpunkte.geom, kuppelpunkte.geom)

FROM public.kuppelpunkte,
public.wandpunkte
WHERE wandpunkte.wall=‘21’
AND kuppelpunkte.azimuth
BETWEEN wandpunkte.range_a
AND wandpunkte.range_b;


ALTER TABLE public.lines
ADD idx SERIAL NOT NULL,
ADD intersection boolean;

CREATE UNIQUE INDEX ind
ON public.lines
USING btree(idx);

ALTER TABLE public.lines
ADD CONSTRAINT ind
PRIMARY KEY USING INDEX ind;

CREATE INDEX lines_gist3d_geom
ON public.lines
USING gist(geom gist_geometry_ops_nd);

DROP TABLE IF EXISTS public.sky;
CREATE TABLE sky (sk, id) AS
(SELECT sum(weight_svf), wandpunkt
FROM (SELECT DISTINCT
bool_or(_ST_3DIntersects(lines.geom, surface_geometry.geometry)), lines.idx, lines.wandpunkt, lines.weight_svf
FROM
public.lines,
public.surface_geometry
WHERE
ST_DWithin(lines.geom,surface_geometry.geometry, 100)
GROUP BY lines.idx HAVING COUNT(DISTINCT lines.idx)=1) test
WHERE NOT bool_or
GROUP BY wandpunkt);

ALTER TABLE public.wandpunkte
ADD svf double precision;

UPDATE public.wandpunkte
SET svf = sky.sk
FROM public.sky
WHERE wandpunkte.wand_pk=sky.id;

===============================================
Es wird aus der Tabelle ‘wandpunkte’ je eine Wandfläche (wall), auf welcher mehrere Punkte liegen, entnommen und mit Punkten der Tabelle ‘kuppelpunkte’ zu Linien verbunden. Diese werden auf Schnitte mit Polygonen aus ‘surface_geometry’ (großes Stadtgebiet) überprüft. Die Werte ‘weight_svf’ aller Linien ohne Schnitte (intersection: f) werden aufsummiert und an den entsprechenden Ausgangspunkt der Linie in die Tabelle ‘wandpunkte’ als neues Attribut hinzugefügt.
Dieses Skript soll vollautomatisch in einer Schleife aufgerufen werden, sodass alle Wandpunkte, die in der DB hinterlegt sind, mit dem berechneten Attribut versehen werden. Vorzugsweise soll das alles in FME implementiert werden.

Zu der Idee, die Daten zu verteilen: An sich wäre es möglich, wenn ich die Daten clone oder teile, allerdings wird dann der Speicerbedarf sehr groß bzw. ist eine Teilung ohne weiteres nicht möglich, da die Daten räumlich voneinander abhängen (wichtig für die Schnitttests).
Eine Frage bzgl. der connections habe ich noch: Ist die Anzahl pro Rechner und IP begrenzt, oder rein programmtechnisch bedingt?


Vielen Dank und VG

Die max. Anzahl an Verbindungen zur DB ist in der postgresql.conf regelbar. Default sind 100. Global, unabhängig von der Source-IP.

D.h. wenn ich z.B. 8 CPU-Kerne habe, 8 user erstelle und für jeden eine Verbindung zur DB aufbaue, kann ich rein theoretisch den gesamten Prozessor auslasten?

Die Anzahl der max. Verbindung setze ich noch herunter, aber das Problem, dass nur eine CPU benutzt wird, kann ich auch damit nicht umgehen, oder?

Du kannst auch mit 1,2,3,4,5,6 oder 7 Usern 8 Verbindungen aufmachen.

Mit welchem Befehl geht das? Ich muss ausprobieren, ob das alles so in FME umsetzbar ist, wie ich mir das vorstelle…

Schon mal vielen Dank für eure Tipps!

Was?

Mit einem User von einem Programm aus mehrere connections zur DB aufbauen, damit mehrere CPU-Kerne verwendet werden können

Das kommt auf das Programm an. In PHP mit pg_connect() oder so, auf der Shell mit psql.

Gibt es einen generellen Befehl für die DB? Ich schreibe und teste das SQL-Skript in PGAdmin und möchte dieses in FME mit mehreren SQLExecutern ausführen, sodass ich genau so viele Connections öffne, wie CPU-Kerne vorhanden sind.
Automatisch wurde keine weitere Connection geöffnet, als das Skript mehrmals gleichzeitig aufgerufen wurde (es wurde trotzdem nur eine CPU benutzt). Muss ich PostgreSQL iwo über einen Parameter sagen, dass mehrere Kerne zur Verfügung stehen?

VG

Noch einmal: wenn Du z.B. einen DB-Server und 37 weitere Clients hast, die jeder in einem anderen Land stehen und via Internet drauf zugreifen und jeder Client schickt im selben Moment eine Abfrage aus, die 1 Stunde braucht und der Server 48 Kerne hat, dann fangen 37 davon an zu leuchten. Kannste also ne super dolle Weihnachtsbaumdeko draus machen.

Wenn Du 48 Kerne hast und einen Client, der 37 Dinge berechnen will und das über eine Verbindung macht, dann laufen die nacheinander auf einem Kern.

Wenn Du 48 Kerne hast und einen Client, der aber von 37 unterschiedlichen Source-Ports 37 Verbindungen aufmacht, dann hast wieder einen schicken Weihnachtsbaum.


Wenn Du in Deiner Anwednung, z.B. einem PHP-Prozess also N Dinge gleichzeitig machen willst, dann mußt Du a) dafür sorgen, daß Du da N Verbindungen aufbaust und b) Deine Anwendung auch selber die N Verbindungen parallel bedient. Also Threads, Forks oder sowas. Wie Du das genau machst ist PG vollständig egal.