Tutorials  /  Databases

Echtzeit-Wasserabrechnung mit PHP, Redis Pub/Sub & MySQL

Ccentron Redaktion · April 2025 ·6 Min. Lesezeit ·Databases, Tutorial

Redis® Pub/Sub ist ein Architekturmodell, das es Publishern ermöglicht, Daten über definierte Kanäle an Subscriber zu senden. Diese Technologie eignet sich besonders für Echtzeitanwendungen, die auf Interprozesskommunikation (IPC) basieren – zum Beispiel Finanzplattformen oder Chatsysteme. In solchen Szenarien ist minimale Latenz entscheidend, da Nutzer eine sofortige Übermittlung von Nachrichten erwarten. Klassische SQL-Datenbanken stoßen hier schnell an ihre Grenzen. Redis® hingegen nutzt den Arbeitsspeicher des Servers und kann extrem viele Lese-/Schreibvorgänge pro Sekunde ausführen.

Ein weiterer Vorteil von Redis® in Kombination mit dem Pub/Sub-Prinzip ist die Entkopplung von Publishern und Subscribern. Daten können einfach an einen Kanal gesendet werden, ohne dass die Empfänger definiert sein müssen. Gleichzeitig können Subscriber beliebige Kanäle abonnieren, ohne die Absender kennen zu müssen.

In solch entkoppelten Systemen können Frontend- und Backend-Teams unabhängig voneinander entwickeln und testen. Dadurch verkürzt sich die Entwicklungszeit, die Entwickler erhalten mehr Freiheiten und die Komplexität sinkt – was auch die Rekrutierung erleichtert.

In dieser Anleitung erstellst du ein modulares Wasserabrechnungssystem mit PHP und Redis®. Dabei übernimmt das Frontend (als Publisher) die Erfassung der Verbrauchsdaten und sendet diese an einen Abrechnungskanal. Das Backend (als Subscriber) verarbeitet die Daten und speichert sie dauerhaft in einer MySQL-Datenbank.

Voraussetzungen

Um dieser Redis® Pub/Sub-Anleitung folgen zu können, benötigst du:

  • einen Server mit Ubuntu 20.04
  • einen Benutzer mit sudo-Rechten
  • einen installierten LAMP-Stack
  • einen Redis®-Server
DB

Passende Infrastruktur bei centron

Datenbanken im Betrieb wollen gepflegt werden: centron übernimmt auf Wunsch Updates, Backups und Monitoring – von der einzelnen Instanz bis zum Cluster. Managed Cluster ansehen →

1. PHP Redis®-Erweiterung installieren

Damit PHP mit Redis® kommunizieren kann, installiere die Erweiterung php-redis. Öffne ein Terminal, verbinde dich via SSH mit dem Server und aktualisiere die Paketquellen:

Konsole
$ sudo apt update

Installiere nun die Erweiterung:

Konsole
$ sudo apt install -y php-redis

Starte Apache neu, um die Änderungen zu aktivieren:

Konsole
$ sudo systemctl restart apache2

Die Umgebung ist nun bereit – als Nächstes wird die Datenbank eingerichtet.

2. Beispieldatenbank und Benutzer einrichten

Redis® speichert Informationen im RAM – ideal für schnelle, temporäre Datenverarbeitung. In diesem Wasserabrechnungssystem nimmt Redis® die Verbrauchsdaten entgegen, die anschließend dauerhaft in MySQL gespeichert werden.

Melde dich als root-Benutzer bei MySQL an:

Konsole
$ sudo mysql -u root -p

Gib dein root-Passwort ein. Führe dann folgende Befehle aus, um die Datenbank billing_db samt Benutzer anzulegen (ersetze EXAMPLE_PASSWORD durch ein sicheres Passwort):

Code
mysql> CREATE DATABASE billing_db;
       CREATE USER 'billing_db_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'EXAMPLE_PASSWORD';
       GRANT ALL PRIVILEGES ON billing_db.* TO 'billing_db_user'@'localhost';           
       FLUSH PRIVILEGES;

Wechsle in die neu erstellte Datenbank:

Code
mysql> USE billing_db;

Erstelle nun die Tabelle customers für Kundendaten:

Code
mysql> CREATE TABLE customers (
           customer_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
           first_name VARCHAR(50),
           last_name VARCHAR(50)           
       ) ENGINE = InnoDB;

Füge Beispieldaten ein:

SQL
mysql> INSERT INTO customers (first_name, last_name) values ('JOHN', 'DOE');
       INSERT INTO customers (first_name, last_name) values ('MARY', 'SMITH');
       INSERT INTO customers (first_name, last_name) values ('STEVE', 'JONES');

Jetzt folgt die Tabelle billings, um monatliche Abrechnungen zu speichern:

Code
mysql> CREATE TABLE billings (
           ref_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
           customer_id BIGINT,
           billing_period VARCHAR(50),
           units_consumed DOUBLE,
           cost_per_unit  DOUBLE          
       ) ENGINE = InnoDB;

Beende die MySQL-Sitzung:

Code
mysql> QUIT;

Die Datenbank samt Tabellenstruktur und Testdaten ist nun bereit. Im nächsten Schritt wird das Frontend-Skript zur Erfassung der Verbrauchsdaten erstellt.

3. PHP-Frontend-Skript entwickeln

Der Wasserverbrauch wird in Kubikmetern erfasst. Falls keine intelligenten Zähler installiert sind, lesen Außendienstmitarbeiter die Werte manuell ab und übermitteln sie an das Backend.

Heute lässt sich dies auch über mobile Apps realisieren, die via API mit einem Server kommunizieren. Erstelle nun ein Frontend-Skript in PHP, das solche Daten verarbeitet. Öffne dazu die Datei frontend.php im Root-Verzeichnis des Webservers:

Konsole
$ sudo nano /var/www/html/frontend.php

Füge folgenden Code ein:

PHP
<?php 

    try {   
             
        $redis = new Redis(); 
        $redis->connect('127.0.0.1', 6379);

        $channel      = 'billings';
        $billing_data = file_get_contents('php://input');          

        $redis->publish($channel, $billing_data); 

        echo "Data successfully sent to the billings channel.\n";         

        } catch (Exception $e) {
            echo $e->getMessage();
        }

Dieses Skript:

  • verbindet sich mit Redis® auf 127.0.0.1
  • liest eingehende JSON-Daten
  • sendet sie an den billings-Kanal
  • gibt bei Erfolg eine Bestätigung aus oder fängt Fehler mit try/catch ab

Damit ist dein Frontend fertig eingerichtet – im nächsten Schritt folgt das Backend.

4. PHP-Backend-Skript erstellen

Um eingehende Verbrauchsdaten weiterzuverarbeiten und dauerhaft in MySQL zu speichern, abonnierst du mit einem PHP-Skript namens backend.php den billings-Kanal. Erstelle die Datei mit folgendem Befehl:

Konsole
$ sudo nano /var/www/html/backend.php

Füge dann folgenden Code in die Datei ein:

PHP
<?php 

    try {   
             
        $redis = new Redis(); 
        $redis->connect('127.0.0.1', 6379);
        $redis->setOption(Redis:: OPT_READ_TIMEOUT, -1);       

        $redis->subscribe(['billings'], function($instance, $channelName, $message) { 
         
            $billing_data = json_decode($message, true); 

            $db_name     = 'billing_db';
            $db_user     = 'billing_db_user';
            $db_password = 'EXAMPLE_PASSWORD';
            $db_host     = 'localhost';

            $pdo = new PDO('mysql:host=' . $db_host . '; dbname=' . $db_name, $db_user, $db_password);
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);   

            $sql = 'insert into billings(
                        customer_id, 
                        billing_period, 
                        units_consumed,
                        cost_per_unit
                    ) 
                    values(
                        :customer_id, 
                        :billing_period, 
                        :units_consumed,
                        :cost_per_unit
                    )'; 

            $data = [];

            $data = [
                    'customer_id'    => $billing_data['customer_id'],
                    'billing_period' => $billing_data['billing_period'],
                    'units_consumed' => $billing_data['units_consumed'],
                    'cost_per_unit'  => 2.5                                 
                    ];

            $stmt = $pdo->prepare($sql);
            $stmt->execute($data); 

            echo "The Redis® data was sent to the MySQL database successfully.\n" ;               
                    
        });         

        } catch (Exception $e) {
            echo $e->getMessage();
        }

Dieses Backend-Skript:

  • stellt eine Verbindung zu Redis® her
  • abonniert den billings-Kanal
  • deaktiviert das Timeout, sodass der Listener unbegrenzt läuft
  • verarbeitet eingehende JSON-Daten
  • speichert die Informationen über ein vorbereitetes SQL-Statement in MySQL

5. Redis® Pub/Sub Anwendung testen

Öffne zwei Terminalfenster. Im ersten Fenster startest du den Backend-Listener mit folgendem Befehl:

Konsole
$ php /var/www/html/backend.php

Hinweis: Das Skript bleibt aktiv und wartet dauerhaft auf neue Nachrichten.

Im zweiten Terminal kannst du über folgende curl-Befehle Testdaten an das Frontend senden:

Konsole
$ curl -X POST http://localhost/frontend.php -H 'Content-Type: application/json' -d '{"customer_id":1, "billing_period": "2021-08-31", "units_consumed":12.36}'
$ curl -X POST http://localhost/frontend.php -H 'Content-Type: application/json' -d '{"customer_id":2, "billing_period": "2021-08-31", "units_consumed":40.20}'
$ curl -X POST http://localhost/frontend.php -H 'Content-Type: application/json' -d '{"customer_id":3, "billing_period": "2021-08-31", "units_consumed":24.36}'

Bei erfolgreichem Versand sollte die Rückmeldung lauten:

Daten erfolgreich an den billings-Kanal gesendet.

Im ersten Terminalfenster mit laufendem Backend-Skript sollte Folgendes erscheinen:

Die Redis®-Daten wurden erfolgreich in die MySQL-Datenbank übertragen.

Um zu überprüfen, ob die Daten in MySQL angekommen sind, melde dich mit folgendem Befehl an:

Konsole
$ mysql -u billing_db_user -p

Gib dein Passwort (z. B. EXAMPLE_PASSWORD) ein. Wechsle dann zur Datenbank:

Code
mysql> USE billing_db;

Erwartete Rückmeldung:

Database changed.

Führe nun folgende SQL-Abfrage aus, um alle Abrechnungen samt Kundendaten anzuzeigen:

Code
mysql> SELECT
           billings.ref_id as bill_reference_no,
           customers.customer_id,
           customers.first_name,
           customers.last_name,
           billings.billing_period,
           billings.units_consumed,
           billings.cost_per_unit,
           CONCAT('$', (billings.units_consumed * billings.cost_per_unit)) as bill_amount
       FROM billings
       LEFT JOIN customers
       ON billings.customer_id = customers.customer_id;

Die Ausgabe sollte in etwa wie folgt aussehen:

+-------------------+-------------+------------+-----------+----------------+----------------+---------------+-------------+
| bill_reference_no | customer_id | first_name | last_name | billing_period | units_consumed | cost_per_unit | bill_amount |
+-------------------+-------------+------------+-----------+----------------+----------------+---------------+-------------+
|                 1 |           1 | JOHN       | DOE       | 2021-08-31     |          12.36 |           2.5 | $30.9       |
|                 2 |           2 | MARY       | SMITH     | 2021-08-31     |           40.2 |           2.5 | $100.5      |
|                 3 |           3 | STEVE      | JONES     | 2021-08-31     |          24.36 |           2.5 | $60.9       |
+-------------------+-------------+------------+-----------+----------------+----------------+---------------+-------------+
3 rows in set (0.00 sec)

Fazit

In dieser Anleitung hast du gezeigt, wie man mit Redis® Pub/Sub in Verbindung mit PHP eine Echtzeitverarbeitung von Wasserverbrauchsdaten realisieren kann. Die Daten wurden erfolgreich aus Redis® entgegengenommen und automatisch in einer MySQL-Datenbank gespeichert – ein anschauliches Beispiel für die Entkopplung von Systemkomponenten durch Redis®.

Jetzt 200 € Guthaben sichern

Testen Sie Ihr Setup auf ccloud³

Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.

centron Redaktion Technische Redaktion

Das Redaktionsteam von centron schreibt Anleitungen aus dem Betriebsalltag: getestet auf unserer eigenen Plattform, betrieben im Rechenzentrum in Hallstadt bei Bamberg.

Kategorie Databases
Teilen
Noch offene Fragen?

Unser Team hilft Ihnen bei Ihrem konkreten Setup weiter – von Menschen, die die Plattform selbst betreiben.

War dieses Tutorial hilfreich?

Ihre Antwort wird anonym gespeichert und hilft uns, die Tutorials zu verbessern.

Kommentare

Noch keine Kommentare – stellen Sie die erste Frage zu diesem Tutorial.

Zum Kommentieren anmelden

Kommentare stehen centron-Kunden offen. Melden Sie sich in Ihrem Konto an, um eine Frage zu diesem Tutorial zu stellen.

Weiterlesen

Das könnte Sie auch interessieren

Jetzt kostenlos anfangen

Melden Sie sich an und erhalten Sie in den ersten 60 Tagen ein Guthaben von 200 € bei centron.

Dieses Werbeangebot gilt nur für neue Konten. Angebot ausschließlich für Gewerbetreibende.

Jetzt loslegen Sales kontaktieren