Einführung | Wir haben die Geburt von Pika, die Eigenschaften von Pika, den Kern von Pika und die Verwendung von Pika in „Redis-Speicher mit großer Kapazität – Alles über Pika“ vorgestellt. Der Artikel analysiert die wichtigen Dateien in der Pika-Synchronisationslogik ausführlich: die Datenspeichermethode und das Implementierungsprinzip von „write2file“, was sehr lesenswert ist! |
pika ist ein Redis-ähnlicher Speicher mit großer Kapazität, der gemeinsam vom DBA der 360 Web Platform-Abteilung und dem Infrastrukturteam entwickelt wurde. Die Entstehung von Pika soll Redis nicht ersetzen, sondern Redis-Szenarien ergänzen. Pika ist bestrebt, die Probleme von Redis in Szenarien mit großer Kapazität durch dauerhaften Speicher zu lösen, unter der Voraussetzung, dass es vollständig mit dem Redis-Protokoll kompatibel ist und das praktische Betriebs- und Wartungsdesign von Redis übernimmt, wie z. B. langsame Wiederherstellungszeit und hohe Master-Slave-Kosten Synchronisation, relativ fragiler einzelner Thread, begrenzte Datenkapazität, hohe Speicherkosten usw.
pika Master-Slave-Replikationsprinzip binlogBinlog-bezogene Dateien enthalten zwei Teile: Manifest und write2file zeichnen Protokoll-Metainformationen auf, einschließlich der aktuellen Protokolldateinummer und des aktuellen Protokolldatei-Offsets.
DateiformatManifest-Dateiformat:
Log-Offset (8 Bytes)|con_offset (8 Bytes, unbenutzt)|Anzahl der Elemente (4 Bytes, unbenutzt)|Protokolldateinummer (4 Bytes).
Binlog-Dateiformat:
Die feste Größe der Binlog-Datei beträgt 100 MB. Jede Binlog-Datei besteht aus mehreren Blöcken. Jeder Schreib-Redis-Befehl wird als Datensatz bezeichnet. Ein Datensatz kann in mehreren Blöcken verteilt werden, er wird jedoch nur in einer Binlog-Datei verteilt, sodass die Binlog-Datei möglicherweise größer als 100 MB ist.
Datensatzformat: Header|Cmd
Header: Datensatzlänge (3 Bytes) |. Zeitstempel (4 Bytes) |.
Cmd: Ein Teil oder der gesamte Redis-Befehl, je nachdem, ob der verbleibende Speicherplatz des aktuellen Blocks den Datensatz speichern kann.
ImplementierungskursGrundkurs
Version: Metainformationsklasse, zugeordnet durch mmap- und Manifestdateien.
Binlog: Protokollklasse, zugeordnet durch mmap- und write2file-Dateien.
PikaBinlogSenderThread: Protokollverbrauchsklasse, liest nacheinander den Inhalt der Protokolldatei und verbraucht Protokolle.
Grundlegende OperationenBinlog erstellen
//file_size kann in der Konfigurationsdatei angegeben werden, der Standardwert ist 100 MB
Binlog::Binlog(const std::string& binlog_path, const int file_size)
1.1 Erstellen Sie ein Binlog-Dateiverzeichnis.
1.2 Überprüfen Sie, ob die Manifestdatei im Protokollverzeichnis vorhanden ist. Wenn sie nicht vorhanden ist, erstellen Sie eine neue.
1.3 Initialisieren Sie die Versionsklasse gemäß der Manifestdatei.
1.4 Suchen Sie die entsprechende Protokolldatei gemäß Dateinum im Manifest, suchen Sie die Dateianhängeposition gemäß pro_offset, initialisieren Sie den Protokollzeiger, zeichnen Sie die Länge des Protokollinhalts und die Anzahl der Blockblöcke auf.
Aktualisieren Sie den aktuellen Protokollproduktionsstatus
//pro_num: Protokolldateinummer
//pro_offset: Protokolldatei-Offset
//Wird verwendet, um die Binlog-Informationen entsprechend der Slave-Instanz zu aktualisieren, wenn eine vollständige Synchronisierung erforderlich ist
Status Binlog::SetProducerStatus(uint32_t pro_num, uint64_t pro_offset)
2.1 Write2file0 löschen.
2.2 write2file+pro_num löschen.
2.3 Erstellen Sie eine neue Datei „write2file+pro_num“, füllen Sie pro_offset-Leerzeichen aus, initialisieren Sie version->pro_num mit pro_num, version->pro_offset mit pro_offset und aktualisieren Sie sie in der Manifestdatei.
2.4 Initialisieren Sie die aktuelle Dateigröße und den Blockoffset.
Aktualisieren Sie den aktuellen Protokollproduktionsstatus
//filenum: aktuelle Protokollnummer
//pro_offset: aktueller Log-Offset
Status Binlog::GetProducerStatus(uint32_t* filenum, uint64_t* pro_offset)
3.1 Lesen Sie pro_num und pro_offset in der Version und geben Sie sie zurück.
Produktionsprotokoll
//Put->Produce->EmitPhysicalRecord
Status Binlog::Put(const std::string &item)
4.1 Überprüfen Sie, ob die aktuelle Protokolldatei die Schnittbedingungen erfüllt, und schneiden Sie sie gegebenenfalls aus.
4.1.1 pro_num erhöht sich um 1 und initialisiert neue Protokolldateien, version->pro_num=pro_num, version->pro_offset = 0, binlog->filesize = 0, binlog->block_offset = 0.
4.1.2 Wenn die verbleibende Größe des aktuellen Blocks 4.1.3 Produce ist eine Schleife, die sicherstellt, dass, wenn die Elementgröße kBlockSize überschreitet, mehrere EmitPhysicalRecord ausgeführt werden können, um alle in die Binlog-Datei fallenden Elementdaten zu vervollständigen. Die Bedingung für das normale Beenden der Schleife ist left==0. 4.1.3.1 Wenn left 4.1.3.2 Wenn links > verfügbar, bedeutet dies, dass mehrere Blöcke zum Speichern von Elementen erforderlich sind, dann Type=kFirstType zum ersten Mal und EmitPhysicalRecord wird mehrmals aufgerufen. 4.1.3.3 Wenn links > verfügbar und es nicht das erste Mal ist, dass EmitPhysicalRecord, dann Type=kMiddleType, EmitPhysicalRecord mehrmals aufgerufen wird. 4.1.4PhysicalRecord ausgeben. 4.1.4.1 RecordHeader verbinden (3 Byte Länge + 4 Byte Zeit + 1 Byte Typ), Daten schreiben und block_offset und pro_offset aktualisieren. Verbrauchsprotokoll //scratch: Das Verbrauchsergebnis gibt einen vollständigen Redis-CMD zurück //Consume->ReadPhysicalRecord, ReadPhysicalRecord liest jedes Mal einen vollständigen Datensatz, mehrere Datensätze bilden einen vollständigen Redis-Cmd Status PikaBinlogSenderThread::Consume(std::string &scratch) 5.1Consume ist eine Schleife, die ReadPhysicalRecord mehrmals aufrufen kann. Die Bedingung für das Beenden der Schleife ist, dass der gelesene Datensatz „record_type==kFullType“ oder „record_type==kLastType“ ist. 5.1.1 Wenn der gelesene kBlockSize-last_record_offset_ <= kHeaderSize bedeutet, dass das Ende des Blocks gelesen wurde und er mit Daten gefüllt ist, überspringen Sie ihn. 5.1.2 Daten lesen, last_record_offset_, con_offset aktualisieren. Das obige ist der detaillierte Inhalt vonPika: Ergänzen Sie anwendbare Szenarien für Redis-Speicher mit großer Kapazität. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!