From cb3c7df5524c92667eb4e81f139c063be064b7a6 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Wed, 24 Apr 2024 23:04:22 -0400 Subject: [PATCH] add design, logo, and memory info --- The_Noid.jpg | Bin 0 -> 57331 bytes docs/design.md | 80 +++++++++++++++++++++++++++++++++++ src/noidb.cc | 10 +++-- tools/viz.sh | 110 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 196 insertions(+), 4 deletions(-) create mode 100644 The_Noid.jpg create mode 100644 docs/design.md create mode 100755 tools/viz.sh diff --git a/The_Noid.jpg b/The_Noid.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c29c52f902782c2a0f5dc388217d15e8524ba98d GIT binary patch literal 57331 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 OevoyLb^ieDfB)Hjt>di# literal 0 HcmV?d00001 diff --git a/docs/design.md b/docs/design.md new file mode 100644 index 0000000..56385f0 --- /dev/null +++ b/docs/design.md @@ -0,0 +1,80 @@ +# NoiDB's Design + +### Name +Formerly named "HanoiDB" but the C++ version needed a new name, so ^H^H and +voila, "NoiDB". + +### History +See [HanoiDB](https://github.com/krestenkrab/hanoidb) and the [lasp-lang](https://github.com/lasp-lang/hanoidb) fork. + +### Basics +If there are N records, there are in log2(N) levels (each being a plain B-tree in a file named "A-*level*.data"). The file `A-0.data` has 1 record, `A-1.data` has 2 records, `A-2.data` has 4 records, and so on: `A-n.data` has 2n records. + +In "stable state", each level file is either full (there) or empty (not there); so if there are e.g. 20 records stored, then there are only data in filed `A-2.data` (4 records) and `A-4.data` (16 records). + +OK, I've told you a lie. In practice, it is not practical to create a new file for each insert (injection at level #0), so we allows you to define the "top level" to be a number higher that #0; currently defaulting to #5 (32 records). That means that you take the amortization "hit" for ever 32 inserts. + +### Lookup +Lookup is quite simple: starting at `A-0.data`, the sought for Key is searched in the B-tree there. If nothing is found, search continues to the next data file. So if there are *N* levels, then *N* disk-based B-tree lookups are performed. Each lookup is "guarded" by a bloom filter to improve the likelihood that disk-based searches are only done when likely to succeed. + +### Insertion +Insertion works by a mechanism known as B-tree injection. Insertion always starts by constructing a fresh B-tree with 1 element in it, and "injecting" that B-tree into level #0. So you always inject a B-tree of the same size as the size of the level you're injecting it into. + +- If the level being injected into empty (there is no A-*level*.data file), then the injected B-tree becomes the contents for that level (we just rename the file). +- Otherwise, + - The injected tree file is renamed to B-*level*.data; + - The files A-*level*.data and B-*level*.data are merged into a new temporary B-tree (of roughly double size), X-*level*.data. + - The outcome of the merge is then injected into the next level. + +While merging, lookups at level *n* first consults the B-*n*.data file, then the A-*n*.data file. At a given level, there can only be one merge operation active. + +### Overwrite and Delete +Overwrite is done by simply doing a new insertion. Since search always starts from the top (level #0 ... level#*n*), newer values will be at a lower level, and thus be found before older values. When merging, values stored in the injected tree (that come from a lower-numbered level) have priority over the contained tree. + +Deletes are the same: they are also done by inserting a tombstone (a special value outside the domain of values). When a tombstone is merged at the currently highest numbered level it will be discarded. So tombstones have to bubble "down" to the highest numbered level before it can be truly evicted. + + +## Merge Logic +The really clever thing about this storage mechanism is that merging is guaranteed to be able to "keep up" with insertion. Bitcask for instance has a similar merging phase, but it is separated from insertion. This means that there can suddenly be a lot of catching up to do. The flip side is that you can then decide to do all merging at off-peak hours, but it is yet another thing that need to be configured. + +With LSM B-Trees; back-pressure is provided by the injection mechanism, which only returns when an injection is complete. Thus, every 2nd insert needs to wait for level #0 to finish the required merging; which - assuming merging has linear I/O complexity - is enough to guarantee that the merge mechanism can keep up at higher-numbered levels. + +A further trouble is that merging does in fact not have completely linear I/O complexity, because reading from a small file that was recently written is faster that reading from a file that was written a long time ago (because of OS-level caching); thus doing a merge at level #*N+1* is sometimes more than twice as slow as doing a merge at level #*N*. Because of this, sustained insert pressure may produce a situation where the system blocks while merging, though it does require an extremely high level of inserts. We're considering ways to alleviate this. + +Merging can be going on concurrently at each level (in preparation for an injection to the next level), which lets you utilize available multi-core capacity to merge. + + +``` +ABC are data files at a given level + A oldest + C newest + X is being merged into from [A+B] + + 270 76 [AB X|ABCX|AB X|ABCX|ABCX|ABCX|ABCX|ABCX|A | | | | | | | | | | + 271 76 [ABCX|ABCX|AB X|ABCX|ABCX|ABCX|ABCX|ABCX|A | | | | | | | | | | + 272 77 [A |AB X|ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|A | | | | | | | | | | + 273 77 [AB X|AB X|ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|A | | | | | | | | | | + 274 77 [ABCX|AB X|ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|A | | | | | | | | | | + 275 78 [A |ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|A | | | | | | | | | | + 276 78 [AB X|ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|A | | | | | | | | | | + 277 79 [ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|A | | | | | | | | | | + 278 79 [ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|ABCX| C |AB | | | | | | | | | | + 279 79 [ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|ABCX| C |AB X| | | | | | | | | | + 280 79 [ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|ABCX|A |AB X| | | | | | | | | | + 281 79 [ABCX|ABCX|ABCX|ABCX|ABCX|ABCX| C |AB |AB X| | | | | | | | | | + 282 80 [ABCX|ABCX|ABCX| BC |AB |AB |AB X|AB X|AB X| | | | | | | | | | + 283 80 [ABCX|ABCX|ABCX| C |AB X|AB |AB X|AB X|AB X| | | | | | | | | | + 284 80 [A |AB X|AB X|AB X|AB X|AB X|AB X|AB X|AB X| | | | | | | | | | + 285 80 [AB X|AB X|AB X|AB X|AB X|AB X|AB X|AB X|AB X| | | | | | | | | | + 286 80 [ABCX|AB X|AB X|AB X|AB X|AB X|AB X|AB X|AB X| | | | | | | | | | + 287 80 [A |ABCX|AB X|AB X|AB X|AB X|AB X|AB X|AB X| | | | | | | | | | +``` + + +When merge finishes, X is moved to the next level [becomes first open slot, in order of A,B,C], and the files merged (AB in this case) are deleted. If there is a C, then that becomes A of the next size. +When X is closed and clean, it is actually intermittently renamed M so that if there is a crash after a merge finishes, and before it is accepted at the next level then the merge work is not lost, i.e. an M file is also clean/closed properly. Thus, if there are M's that means that the incremental merge was not fast enough. + +ABC files have 2^level KVs in it, regardless of the size of those KVs. XM files have 2^(level+1) approximately ... since tombstone merges might reduce the numbers or repeat PUTs of cause. + +### File Descriptors +NoiDB needs a lot of file descriptors, currently 6*⌈log2(N)-TOP_LEVEL⌉, with a nursery of size 2TOP_LEVEL, and N Key/Value pairs in the store. Thus, storing 1.000.000 KV's need 72 file descriptors, storing 1.000.000.000 records needs 132 file descriptors, 1.000.000.000.000 records needs 192. diff --git a/src/noidb.cc b/src/noidb.cc index 852448a..408a956 100644 --- a/src/noidb.cc +++ b/src/noidb.cc @@ -1,5 +1,6 @@ #include #include +#include #include // using namespace seastar; @@ -15,11 +16,12 @@ static seastar::future<> hello_from_all_cores_serial() { } static seastar::future<> hello_from_all_cores_parallel() { - co_await seastar::smp::invoke_on_all( - []() -> seastar::future<> { - lg.info("parallel - Hello from every core"); + co_await seastar::smp::invoke_on_all([]() -> seastar::future<> { + auto memory = seastar::memory::get_memory_layout(); + lg.info( + "parallel - memory layout start={} end={} size={}", memory.start, memory.end, memory.end - memory.start); co_return; - }); + }); co_return; } diff --git a/tools/viz.sh b/tools/viz.sh new file mode 100755 index 0000000..7047202 --- /dev/null +++ b/tools/viz.sh @@ -0,0 +1,110 @@ +#!/bin/bash + +## ---------------------------------------------------------------------------- +## +## hanoi: LSM-trees (Log-Structured Merge Trees) Indexed Storage +## +## Copyright 2011-2012 (c) Trifork A/S. All Rights Reserved. +## http://trifork.com/ info@trifork.com +## +## Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved. +## http://basho.com/ info@basho.com +## +## This file is provided to you under the Apache License, Version 2.0 (the +## "License"); you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +## License for the specific language governing permissions and limitations +## under the License. +## +## ---------------------------------------------------------------------------- + +function periodic() { + t=0 + while sleep 1 ; do + let "t=t+1" + printf "%5d [" "$t" + + for ((i=0; i<35; i++)) ; do + if ! [ -f "A-$i.data" ] ; then + echo -n " " + elif ! [ -f "B-$i.data" ] ; then + echo -n "-" + elif ! [ -f "C-$i.data" ] ; then + echo -n "#" + elif ! [ -f "X-$i.data" ] ; then + echo -n "=" + else + echo -n "*" + fi + done + echo + done +} + +merge_diff() { + SA=`ls -l A-${ID}.data 2> /dev/null | awk '{print $5}'` + SB=`ls -l B-${ID}.data 2> /dev/null | awk '{print $5}'` + SX=`ls -l X-${ID}.data 2> /dev/null | awk '{print $5}'` + if [ \( -n "$SA" \) -a \( -n "$SB" \) -a \( -n "$SX" \) ]; then + export RES=`expr ${SX}0 / \( $SA + $SB \)` + else + export RES="?" + fi +} + +function dynamic() { + local old s t start now + t=0 + start=`date +%s` + while true ; do + s="" + for ((i=8; i<22; i++)) ; do + if [ -f "C-$i.data" ] ; then + s="${s}C" + else + s="$s " + fi + if [ -f "B-$i.data" ] ; then + s="${s}B" + else + s="$s " + fi + if [ -f "A-$i.data" ] ; then + s="${s}A" + else + s="$s " + fi + if [ -f "X-$i.data" ] ; then + export ID="$i" + merge_diff + s="${s}$RES" + elif [ -f "M-$i.data" ] ; then + s="${s}M" + else + s="$s " + fi + s="$s|" + done + + if [[ "$s" != "$old" ]] ; then + let "t=t+1" + now=`date +%s` + let "now=now-start" + free=`df -m . 2> /dev/null | tail -1 | awk '{print $4}'` + used=`du -m 2> /dev/null | awk '{print $1}' ` + printf "%5d %6d [%s\n" "$t" "$now" "$s ${used}MB (${free}MB free)" + old="$s" + else + # Sleep a little bit: + sleep 1 + fi + done +} + +dynamic