So erstellen Sie einen Redis-Cluster mit Docker

So erstellen Sie einen Redis-Cluster mit Docker

Zusammenfassung: Seit ich mit Docker in Berührung gekommen bin, habe ich anscheinend die Angewohnheit entwickelt, jede Anwendungssoftware in Docker-Richtung zu installieren. Heute möchte ich versuchen, mit Docker einen Redis-Cluster zu erstellen.

Zunächst benötigen wir theoretisches Wissen: Redis Cluster ist eine verteilte Lösung für Redis, die das Problem der Zentralisierung einzelner Redis-Maschinen löst. Verteilte Datenbanken – lösen Sie zunächst das Problem der Zuordnung des gesamten Datensatzes zu mehreren Knoten gemäß Partitionierungsregeln.

Hierfür müssen Sie die Partitionierungsregel kennen – die Hash-Partitionierungsregel. Redis Cluster verwendet in der Hash-Partitionierungsregel eine virtuelle Slot-Partitionierung. Alle Schlüssel werden gemäß der Hash-Funktion auf 0 bis 16383 abgebildet und die Berechnungsformel lautet: Steckplatz = CRC16 (Schlüssel) und 16383. Jeder Knoten ist für die Verwaltung eines Teils der Slots und der von den Slots zugeordneten Schlüssel-Wert-Daten verantwortlich.

1. Erstellen Sie ein Redis-Docker-Basisimage

Laden Sie das Redis-Installationspaket herunter und verwenden Sie Version: 4.0.1

[root@etcd1 tmp]# mkdir docker_redis_cluster
[root@etcd1 tmp]# cd docker_redis_cluster/
[root@etcd2 docker_redis_cluster]# wget http://download.redis.io/releases/redis-4.0.1.tar.gz

Entpacken und kompilieren Sie Redis

[root@etcd1 docker_redis_cluster]# tar zxvf redis-4.0.1.tar.gz
[root@etcd1 docker_redis_cluster]# cd redis-4.0.1/
[root@etcd1 redis-4.0.1]# machen

Redis-Konfiguration ändern

[root@etcd3 redis-4.0.1]# vi /tmp/docker_redis_cluster/redis-4.0.1/redis.conf

Bind-IP-Adresse ändern

# ~~~ WARNUNG ~~~ Wenn der Computer, auf dem Redis läuft, direkt dem
# Internet, die Bindung an alle Schnittstellen ist gefährlich und setzt die
# Instanz für alle im Internet. Standardmäßig entfernen wir also das Kommentarzeichen
# folgende Bind-Direktive, die Redis zwingt, nur in
# die IPv4-Lookback-Schnittstellenadresse (das bedeutet, dass Redis in der Lage sein wird,
# Akzeptiere nur Verbindungen von Clients, die auf demselben Computer laufen wie
# läuft).
#
# WENN SIE SICHER SIND, DASS IHRE INSTANZEN AUF ALLE SCHNITTSTELLEN HÖREN SOLL
# KOMMENTIEREN SIE EINFACH DIE FOLGENDE ZEILE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#binden 127.0.0.1
binden 0.0.0.0

Ändern Sie den Daemon-Prozess „Ja“ in „Nein“

# Standardmäßig wird Redis nicht als Daemon ausgeführt. Verwenden Sie „yes“, wenn Sie es benötigen.
# Beachten Sie, dass Redis bei der Daemonisierung eine PID-Datei in /var/run/redis.pid schreibt.
dämonisieren nein

Entfernen Sie die Kommentarzeichen aus dem Kennwortelement und fügen Sie ein neues Kennwort hinzu

# Warnung: Da Redis ziemlich schnell ist, kann ein externer Benutzer bis zu
# 150k Passwörter pro Sekunde gegen eine gute Box. Das bedeutet, dass Sie
# Verwenden Sie ein sehr sicheres Passwort, da es sonst sehr leicht zu knacken ist.
#
# requirepass foobared

Geändert zu

# Warnung: Da Redis ziemlich schnell ist, kann ein externer Benutzer bis zu
# 150k Passwörter pro Sekunde gegen eine gute Box. Das bedeutet, dass Sie
# Verwenden Sie ein sehr sicheres Passwort, da es sonst sehr leicht zu knacken ist.
#
erforderlichpass 123456

Da das Passwort konfiguriert ist, muss das Passwort auch für eine andere Master-Slave-Verbindung in der Konfiguration konfiguriert werden

# Wenn der Master durch ein Passwort geschützt ist (mit der Konfiguration „requirepass“
# Anweisung unten) ist es möglich, den Slave anzuweisen, sich zu authentifizieren, bevor
# Starten des Replikationssynchronisationsprozesses, sonst wird der Master
# die Slave-Anfrage ablehnen.
#
# masterauth <Master-Passwort>

Geändert zu

# Wenn der Master durch ein Passwort geschützt ist (mit der Konfiguration „requirepass“
# Anweisung unten) ist es möglich, den Slave anzuweisen, sich zu authentifizieren, bevor
# Starten des Replikationssynchronisationsprozesses, sonst wird der Master
# die Slave-Anfrage ablehnen.
#
# masterauth <Master-Passwort>
Masterauth 123456

Festlegen des Protokollpfads

# Geben Sie den Namen der Protokolldatei an. Auch die leere Zeichenfolge kann verwendet werden, um
# Redis, um sich bei der Standardausgabe anzumelden. Beachten Sie, dass bei Verwendung von Standard
# Ausgabe für Protokollierung, aber Daemonisierung, Protokolle werden an /dev/null gesendet
Protokolldatei "/var/log/redis/redis-server.log"

Konfigurieren Sie clusterbezogene Informationen und entfernen Sie die Kommentare vor den Konfigurationselementen.

# Normale Redis-Instanzen können nicht Teil eines Redis-Clusters sein; nur Knoten, die
# gestartet werden, wie Clusterknoten können. Um eine Redis-Instanz als
# Clusterknoten aktiviert die Clusterunterstützung, indem er das Folgende auskommentiert:
#
Clusterfähig ja
 
# Jeder Clusterknoten hat eine Clusterkonfigurationsdatei. Diese Datei ist nicht
# soll manuell bearbeitet werden. Es wird von Redis-Knoten erstellt und aktualisiert.
# Jeder Redis-Clusterknoten erfordert eine andere Clusterkonfigurationsdatei.
# Stellen Sie sicher, dass Instanzen, die im selben System laufen, nicht
# Überlappende Clusterkonfigurationsdateinamen.
#
Cluster-Konfigurationsdatei nodes-6379.conf
 
# Das Clusterknoten-Timeout ist die Anzahl der Millisekunden, die ein Knoten nicht erreichbar sein muss
# damit es als Fehlerzustand betrachtet wird.
# Die meisten anderen internen Zeitlimits sind ein Vielfaches des Knoten-Timeouts.
#
Cluster-Knoten-Timeout 15000

Spiegelbildproduktion

[root@etcd3 docker_redis_cluster]# cd /tmp/docker_redis_cluster
[root@etcd3 docker_redis_cluster]# vi Docker-Datei
# Redis
# Version 4.0.1
 
VON Centos:7<br>
ENV REDIS_HOME /usr/local<br>
ADD redis-4.0.1.tar.gz / # Das lokale Redis-Quellpaket wird in den Stammpfad des Images kopiert. Der ADD-Befehl entpackt es nach dem Kopieren automatisch. Das kopierte Objekt muss im selben Pfad wie das Dockerfile liegen und nach ADD RUN mkdir -p $REDIS_HOME/redis muss ein relativer Pfad verwendet werden. # Installationsverzeichnis erstellen ADD redis-4.0.1/redis.conf $REDIS_HOME/redis/ # Die zu Beginn der Kompilierung generierte und angepasste Konfiguration in das Installationsverzeichnis kopieren RUN yum -y update # Yum-Quelle aktualisieren RUN yum install -y gcc make # Zur Kompilierung benötigte Tools installieren WORKDIR /redis-4.0.1
RUN machen
RUN mv /redis-4.0.1/src/redis-server $REDIS_HOME/redis/ # Nach der Kompilierung wird im Container nur noch die ausführbare Datei redis-server benötigt
 
ARBEITSVERZEICHNIS /
RUN rm -rf /redis-4.0.1 # Löschen Sie die entpackte Datei RUN yum remove -y gcc make # Nachdem die Installation und Kompilierung abgeschlossen sind, können Sie den redundanten gcc löschen und make
 
VOLUME ["/var/log/redis"] # Datenvolumen hinzufügen EXPOSE 6379 # Port 6379 freigeben. Sie können auch mehrere Ports freigeben, was hier jedoch nicht notwendig ist.

PS. Das aktuelle Image ist kein ausführbares Image und enthält daher keine ENTRYPOINT- und CMD-Anweisungen

Erstellen des Images

# Zur chinesischen Quelle wechseln [root@etcd3 docker_redis_cluster]# vi /etc/docker/daemon.json
{
  "Registrierungsspiegel": ["https://registry.docker-cn.com"]
}
 
# Kompilieren Sie [root@etcd3 docker_redis_cluster]# docker build -t hakimdstx/cluster-redis .
...
 
Vollständig!
 ---> 546cb1d34f35
Zwischenbehälter ausbauen 6b6556c5f28d
Schritt 14/15: VOLUME /var/log/redis
 ---> Wird ausgeführt in 05a6642e4046
 ---> e7e2fb8676b2
Zwischenbehälter ausbauen 05a6642e4046
Schritt 15/15: EXPOSE 6379
 ---> Wird ausgeführt in 5d7abe1709e2
 ---> 2d1322475f79
Zwischenbehälter entfernen 5d7abe1709e2
Erfolgreich erstellt 2d1322475f79

Das Image wird erstellt. Während der Erstellung erhalten Sie möglicherweise die Fehlermeldung: Der öffentliche Schlüssel für glibc-headers-2.17-222.el7.x86_64.rpm ist nicht installiert. In diesem Fall müssen Sie der Image-Konfiguration einen Befehl hinzufügen:

...
RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
RUN yum -y update # Yum-Quelle aktualisieren RUN yum install -y gcc make # Die für die Kompilierung benötigten Tools installieren

Sehen Sie sich das Bild an:

[root@etcd3 docker_redis_cluster]# Docker-Bilder
REPOSITORY TAG BILD ID ERSTELLT GRÖSSE
hakimdstx/cluster-redis 4.0.1 1fca5a08a4c7 vor 14 Sekunden 435 MB
centos 7 49f7960eb7e4 vor 2 Tagen 200 MB

Oben ist das Redis-Basisbild abgeschlossen

2. Erstellen Sie ein Redis-Knoten-Image

Erstellen Sie ein Redis-Knoten-Image basierend auf dem zuvor erstellten Redis-Basis-Image

[root@etcd3 tmp]# mkdir docker_redis_nodes
[root@etcd3 tmp]# cd docker_redis_nodes
[root@etcd3 docker_redis_nodes]# vi Docker-Datei
# Redis-Knoten
# Version 4.0.1<br>
VON hakimdstx/cluster-redis:4.0.1
 
#MAINTAINER_INFO
WARTUNGSPERSÖNLICHKEIT hakim [email protected]
 
EINSTIEGSPUNKT ["/usr/local/redis/redis-server", "/usr/local/redis/redis.conf"]

Redis-Knoten-Image erstellen

[root@etcd3 docker_redis_nodes]# docker build -t hakimdstx/nodes-redis:4.0.1 .      
Senden des Build-Kontexts an den Docker-Daemon 2.048 kB
Schritt 1/3: VON hakimdstx/cluster-redis:4.0.1
 ---> 1fca5a08a4c7
Schritt 2/3: MAINTAINER hakim [email protected]
 ---> Wird ausgeführt in cc6e07eb2c36
 ---> 55769d3bfacb
Zwischenbehälter entfernen cc6e07eb2c36
Schritt 3/3: ENTRYPOINT /usr/local/redis/redis-server /usr/local/redis/redis.conf
 ---> Läuft in f5dedf88f6f6
 ---> da64da483559
Zwischencontainer entfernen f5dedf88f6f6
da64da483559 wurde erfolgreich erstellt

Spiegel anzeigen

[root@etcd3 docker_redis_nodes]# Docker-Bilder
REPOSITORY TAG BILD ID ERSTELLT GRÖSSE
hakimdstx/nodes-redis 4.0.1 da64da483559 vor 51 Sekunden 435 MB
hakimdstx/cluster-redis 4.0.1 1fca5a08a4c7 vor 9 Minuten 435 MB
centos 7 49f7960eb7e4 vor 2 Tagen 200 MB

3. Redis-Cluster ausführen

Ausführen des Redis-Containers

[root@etcd3 docker_redis_nodes]# docker run -d --name redis-6379 -p 6379:6379 hakimdstx/nodes-redis:4.0.1  
1673a7d859ea83257d5bf14d82ebf717fb31405c185ce96a05f597d8f855aa7d
[root@etcd3 docker_redis_nodes]# docker run -d --name redis-6380 -p 6380:6379 hakimdstx/nodes-redis:4.0.1   
df6ebce6f12a6f3620d5a29adcfbfa7024e906c3af48f21fa7e1fa524a361362
[root@etcd3 docker_redis_nodes]# docker run -d --name redis-6381 -p 6381:6379 hakimdstx/nodes-redis:4.0.1  
396e174a1d9235228b3c5f0266785a12fb1ea49efc7ac755c9e7590e17aa1a79
[root@etcd3 docker_redis_nodes]# docker run -d --name redis-6382 -p 6382:6379 hakimdstx/nodes-redis:4.0.1
d9a71dd3f969094205ffa7596c4a04255575cdd3acca2d47fe8ef7171a3be528
[root@etcd3 docker_redis_nodes]# docker run -d --name redis-6383 -p 6383:6379 hakimdstx/nodes-redis:4.0.1
73e4f843d8cb28595456e21b04f97d18ce1cdf8dc56d1150844ba258a3781933
[root@etcd3 docker_redis_nodes]# docker run -d --name redis-6384 -p 6384:6379 hakimdstx/nodes-redis:4.0.1
10c62aafa4dac47220daf5bf3cec84406f086d5261599b54ec6c56bb7da97d6d

Containerinformationen anzeigen

[root@etcd3 redis]# Docker ps
CONTAINER ID BILD BEFEHL ERSTELLT STATUS PORTS NAMEN
10c62aafa4da hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." vor 3 Sekunden Vor 2 Sekunden aktiv 0.0.0.0:6384->6379/tcp redis-6384
73e4f843d8cb hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." vor 12 Sekunden Vor 10 Sekunden aktiv 0.0.0.0:6383->6379/tcp redis-6383
d9a71dd3f969 hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." vor 20 Sekunden. Vor 18 Sekunden aktiv. 0.0.0.0:6382->6379/tcp redis-6382
396e174a1d92 hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." vor 3 Tagen Seit 3 ​​Tagen aktiv 0.0.0.0:6381->6379/tcp redis-6381
df6ebce6f12a hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." vor 3 Tagen Seit 3 ​​Tagen aktiv 0.0.0.0:6380->6379/tcp redis-6380
1673a7d859ea hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." vor 3 Tagen Seit 3 ​​Tagen aktiv 0.0.0.0:6379->6379/tcp redis-6379

Ausführen des Redis-Clustercontainers

Zeigen Sie Replikationsinformationen für Redis Info über eine Remoteverbindung an

[root@etcd2 ~]# redis-cli -h 192.168.10.52 -p 6379
192.168.10.52:6379> Info-Replikation
NOAUTH-Authentifizierung erforderlich.
192.168.10.52:6379> Authentifizierung 123456
OK
192.168.10.52:6379> Info-Replikation
# Replikation
Rolle: Meister
verbundene_Slaves:0
master_replid:2f0a7b50aed699fa50a79f3f7f9751a070c50ee9
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
zweiter_Repl_Offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
192.168.10.52:6379>
# Die restlichen Basisinformationen sind dieselben wie oben

Es ist ersichtlich, dass der Kunde nach der Verbindung, da zuvor ein Kennwort festgelegt wurde, zuerst das Kennwort zur Authentifizierung eingeben muss, da er sonst nicht durchkommen kann. Aus den obigen Informationen wissen wir, dass sich alle Redis in der Masterrolle „role:master“ befinden, was offensichtlich nicht das ist, was wir wollen.

Vor der Konfiguration müssen wir die aktuellen IP-Adressen aller Container anzeigen

[root@etcd3 redis]# Docker ps
CONTAINER ID BILD BEFEHL ERSTELLT STATUS PORTS NAMEN
10c62aafa4da hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." vor 3 Sekunden Vor 2 Sekunden aktiv 0.0.0.0:6384->6379/tcp redis-6384
73e4f843d8cb hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." vor 12 Sekunden Vor 10 Sekunden aktiv 0.0.0.0:6383->6379/tcp redis-6383
d9a71dd3f969 hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." vor 20 Sekunden. Vor 18 Sekunden aktiv. 0.0.0.0:6382->6379/tcp redis-6382
396e174a1d92 hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." vor 3 Tagen Seit 3 ​​Tagen aktiv 0.0.0.0:6381->6379/tcp redis-6381
df6ebce6f12a hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." vor 3 Tagen Seit 3 ​​Tagen aktiv 0.0.0.0:6380->6379/tcp redis-6380
1673a7d859ea hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." vor 3 Tagen Seit 3 ​​Tagen aktiv 0.0.0.0:6379->6379/tcp redis-6379
[root@etcd3 redis]
[root@etcd3 redis]# docker inspect 10c62aafa4da 73e4f843d8cb d9a71dd3f969 396e174a1d92 df6ebce6f12a 1673a7d859ea | grep IPA
            "SekundäreIP-Adressen": null,
            "IP-Adresse": "172.17.0.7",
                    "IPAMConfig": null,
                    "IP-Adresse": "172.17.0.7",
            "SekundäreIP-Adressen": null,
            "IP-Adresse": "172.17.0.6",
                    "IPAMConfig": null,
                    "IP-Adresse": "172.17.0.6",
            "SekundäreIP-Adressen": null,
            "IP-Adresse": "172.17.0.5",
                    "IPAMConfig": null,
                    "IP-Adresse": "172.17.0.5",
            "SekundäreIP-Adressen": null,
            "IP-Adresse": "172.17.0.4",
                    "IPAMConfig": null,
                    "IP-Adresse": "172.17.0.4",
            "SekundäreIP-Adressen": null,
            "IP-Adresse": "172.17.0.3",
                    "IPAMConfig": null,
                    "IP-Adresse": "172.17.0.3",
            "SekundäreIP-Adressen": null,
            "IP-Adresse": "172.17.0.2",
                    "IPAMConfig": null,
                    "IP-Adresse": "172.17.0.2",

Es ist bekannt, dass: redis-6379: 172.17.0.2, redis-6380: 172.17.0.3, redis-6381: 172.17.0.4, redis-6382: 172.17.0.5, redis-6383: 172.17.0.6, redis-6384: 172.17.0.7

Redis konfigurieren
ert

Clusterfähige Operationen von Redis Cluster

//Cluster 
CLUSTER-INFO: Druckt Cluster-Informationen. CLUSTER-KNOTEN: Listet alle derzeit dem Cluster bekannten Knoten und zugehörige Informationen zu diesen Knoten auf.  
   
//Knoten 
CLUSTER MEET <ip> <port> Fügen Sie den durch IP und Port angegebenen Knoten zum Cluster hinzu und machen Sie ihn zu einem Teil des Clusters. 
CLUSTER FORGET <node_id> Entfernt den durch node_id angegebenen Knoten aus dem Cluster. 
CLUSTER REPLICATE <node_id> Legt den aktuellen Knoten als Slave des durch node_id angegebenen Knotens fest. 
CLUSTER SAVECONFIG Speichert die Konfigurationsdatei des Knotens auf der Festplatte.  
   
//Slot 
CLUSTER ADDSLOTS <Slot> [Slot ...] Weisen Sie dem aktuellen Knoten einen oder mehrere Slots zu. 
CLUSTER DELSLOTS <Slot> [Slot ...] Entfernt einen oder mehrere Slots aus der Zuweisung des aktuellen Knotens. 
CLUSTER FLUSHSLOTS entfernt alle dem aktuellen Knoten zugewiesenen Steckplätze und macht den aktuellen Knoten zu einem Knoten ohne zugewiesene Steckplätze. 
CLUSTER SETSLOT <slot> NODE <node_id> Weist den Slot dem durch node_id angegebenen Knoten zu. Wenn der Slot einem anderen Knoten zugewiesen wurde, lassen Sie den anderen Knoten den Slot zuerst löschen und ihn dann zuweisen. 
CLUSTER SETSLOT <Slot> MIGRATING <Knoten-ID> Migriert den Slot dieses Knotens zum durch die Knoten-ID angegebenen Knoten. 
CLUSTER SETSLOT <Slot> IMPORTING <Knoten-ID> Importiert den Slot vom durch die Knoten-ID angegebenen Knoten in diesen Knoten. 
CLUSTER SETSLOT <Slot> STABLE Bricht den Import oder die Migration des Slots Slot ab.  
   
//Schlüssel 
CLUSTER KEYSLOT <Schlüssel> Berechnet den Steckplatz, in dem der Schlüssel platziert werden soll. 
CLUSTER COUNTKEYSINSLOT <Slot> Gibt die Anzahl der Schlüssel-Wert-Paare zurück, die aktuell im Slot Slot enthalten sind. 
CLUSTER GETKEYSINSLOT <Slot> <Anzahl> Gibt die Schlüssel in count Slots zurück. 

Redis-Clusterbewusstsein: Knoten-Handshake – bezieht sich auf den Prozess, bei dem eine Gruppe von Knoten, die im Clustermodus ausgeführt werden, über das Gossip-Protokoll miteinander kommunizieren, um sich gegenseitig wahrzunehmen.

192.168.10.52:6379> Cluster-Treffen 172.17.0.3 6379
OK
192.168.10.52:6379> Cluster-Treffen 172.17.0.4 6379
OK
192.168.10.52:6379> Cluster-Treffen 172.17.0.5 6379
OK
192.168.10.52:6379> Cluster-Treffen 172.17.0.6 6379
OK
192.168.10.52:6379> Cluster-Treffen 172.17.0.7 6379
OK
192.168.10.52:6379> CLUSTERKNOTEN
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 Master - 0 1528697195600 1 verbunden
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 Master - 0 1528697195600 0 verbunden
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 Master - 0 1528697195600 5 verbunden
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 Master - 0 1528697194000 4 verbunden
0bbdc4176884ef0e3bb9b2e7d03d91b0e7e11f44 172.17.0.5:6379@16379 Master - 0 1528697194995 3 verbunden
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 ich selbst, Master - 0 1528697195000 2 verbunden

Die sechs Knoten wurden nun zu einem Cluster zusammengefasst, aber dies funktioniert noch nicht, da den Clusterknoten noch keine Slots zugewiesen wurden.

Informationen zum Zuweisungsslot

Überprüfen Sie die Anzahl der Slots auf 172.17.0.2:6379

192.168.10.52:6379> CLUSTER-INFO
cluster_state:Fehler
cluster_slots_assigned:0 # Die Anzahl der zugewiesenen Slots beträgt 0
cluster_slots_ok:0
cluster_slots_pfail:0
Fehler bei Clusterslots: 0
Bekannte Clusterknoten: 6
Clustergröße: 0
cluster_current_epoch:5
cluster_meine_Epoche:2
cluster_stats_messages_ping_sent:260418
cluster_stats_messages_pong_sent:260087
cluster_stats_messages_meet_sent:10
cluster_stats_messages_sent:520515
cluster_stats_messages_ping_received:260086
cluster_stats_messages_pong_received:260328
cluster_stats_messages_meet_received:1
cluster_stats_messages_received:520415

Wie Sie oben sehen können, lautet der Clusterstatus „Fehlgeschlagen“, da die Steckplätze nicht zugewiesen sind. Darüber hinaus müssen alle 16384 Steckplätze gleichzeitig zugewiesen werden, bevor der Cluster verwendet werden kann.

Slots zuweisen

Slots zuweisen: CLUSTER ADDSLOTS-Slots. Ein Slot kann nur einem Knoten zugewiesen werden. Alle 16384 Slots müssen zugewiesen werden und es dürfen keine Konflikte zwischen verschiedenen Knoten auftreten.
Weisen Sie es also über das Skript addslots.sh zu:

#!/bin/bash
# Knoten1 192.168.10.52 172.17.0.2
n = 0
für ((i=n;i<=5461;i++))
Tun
   /usr/local/bin/redis-cli -h 192.168.10.52 -p 6379 -a 123456 CLUSTER ADDSLOTS $i
Erledigt
 
 
# Knoten2 192.168.10.52 172.17.0.3
n = 5462
für ((i=n;i<=10922;i++))
Tun
   /usr/local/bin/redis-cli -h 192.168.10.52 -p 6380 -a 123456 CLUSTER ADDSLOTS $i
Erledigt
 
 
# Knoten3 192.168.10.52 172.17.0.4
n = 10923
für ((i=n;i<=16383;i++))
Tun
   /usr/local/bin/redis-cli -h 192.168.10.52 -p 6381 -a 123456 CLUSTER ADDSLOTS $i
Erledigt

Darunter gibt -a 123456 das Passwort an, das eingegeben werden muss.

192.168.10.52:6379> CLUSTER-INFO
cluster_state:fail # Der Clusterstatus ist fehlgeschlagen cluster_slots_assigned:16101 # Nicht vollständig zugewiesen cluster_slots_ok:16101
cluster_slots_pfail:0
Fehler bei Clusterslots: 0
Bekannte Clusterknoten: 6
Clustergröße: 3
cluster_current_epoch:5
cluster_meine_Epoche:2
cluster_stats_messages_ping_sent:266756
cluster_stats_messages_pong_sent:266528
cluster_stats_messages_meet_sent:10
cluster_stats_messages_sent:533294
cluster_stats_messages_ping_received:266527
cluster_stats_messages_pong_received:266666
cluster_stats_messages_meet_received:1
Empfangene Clusterstatistiknachrichten: 533194<br>
192.168.10.52:6379> CLUSTER-INFO
cluster_state:ok # Der Clusterstatus ist erfolgreich cluster_slots_assigned:16384 # Alle Zuweisungen wurden abgeschlossen cluster_slots_ok:16384
cluster_slots_pfail:0
Fehler bei Clusterslots: 0
Bekannte Clusterknoten: 6
Clustergröße: 3
cluster_current_epoch:5
cluster_meine_Epoche:2
cluster_stats_messages_ping_sent:266757
cluster_stats_messages_pong_sent:266531
cluster_stats_messages_meet_sent:10
cluster_stats_messages_sent:533298
cluster_stats_messages_ping_received:266530
cluster_stats_messages_pong_received:266667
cluster_stats_messages_meet_received:1
cluster_stats_messages_received:533198

Zusammenfassend lässt sich sagen, dass der Cluster immer noch funktionsfähig ist, wenn alle Slots zugewiesen sind. Wenn wir einen Slot entfernen, fällt der Cluster sofort aus. Probieren Sie es selbst aus – CLUSTER DELSLOTS 0.

So erreichen Sie Hochverfügbarkeit

Wir haben oben einen vollständigen und betriebsbereiten Redis-Cluster erstellt, aber jeder Knoten ist ein einzelner Punkt. Wenn also ein Knoten ausfällt, kann der gesamte Cluster aufgrund unvollständiger Slot-Zuweisung abstürzen. Daher müssen wir für jeden Knoten einen Replikations-Standbyknoten konfigurieren.
Wir haben bereits im Vorfeld sechs Standby-Knoten erstellt. Drei davon wurden zum Aufbau des Clusters verwendet, die restlichen drei können daher direkt als Standby-Replikate verwendet werden.

192.168.10.52:6379> CLUSTER-INFO
cluster_state: ok
Zugewiesene Clusterslots: 16384
cluster_slots_ok:16384
cluster_slots_pfail:0
Fehler bei Clusterslots: 0
cluster_known_nodes:6 # 6 Knoten insgesamt cluster_size:3 # Der Cluster hat 3 Knoten cluster_current_epoch:5
cluster_meine_Epoche:2
cluster_stats_messages_ping_sent:270127
cluster_stats_messages_pong_sent:269893
cluster_stats_messages_meet_sent:10
cluster_stats_messages_sent:540030
cluster_stats_messages_ping_received:269892
cluster_stats_messages_pong_received:270037
cluster_stats_messages_meet_received:1
cluster_stats_messages_received:539930

Alle Knoten-IDs anzeigen

192.168.10.52:6379> CLUSTERKNOTEN
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 Master - 0 1528704114535 1 verbunden 5462-10922
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 Master - 0 1528704114000 0 verbunden 10923-16383
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 Master - 0 1528704114023 5 verbunden
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 Master - 0 1528704115544 4 verbunden
0bbdc4176884ef0e3bb9b2e7d03d91b0e7e11f44 172.17.0.5:6379@16379 Master - 0 1528704114836 3 verbunden
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 ich selbst, Master - 0 1528704115000 2 verbunden 0-5461

Schreiben Sie ein Skript zum Hinzufügen eines Replikationsknotens

[root@etcd2 tmp]# vi addSlaveNodes.sh
#!/bin/bash
 
/usr/local/bin/redis-cli -h 192.168.10.52 -p 6382 -a 123456 CLUSTER REPLIZIEREN 760e4d0039c5ac13d04aa4791c9e6dc28544d7c7
 
/usr/local/bin/redis-cli -h 192.168.10.52 -p 6383 -a 123456 CLUSTER REPLIZIEREN 54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c
 
/usr/local/bin/redis-cli -h 192.168.10.52 -p 6384 -a 123456 CLUSTER REPLIZIEREN f45f9109f2297a83b1ac36f9e1db5e70bbc174ab

Hinweis: 1. Der als Standby verwendete Knoten muss über nicht zugewiesene Steckplätze verfügen, andernfalls schlägt der Vorgang fehl (Fehler) ERR. Um einen Master festzulegen, muss der Knoten leer und ohne zugewiesene Steckplätze sein.
2. Sie müssen den Vorgang CLUSTER REPLICATE [node_id] auf dem hinzuzufügenden Knoten ausführen, um den aktuellen Knoten zu einem Replikatknoten der Knoten-ID zu machen.
3. Slave-Knoten hinzufügen (Cluster-Replikation): Das Replikationsprinzip ist das gleiche wie bei einer Redis-Replikation auf einer einzelnen Maschine. Der Unterschied besteht darin, dass die Slave-Knoten unter dem Cluster ebenfalls im Clustermodus ausgeführt werden müssen und vor der Replikation zum Cluster hinzugefügt werden müssen.

Alle Knoteninformationen anzeigen:

192.168.10.52:6379> CLUSTERKNOTEN
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 Master - 0 1528705604149 1 verbunden 5462-10922
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 Master - 0 1528705603545 0 verbunden 10923-16383
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 Slave f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 0 1528705603144 5 verbunden
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 Slave 54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 0 1528705603000 4 verbunden
0bbdc4176884ef0e3bb9b2e7d03d91b0e7e11f44 172.17.0.5:6379@16379 Slave 760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 0 1528705603000 3 verbunden
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 ich selbst, Master - 0 1528705602000 2 verbunden 0-5461

Sie sehen, dass wir nun einen Hochverfügbarkeitscluster mit drei Mastern und drei Slaves implementiert haben.

Hochverfügbarkeitstest - Failover zur Anzeige des aktuellen Betriebsstatus:

192.168.10.52:6379> CLUSTERKNOTEN
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 Master - 0 1528705604149 1 verbunden 5462-10922
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 Master - 0 1528705603545 0 verbunden 10923-16383
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 Slave f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 0 1528705603144 5 verbunden
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 Slave 54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 0 1528705603000 4 verbunden
0bbdc4176884ef0e3bb9b2e7d03d91b0e7e11f44 172.17.0.5:6379@16379 Slave 760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 0 1528705603000 3 verbunden
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 ich selbst, Master - 0 1528705602000 2 verbunden 0-5461

Das obige läuft normal

Versuchen Sie, einen Master herunterzufahren, wählen Sie den Container mit Port 6380 aus und stoppen Sie ihn:

192.168.10.52:6379> CLUSTERKNOTEN
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 Master, Fehler - 1528706408935 1528706408000 1 verbunden 5462-10922
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 Master - 0 1528706463000 0 verbunden 10923-16383
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 Slave f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 0 1528706462980 5 verbunden
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 Slave 54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 0 1528706463000 4 verbunden
0bbdc4176884ef0e3bb9b2e7d03d91b0e7e11f44 172.17.0.5:6379@16379 Slave 760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 0 1528706463985 3 verbunden
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 ich selbst, Master - 0 1528706462000 2 verbunden 0-5461
192.168.10.52:6379>
192.168.10.52:6379> CLUSTER-INFO
cluster_state:Fehler
Zugewiesene Clusterslots: 16384
cluster_slots_ok:10923
cluster_slots_pfail:0
cluster_slots_fail:5461
Bekannte Clusterknoten: 6
Clustergröße: 3
cluster_current_epoch:5
cluster_meine_Epoche:2
cluster_stats_messages_ping_sent:275112
cluster_stats_messages_pong_sent:274819
cluster_stats_messages_meet_sent:10
cluster_stats_messages_fail_sent:5
cluster_stats_messages_sent:549946
cluster_stats_messages_ping_received:274818
cluster_stats_messages_pong_received:275004
cluster_stats_messages_meet_received:1
cluster_stats_messages_fail_received:1
cluster_stats_messages_received:549824

Aus dem Obigen geht hervor, dass der gesamte Cluster ausgefallen ist und der Slave-Knoten nicht automatisch zum Master-Knoten aktualisiert wurde. Was ist passiert? ?
Starten Sie den angehaltenen Container neu und überprüfen Sie die Protokollinformationen [root@df6ebce6f12a /]# tail -f /var/log/redis/redis-server.log :

1:S 11 Jun 09:57:46.712 # Clusterstatus geändert: ok
1:S 11. Juni 09:57:46.718 * (Nicht kritisch) Der Master versteht den REPLCONF-Abhörport nicht: -NOAUTH. Authentifizierung erforderlich.
1:S 11. Juni 09:57:46.718 * (Nicht kritisch) Master versteht REPLCONF nicht. Kapazität: -NOAUTH. Authentifizierung erforderlich.
1:S 11 Jun 09:57:46.719 * Teilweise Neusynchronisierung nicht möglich (kein zwischengespeicherter Master)
1:S 11. Juni 09:57:46.719 # Unerwartete Antwort an PSYNC vom Master: -NOAUTH Authentifizierung erforderlich.
1:S 11. Juni 09:57:46.719 * Erneuter Versuch mit SYNC …
1:S 11. Juni 09:57:46.719 # MASTER hat die Replikation mit einem Fehler abgebrochen: NOAUTH-Authentifizierung erforderlich.
1:S 11. Juni 09:57:46.782 * Verbindung zu MASTER 172.17.0.6:6379 wird hergestellt
1:S 11 Jun 09:57:46.782 * MASTER <-> SLAVE Synchronisierung gestartet
1:S 11. Juni 09:57:46.782 * Nicht blockierende Verbindung für SYNC hat das Ereignis ausgelöst.

Wie Sie sehen, ist für den Zugriff zwischen Master und Slave eine Authentifizierung erforderlich. Ich habe zuvor vergessen, # masterauth <Master-Passwort> in redis.conf zu konfigurieren, sodass Master und Slave nicht kommunizieren können. Nach der Änderung der Konfiguration funktioniert das automatische Failover normal.

Manchmal ist ein manuelles Failover erforderlich:

Melden Sie sich beim Slave-Knoten von Port 6380: 6383 an und führen Sie den Befehl CLUSTER FAILOVER aus:

192.168.10.52:6383> CLUSTER-FAILOVER
(Fehler) ERR Der Master ist ausgefallen oder fehlgeschlagen. Verwenden Sie CLUSTER FAILOVER FORCE.

Wir haben festgestellt, dass wir eine erzwungene Übertragung durchführen müssen, da der Master ausgefallen ist.

192.168.10.52:6383> Cluster-Failover erzwingen
OK

Zeigen Sie den aktuellen Clusterknotenstatus an:

192.168.10.52:6383> CLUSTERKNOTEN
0bbdc4176884ef0e3bb9b2e7d03d91b0e7e11f44 172.17.0.5:6379@16379 Slave 760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 0 1528707535332 3 verbunden
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 Slave f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 0 1528707534829 5 verbunden
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 Master - 0 1528707534527 0 verbunden 10923-16383
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 ich selbst, Master - 0 1528707535000 6 verbunden 5462-10922
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 Master - 0 1528707535834 2 verbunden 0-5461
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 Master, Fehler - 1528707472833 1528707472000 1 verbunden

Der Slave-Knoten wurde zu einem Master-Knoten aktualisiert. Zu diesem Zeitpunkt haben wir versucht, das Redis des Knotens 6380 neu zu starten (tatsächlich den gestoppten Container neu zu starten):

192.168.10.52:6383> CLUSTERKNOTEN
0bbdc4176884ef0e3bb9b2e7d03d91b0e7e11f44 172.17.0.5:6379@16379 Slave 760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 0 1528707556044 3 verbunden
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 Slave f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 0 1528707555000 5 verbunden
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 Master - 0 1528707556000 0 verbunden 10923-16383
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 ich selbst, Master - 0 1528707556000 6 verbunden 5462-10922
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 Master - 0 1528707556000 2 verbunden 0-5461
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 Slave 98aebcfe42d8aaa8a3375e4a16707107dc9da683 0 1528707556547 6 verbunden

Wir haben festgestellt, dass Knoten 6380 zu einem Slave-Knoten von Knoten 6383 geworden ist.

Jetzt sollte der Cluster vollständig sein und der Clusterstatus wiederhergestellt sein. Überprüfen wir:

192.168.10.52:6383> CLUSTER-INFO
cluster_state: ok
Zugewiesene Clusterslots: 16384
cluster_slots_ok:16384
cluster_slots_pfail:0
Fehler bei Clusterslots: 0
Bekannte Clusterknoten: 6
Clustergröße: 3
cluster_current_epoch:6
cluster_meine_epoch:6
cluster_stats_messages_ping_sent:19419
cluster_stats_messages_pong_sent:19443
cluster_stats_messages_meet_sent:1
cluster_stats_messages_auth-req_sent:5
cluster_stats_messages_update_sent:1
cluster_stats_messages_sent:38869
cluster_stats_messages_ping_received:19433
cluster_stats_messages_pong_received:19187
cluster_stats_messages_meet_received:5
cluster_stats_messages_fail_received:4
cluster_stats_messages_auth-ack_received:2
cluster_stats_messages_received:38631

Ok, kein Problem.

Wenn der Clusterzugriffsclient initialisiert wird, muss er nur die Adresse eines Knotens kennen. Der Client versucht dann zunächst, einen Befehl an diesen Knoten auszuführen, z. B. „get key“. Befindet sich der Slot, in dem sich der Schlüssel befindet, zufällig auf dem Knoten, kann er direkt erfolgreich ausgeführt werden. Wenn sich der Steckplatz nicht im Knoten befindet, gibt der Knoten einen MOVED-Fehler zurück und teilt dem Client den dem Steckplatz entsprechenden Knoten mit. Der Client kann zum Knoten gehen, um den Befehl auszuführen.

192.168.10.52:6383> hallo bekommen
(Fehler) VERSCHOBEN 866 172.17.0.2:6379
 
192.168.10.52:6379> Setnummer 20004
(Fehler) VERSCHOBEN 7743 172.17.0.3:6379

Darüber hinaus verwendet die Redis-Clusterversion nur db0, obwohl der Select-Befehl Select 0 unterstützen kann. Alle anderen Datenbanken geben einen Fehler zurück.

192.168.10.52:6383> wähle 0
OK
192.168.10.52:6383> wähle 1
(Fehler) ERR SELECT ist im Clustermodus nicht zulässig

Vor kurzem haben einige Internetnutzer nach dem Problem des Verbindungsfehlers beim Docker-Redis-Cluster gefragt. Der spezifische Fehler lautet wie folgt:

Der erste Gedanke ist, dass nicht alle Knoten hinzugefügt werden. Nach dem Hinzufügen bestehen die oben genannten Probleme weiterhin. Wenn man davon ausgeht, dass es sich um einen hostübergreifenden Zugriff handelt, dürfte die Ursache darin liegen, dass die Routing-Adresse nicht gefunden werden kann. Als ich das obige Tutorial schrieb, lief Docker im Standardnetzwerkmodus Bridge-Modus. Schließlich bestand der Hauptzweck darin, Dokumente zu lernen und zu organisieren, hauptsächlich für den eigenständigen Zugriff. In tatsächlichen Anwendungsszenarien ist jedoch meistens ein Host-übergreifender Zugriff auf das öffentliche Netzwerk erforderlich. Das Problem ist klar. Ich denke, es ist besser, den Cluster so einzurichten, dass er die öffentliche IP-Adresse des Hosts gemeinsam nutzt. Die Lösung lautet also wie folgt:

  • Wenn Docker ausgeführt wird, lautet der Ausführungsnetzwerkmodus: Host.
  • Lösung von Portkonflikten. Schließlich belegt der Container im Hostmodus den Port des Hostcomputers. Daher beginnen wir mit der Konfiguration und generieren die Konfigurationen redis-60001.conf, redis-60002.conf, redis-60003.conf... auf dem Hostcomputer. Erstellen Sie so viele Dateien wie Ports vorhanden sind, führen Sie schließlich einen Container aus und mounten Sie eine Konfiguration in den Container, um die Konfiguration im Host zu überschreiben.

Der abschließende Vorgang ist wie folgt:

Docker Run -d --Name Redis -6380 --NET HOST -V /TMP/REDIS.CONF:/USR/LOCAL/REDIS/REDIS.CONF HAKIMDSTX/NODES-REDIS: 4.0.1

Zu diesem Zeitpunkt wurde das Netzwerkproblem behoben.
PS.

Zitat:

1. Bereitstellung, Verwaltung und Tests von Redis Cluster

2. Master-Slave- und Persistenzkonfiguration von Redis unter Docker

Dies ist das Ende dieses Artikels über die Schritte zum Aufbau eines Redis -Clusters mit Docker.

Das könnte Sie auch interessieren:
  • Docker installiert das offizielle Redis -Bild und aktiviert die Authentifizierung der Kennwortauthentifizierung
  • Docker Deployment Springboot -Projektintegration Redis -Bild für den Zugriffszählungs -Beispielcode
  • So erstellen Sie ein Redis -Bild in Docker
  • Implementierungsschritte zur Installation eines Redis-Containers in Docker
  • Bringen Sie Ihnen bei, wie Sie in 5 Minuten den Redis-Clustermodus und den Sentinelmodus mit Docker erstellen
  • Docker erstellt Redis5.0 und mountet Daten
  • 5 Minuten, um Ihnen beizubringen, wie Sie Redis in Docker installieren und starten (neue Methode)
  • Docker-Installations- und Konfigurationsschritte für das Redis-Image

<<:  Detaillierte Erklärung zur Verwendung von Filtereigenschaften in CSS3

>>:  MySQL-Serie 15: Allgemeine MySQL-Konfiguration und Leistungsstresstest

Artikel empfehlen

MySQL-Einschränkungstypen und Beispiele

Zwang Einschränkungen gewährleisten Datenintegrit...

Detaillierte Erklärung des JavaScript-Timer-Prinzips

Inhaltsverzeichnis 1. setTimeout()-Timer 2. Stopp...

Richtige Verwendung der Vue-Funktion Anti-Shake und Throttling

Vorwort 1. Entprellen: Nach dem Auslösen eines Ho...

Unterschied und Implementierung von JavaScript Anti-Shake und Throttling

Inhaltsverzeichnis 1. Anti-Shake 2. Drosselung 3....

So stellen Sie FastDFS in Docker bereit

Installieren Sie Fastdfs auf Docker Mount-Verzeic...

Neue Funktionen von JS ES: Einführung in Erweiterungsoperatoren

1. Spread-Operator Der Spread-Operator besteht au...

Nginx löst Cross-Domain-Probleme und bindet Seiten von Drittanbietern ein

Inhaltsverzeichnis Vorwort Schwierigkeit Domänenü...

Umfassende Zusammenfassung der MySQL-Tabellen

Inhaltsverzeichnis 1. Erstellen Sie eine Tabelle ...

Bidirektionale verknüpfte Liste der JavaScript-Datenstruktur

Eine einfach verkettete Liste kann nur vom Anfang...

Teilen Sie 5 hilfreiche CSS-Selektoren, um Ihr CSS-Erlebnis zu bereichern

Dank unserer umfassenden CSS-Erfahrung als Webdesi...

Drei Diskussionen zum Iframe Adaptive Height Code

Beim Erstellen einer B/S-Systemschnittstelle stößt...