{"id":4823,"date":"2023-01-20T22:47:59","date_gmt":"2023-01-20T21:47:59","guid":{"rendered":"https:\/\/launix.de\/launix\/?p=4823"},"modified":"2024-04-12T16:21:44","modified_gmt":"2024-04-12T14:21:44","slug":"cpdb-eine-opensource-hochperformante-spaltenbasierte-in-memory-datenbank-als-alternative-zu-proprietaeren-analytischen-datenbanken","status":"publish","type":"post","link":"https:\/\/launix.de\/launix\/en\/cpdb-eine-opensource-hochperformante-spaltenbasierte-in-memory-datenbank-als-alternative-zu-proprietaeren-analytischen-datenbanken\/","title":{"rendered":"memcp: Eine  OpenSource hochperformante Spaltenbasierte In-Memory-Datenbank als Alternative zu propriet\u00e4ren analytischen Datenbanken"},"content":{"rendered":"<p>In den letzten 13 Jahren gab es eine Menge Innovationen im Bereich spaltenbasierte Datenbanken. Zu verdanken ist das vor allem einem deutschen ERP-Hersteller, der sich entschieden hat, sich vom Datenbank-Marktf\u00fchrer abzusetzen und sein eigenes Ding zu machen. Es wurde zu einer Erfolgsstory. Zeit, dass OpenSource nachzieht.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>In der kommerziellen Datenbank-Welt haben sich spaltenbasierte Datenbanken bereits l\u00e4ngst durchgesetzt. Die OpenSource-Welt hinkt unterdes immer noch mit MariaDB und PostgreSQL hinterher. Das behindert nicht nur OpenSource-Projekte, sondern s\u00e4mtliche Produkte, die auf OpenSource-Datenbanken setzen.<\/p>\n\n\n\n<p>Aus diesem Grund stellen wir in diesem Artikel die <code>memcp<\/code> vor, eine spaltenbasierte In-Memory-Datenbank, die sowohl OLAP, als auch OLTP-Arbeitslasten performant handhaben kann.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Vorteile spaltenbasierter Datenbanken gegen\u00fcber Zeilenbasierter Speicher<\/h2>\n\n\n\n<p>Gerade komplexere Anwendungen wie z.B. ERP-Systeme haben oft Tabellen mit \u00fcber hundert Spalten. Meistens steht in vielen Spalten nicht einmal ein Wert. Zeilenbasierte Datenbanken m\u00fcssen aber f\u00fcr jede Speicherzelle entsprechend Speicher vorhalten.<\/p>\n\n\n\n<p>Gleichzeitig gibt es auch viele Datenbank-Anfragen, die nur auf 2 Spalten arbeiten &#8211; meist einem Fremdschl\u00fcssel, nach dem gefiltert wird und einer Wert-Spalte, nach der summiert wird. Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT SUM(lineItem.quantity * lineItem.price) FROM lineItem WHERE lineItem.line = &#91;ID]<\/code><\/pre>\n\n\n\n<p>In dieser SQL-Abfrage werden zum Beispiel von einer Liste von Verk\u00e4ufen die Umsatzsumme gebildet &#8211; ein durchaus h\u00e4ufiger Anwendungsfall. Die Krux: Nutzt man eine Zeilenbasierte Datenbank wie MySQL, muss man immer die kompletten Datenbankzeilen von der Festplatte einlesen, um die zwei Spalten Menge und Preis miteinander zu multiplizieren. Die Spalten Einheit, Artikelnummer, Beschreibung, MwSt-Satz usw. h\u00e4ngen einfach am Datensatz &#8220;mit dran&#8221;.<\/p>\n\n\n\n<p>Spaltenbasierte Speicher haben dieses Problem nicht. In einem spaltenbasierten Speicher werden alle Spalten separat voneinander im Speicher aufbewahrt. Das macht das Auslesen einer einzelnen &#8220;Komplett&#8221;-Zeile zwar etwas langsamer, die Gesamtperformance des Systems steigt aber im Verh\u00e4ltnis dazu st\u00e4rker.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Spaltenbasierte Datenbanken erlauben auch Komprimierung und Optimierung<\/h2>\n\n\n\n<p>W\u00e4hrend Datenbank-Zeilen sehr komplex aufgebaut sind &#8211; eine Datenbank-Zeile hat etliche Spalten und jede Spalte kann einen anderen Datentyp haben &#8211; sind spaltenbasierte Speicher einfacher aufgebaut: Man hat einfach eine riesige homogene Liste von Zahlen.<\/p>\n\n\n\n<p>Das macht das Rechnen mit gro\u00dfen Datenmengen einfacher. So k\u00f6nnen zum Beispiel Zahlen &#8220;Bit-komprimert&#8221; werden, das hei\u00dft: Enth\u00e4lt die Spalte nur Nullen und Einsen, braucht man keine 64 Bit, sondern nur ein einziges Bit, um die Zahl darzustellen. <strong>Eine Speicher-Ersparnis um das 64-fache!<\/strong><\/p>\n\n\n\n<p>F\u00fcr Zeichenketten (Strings) gilt dasselbe: Sie k\u00f6nnen &#8220;W\u00f6rterbuch-komprimiert&#8221; werden. Enth\u00e4lt die Spalte Geschlecht zum Beispiel nur abwechselnd die Werte &#8220;m\u00e4nnlich&#8221; und &#8220;weiblich&#8221;, speichern traditionelle Datenbanken die komplette Zeichenkette ab. Mit einer W\u00f6rterbuch-Komprimierung w\u00fcrde man jedem Wort eine Zahl zuweisen und k\u00f6nnte die Werte mit einem Speicherverbrauch von 1 Bit pro Wert abspeichern, anstatt mit 8 Bytes. <strong>Eine Ersparnis vom 256-fachen!<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Die Balance zwischen OLAP und OLTP<\/h2>\n\n\n\n<p>Bei OLTP-Arbeitslasten haben zeilenbasierte Speicher hingegen weiterhin die Nase vorn. Eine typische OLTP-Anfrage w\u00e4re zum Beispiel das Anlegen eines neuen Datensatzes oder das ver\u00e4ndern eines einzelnen Datums. <\/p>\n\n\n\n<p>In einer zeilenbasierten Datenbank \u00e4ndert man nur die eine Zeile &#8211; nutzt man hingegen einen bereits komprimierten Spalten-Speicher, kann es sein, dass man die komplette Komprimierung aufl\u00f6sen muss, den Speicher neu alloziieren und den kompletten Spaltenspeicher neu aufbauen muss.<\/p>\n\n\n\n<p>Doch daf\u00fcr gibt es auch eine L\u00f6sung: Man kombiniert einfach beide Welten.<\/p>\n\n\n\n<p>Im sogenannten <strong>Stammspeicher<\/strong> (engl. &#8220;<strong>Main Storage<\/strong>&#8220;) werden die alten unver\u00e4nderten Daten spaltenbasiert abgelegt. Der Stammspeicher ist performant f\u00fcr Statistiken einsetzbar und \u00e4ndert sich nie. Im Stammspeicher werden auch Indizes gebildet, um Daten schneller suchen zu k\u00f6nnen.<\/p>\n\n\n\n<p>Im <strong>\u00c4nderungsspeicher<\/strong> (engl. &#8220;<strong>Delta Storage<\/strong>&#8220;) hingegen speichert man die L\u00f6sch-Markierungen, sowie die zeilenbasierten neuen oder ver\u00e4nderten Datens\u00e4tze. Das Einf\u00fcgen in den \u00c4nderungsspeicher geht dabei sehr schnell, da man keine Komprimierung anwendet.<\/p>\n\n\n\n<p>In einem gewissen Intervall &#8220;verfestigt&#8221; man anschlie\u00dfend die \u00c4nderungen aus dem \u00c4nderungsspeicher, indem man einen <strong>neuen Stammspeicher <\/strong>aus dem alten Stammspeicher und dem \u00c4nderungsspeicher aufbaut. Somit hat man &#8211; wenn das Intervall 15 Minuten betr\u00e4gt &#8211; sp\u00e4testens nach 15 Minuten f\u00fcr alle neuen Daten die volle OLAP-Performance, w\u00e4hrend man trotzdem mit voller Performance OLTP-Arbeitslasten in den \u00c4nderungsspeicher schreiben kann.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">OLAP-Lasten durch verteiltes Rechnen z\u00e4hmen<\/h2>\n\n\n\n<p>Ein gro\u00dfer Nutzer von OLAP-Datenbanken sind sogenannte <strong>BI-Tools<\/strong> (Business Intelligence). Diese Programme erlauben das Analysieren und Durchforsten von Daten. Die Problematik hier: Je mehr Daten anfallen, desto langsamer wird die Analytik. Ein Klick im BI-Programm dauert dann mehrere Sekunden bis hin zu Minuten oder Stunden. <\/p>\n\n\n\n<p>Allerdings ist hier Abhilfe m\u00f6glich: Analytische Datenbank-Anfragen lassen sich sehr leicht parallelisieren. Anstatt dass eine CPU die Summe \u00fcber alle Datens\u00e4tze bildet, kann man den Speicher zum Beispiel auf 8 verschiedene Rechenknoten aufteilen. Das Kommando zum Errechnen der Summe verteilt man dann auf alle 8 Knoten und errechnet das Ergebnis dann aus den 8 Teilsummen.<\/p>\n\n\n\n<p>Will man zum Beispiel, dass jeder Klick im BI-Tool nicht l\u00e4nger als 100ms Rechenzeit in Anspruch nimmt, kann man genau errechnen, wie gro\u00df das Verh\u00e4ltnis von RAM zu CPU-Kernen sein muss. So k\u00f6nnte man alle 1 GiB RAM dann einen CPU-Kern dazustellen.<\/p>\n\n\n\n<p>In Produkten gesprochen, w\u00fcrde man beispielsweise einen Mini-Server aus einem Raspberry Pi mit 4 Kernen und 8 GiB RAM f\u00fcr die ersten 8 GiB Daten in der Datenbank verkaufen. Sobald der Nutzer mehr als 8 GiB Daten hat, kauft er einen zweiten Mini-Server und so weiter &#8211; damit steht f\u00fcr eine definierte Menge Speicher immer ausreichend Rechenzeit zur Verf\u00fcgung, um den Speicher auch &#8220;verarbeiten&#8221; zu k\u00f6nnen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Datenbanken neu denken<\/h2>\n\n\n\n<p>Neben den \u00dcberlegungen zur bestm\u00f6glichen Speicherung, Komprimierung und Parallelisierung, soll auch die Kommunikation mit der Au\u00dfenwelt etwas \u00fcberdacht werden.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignright size-full\"><a href=\"https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/memcp-logo.png\"><img loading=\"lazy\" decoding=\"async\" width=\"256\" height=\"216\" src=\"https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/memcp-logo.png\" alt=\"\" class=\"wp-image-4842\"\/><\/a><\/figure><\/div>\n\n\n<p>Die meisten Datenbanken haben ein <strong>SQL<\/strong>-Frontend, damit die Anwendung mit dem Storage kommunizieren kann. Es gibt aber auch andere Anfragesprachen, wie zum Beispiel <strong>SPARQL<\/strong>, einer Sprache, mit der man RDF-Daten aus dem semantischen Web abfragen kann. Mit dieser graphbasierten Anfragesprache ist es m\u00f6glich, zum Beispiel Wiki-Daten abzufragen &#8211; beispielsweise die Namen aller Hauptst\u00e4dte mit mehr als 1 Mio Einwohner, die sich in einem Land mit der Regierungsform Demokratie befinden. Auch diverse NoSQL-Datenbanken haben jeweils ihre komplett eigenen Anfragesprachen.<\/p>\n\n\n\n<p>Momentan war es so, dass solche alternativen Datenbanken von Grund auf programmieren m\u00fcsste, da es keine einheitliche Storage-Engine gibt. Mit memcp wird das anders:<\/p>\n\n\n\n<p>memcp implementiert zuerst eine spaltenbasierte Storage-Engine, die man mit einer einfachen Schnittstelle auslesen und mit Daten bef\u00fcllen kann. Gleichzeitig fungiert die memcp als HTTP-Server und nimmt Anfragen entgegen. Je nach Plugin kann man nun beliebige Endpunkte an dem HTTP-Server etablieren, die auf die Daten zugreifen k\u00f6nnen.<\/p>\n\n\n\n<p>So k\u00f6nnte ein SQL-Endpunkt eingehende SQL-Anfragen in die interne Anfragesprache \u00fcbersetzen und die Ergebnisse zeilenweise zur\u00fcckgeben. Selbiges ist auch f\u00fcr die SPARQL-Anfragesprache m\u00f6glich.<\/p>\n\n\n\n<p>Gleichzeitig k\u00f6nnte man aber bereits komplette REST-APIs direkt in der Datenbank programmieren. Damit w\u00fcrde die Prozesstrennung zwischen Anwendung und Datenbank wegfallen, womit man nochmals eine deutliche Performance-Steigerung erreichen kann &#8211; gerade wenn die Datenbank-Daten sehr eng mit &#8220;spezielleren Algorithmen&#8221; &#8211; z.B. einer KI &#8211; verkn\u00fcpft sind.<\/p>\n\n\n\n<p>Arbeitspferd ist hier die altbew\u00e4hrte funktionale Programmiersprache Scheme, ein LISP-Dialekt, der sich durch seine Einfachheit und Erweiterbarkeit auszeichnet. Wir haben in der <code>memcp<\/code> sogar eine Serialisierungsroutine f\u00fcr Scheme entwickelt, sodass man Rechenaufgaben mitten in der Berechnung abbrechen, \u00fcbers Netzwerk versenden und auf dem n\u00e4chsten Rechner weiterrechnen k\u00f6nnte.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n\n\n<p>memcp wird die Welt der In-Memory-Datenbanken zwar nicht revolutionieren &#8211; das hat schon das propriet\u00e4re Projekt &#8211; es wird aber die Technologie auch f\u00fcr freie Anwendungen \u00f6ffnen und damit die Menschheit voran bringen. Und nat\u00fcrlich &#8211; (und das ist jetzt mein pers\u00f6nlicher Antrieb) &#8211; dem Hauptkonkurrenten der Launix seinen Wettbewerbsvorteil zu rauben.<\/p>\n\n\n\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>In den letzten 13 Jahren gab es eine Menge Innovationen im Bereich spaltenbasierte Datenbanken. Zu verdanken ist das vor allem einem deutschen ERP-Hersteller, der sich entschieden hat, sich vom Datenbank-Marktf\u00fchrer abzusetzen und sein eigenes Ding zu machen. Es wurde zu einer Erfolgsstory. Zeit, dass OpenSource nachzieht.<\/p>","protected":false},"author":2,"featured_media":4828,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":4,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_uag_custom_page_level_css":"","footnotes":""},"categories":[129],"tags":[],"class_list":["post-4823","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-memcp","single-item"],"featured_image_urls_v2":{"full":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920.jpg",1920,1272,false],"thumbnail":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920-150x150.jpg",150,150,true],"medium":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920-300x199.jpg",300,199,true],"medium_large":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920-768x509.jpg",751,498,true],"large":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920-1024x678.jpg",751,497,true],"1536x1536":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920-1536x1018.jpg",1536,1018,true],"2048x2048":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920.jpg",1920,1272,false],"trp-custom-language-flag":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920.jpg",18,12,false],"xs-thumb":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920-64x64.jpg",64,64,true],"appku-shop-single":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920.jpg",620,411,false]},"post_excerpt_stackable_v2":"<p>In den letzten 13 Jahren gab es eine Menge Innovationen im Bereich spaltenbasierte Datenbanken. Zu verdanken ist das vor allem einem deutschen ERP-Hersteller, der sich entschieden hat, sich vom Datenbank-Marktf\u00fchrer abzusetzen und sein eigenes Ding zu machen. Es wurde zu einer Erfolgsstory. Zeit, dass OpenSource nachzieht. In der kommerziellen Datenbank-Welt haben sich spaltenbasierte Datenbanken bereits l\u00e4ngst durchgesetzt. Die OpenSource-Welt hinkt unterdes immer noch mit MariaDB und PostgreSQL hinterher. Das behindert nicht nur OpenSource-Projekte, sondern s\u00e4mtliche Produkte, die auf OpenSource-Datenbanken setzen. Aus diesem Grund stellen wir in diesem Artikel die memcp vor, eine spaltenbasierte In-Memory-Datenbank, die sowohl OLAP, als auch OLTP-Arbeitslasten&hellip;<\/p>\n","category_list_v2":"<a href=\"https:\/\/launix.de\/launix\/en\/category\/memcp\/\" rel=\"category tag\">MemCP<\/a>","author_info_v2":{"name":"Carl-Philip H\u00e4nsch","url":"https:\/\/launix.de\/launix\/en\/author\/carli\/"},"comments_num_v2":"0 comments","uagb_featured_image_src":{"full":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920.jpg",1920,1272,false],"thumbnail":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920-150x150.jpg",150,150,true],"medium":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920-300x199.jpg",300,199,true],"medium_large":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920-768x509.jpg",751,498,true],"large":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920-1024x678.jpg",751,497,true],"1536x1536":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920-1536x1018.jpg",1536,1018,true],"2048x2048":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920.jpg",1920,1272,false],"trp-custom-language-flag":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920.jpg",18,12,false],"xs-thumb":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920-64x64.jpg",64,64,true],"appku-shop-single":["https:\/\/launix.de\/launix\/wp-content\/uploads\/2023\/01\/mountains-3048299_1920.jpg",620,411,false]},"uagb_author_info":{"display_name":"Carl-Philip H\u00e4nsch","author_link":"https:\/\/launix.de\/launix\/en\/author\/carli\/"},"uagb_comment_info":0,"uagb_excerpt":"In den letzten 13 Jahren gab es eine Menge Innovationen im Bereich spaltenbasierte Datenbanken. Zu verdanken ist das vor allem einem deutschen ERP-Hersteller, der sich entschieden hat, sich vom Datenbank-Marktf\u00fchrer abzusetzen und sein eigenes Ding zu machen. Es wurde zu einer Erfolgsstory. Zeit, dass OpenSource nachzieht.","_links":{"self":[{"href":"https:\/\/launix.de\/launix\/en\/wp-json\/wp\/v2\/posts\/4823","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/launix.de\/launix\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/launix.de\/launix\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/launix.de\/launix\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/launix.de\/launix\/en\/wp-json\/wp\/v2\/comments?post=4823"}],"version-history":[{"count":9,"href":"https:\/\/launix.de\/launix\/en\/wp-json\/wp\/v2\/posts\/4823\/revisions"}],"predecessor-version":[{"id":5992,"href":"https:\/\/launix.de\/launix\/en\/wp-json\/wp\/v2\/posts\/4823\/revisions\/5992"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/launix.de\/launix\/en\/wp-json\/wp\/v2\/media\/4828"}],"wp:attachment":[{"href":"https:\/\/launix.de\/launix\/en\/wp-json\/wp\/v2\/media?parent=4823"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/launix.de\/launix\/en\/wp-json\/wp\/v2\/categories?post=4823"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/launix.de\/launix\/en\/wp-json\/wp\/v2\/tags?post=4823"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}