<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Cloud-Services und effiziente Anfrageverarbeitung für Linked Open Data</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Heiko Betz</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Kai-Uwe Sattler</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Department of Computer Science and Automation TU Ilmenau</institution>
          ,
          <country country="DE">Germany</country>
        </aff>
      </contrib-group>
      <pub-date>
        <year>2012</year>
      </pub-date>
      <abstract>
        <p>Der Verbreitungsgrad von Linked Open Data hat in den letzten Jahren massiv zugenommen. Stetig erscheinen neue Quellen, die RDF-Daten frei zur Verfugung stellen. Aktuell diskutiert die Bundesregierung uber ein neues Gesetz, welches zur O enlegung von Daten der o entlichen Hand verp ichtet. Durch diese Ma nahme, steigt u. a. die Menge an Linked Open Data sehr schnell an. Es werden neue Verfahren benotigt, die mit sehr vielen RDF-Daten gleichzeitig eine e ziente, skalierbare und mit Garantien versehene Abfrage von Daten mittels SPARQL gewahrleistet. In dieser Arbeit wird ein reines In-Memory Shared-Nothing-System vorgestellt, das die genannten Anforderungen in e zienter Weise erfullt. Hierfur werden verschiedenste Optimierungsma nahmen ergri en, die das Potenzial moderner Hardware umfassend ausnutzen.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>EINFÜHRUNG</title>
      <p>Punkt 1 besitzt mehrere potenzielle Vorteile. Durch die
Verteilung wird ein Single Point of Failure (SPOF) vermieden.
Der Koordinator muss keine Daten speichern, da sie alle
in den Quellen vorliegen. Er muss nur einen geringen
Speicherplatz und nur eine geringe Rechenkapazitat zur
Verfugung stellen. Ein wichtiger Punkt, der fur eine Verteilung der
Quellen spricht, ist, dass die Daten nicht an andere
Unternehmen herausgegeben werden mussen. Es konnen
'Firmengeheimnisse' bewahrt werden. Als Nachteile ergeben sich
jedoch einige Punkte. Die Zerlegung von Anfragen in
Subqueries und alle daraus folgenden Schritte sind ein hoch
komplexes Problem (Parsing, Normalisierung, eingebettete
Anfragen 'herausdrucken', Vereinfachung, Datenlokalisation,
Optimierung). Zwei weiter nicht zu unterschatzende
Nachteile sind die fehlenden Kontroll- und U
berwachungsmechanismen der Quellen. Die Antwortzeit in einem solchen Szenario
ist nach oben unbeschrankt. Es ergibt sich, dass keinerlei
Garantien abgegeben werden konnen. Weiterhin ist durch die
Verteilung das verwendete Schema dem Koordinator
ganzlich unbekannt. Viele Quellen sind zudem nicht in der Lage,
SPARQL-Anfragen zu verarbeiten. Sie liefern nur die
Quellen uber einen Webserver aus. Waren SPARQL-Anfragen
moglich, waren Analyseanfragen a la Data Warehouse-Anfragen
auch nur bedingt moglich.</p>
      <p>Die zentralen Nachteile des Punktes 2 sind die (i.)
benotigte Zeit zum Einsammeln aller Daten, die (ii.) Durchfuhrung
einer Vorberechnung und das Problem, dass niemals
gewahrleistet werden kann, dass (iii.) alle Daten aktuell sind.
Zudem wird (iv.) ein SPOF, sowie ein (v.) extrem hoher
Speicherplatz an einer einzigen zentralen Instanz in Kauf
genommen. Ein weiterer Nachteil beider Falle ist das (vi.)
unbekannte Schema und die (vii.) geringe Datenqualitat. Im
zentralisierten Fall kann jedoch auf die letzten beiden Probleme
e zient reagiert werden, indem entsprechende Indizes
angelegt und/oder verschiedenste Optimierungen durchgefuhrt
werden. Eine entsprechende Datenvorverarbeitung kann
zudem davor gestartet werden, um die Datenqualitat zu
verbessern. Beides wird durch die einheitliche Form der Daten
als reine Tripel unterstutzt. Der gro e Vorteil, der sich aus
dem zentralisierten Ansatz ergibt, ist die Moglichkeit,
Anfragezeiten zu einem bestimmten Prozentsatz zu
gewahrleisten, da sich das gesamte System unter der Kontrolle einer
Instanz be ndet. Weiterhin kann ein Scale-Out (Erhohung
der Speicherkapazitat (v.), Verbesserung der Antwortzeiten)
und eine Replikation (Beseitigung SPOF (iv.), Verbesserung
der Antwortzeiten) angestrebt werden. Zur Verringerung der
Speicherkapazitat (v.) konnen e ziente
Kompressionstechniken verwendet werden, die zugleich lese- und
schreiboptimiert sind, was zu einer weiteren Verringerung des
benotigten Speicherplatzes fuhrt. Durch die Verwendung von push
und Bulk Load-Techniken zur Datenintegration anstelle von
reinen pull-Techniken kann garantiert werden, dass die
abgefragten Daten aktuell (iii.) sind. Das Einsammeln von Daten
ist nur zu Beginn einmal notig, wenn eine neue Datenquelle
erschlossen wird (i. und ii.).</p>
      <p>Der Mechanismus des Scale-Outs und der Replikation
bedingen jedoch, dass eine Zerlegung der Anfrage durchgefuhrt
werden muss. Wobei dieser eine Nachteil durch die oben
genannten Vorteile aufgewogen wird. Insgesamt sprechen viele
Faktoren fur die Verwendung eines zentralisierten Ansatzes.</p>
      <p>Garantien bezuglich den soeben erwahnten
Antwortzeiten sind au erst komplex in ihrer Umsetzung und benotigen
im extremen Fall viele vorallokierte Kapazitaten, die
wahrend normaler Nutzung brachliegen und hohe Kosten
verursachen. Stattdessen werden sie nur wahrend Lastspitzen
benotigt. Folglich werden aus diesem Grund hau g
prozentuale Werte angegeben. Es sollen beispielswei e 99,99 % aller
Anfragen in der maximal erlaubten Zeitspanne beantwortet
werden. Erst ein solches Vorgehen erlaubt es, dass wahrend
einer Lastspitze neue Kapazitaten hinzugenommen werden
konnen (automatisierter Scale-Out). Das Ziel hierbei ist,
zukunftige Anfragen wieder innerhalb der gesetzten
Antwortzeit beantworten zu konnen. Am Ende der Lastspitze
werden die zusatzlich allokierten Ressourcen wieder
freigegeben. Letztendlich werden hierdurch Kosten fur den
Betreiber des Services eingespart. Wichtig zu erwahnen ist, dass
die Garantie bezuglich der Antwortzeit nicht fur jede
beliebige SPARQL-Anfrage garantiert werden kann. Stattdessen
soll dies nur fur "gewohnliche\ Anfragen gelten.</p>
      <sec id="sec-1-1">
        <title>Projektziel.</title>
        <p>Das Ziel dieses Projektes ist es, ein hochverfugbares,
skalierbares und -e zientes System aufzubauen, welches
mehrere hundert Milliarden bzw. mehrere Billionen Tripel von
RDF-Daten in einer materialisierten Form vorhalt. Es soll
hierbei als Framework und nicht als reine Datenablage
angesehen werden. Neben SPARQL-Anfragen soll es den
Benutzer im gesamten Work ow unterstutzen. Unter
Workow werden die Folgenden Operationen verstanden:
Einfugen/Loschen/A ndern von Tripeln sowie die
Abfrage/Analyse von Daten. Unter dem Stichpunkt Analyse fallen
samtliche Data-Mining-Aufgaben, die in einem
Data-WarehouseSzenario moglich sind. Ein weiteres Ziel ist die
Unterstutzung von SLAs. Neben dem Garantieren von maximalen
Antwortzeiten sollen auch Garantien bezuglich der
Verfugbarkeit und der Aktualitat von Daten, sowie einige
andere mehr beachtete werden. Letztendlich soll das System als
ein Cloud-Service fur LOD-Daten propagiert werden. Das
Ziel hierbei ist, Kosten fur den Endbenutzer einzusparen.
Er mochte nur fur den von ihm selbst verursachten Aufwand
bezahlen (Service on Demand). Im alternativen Fall musste
eine eigene Infrastruktur aufgebaut werden, was hau g zu
viel hoheren Kosten fuhrt.</p>
        <p>Diese Arbeit beschaftigt sich mit einem Teil aus dem
soeben beschriebenen Zieles. Es soll ein erster Ansatz fur einen
Datenspeicher fur Linked Open Data aufgezeigt werden, der
mit sehr gro en Datenmengen eine e ziente
Anfrageverarbeitung ermoglicht. Hierfur ist ein zuverlassiges
Scale-OutVerfahren notwendig, welches vorgestellt wird. Des Weiteren
soll das gewahlte Verfahren auf eine wechselnde Anfragelast
reagieren konnen.</p>
      </sec>
    </sec>
    <sec id="sec-2">
      <title>2. STATE-OF-THE-ART</title>
      <p>
        Fur die Verarbeitung von LOD existieren bereits viele
verschiedene Systeme, die RDF-Daten entgegennehmen und
SPARQL-Queries ausfuhren. Einige bekanntere System sind
Virtuoso [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ], MonetDB [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ], Hexastore [
        <xref ref-type="bibr" rid="ref14">14</xref>
        ], Jena [
        <xref ref-type="bibr" rid="ref15">15</xref>
        ] und
RDF-3X [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ]. Virtuoso ist ein weitverbreitetes relationales
Datenbanksystem, das aus allen Kombinationen des
Subjektes, Pradikates und Objektes Indizes erzeugt. Somit kann
sehr schnell auf Daten zugegri en werden. MonetDB ist ein
OpenSource Column-Store, der eine Menge von
Zwischenergebnissen im Speicher halt, um neue und ahnliche
Anfragen schneller bearbeiten zu konnen. Hexastore ist eine
In-Memory-Losung. Es erzeugt aus allen moglichen
Kombinationen von Tripeln Indizes, die daraufhin in einer
Liste abgelegt werden. Fur die Vermeidung von Dopplungen
und zur Kompression werden Strings in einem Worterbuch
abgelegt. Jena ein bekanntes OpenSource-Projekt kann
verschiedene Datenspeicher verwenden. Einerseits konnen die
Daten in einem eigenen Format abgelegt werden,
andererseits in einer relationalen Datenbank. Auch Jena verwendet
ein Worterbuch zur Kompression. RDF-3X verwendet auch
mehrere Indizes, um alle moglichen Kombinationen
abzuspeichern und legt diese in B+-Baumen ab. Zudem enthalt
es eine ausgeklugelte Anfrageoptimierung, die speziell auf
die Besonderheiten von RDF abgestimmt ist.
      </p>
      <p>Werden alle vorgestellten Systeme genauer betrachtet, stellt
man fest, dass diese einige Nachteile besitzen. Entweder sind
diese auf bestimmte Operationen (lesen, andern) und/oder
Domanen getrimmt und/oder sind nicht skalierbar im Sinne
eines Scale-Outs und somit ungeeignet fur sehr gro e
Datenmengen. Stattdessen setzten sie auf die Leistung einer
einzigen Maschine, was zu einem erheblichen
Performance, Speicherplatz- und Verfugbarkeitsproblem werden kann.
Weiterhin unterstutzt keines der erwahnten Systeme
Garantien bezuglich Antwortzeiten. Sie setzen zudem auf einen
Permanentspeicher, welcher I/O-Zugri e erfordert. Dies
er...
Datenquellen
Push</p>
      <p>InnereA ufbau
hoht wiederum sehr schnell die Antwortzeit. Eine
Gewahrung von Garantien wird erschwert. Einige dieser Ansatze
sind zudem bereits mit wenigen Milliarden Tripeln
uberfordert (Jena). Andere verwenden alte Konzepte fur neuere
Probleme (Virtuoso), was nicht immer zu einer optimalen
Losung beitragt.</p>
      <p>
        Bezuglich den Garantien von Antwortzeiten, beschreiben
die Autoren in [
        <xref ref-type="bibr" rid="ref12">12</xref>
        ] und [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ] ein Verfahren zur Beantwortung
von Anfragen in einem konstanten Zeitintervall. Dies wird
durch verschiedenste Optimierungen erreicht. Unter
anderem wird beschrieben, wie ein Row- und Column-Store
miteinander verschmolzen wird und trotzdem eine e ziente
Anfrageverarbeitung ermoglicht wird.
      </p>
    </sec>
    <sec id="sec-3">
      <title>ARCHITEKTUR</title>
      <p>Die Architektur des Gesamtsystems ist in Abbildung 1
aufgezeigt. Sie folgt dem typischen Scale-Out-Paradigma mit
verschiedenen Shared-Nothing-Systemen (Kreise in der
Mitte), die alle gleichberechtigt sind. Anfragen konnen von
beliebigen Knoten entgegengenommen werden. Im nachsten
Schritt wird ein Queryrewriting durchgefuhrt und an die
entsprechenden Knoten weitergegeben. Die Empfanger nehmen
die umgeschriebenen Anfragen entgegen, bearbeiten diese
und senden letztendlich das Ergebnis zuruck. Nachdem alle
Einzelergebnisse eingetro en sind werden diese mittels
verschiedener Join-Operationen zu einem Ergebnis verknupft.
Dieses wird letztlich an den ursprunglich anfragenden
Client als Ergebnis zuruck gesandt. Auf der rechten Seite der
Gra k ist ersichtlich, dass neue Daten mittels push- oder
pull-Techniken eingespielt werden konnen und dies wahrend
der Laufzeit, mit Einhaltung der Antwortzeitgarantien.
3.1</p>
    </sec>
    <sec id="sec-4">
      <title>Lokale Verarbeitung</title>
      <p>Die lokale Verarbeitungseinheit liegt auf einem Knoten
und besteht aus einem Java-Programm, sowie vorwiegend
aus einer C++ In-Memory-Datenhaltung und
Datenabfragemoglichkeit, die LODCache genannt wird. Dies ist eine
hochperformante, reine In-Memory Losung fur LOD, die den
L2-, wenn vorhanden L3-Cache und die RAM-Struktur
moderner Hardware e zient ausnutzt. Allokierte Datenfelder,
sogenannte Chunks, entsprechen genau der Gro e des
L2Caches. Dies ermoglicht es sehr e zient auf Daten
zuzugreifen, diese zu Bearbeiten und Berechnungen auf diesen
durchzufuhren. Des Weiteren konnen Anfragen an den LODCache
gestellt, sowie A nderungen und Einfugeoperationen
durchgefuhrt werden. Die Verwendung einer reinen In-Memory
Losung basiert auf der Grundlage, zukunftig Antwortzeiten
garantieren zu konnen.</p>
      <p>Linked Open Data bestehen ausschlie lich aus Tripeln, die
wiederum aus Strings bestehen. Werden die darin
abgespeicherten Werte genauer untersucht, stellt man fest, dass
dieselben Stringwerte mehrmals auftreten. Hier ist eine
Kompression nutzlich, um Speicherplatz einzusparen. Dies fallt
umso mehr ins Gewicht, da der Data-Warehouse Ansatz
angestrebt wird. Die naheliegenste Technik, ist der Einsatz
eines rein lokalen Worterbuches. In einem solchen wird jeder
Stringwert auf eine eindeutige ID gemappt. Hierfur ist
wiederum eine e ziente Anfrageverarbeitung von Noten, die im
folgenden Abschnitt beschrieben wird.</p>
      <sec id="sec-4-1">
        <title>Kombinierte Row- und Column-Store.</title>
        <p>
          Ein Chunk besteht intern aus einer Kombination von
Rowund Column-Store [
          <xref ref-type="bibr" rid="ref9">9</xref>
          ]. Jede logische Zeile enthalt drei
Spalten fur Subjekt, Pradikat und Objekt, wobei in einem
jeden Feld nur ein einzelner Integerwerte abgelegt ist. Werden
nun alle einzelnen Integerwerte eines Tripels mittels
ShiftOperationen disjunkt zu einem Wert vereint, ergibt sich ein
Wort mit 96 Bit Breite, wenn jeweils 32 Bit fur Subjekt,
Pradikat und Objekt angenommen werden. Somit wird die
Datenzeile aus drei logischen Spalten zu einer physischen
Spalte vereint, die in einem theoretischen Drittel der Zeit
uberpruft werden kann.
        </p>
        <p>Moderne CPUs besitzen interne SIMD3-Register die
eine Breite von 256-Bit besitzen. Diese wurde mit dem
neuen AVX4-Befehlsatz von Intel eingefuhrt. In einem solchen
Register werden mehrere logisch getrennte Einheiten zu
einer physischen Einheit verbunden, die in einer Instruktion
gleichzeitig bearbeitet werden konnen. Hierfur mussen die
einzulesenden Daten auf eine volle 2-er Potenz erganzt und
die Wortgrenze bekannt sein.</p>
        <p>Werden die Fakten vereint, muss zuerst das 96 Bit Wort
auf 128 Bit, erganzt werden. Mit Hilfe der verfugbaren
256Bit konnen nun zwei logische Datenzeilen mit jeweils
128Bit gleichzeitig uberpruft werden. Theoretisch ergibt sich
eine bis zu sechsfache Performancesteigerung. Mittels der
Vermeidung von Sprung- und sonstigen Befehlen, die
Leerlauf produzieren, ist dieses Verfahren sehr Cache freundlich.
Einmal verwendete Daten konnen stur linear abgearbeitet
werden. Zugri e auf dem langsamen RAM werden damit
vermieden. Insgesamt wird die Struktur moderner Hardware
sehr gut ausgenutzt und eine Performancesteigerung ergibt
sich.</p>
        <p>
          Wie oben erwahnt, muss in diesem Fall eine Erganzung
von 96-Bit auf 128-Bit durchgefuhrt werden. Es verbleiben
32 ungenutzte Bit. Diese konnen fur eine weitere Spalte
verwendet werden. In dieser kann die Sprache bzw. der
Datentyp des (Literal)Objektes vermerkt werden [
          <xref ref-type="bibr" rid="ref1">1</xref>
          ]. Sollten
entsprechende Filterbedingungen auftreten, konnen diese direkt
mit ubernommen werden, was zu einer weiteren
Performancesteigerung beitragt. Andererseits konnen die 32-Bit pro
Spalte zu gering sein und entsprechend erweitert werden. Es
ist auch eine Kombination aus beiden moglich (z. B. 40 Bit
pro Spalte und 8 Bit fur Sprache und Datentyp).
        </p>
        <p>Durch die Verwendung von Integerwerten, die eine feste
Bitbreite besitzen, wird auf einen expliziten und
unvorher</p>
        <sec id="sec-4-1-1">
          <title>3Single instruction, multiple data</title>
          <p>4Advanced Vector Extensions
sehbar langen Stringvergleich verzichtet. Dies erhoht weiter
die Performance und verbessert die Antwortzeit.</p>
          <p>Wie zu erkennen ist, wird auf eine Erzeugung von
zusatzlichen Indixes verzichtet. Dies ergibt sich aus der
Speicherrestriktion und dem notigen Wartungsaufwand, der wahrend
jeder A nderung anfallt. Hierdurch konnen Operationen
unvorhersehbar lange blockiert werden. Es sind keine
Garantien mehr moglich. Anstelle werden wie in einem
gewohnlichen Column-Store alle Elemente stetig gepruft. Dies ist
durch moderne Hardware und der standig steigenden
Parallelisierung problemlos moglich. Sind c Cores gegeben, muss
jeder Core nur maximal d ccC e Elemente uberprufen, wobei
cC die Anzahl der Chunks angibt.</p>
        </sec>
      </sec>
      <sec id="sec-4-2">
        <title>Lokale Anfrageverarbeitung.</title>
        <p>Der LODCache besitzt keinerlei Logik fur die
Optimierung von Anfragen. Aus diesem Grund ist eine vorgelagerte
Java-Applikation vorhanden. Diese nimmt SPARQL-Anfragen
entgegen, zerlegt diese, optimiert sie (lokale Optimierung)
und uberfuhrt sie in die Sprache des LODCaches. Dieser
fuhrt die entsprechende Operation durch und ubergibt das
Ergebnis dem Java-Programm mittels JNI5, dass die
ermittelten Daten an den Aufrufer sendet.</p>
        <p>Wird eine exakt Match Anfrage mit Subjekt1, Objekt1
und einem freien Pradikat ?p an den LODCache gesandt,
werden zuerst die Integerwerte der fest de nierten Strings
gesucht und in ein Wort mittels Shift und logischen
OROperationen zu einer Maske (m) erganzt. Dies wird
mittels vier CPU-Operationen durchgefuhrt werden (COPY,
SHIFT, OR, SHIFT). Die Operationen zum Filtern der
Daten aus einem Chunk beschranken sich daraufhin nur noch
auf ein logisches AND und einen Vergleich (CMP), je
Eintrag und Chunk. Die genaue Berechnung ist im Folgenden
nochmals dargestellt. Wobei e das zu uberprufende Element
ist, m die Maske und r das Ergebnis als boolescher Wert.
r = (e AND m) CMP m</p>
        <p>
          Werden Bereichsanfragen betrachtet, muss das Mapping
der Strings auf Integerwerte eindeutig und
ordnungserhaltend sein, da sonst immer das Worterbuch zu Rate
gezogen werden musste. Dies bedeutet, jeder Integerwert muss
mit der lexikogra schen Ordnung seines gegenuberliegenden
Strings ubereinstimmen. Nur so konnen die in [
          <xref ref-type="bibr" rid="ref9">9</xref>
          ]
aufgefuhrten Operationen angewandt und die Performance von
SIMD-Befehlen ausgenutzt werden. Hierfur muss zuerst der
minimale und maximale Integerwert der Bereichsanfrage
ermittelt werden. Daraufhin werden zwei Masken erstellt und
die Daten in den Chunks mit diesen, durch verschiedene
logische Operationen, verglichen.
        </p>
      </sec>
      <sec id="sec-4-3">
        <title>Ordnungserhaltender Baum.</title>
        <p>Ein Problem tritt jedoch beim Einfugen von neuen
Stringwerten auf. Diese werden meist lexikogra sch zwischen zwei
bereits bestehenden Elementen eingeordnet. Somit mussten
sich in einem naiven Ansatz alle IDs aller nachfolgenden
Stringwerte andern. Das Worterbuch und alle bestehenden
Chunks mussen daraufhin uberpruft und ggf. abgeandert
werden.</p>
        <p>Dies ist ein sehr gro es und au erst schwerwiegendes
Problem, welches sich nicht vermeiden lasst. Es kann nur
versucht werden, dass die Reorganisation moglichst selten und</p>
        <sec id="sec-4-3-1">
          <title>5Java Native Interface</title>
          <p>1
B
2
gleichzeitig e zient durchgefuhrt werden kann. Dies konnte
naiv erreicht werden, indem jeder nachfolgende
Mappingwert einige Zahlen zu seinem Vorganger uberspringt. Treten
nun neue Eintrage auf, konnen diese solange eingefugt
werden, wie freie Platze existieren. Ein Problem dieses
Ansatzes ist jedoch, dass nicht bekannt ist, in welcher Reihenfolge
Strings auftreten und es ist ganzlich unbekannt an welcher
freien Position ein Element eingefugt werden muss/soll (in
der Mitte, an der ersten oder letzten freien Position?). Eine
falsche Position bedingt eine schnellere Reorganisation. Aus
diesem Grund muss ein besser geeignetes Verfahren
verwendet werden.</p>
          <p>
            Ein solches wird fur XML-Daten in [
            <xref ref-type="bibr" rid="ref8">8</xref>
            ] beschrieben. Die
Autoren zeigen ein rekursives Verfahren, um Daten in
einem Baum abzulegen und eine eindeutige ID zu
generieren. Hierfur wird auf jeder Ebene jede mogliche Verzweigung
durchnummeriert6. Nun wird zwischen geraden und
ungeraden Elementen unterschieden. Die ungeraden Elemente sind
vorhanden, um darin Werte sortiert aufzunehmen
(durchgezogene Linie). Im Gegensatz zu den Ungeraden, denn
diese spannen einen neuen Unterbaum auf (gestrichelte Linie).
Soll ein neuer Wert eingefugt werden, wird dieser auf der
hochsten Ebene (sortiert) hinzugefugt, die (i.) mindestens
einen freien Platz besitzt und (ii.) lexikogra sch den String
korrekt einordnet. Das neue Element kann nun uber die
Konkatenation aller traversierten Baumverzweigungen eindeutig
identi ziert werden und wird sinnvollerweise in einem String
uberfuhrt. In Abbildung 2 ist ein Beispiel mit den Elementen
'A', 'B' und dem neuen Element 'AB' gegeben. Durch
diesen Ansatz ist gewahrleistet, dass sich neue Elemente immer
zwischen zwei bereits bestehenden Elementen einsortieren
lassen. Problematisch an diesem Ansatz ist jedoch, dass
beliebig viele Unterbaume generiert werden konnen, der Baum
zu einer Liste entartet und somit die Pfadlange zu einem
Element sehr lang werden kann. Dies widerspricht jedoch
der oben genannten Forderung, nach einer festen Breite fur
Elemente, sowie der Verwendung eines Integerwertes. Aus
diesem Grund muss eine Modi kation dieses Ansatzes
verwendet werden.
          </p>
          <p>Anstelle eines Strings, um den Pfad eindeutig zu identi
zieren, werden nun beispielsweise 32 Bit Werte verwendet.
Im Folgenden werden weiterhin jeweils 2 Bit pro Ebene
verwendet. Wobei fur jede neue Ebene, die neu
hinzukommenden Bits an den bereits bestehenden Bits dahinter
gehangen werden (von der gro ten zur kleinsten Wertigkeit). Es
ergeben sich insgesamt maximal 16 Ebenen. Von den
moglichen vier (2b = 22) Werten pro Ebene konnen nur drei
verwendet werden (00, 01, 10). Dies ergibt sich daraus, da
der Wert 11 ungerade ist. In einem solchen musste nach der</p>
        </sec>
        <sec id="sec-4-3-2">
          <title>6In den weiteren Ausfuhrungen wird von 0 gestartet.</title>
          <p>oben genannten De nition ein Element ablegt werden.
Jedoch existiert nach diesem kein weiteres gerades Element,
womit nach einem falsch einsortierten Element kein
weiteres lexikogra sch dahinter liegendes Element eingefugt
werden kann. Dies wurde eine fruhere Reorganisation erzwingen,
was zu vermeiden ist. In Abbildung 3 ist das bereits weiter
oben gezeigte Beispiel nochmals auf diesen Sachverhalt
abgebildet.</p>
        </sec>
      </sec>
      <sec id="sec-4-4">
        <title>Bewertung.</title>
        <p>Ein gro es Problem dieses Ansatzes ist jedoch die geringe
Auslastung. So werden hochstens 50 % der moglichen Werte
verwendet und auch nur genau dann, wenn keine
zusatzlichen Ebenen vorhanden sind. Somit treten wiederum sehr
schnelle Reorganisationen auf. Auf der anderen Seite kann
eine Reorganisation sehr schnell durchgefuhrt werden. Sie
ist auf wenige logische Operationen pro Worterbuch- und
Chunk-Eintrag beschrankt (SHIFT- und OR-Operationen).
Gleichzeitig kann durch eine Reorganisation die
Ebenenanzahl verringert und somit die Anzahl an Bits pro Ebene
vergro ert werden. Die theoretisch mogliche Auslastungsgrenze
steigt automatisch an.
3.2</p>
      </sec>
    </sec>
    <sec id="sec-5">
      <title>Globale Verarbeitung</title>
      <p>
        Die globale Architektur besteht aus der Zusammenfassung
aller lokalen Verarbeitungseinheiten zu einer globalen
Einheit. Diese sind mittels der Technik eines Chord-Ringes [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ]
miteinander verbunden. Er besteht aus n unabhangigen und
gleichwertigen Elementen, die in einem geschlossenen Ring
angeordnet sind. Wobei jedes Element einen Vorganger und
einen Nachfolger besitzt (siehe Abbildung 1; Doppeltpfeile
mit durchgehender Linie). Neben diesen Verbindungen
existieren noch sogenannte Finger (siehe Abbildung 1; einfacher
Pfeil mit gestrichelter Linie). Dies sind zusatzliche
unidirektionale Verbindungen, die mehrere Nachfolger uberspringen
und somit fur eine schnellere Kontaktaufnahme mit einem
beliebigen Element vorhanden sind. Waren diese nicht
vorhanden, musste eine Anfrage von einem Element zum
anderen solange weitergereicht werden, bis der Empfanger
erreicht ist (O(n)). Dies wird durch die Finger auf O(log2 n)
verkurzt.
      </p>
      <sec id="sec-5-1">
        <title>Fragmentierungsfunktion.</title>
        <p>Fur die Umsetzung eines Scale-Outs wird eine
Fragmentierungs- und Allokationsfunktion benotigt. Erstere de niert
wie welche Daten aufgeteilt werden, letztere auf welchen
Knoten welches Element abgelegt wird. Beide sollten
moglichst einfach zu berechnen sein, da sie fur jede Anfrage
benotigt werden (Datenlokalisation). Der Chord-Ring de niert
hier bereits eine Hashfunktion h(x). Diese erzeugt durch die
Eingabe von Daten einen Hashwert, der genau einem Knoten
im Chord-Ring zugeordnet ist. Eine einfache
Datenlokalisationsfunktion ist hierdurch gegeben. Der Vorteil, der hieraus
entsteht ist ein globaler und uchtiger Index, der keinerlei
Wartung benotigt und auf allen n Elementen gleicherma en
zur Verfugung steht.</p>
        <p>Fur die Indizierung von RDF-Tripeln werden alle
einstelligen Kombinationen aus Subjekt, Pradikat und Objekt
erzeugt (s!op, p!so, o!sp). Diese werden nun mittels h(x)
auf den Ring verteilt, indem das zu indizierende Element in
h(x) gegeben wird und der entsprechende Knoten bestimmt
wird. Fur dasselbe Literal ergibt sich immer derselbe Hash
und somit ist immer derselbe Knoten zustandig.</p>
      </sec>
      <sec id="sec-5-2">
        <title>Globale Anfrageverarbeitung.</title>
        <p>Im ersten Schritt wird eine beliebige SPARQL-Anfrage
einem Client an einem beliebigen Knotenelement gesandt.
Der Empfanger wird zum Koordinator dieser Anfrage. Nun
zerlegt er die SPARQL-Anfrage und uberpruft, ob er alle
Daten lokal besitzt. Ist dies der Fall, liest er die Daten aus
und fuhrt die gesamte Berechnung durch. Ansonsten leitet er
die umgeschriebenen Subanfragen an die zustandigen
Knoten weiter. Hierfur wird die Hashfunktion h(x) benotigt, in
dem der nicht variable Teil einer jeden WHERE-Bedingung
eingetragen wird. Wahrend des Rewriting-Vorganges werden
FILTER-Statements beachtet und in die Subqueries
einbezogen, falls dies moglich ist (globale Optimierung). Durch
diese Technik arbeiten mehrere Knoten parallel an derselben
Ausgangsquery. Als Nebene ekt wird die Datenmenge
verkleinert. Nach dem Erhalt der Subqueries arbeiten die
Knoten diese ab (lokale Anfrageverarbeitung; siehe Kapitel 3.1)
und senden das Ergebnis an den Koordinator zuruck.
Dieser fuhrt die benotigten Joins und die restlichen FILTER-,
GROUP BY-, HAVING-, ORDER BY-, LIMIT-,
OFFSET, Projektions-, usw. Operationen durch. Zum Schluss wird
das Ergebnis an den Client gesandt.</p>
      </sec>
      <sec id="sec-5-3">
        <title>Bewertung.</title>
        <p>
          Ein Problem dieses Ansatzes ist die mehrfache redundante
Datenhaltung derselben Daten in maximal drei
verschiedenen Knoten und die dafur zweimal hohere
Speicherkapazitat. Dies ist jedoch nur bedingt ein Nachteil. Durch den
automatisierten Scale-Out-Mechanismus kann ein lokales
Element entlastet werden, indem ein neuer Knoten einen
Teilbereich der Hashwerte und die darin abgebildeten Daten fur
sich beansprucht. Ein weiterer Vorteil ist die Moglichkeit
auf sehr gro e Anfragelasten dynamisch reagieren zu
konnen. Es konnen automatisch neue Knoten hinzugefugt
werden, die einen Teil der Anfragelast ubernehmen. Die
Aufteilung des Speicherplatzes und Anfragelast, wird jeweils durch
die konsistente Hash-Funktion h(x) garantiert [
          <xref ref-type="bibr" rid="ref10">10</xref>
          ]. Durch
den beschriebenen Scale-Out, wachst die maximale
Pfadlange nur bedingt an, da diese durch O(log2 n) de niert ist
(was einem Vorteil entspricht). Ein weiterer Vorteil ist, dass
zu jeder WHERE-Bedingung maximal ein Knoten involviert
ist. Es mussen keine knotenubergreifenden Daten fur bspw.
Bereichsanfrage gesammelt werden. Dies ist nur zwischen
verschiedenen WHERE-Bedingungen notig, die mittels Join
verknupft werden.
        </p>
      </sec>
    </sec>
    <sec id="sec-6">
      <title>ZUSAMMENFASSUNG</title>
      <p>In dieser Arbeit wurde ein Ansatz vorgestellt, der
mehrere Hundert Milliarden bzw. mehrere Billionen RDF-Tripel
Linked Open Data e zient verwalten kann. Es wurde eine
Unterscheidung in lokaler und globaler Verarbeitung
durchgefuhrt. Die lokale Verarbeitungseinheit besteht aus einem
hochoptimierten In-Memory C++-Programm zur
Datenhaltung und -abfrage, das die Strukturen moderner Hardware
e zient ausnutzt. Im selben Abschnitt wurde eine
Moglichkeit aufgezeigt, Bereichsanfragen e zient zu verarbeiten,
indem ein ordnungserhaltendes Mapping von Strings auf
Integerwerten dargestellt wurde. Dies wird durch einen
ordnungserhaltenden und updatefreundlichen Baum garantiert.</p>
      <p>Die globale Verarbeitungseinheit besteht aus dem
Zusammenschluss mehrerer lokaler Komponenten und verwendet
hierzu die Technik des Chord-Ringes. Jedes Element ist
gleichberechtigt, es existiert somit kein zentraler Koordinator. Fur
die Verbindung untereinander existieren Finger, die eine
maximale Anzahl an Weiterleitungen garantieren. Zur
Verarbeitung von beliebigen SPARQL-Anfragen werden diese von
einem Knoten entgegengenommen, optimiert und an den
betre enden Knoten gesandt. Zur Datenlokalisation wird
eine einfache Hashfunktion und kein global zu p egender
Index benotig. Des Weiteren ist dieses Verfahren
unabhangig gegenuber der Anzahl an Tripeln und dem benotigten
Speicherplatz, da ein automatischer Scale-Out-Mechanismus
existiert.</p>
    </sec>
    <sec id="sec-7">
      <title>AUSBLICK</title>
      <p>In der weiteren Forschung mussen einige Punkte naher
betrachtet werden, die als Motivation zu diesem Ansatz dienen.
Hierunter fallt die Einhaltung der garantierten Antwortzeit
aller Anfragen bis zu einem vorher de nierten Prozentsatz.
Zur Unterstutzung dieser Forderung ist eine Replikation der
Daten denkbar.</p>
      <p>
        Dies fuhrt zum nachsten Problem, der e zienten
Replikation. Bis zu diesem Zeitpunkt werden alle Daten nur auf
einem Knoten vorgehalten. Sturzt dieser ab, sind all seine
Daten verloren und nachfolgende Anfragen konnen nicht mehr
beantwortet werden. Als Ausweg bestunde die Moglichkeit,
ein ahnliches Vorgehen umzusetzen, wie es in Amazons
Dynamo [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ] implementiert ist.
      </p>
      <p>Zur weiteren Performancesteigerung ist es notwendig den
LODCache weiter zu optimieren. Es existiert zum Beispiel
die Moglichkeit auf einer SandyBridge-CPU eine Schleife
direkt im CPU eigenen Loop-Cache abzulegen. Eine
Performancesteigerung von uber 100 % soll moglich sein. Jedoch
ist die Bedingung hierfur, dass alle Instruktionen hochstens
28 -Operationen lang sind.</p>
      <p>Der oben beschriebene Ansatz zum Mapping von Strings
auf ordnungserhaltende Integerwerte muss weiter erforscht
werden. Es ist u. a. notwendig, die Operationen zur
Reorganisation e zienter anzuordnen. Eine Moglichkeit zur
Erhohung der Auslastung wird au erdem angestrebt. In
diesem Zusammenhang soll gleichzeitig ein Verfahren
entwickelt werden, um Updates auf bestehende Daten moglichst
e zient durchzufuhren.</p>
      <p>
        Fur die weitere Entwicklung und Evaluierung des Systems
wird zukunftig ein Benchmark eingesetzt. Es wurde der
Berlin SPARQL Benchmark [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ] ausgewahlt. Dieser erzeugt
akzeptierte Resultate und ist fur das Testen von beliebigen
SPARQL-Systemen entwickelt worden. Fur Skalierungstests
kann ein Skalierungsfaktor angepasst werden, der die Anzahl
an automatisch erzeugten Tripeln vergro ert.
      </p>
      <p>Die Performanz des Systems wird durch
verschiedenartige SPARQL-Anfragen ermittelt, die sich in A
quivalenzklassen einteilen lassen. Den einfachen SPARQL-Anfragen, den
Anfragen, die eine Datenmanipulation erfordern sowie den
analytischen SPARQL-Anfragen.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          <article-title>[1] Rdf - semantic web standards</article-title>
          . http://www.w3.org/RDF.
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          <article-title>[2] Sparql query language for rdf</article-title>
          . http://www.w3.org/TR/rdf-sparql-query.
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>P. A.</given-names>
            <surname>Boncz</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M. L.</given-names>
            <surname>Kersten</surname>
          </string-name>
          , and
          <string-name>
            <given-names>S.</given-names>
            <surname>Manegold</surname>
          </string-name>
          .
          <article-title>Breaking the memory wall in monetdb</article-title>
          .
          <source>Commun. ACM</source>
          ,
          <volume>51</volume>
          (
          <issue>12</issue>
          ):
          <volume>77</volume>
          {
          <fpage>85</fpage>
          ,
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>G.</given-names>
            <surname>DeCandia</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Hastorun</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Jampani</surname>
          </string-name>
          ,
          <string-name>
            <given-names>G.</given-names>
            <surname>Kakulapati</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Lakshman</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Pilchin</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Sivasubramanian</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Vosshall</surname>
          </string-name>
          , and
          <string-name>
            <given-names>W.</given-names>
            <surname>Vogels</surname>
          </string-name>
          . Dynamo:
          <article-title>Amazon's highly available key-value store</article-title>
          .
          <source>SIGOPS Oper. Syst. Rev.</source>
          ,
          <volume>41</volume>
          (
          <issue>6</issue>
          ):
          <volume>205</volume>
          {
          <fpage>220</fpage>
          ,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>O.</given-names>
            <surname>Erling</surname>
          </string-name>
          and
          <string-name>
            <surname>I. Mikhailov.</surname>
          </string-name>
          <article-title>RDF support in the virtuoso DBMS</article-title>
          . In S. Auer,
          <string-name>
            <given-names>C.</given-names>
            <surname>Bizer</surname>
          </string-name>
          ,
          <string-name>
            <surname>C.</surname>
          </string-name>
          <article-title>Muller, and</article-title>
          <string-name>
            <given-names>A. V.</given-names>
            <surname>Zhdanova</surname>
          </string-name>
          , editors,
          <source>CSSW</source>
          , volume
          <volume>113</volume>
          <source>of LNI</source>
          , pages
          <volume>59</volume>
          {
          <fpage>68</fpage>
          .
          <string-name>
            <surname>GI</surname>
          </string-name>
          ,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <surname>FU-Berlin</surname>
          </string-name>
          . Berlin sparql benchmark. http://www4.wiwiss.fuberlin.de/bizer/berlinsparqlbenchmark.
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>A.</given-names>
            <surname>Harth</surname>
          </string-name>
          ,
          <string-name>
            <given-names>K.</given-names>
            <surname>Hose</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Karnstedt</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Polleres</surname>
          </string-name>
          , K.-U. Sattler, and
          <string-name>
            <given-names>J.</given-names>
            <surname>Umbrich</surname>
          </string-name>
          .
          <article-title>Data summaries for on-demand queries over linked data</article-title>
          .
          <source>In WWW</source>
          , pages
          <volume>411</volume>
          {
          <fpage>420</fpage>
          ,
          <year>2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>M. P.</given-names>
            <surname>Haustein</surname>
          </string-name>
          , T. Harder, C. Mathis, and
          <string-name>
            <surname>M. W.</surname>
          </string-name>
          <year>0002</year>
          .
          <article-title>Deweyids - the key to ne-grained management of xml documents</article-title>
          .
          <source>JIDM</source>
          ,
          <volume>1</volume>
          (
          <issue>1</issue>
          ):
          <volume>147</volume>
          {
          <fpage>160</fpage>
          ,
          <year>2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>R.</given-names>
            <surname>Johnson</surname>
          </string-name>
          , V. Raman,
          <string-name>
            <given-names>R.</given-names>
            <surname>Sidle</surname>
          </string-name>
          , and
          <string-name>
            <given-names>G.</given-names>
            <surname>Swart</surname>
          </string-name>
          .
          <article-title>Row-wise parallel predicate evaluation</article-title>
          .
          <source>PVLDB</source>
          ,
          <volume>1</volume>
          (
          <issue>1</issue>
          ):
          <volume>622</volume>
          {
          <fpage>634</fpage>
          ,
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <given-names>D. R.</given-names>
            <surname>Karger</surname>
          </string-name>
          ,
          <string-name>
            <given-names>E.</given-names>
            <surname>Lehman</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F. T.</given-names>
            <surname>Leighton</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Panigrahy</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M. S.</given-names>
            <surname>Levine</surname>
          </string-name>
          , and
          <string-name>
            <given-names>D.</given-names>
            <surname>Lewin</surname>
          </string-name>
          .
          <article-title>Consistent hashing and random trees: Distributed caching protocols for relieving hot spots on the world wide web</article-title>
          . In F. T. Leighton and P. W. Shor, editors,
          <source>STOC</source>
          , pages
          <volume>654</volume>
          {
          <fpage>663</fpage>
          . ACM,
          <year>1997</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <given-names>T.</given-names>
            <surname>Neumann</surname>
          </string-name>
          and
          <string-name>
            <given-names>G.</given-names>
            <surname>Weikum. RDF-</surname>
          </string-name>
          <article-title>3X: A RISC-Style Engine for RDF</article-title>
          .
          <string-name>
            <surname>In</surname>
            <given-names>VLDB</given-names>
          </string-name>
          , Auckland, New Zealand,
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <given-names>V.</given-names>
            <surname>Raman</surname>
          </string-name>
          ,
          <string-name>
            <given-names>G.</given-names>
            <surname>Swart</surname>
          </string-name>
          ,
          <string-name>
            <given-names>L.</given-names>
            <surname>Qiao</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>Reiss</surname>
          </string-name>
          ,
          <string-name>
            <given-names>V.</given-names>
            <surname>Dialani</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Kossmann</surname>
          </string-name>
          ,
          <string-name>
            <surname>I. Narang</surname>
          </string-name>
          , and
          <string-name>
            <given-names>R.</given-names>
            <surname>Sidle</surname>
          </string-name>
          .
          <article-title>Constant-time query processing</article-title>
          . In G. Alonso,
          <string-name>
            <given-names>J. A.</given-names>
            <surname>Blakeley</surname>
          </string-name>
          ,
          <article-title>and</article-title>
          <string-name>
            <surname>A. L. P.</surname>
          </string-name>
          Chen, editors,
          <source>ICDE</source>
          , pages
          <volume>60</volume>
          {
          <fpage>69</fpage>
          . IEEE,
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13]
          <string-name>
            <surname>I. Stoica</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Morris</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Liben-Nowell</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D. R.</given-names>
            <surname>Karger</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M. F.</given-names>
            <surname>Kaashoek</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>Dabek</surname>
          </string-name>
          , and
          <string-name>
            <given-names>H.</given-names>
            <surname>Balakrishnan</surname>
          </string-name>
          .
          <article-title>Chord: a scalable peer-to-peer lookup protocol for internet applications</article-title>
          .
          <source>IEEE/ACM Trans. Netw</source>
          .,
          <volume>11</volume>
          (
          <issue>1</issue>
          ):
          <volume>17</volume>
          {
          <fpage>32</fpage>
          ,
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          [14]
          <string-name>
            <given-names>C.</given-names>
            <surname>Weiss</surname>
          </string-name>
          , P. Karras,
          <article-title>and</article-title>
          <string-name>
            <given-names>A.</given-names>
            <surname>Bernstein</surname>
          </string-name>
          . Hexastore:
          <article-title>Sextuple Indexing for Semantic Web Data Management</article-title>
          . In VLDB, Auckland, New Zealand,
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          [15]
          <string-name>
            <given-names>K.</given-names>
            <surname>Wilkinson</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C.</given-names>
            <surname>Sayers</surname>
          </string-name>
          ,
          <string-name>
            <given-names>H.</given-names>
            <surname>Kuno</surname>
          </string-name>
          , and
          <string-name>
            <given-names>D.</given-names>
            <surname>Reynolds</surname>
          </string-name>
          .
          <article-title>E cient RDF storage and retrieval in Jena2</article-title>
          .
          <source>In Proc. First International Workshop on Semantic Web and Databases</source>
          ,
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>