Column Stores

42
Column Stores Arno Schmidhauser Letzte Revision: Januar 2011

Transcript of Column Stores

Page 1: Column Stores

Column Stores

Arno SchmidhauserLetzte Revision: Januar 2011

Page 2: Column Stores

Neues technisches Umfeld• RAM Zugriff: 1 GB/sec Random (Seek Time 1-3 nsec, 3-6 Bus-

Cycles, 64 Byte Block), 10 GB/sec Maximum(Peak) • Diskzugriff: 1 MB/sec Random (Seek Time 1 msec, 1 KB Block),

100 MB/sec Stream.• Sehr performante Vektorverarbeitung in modernen CPU's mit

mehreren Cache-Levels.• Das Absuchen eines Vektors mit 106 Datensätzen à 10 Bytes

dauert ca 0.01sec bei 1GB/sec, 0.001sec bei 10 GB/sec.• Verfügbares Memory problemlos > 4 GB für Standard Server.• Memory hat kleinere Random/Stream Problematik, Durchsatz ist

unabhängiger vom Ort der Daten im Ggs. zu Disk.

Page 3: Column Stores

Neue Anfragetypen

Früher vorallem OLTP

select * from Bestellungwhere id = 4711

insert into Bestellungvalues (…)

datensatzweise Abfragen

Heute zunehmend OLAP

select avg( betrag )from Bestellung

spaltenweise Abfragen

Page 4: Column Stores

Leseoperation überwiegen

• Frühe Annahme: Einfügen, Ändern, Löschen machen einen relevanten Anteil der Datenbankoperationen aus.

• Neue Untersuchungen: Selbst bei OLTP-Systemen überwiegen heute die AnzahlLeseoperationen deutlich.

Page 5: Column Stores

Viele Spalten mit wenig Werten

• Sehr viele Spalten in Datenbanksystem enthalten tatsächlich nur wenig verschiedene Werte.

• Beispiel: 29% aller Spalten (Attribute) enthalten lediglich 2 bis 32 verschiedene Werte.

Page 6: Column Stores

Column Stores, wofür?

• Für viele Anwendungen ist die Architektur klassischer Datenbanksysteme nicht optimal. Der Datensatz als logische und technische Einheit ist nicht immer sinnvoll.

• Column Stores sind eine neue technologische Richtung. Im Fokus steht dabei:– Leseoperationen überwiegen gegenüber Änderungen.– Abfragen überstreichen oft einen grossen Teil der

vorhanden Daten. – Spaltenorientierte Abfragen überwiegen.– Ganze Spalten oder ganze DB wird im Speicher gehalten.– Vorallem numerische und kleine Datentypen, wenig

Strings.

Page 7: Column Stores

Zeilenspeicherung

• Die klassische Datenbank-Technologie geht von OLTP-Applikationen aus:

1. Datensatzorientierte Speicherung2. Sequentielle Anhäufung von Datensätzen3. Seitenorientierte Zusammenfassung von Datensätzen

Page 1 (Disk und Memory)

Datensatz 1 Date-

satz 2 Datensatz 3

Datensatz 4 Datensatz

5 Datensatz 6

Datensatz 7 Datensatz 8

Page 2 (Disk und Memory)

Datensatz 9 Date-

satz 10 Datensatz 11

Datensatz 12 Datensatz

1 3 Datensatz 14

Datensatz 15 Datensatz 16

Page 8: Column Stores

Spaltenspeicherung

• Wenn OLAP-Anfragen dominieren, sind spaltenorientierte Speichertechnologieneffizienter:

• Nur benötigte Spalten ins Memory laden,dafür Spalte in der ganzen Länge.

• Effiziente Aggregatbildung.• Zugehörigkeit eines Attributwertes

in einer Spalte zu einem Datensatz:1. duch die Position (Array)2. durch einen Schlüssel (ObjectId, RecordId)

Spa

lte A

Spa

lte B

Spa

lte C

Datensatz 1 w1 w1 w1Datensatz 2 w2Datensatz 3 w3 w2Datensatz 4 w4 w2Datensatz 5 w5 w3

w4 w3

w5w4

w5

Page 9: Column Stores

Zeilen- und Spaltenspeicherung

Spa

lte A

Spa

lte B

Spa

lte C

Spa

lte D

Spa

lte E

Spa

lte N

Datensatz 1Datensatz 2Datensatz 3Datensatz 4Datensatz n

effizient

Datensatz 1Datensatz 2Datensatz 3Datensatz 4Datensatz n

ineffizient

inef

fizie

ntef

fizie

nt

Spaltenorientierte Speicherung

Datensatzorientierte Speicherung

OLT

PO

LAP

Page 10: Column Stores

Komprimierung

• Ein wesentlicher Vorteil von Column-Stores liegt darin, dass Spalten oft eine hohe Anzahl gleicher Werte enthalten.

• Komprimierung der Daten auf der Disk beschleunigt das Laden und Speichern der Datenbank bei den Checkpoints.

• In der Regel heute im Memory dekomprimiert.• Neueste Entwicklungen jedoch so, dass Daten auch im

Memory komprimiert abgelegt sind, und erst für die Verarbeitung in der CPU (Level 2 Cache) dekomprimiert werden.

Page 11: Column Stores

Run Length Encoding

• Sehr effizient für sortierte Spalten, Beispiel:

1 1;51 3;21 10;511331010101010

Quantity(Wert;Anzahl)

Quantityunkompr.

Page 12: Column Stores

Delta Encoding

• Variante 1: Numerische Werte werden als Differenz zum kleinsten Wert codiert.

• Variante 2: Numerische Werte werden als Differenz zum jeweils vorhergehenden Wert dargestellt.

Page 13: Column Stores

Bit Vector Encoding

• für Spalten mit wenigverschiedenen Werten,z.B. Geschlecht, Wochentag, Land, Status usw.

Bit Vektor Werte1000000 Montag0100000 Dienstag0010000 Mittwoch0001000 Donnerstag0000100 Freitag0000010 Samstag0000001 Sonntag

Tabelle mit Bit Vektor WertenWochenTag Artikel ID Kunden ID Menge

0000001 43 4711 1.000000010 56 4711 2.000000100 43 6900 1.00

Bit Vektor Index0000001 heisst: Datensatz 1 hat den Wert 00000010000010 heisst: Datensatz 2 hat den Wert 00000100000100 heisst: Datensatz 3 hat den Wert 0000100

Page 14: Column Stores

Dictionary Encoding

• Lange und wiederholt vorkommende Werte werden in einen Dictionary ausgelagert:

• Wird z.B. auch bei der XML Speicherung für Element-namen verwendet!

DokumentURL Begriff ID

ti.bfh.ch Studiumti.bfh.ch Bachelor

hkb.bfh.ch Studiumhkb.bfh.ch Kunst

Dokument DictionaryURL dict ID dict ID Begriff

ti.bfh.ch 1 1 Studiumti.bfh.ch 2 2 Bachelor

hkb.bfh.ch 1 3 Kunsthkb.bfh.ch 3

Page 15: Column Stores

Indexierungsstrategie

• Bei klassischen Datenbanken werden alle Index auf Disk gespeichert. Indexstrukturen können grösser als die Datenbank selbst sein, oft sogar bis Faktor 10.

• Column Stores und In Memory Datenbank halten Indexe nur im Memory. Indexe unterliegen keinem Recovery bei einem System Crash, sondern werden neu gebaut.

• Indexzugriffe erfordern bei Column Stores nie Disk-I/O. Indexe referenzieren nur Memory-Adressen oder Arraypositionen in Spalten, jedoch keine externen Datensatz ID's, Primary Keys o.ä.

Page 16: Column Stores

Produktbeispiel MonetDB

• Open Source, Enge Zusammenarbeit mit Open Source Datawarehouse Tools von Pentaho.

• SQL 93 kompatibel.• ACID kompatibel, Snapshot-Isolation.• Schnelles Erzeugen und Laden von Spalten-Files mit COPY

Utility.• Extrem schnell bei spaltenorientierten Abfragen (Bis zu

Faktor 100 gegenüber mySQL).• Performance bezüglich Einfügen, Ändern, Löschen mit SQL

ist kritisch, da bei Checkpoints ganze Spalten-Files geschrieben werden.

• Kommerzielle Weiterentwicklung im Rahmen von Ingres Vectorwise.

Page 17: Column Stores

Tabellen, Aufspaltung in Spalten

• Originale Tabelle

• Pro Attribut eine binäre Relation (BAT)im Memory mit Objekt-ID's und Attributwerten

• Binary Association Tables (BATs) sind die Grundstruktur der Tabellenspeicherung in MonetDB (und anderen ColumnStores)

Page 18: Column Stores

Binary Association Table (BAT)

Hash Zugriff mit OID als Schlüssel

Memory Mapped File (.tail)Kompression auf Disk, um I/O zu vermindern.

Kompressiosnsvarianten siehe weiter unten

Werden beim Laden erzeugt

Page 19: Column Stores

Indexierung

• Beim ersten Zugriff auf ein Attribut wird eine Kopie seiner BAT erstellt. Diese Kopie wird als Index nachgeführt und schrittweise verfeinert, z.B. bei der ersten Abfrage wie folgt:

> 0.1

≤ 0.1

select … from Discount where Discount > 0.1

Kopie

Page 20: Column Stores

Einfaches Query

• Abfrage:

select * from Discount where Discount > 0.1

• Ausführung:

1. Sequentielles Scannen der Discount-BAT: alle OID's suchen, für die Discount > 0.1.

2. Mit den OID's in den übrigen BATs die anderen Attribute des Datensatzes suchen.

Page 21: Column Stores

Aggregat Query

• Abfrage:

select Day, avg(Discount) from Discountwhere Discount = 0.065 and Day = '9/4/98'

• Ausführung ohne Index:

1. Spalten sequentiell scannen und je einen Bit-Vektor bilden: 1 = Bedingung erfüllt, 0 = Bedingung nicht erfüllt.

2. and-Verknüpfung der beiden Bit-Vektoren durchführen.3. Korrespondierende Array-Positionen in der Day- und

Discount-BAT entnehmen, avg() bilden und ausgeben.

Page 22: Column Stores

Aggregat Query

select Day, avg(Discount) from Discountwhere Discount = 0.065 and Day = '9/4/98'

01000

01001

01000

AND

Page 23: Column Stores

Aggregat Query mit Joins

• Beispiel einer Join-Abfrage

select o.year, sum(o.quantity)from Order o, Customer c, Product pwhere o.custID = c.custID and o.prodID = p.prodIDand p.name = 'P1'and c.region = 'europe'group by o.year

• Im folgenden soll die spaltenorientierte Verarbeitung dieser Abfrage gezeigt werden.

Page 24: Column Stores

Join, Tabellen

OrdercustID prodID year quantity

1 1 2009 101 5 2010 102 1 2009 10003 1 2009 5003 4 2009 5003 2 2010 5002 1 2007 100

CustomercustID name region

1 C1 europe2 C2 europe3 C3 asia4 C4 asia5 C5 pacific

ProductprodID name

1 P12 P23 P34 P45 P5

Page 25: Column Stores

Join, Spalten

• Achtung: Die Datenbank besteht physisch aus einer Sammlung von Spalten (BATs in MonetDB)

OID o.custID OID o.prodID OID o.year OID o.quantity1001 1 1001 1 1001 2009 1001 101002 1 1002 5 1002 2010 1002 101003 2 1003 1 1003 2009 1003 10001004 3 1004 1 1004 2009 1004 5001005 3 1005 4 1005 2009 1005 5001006 3 1006 2 1006 2010 1006 5001007 2 1007 1 1007 2007 1007 100

BAT BAT BAT BAT

OID c.custID OID c.name OID c.region OID p.prodID OID p.name101 1 101 C1 101 europe 201 1 201 P1102 2 102 C2 102 europe 202 2 202 P2103 3 103 C3 103 asia 203 3 203 P3104 4 104 C4 104 asia 204 4 204 P4105 5 105 C5 105 pacific 205 5 205 P5

BAT BAT BATBAT BAT

Page 26: Column Stores

Join, Ablauf, Schritt 1 und 2

c.region = 'europe'BV1 TB1

OID c.region Bit OID c.custID custID101 europe 1 101 1 1102 europe 1 102 2 2103 asia 0 103 3104 asia 0 104 4105 pacific 0 105 5

p.name = 'P1'BV2 TB2

OID p.name Bit OID p.prodID prodID201 P1 1 201 1 1202 P2 0 202 2203 P3 0 203 3204 P4 0 204 4205 P5 0 205 5

Page 27: Column Stores

Join, Ablauf Schritt 1 und 2

Operation Algorithmus Resultat

c.region = 'europe' auswerten

linearer Scan über c.region (Verbesserung für Stringdaten:Indexzugriff, Dictionary Lookup, Komprimierte Daten usw.)

BV1: Bit Vektor, ermittelt über c.region, welcher pro Position in der Customer Tabelle angibt, ob der Datensatz die Bedingung erfüllt.

BV1 auf c.custID anwenden Scan über BV1 und c.custID, jeweils in beiden Vektoren Position für Position vorrücken, da beide gleichviele Einträge haben. Alle custID entnehmen, welche an entsprechender Positione im Bit Vektor eine 1 haben.

TB1: Temoräre BAT mit allen custID. CustID als Hashkey

p.name = 'P1' auswerten linearer Scan über p.name (Verbesserung

für Stringdaten:Indexzugriff, Dictionary Lookup, Komprimierte Daten usw.)

BV2: Bit Vektor, ermittelt über c.region, welcher pro Position in der Product Tabelle angibt, ob der Datensatz die Bedingung erfüllt

BV2 auf p.prodID anwenden Scan über BV2 und p.prodtID, jeweils in beiden Vektoren Position für Position vorrücken, da beide gleichviele Einträge haben. Alle prodID entnehmen, welche an entsprechender Positione im Bit Vektor eine 1 haben.

TB1: Temoräre BAT mit allen prodID. ProdID als Hashkey

Page 28: Column Stores

Join-Ablauf, Schritt 3 bis 7TB1 1

custID 2

BV3OID o.custID Bit

1001 1 11002 1 11003 2 11004 3 01005 3 0 BV41006 3 0 Bit OID o.year OID o.quantity1007 2 1 1 1001 2009 1001 10

0 1002 2010 1002 101 1003 2009 1003 1000

AND Verknüpfung 0 1004 2009 1004 500TB2 1 0 1005 2009 1005 500

prodID 0 1006 2010 1006 5001 1007 2007 1007 100

BV4OID o.prodID Bit OID o.year

1001 1 1 1001 20091002 5 0 1003 20091003 1 1 1007 20071004 1 11005 4 01006 2 0 o.year1007 1 1 2009

2007

Scan über o.custID mit Lookup in TB1. Wenn custID in TB1 vorkommt, dann in BV3 1 eintragen.

o.quantity1010100

1000100

Aus den BATs o.year und o.quantity Zeilen gemäss Bit Vektor BV4 entnehmen.

Gruppiert = Sortiert und zusammen-gefasst, z.B. über Merge-Sort

o.quantity10

Scan über o.prodID mit Lookup in TB2. Wenn custID in TB2 vorkommt, dann in BV4 1

Page 29: Column Stores

Join-Ablauf, Schritt 3 bis 7

c.region = 'europe' auswerten linearer Scan über c.region (Verbesserung für Stringdaten:Indexzugriff, Dictionary Lookup, Komprimierte Daten usw.)

BV1: Bit Vektor, ermittelt über c.region, welcher pro Position in der Customer Tabelle angibt, ob der Datensatz die Bedingung erfüllt.

BV1 auf c.custID anwenden Scan über BV1 und c.custID, jeweils in beiden Vektoren Position für Position vorrücken, da beide gleichviele Einträge haben. Alle custID entnehmen, welche an entsprechender Positione im Bit Vektor eine 1 haben.

TB1: Temoräre BAT mit allen custID. CustID als Hashkey

p.name = 'P1' auswerten linearer Scan über p.name (Verbesserung für Stringdaten:Indexzugriff, Dictionary Lookup, Komprimierte Daten usw.)

BV2: Bit Vektor, ermittelt über c.region, welcher pro Position in der Product Tabelle angibt, ob der Datensatz die Bedingung erfüllt

BV2 auf p.prodID anwenden Scan über BV2 und p.prodtID, jeweils in beiden Vektoren Position für Position vorrücken, da beide gleichviele Einträge haben. Alle prodID entnehmen, welche an entsprechender Positione im Bit Vektor eine 1 haben.

TB1: Temoräre BAT mit allen prodID. ProdID als Hashkey

Vergleich o.custID mit Einträgen in TB1 Scan über o.custID, lookup jeder custID in TB1 BV3: Bit Vektor, welcher pro Eintrag in o.custID angibt, ob die entsprechende custID in TB1 vorkommt.

Vergleich o.prodID mit Einträgen in TB2 Scan über o.prodID, lookup jeder custID in TB2 BV4: Bit Vektor, welcher pro Eintrag in o.custID angibt, ob die entsprechende custID in TB2 vorkommt.

AND Verknüpfung auswerten AND Verknüpfung von BV3 und BV4 BV5: Bit Vektor, welcher pro Eintrag für Tabelle Order angibt, ob er den Bedingungen c.region = 'europe' und p.name = 'P1' genügt.

� BV5 auf o.year anwenden linearer Scan über BV5 und o.year TB3: Temporäre BAT mit year

BV5 auf o.quantity anwenden linearer Scan über BV5 und o.quantity TB4: Temporäre BAT mit quantity

Algorithmus zum Gruppieren anwenden

Verbund von TB3 und TB4 TB5: Temporäre BAT mit 2 Attributen (year, quantity)

TB5 sortieren nach year, summieren von quantity

Irgendeine Gruppier-Algorithmus, z.B. Sortieralgorithmus, z.B. Merge-Sort, dann zusammenfassen.

Ausgabe von year und sum(quantity)

Page 30: Column Stores

Produktbeispiel Ingres Vectorwise

• kommerzielles Produkt. 64 Bit auf Windows, Linux und als Amazon Webservice (Amazon Machine Image).

• Datensätze, resp. Werte in den Spalten werden in Einfügereihenfolge gespeichert (RAW Mode).

• Parameter block_size definiert Blockgrösse, die für das Ablegen von Spalten benützt werden. Ein Block ist die I/O Einheit zur Disk. Jeder Block beinhaltet Statistikangaben, z.B. grösster und kleinster Spaltenwert.

• Blöcke werden komprimiert. Datenbank bestimmt automatisch Algorithmus pro Block: Run Length Encoding, Dictionary Encoding und Delta Encoding.

Page 31: Column Stores

Produktbeispiel Ingres Vectorwise

• Von jedem Datenblock einer Spalte wird der Minimum und Maximumwert im Memory gehalten ("Index" ).

• Jede Tabellen kann einen Clustered Index haben (create index Befehl). Keine anderen Indexe sind möglich.

• Indexstrukturen werden ausschliesslich im Memory gehalten (Bei Crash zerstört).

• Änderungen werden über Positional Delta Trees verwaltet. Bei einem bestimmtem Umfang an Änderungen wird die gesamte DB auf Disk propagiert (Checkpoint).

Page 32: Column Stores

Änderungen in Column Stores

• Einfügen/Ändern/Löschen in Column Stores werden als "notwendiges Übel" angesehen, im Gegensatz zur klassischen DB-Technologie.

Änderungen über eine bestimmte Zeit hinweg in einer "Delta-Struktur" sammeln.Bei Checkpoint anwenden auf Hauptstruktur der Datenbank.

HauptstrukturDisk/Memory

Spalte/Datensatz

Delta-Struktur (Änderungen)

Nach Checkpoint

A a einfügen aB a einfügen aC a einfügen aD d einfügen AE B ändern auf b bF C löschen d

DEF

Page 33: Column Stores

Positional Delta Tree, PDT

• Der Positional Delta Tree ist eine hocheffiziente Delta-Struktur, damit beim Lesen von Spalten auch Änderungen miteinbezogen werden.

• Ausgangslage:– Spalten (oder Datensätze) liegen in einer bestimmten

Sortierung vor, die bei Abfragen verwendet wird.– Die Sortierung von Spalten und Datensätzen muss

daher zusammen mit der Delta-Struktur jederzeit rekonstruiert werden können.

– Die Delta-Struktur darf Abfragen nur minimal verlangsamen.

Page 34: Column Stores

PDT-Beispiel, Tabelle

• Die SID ist die Position des Datensatzes, respektive der Spaltenwerte, auf Disk oder im Memory, wenn noch keine Änderungen stattgefunden haben.

Sortier-Schlüssel, physische Reihenfolge

Page 35: Column Stores

PDT-Beispiel, Änderungsbefehle

• Folgende Änderungen sollen nun vorgenommen werden:

1. INSERT INTO inventory VALUES ('Berlin','table','Y',10)2. INSERT INTO inventory VALUES ('Berlin','cloth','Y',5)3. INSERT INTO inventory VALUES ('Berlin','chair','Y',20)4. INSERT INTO inventory VALUES ('Paris','sofa','Y',3)5. UPDATE inventory SET qty=13 WHERE store='London' AND

product='stool'6. DELETE FROM inventory WHERE store='London' AND product='table'

Page 36: Column Stores

Durch die Änderungen erzeugter PDT

Page 37: Column Stores

PDT-Beispiel, neue Tabelle

• Die nach dem Checkpoint erzeugte Tabelle sieht wie folgt aus:

Page 38: Column Stores

Mehrschichtige Deltastruktur

• Delta-Strukturen können auch zur Realisierung von Snapshot-Isolation verwendet werden.

• Für jede neue Transaktion: Datenbankweite Delta-Struktur für die Transaktion kopieren, und mit Zeitstempel resp. Versionennummer der Transaktion versehen.

• Transaktion arbeitet mit der kopierten Delta-Struktur lokal für sich weiter.

• Beim Commit: lokale Delta-Struktur der Datenbank übergeben. Diese gleicht mit der datenbankweiten Delta-Struktur ab (Siehe Versionenverfahren für Concurrency Control).

Page 39: Column Stores

Spaltenspeicherung in klassischen DB's

• Ideen der Spaltenspeicherung zur Abfrage-Beschleunigung existieren bereits in den klassischen Datenbanksystemen. Beispiel mit MSSQL 2008:

create index on Bestellung ( bestDatum )include ( menge )

Das Attribut menge wird damit in den Blattknoten des Index abgelegt. So wird für folgende Abfragen der Zugriff auf die Haupttabelle überflüssig:

select bestDatum, sum( menge )from Bestellunggroup by bestDatum

Page 40: Column Stores

Spaltenspeicherung in klassischen DB's

• Pros: – Perfekt integriert in bestehende DB-Lösung. – 100% unsichtbar gegenüber Applikationen und

Clientsystemen.– Macht das Laden der Basistabelle überflüssig, wenn die

Abfrage aus allen Attributen des Index befriedigt werden kann.

• Cons:– Klassische I/O Technologie: der Index muss zuerst

geladen werden. I/O Pages sind nicht immer garantiert im Memory.

– Index kann andere Daten aus dem Memory verdrängen, da er zusätzlich Platz benötigt.

Page 41: Column Stores

Zusammenfassung Column Stores

• Für grosse Datenbanken mit Schwergewicht OLAP Abfragen.• Abfrage-Performance kann sich um Faktor 100 verbessern,

bei vergleichbarer Hardware.• Schlechtere Update-Performance.• Gute Bulk-Load Performance, da einfache Datenstrukturen

(wenig Indexe). Eignung als Datawarehouse oder Data Mart.

DWH

Data Mart

Quelldaten

Data Mart

QuelldatenQuelldaten

ETL Column Store Load

Page 42: Column Stores

Produkte

• MonetDB • SybaseIQ• Ingres Vectorwise• SyncSort• Vertica• Informatica