RIAK kompaktiert e/leveldb Tombstones und gewinnt Plattenplatz zurück
Steckbrief
Veröffentlicht:
Kategorien:
Tags:
Das Problem
Wenn man versucht, Speicherplatz zurückzugewinnen, scheint das Löschen von Daten der naheliegende erste Schritt zu sein. In Riak ist dies jedoch nicht unbedingt die beste Lösung, wenn die Festplatte fast voll ist. Der Grund dafür ist, dass das Löschen von Objekten in Riak kompliziert ist. Wie im Abschnitt zum Löschen von Objekten in der aktuellen Riak-Dokumentation beschrieben:
*In Single-Server, nicht geclusterten Datenspeichersystemen ist das Löschen von Objekten ein trivialer Prozess. In einem konsistenten, geclusterten System wie Riak ist das Löschen von Objekten jedoch weit weniger trivial, da sich die Objekte auf mehreren Knoten befinden, was bedeutet, dass ein Löschprozess gewählt werden muss, um zu bestimmen, wann ein Objekt aus dem Speicher-Backend entfernt werden kann.
Wie die Löschung funktioniert
- Riak schreibt einen "tombstone" Wert für den Schlüssel zu den N vnodes, die ihn enthalten (dies ist ein neuer Datensatz)
- Riak wartet standardmäßig 3 Sekunden, um zu überprüfen, ob alle vnodes mit dem Tombstone/Löschen
- Riak gibt eine tatsächliche Löschoperation gegen den Schlüssel an leveldb aus
- leveldb erstellt seinen eigenen Tombstone
- Der Tombstone von Leveldb "schwebt" durch Level-0 und Level-1 als Teil der normalen Komprimierungen
- Beim Erreichen von Level-2 wird Leveldb sofort die Komprimierung und Verbreitung der Tombstones in .sst-Tabellendateien mit 1000 oder mehr Tombstones eingeleitet.
Dies hat zur Folge, dass die Freigabe von Plattenplatz, wenn überhaupt, nur sehr langsam erfolgt.
Lösung für e/leveldb
Kurz gesagt, es gibt eine C++-Funktion in Leveldb, die zur Komprimierung des zugrunde liegenden Speichers verwendet wird. Die Funktion heißt "CompactRange".
Insbesondere werden gelöschte und überschriebene Versionen verworfen, und die Daten werden neu angeordnet, um die Kosten der für den Zugriff auf die Daten erforderlichen Operationen zu verringern.
Diese Funktion ist im Erlang-Code, der diese C++-Bibliothek verwendet, nicht vorhanden. Das bedeutet, dass wir ein eigenständiges Tool entwickeln mussten, das diese Bibliotheksfunktion für alle Leveldb-Dateien in Riak aufruft. Der Nachteil dabei ist, dass der Riak Server offline sein muss, während ein solches 3rd Party Tool läuft.
Anwendungsfall
Wir haben ein solches Tool gebaut, Sie können es von github RiakToolsCxx.git auschecken und mit cmake bauen. Die externe Abhängigkeit leveldb-basho wird automatisch von cmake gezogen.
Der Checkout- und Build-Prozess könnte wie folgt aussehen:
dwalter@knxwork:~/Projects$ git clone https://github.com/hw-dwalter/RiakToolsCxx.git RiakToolsCxx
Cloning into 'RiakToolsCxx'...
remote: Counting objects: 11, done.
remote: Total 11 (delta 0), reused 0 (delta 0), pack-reused 11
Unpacking objects: 100% (11/11), done.
dwalter@knxwork:~/Projects$ cd RiakToolsCxx/
dwalter@knxwork:~/Projects/RiakToolsCxx$ mkdir build
dwalter@knxwork:~/Projects/RiakToolsCxx$ cd build/
dwalter@knxwork:~/Projects/RiakToolsCxx/build$ cmake ..
-- The CXX compiler identification is GNU 6.3.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test COMPILER_SUPPORTS_CXX11
-- Performing Test COMPILER_SUPPORTS_CXX11 - Success
-- Performing Test COMPILER_SUPPORTS_CXX0X
-- Performing Test COMPILER_SUPPORTS_CXX0X - Success
-- The C compiler identification is GNU 6.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Boost version: 1.62.0
-- Found the following Boost libraries:
-- filesystem
-- system
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dwalter/Projects/RiakToolsCxx/build
dwalter@knxwork:~/Projects/RiakToolsCxx/build$ make
Scanning dependencies of target leveldb-basho
[ 10%] Creating directories for 'leveldb-basho'
[ 20%] Performing download step (git clone) for 'leveldb-basho'
Cloning into 'leveldb-basho'...
Already on 'develop'
Your branch is up-to-date with 'origin/develop'.
[ 30%] No patch step for 'leveldb-basho'
[ 40%] No update step for 'leveldb-basho'
[ 50%] No configure step for 'leveldb-basho'
[ 60%] Performing build step for 'leveldb-basho'
ar: creating libleveldb.a
[ 70%] No install step for 'leveldb-basho'
[ 80%] Completed 'leveldb-basho'
[ 80%] Built target leveldb-basho
Scanning dependencies of target riakcompact
[ 90%] Building CXX object src/CMakeFiles/riakcompact.dir/main.cpp.o
[100%] Linking CXX executable riakcompact
[100%] Built target riakcompact
dwalter@knxwork:~/Projects/RiakToolsCxx/build$ ./src/riakcompact
usage: ./src/riakcompact [path]
Nachdem dieses Tool erstellt wurde, können Sie es wie folgt verwenden. Beachten Sie, dass Ihr Riak-Knoten ausgeschaltet sein muss!
root@knxwork:/home/dwalter/Projects/RiakToolsCxx/build# ./src/riakcompact /var/lib/riak/leveldb/
"/var/lib/riak/leveldb/91343852333181432387730302044767688728495783936" [directory]
compacting...
done
"/var/lib/riak/leveldb/685078892498860742907977265335757665463718379520" [directory]
compacting...
done
Fazit
Nach dem Löschen eines kompletten Buckets in unserem riak (Schlüssel für Schlüssel), sind wir in der Lage, den verbrauchten Speicherplatz von 75 GB auf 25 GB mit diesem Tool zu reduzieren!