Pudge 500 Zeilen einbettbare Datenbank auf Golang

pudge ist eine einbettbare Schlüssel- / Wertedatenbank, die in die Go-Standardbibliothek geschrieben wurde.

Bild

Ich werde auf die grundlegenden Unterschiede zu bestehenden Lösungen eingehen.

Staatenlos

pudge.Set("../test/test", "Hello", "World") 

Puj erstellt automatisch die Testdatenbank einschließlich der Unterverzeichnisse oder öffnet sie. Der Tabellenstatus muss nicht gespeichert werden, und Sie können Werte sicher in Multithread-Anwendungen speichern. Pooj ist threadsicher.

Maschinenfrei

In puj können Sie Bytes, Strings, Zahlen oder Strukturen schreiben. Ohne sich Gedanken über die Konvertierung von Daten in ihre binäre Darstellung zu machen.

  type Point struct { X int Y int } for i := 100; i >= 0; i-- { p := &Point{X: i, Y: i} db.Set(i, p) } var point Point db.Get(8, &point) log.Println(point) 

Abfragesystem

Puj bietet die Möglichkeit, Schlüssel in einer bestimmten Reihenfolge zu extrahieren, einschließlich Auswahl mit Begrenzung, Einrückung, Sortierung und Auswahl nach Präfix.

  keys, _ := db.Keys(7, 2, 0, true) 

Der obige Code ähnelt der SQL-Abfrage:

 select keys from db where key>7 order by keys asc limit 2 offset 0 

Bitte beachten Sie, dass das Sortieren von Schlüsseln "faul" ist. Andererseits sind die Schlüssel im Speicher gespeichert und es läuft ziemlich schnell.

Parallelität

Pooj verwendet, wie die meisten modernen Datenbanken, ein nicht blockierendes Lesemodell, aber das Schreiben in eine Datei blockiert alle Vorgänge. Sie können jedoch Dateien im laufenden Betrieb erstellen / öffnen und so die Anzahl der Sperren minimieren. Es gibt keinen Fehler "Datenbank bereits geöffnet" in Puja. Beispiel für die Verwendung im http-Router:

 func write(c *gin.Context) { var err error group := c.Param("group") counter := c.Param("counter") db, err := pudge.Open(group, cfg) if err != nil { renderError(c, err) return } _, err = db.Counter(counter, 1) if err != nil { renderError(c, err) return } c.String(http.StatusOK, "%s", "ok") } 

Motoren

Trotz seiner geringen Größe unterstützt der Puj zwei Datenspeichermodi. Im Speicher und auf der Festplatte. Standardmäßig speichert puj nur Daten (Werte) auf der Festplatte. Wenn Sie möchten, können Sie den Modus zum Speichern von Daten im Speicher aktivieren. In diesem Fall werden sie auf Anfrage oder beim Schließen der Datenbank auf die Festplatte geleert.

Status

Pooj wird sowohl in Heimprojekten als auch in der Produktion verwendet (siehe Grafik unten) - die Anzahl der Anforderungen an den http-Server basierend auf puj und die Anzahl der Anforderungen ist länger als 20 ms



In diesem Fall wird die Puja im Vollsynchronisationsmodus eingeschaltet, und zum Zeitpunkt von fsync treten signifikante Verzögerungen (mehr als 20 ms) auf. Aber zum Glück gibt es nicht so viele in Prozent.

Auf der Projektseite finden Sie weitere Links mit Beispielen für die Integration von Puja in verschiedene Projekte.

Geschwindigkeit

Im Repository mit Benchmark'y können Sie Puj mit anderen Datenbanken vergleichen:

Test 1


 Number of keys: 1000000 Minimum key size: 16, maximum key size: 64 Minimum value size: 128, maximum value size: 512 Concurrency: 2 
Pogreb
goleveldb
Schraube
badgerdb
Pudge
Slowpoke
pudge (mem)
1M (Put + Get), Sekunden
187
38
126
34
23
23
2
1M Put, ops / sec
5336
34743
8054
33539
47298
46789
439581
1M Get, ops / sec
1782423
98406
499871
220597
499172
445783
1652069
FileSize Mb
568
357
552
487
358
358
358

Pooja ist im Verhältnis zwischen Schreibgeschwindigkeit und Lesegeschwindigkeit sehr ausgewogen. Dass es sich nicht um eine hochspezialisierte Datenbank handelt, die zum Lesen oder Schreiben optimiert ist. Bei hoher Lesegeschwindigkeit wird eine ziemlich hohe Schreibgeschwindigkeit beibehalten. Dies kann jedoch durch Parallelisieren von Aufzeichnungen zu verschiedenen Dateien weiter erhöht werden (wie dies bei LSM Tree-Engines der Fall ist).

Links zu den im Test verwendeten Datenbanken:

  • pogreb Eingebetteter Schlüsselwertspeicher für leselastige Workloads, die in Go geschrieben wurden
  • goleveldb LevelDB-Schlüssel- / Wertedatenbank in Go.
  • Schraube Eine eingebettete Schlüssel- / Wertedatenbank für Go.
  • badgerdb Schneller Schlüsselwert-DB in Go
  • slowpoke Low-Level-Schlüssel- / Wertspeicher in pure Go (basierend auf Pudge)
  • pudge Schneller und einfacher Schlüssel- / Wertspeicher , der mit der Standardbibliothek von Go geschrieben wurde

Sie baten mich, mit Memcache und Redis zu vergleichen, aber da der Löwenanteil der Zeit für Netzwerkschnittstellen bei der Interaktion mit Datenbankdaten aufgewendet wird, ist dies nicht ganz fair. Auf der anderen Seite gewinnt die Puja durch Multithreading, obwohl sie Daten auf die Festplatte schreibt.

Weiterentwicklung

  • Transaktionen Es wäre praktisch, Schreibanforderungen an den Pool mit einem automatischen Rollback im Fehlerfall zu kombinieren.
  • Möglichkeit zur Begrenzung der Schlüssellebensdauer (wie TTL in Memcache / Cassandra usw.)
  • Das Fehlen eines Servers. Es ist praktisch, die Puja in vorhandene Microservices einzubetten, aber höchstwahrscheinlich wird ein separater Server angezeigt. Im Rahmen eines separaten Projekts.
  • Mobile Version. Zur Verwendung unter Android, iOS und als Plugin für Flutter.

Source: https://habr.com/ru/post/de439216/


All Articles