[Narzędzia] Analiza dostępnych triplestores

Zespół

Cel i opis projektu

Celem projektu jest porównanie aktualnie dostępnych całych środowisk do przechowywania i odpytywania danych RDF (triple store + silnik zapytań + wszelkie dostępne .*I - API, GUI, CLI itp.). Ze względu na ograniczone możliwości sprzętowe (dostępny w zasadzie tylko jeden komputer, ogólnego użytku, nieskonfigurowany do bycia używanym w benchmarkach) oraz mnogość znacznie bardziej profesjonalnych publikacji na ten temat w internecie (choćby hasło „rdf stores efficiency comparison” zwraca sporo sensownych wyników, przykładowa lista poniżej), projekt skupia się głównie na 'ludzkim' aspekcie rozpatrywanych rozwiązań. W szczególności stawianie triple stores jako takich okazuje się często kłopotliwe, więc duża część kombinacji czyta bezpośrednio pliki rdf, co co prawda jest wolniejsze przy wielokrotnym użyciu, ale prostsze o krok tworzena bazy. Wykonane testy wydajnościowe są raczej testami jakościowymi niż ilościowymi, mającymi stwierdzić na przykład „to narzędzie nie nadaje się do dużych baz” lub „to narzędzie jest raczej szybsze od tamtego”.

Kilka artykułów zawierających poważne benchmarki triple stores:

Użyte w testach

Sprzęt używany w testach

  • Procesor: 2C/2T@1.8GHz
  • Pamięć: 4GB@800MHz (DDR2) + 8GB pamięci wirtualnej
  • Dysk: SATA II HDD@7200rpm

(Inaczej mówiąc przeciętny desktop sprzed ~ośmiu lat)

Poboczny software używany w testach

(czas i problemy związane z instalacją poniższych niewliczane do ocen narzędzi)

  • Windows Vista 64bit - Semwebowe środowisko niestety niezbyt lubi się z Windowsem, ostatecznie wszystkie działające narzędzia działają dlatego, że są napisane w Javie.
  • Java 1.8u25 - Zakładając nawet, że ktoś nie ma żadnej wersji, instalacja nie powinna stanowić żadnego problemu (oprócz faktu, że JDK przeciętnie waży blisko 200MB, ale czas modemów 56k dawno minął).
  • MySQL 5.6 (64bit) - Relacyjna baza danych. MySQL jako niemały i dojrzały projekt ma bardzo elegancki i elastyczny instalator. W związku z tym można się dość łatwo pomylić wybierając elementy do zainstalowania. Nowsze Workbenche (coś jakby IDE do MySQLa) działają tylko na Windows 7/8 (da się ściągnąć starsze). Mimo wszystko ogółem instalacja raczej nie powinna zajmować więcej niż godzinę.
  • PostgreSQL 9.4.0 (64 bit) Druga relacyjna baza danych. Uwagi co do instalacji podobne jak dla MySQL.
  • RDF2RDF - Mały helper do konwersji pomiędzy różnymi formatami dla LAK. Zajmuje poniżej 1MB, działa od ręki (pod warunkiem posiadania instalacji Javy).
  • Wildfly 8.2.0 - Pełen, certyfikowany serwer aplikacyjny Javy EE7, rebranding JBoss AS. Wśród całego wachlarza funkcjonalności JEE w szczególności pozwala uruchamiać aplikacje spakowane w archiwa .war i .ear. Do wielu zastosowań mógłby zostać zastąpiony lżejszym Tomcatem (serwer do okrojonej Javy EE) czy Jetty. Teoretycznie instalacja i uruchomienie JBossa/Wildfly'a/Tomcata/któregokolwiek innego serwera to download, unzip & run, ale ogólnie jest to raczej technologia, którą odradzałbym osobom niezajmującym się nią i niezamierzającym się nią zajmować. Na marginesie, jeżeli ktoś i tak się na to zdecyduje, JBossy do wersji 7 włącznie mogą mieć poważne problemy z JVM 1.8 i uruchamianie ich na 1.7 jest mocno zalecane. Prawdopodobnie dotyczy to też innych serwerów w porównywalnie starych wersjach. Potencjalna konieczność żonglowania wersjami Javy jest właśnie jednym z powodów, dla których odradzałbym tę technologię, jeżeli potrzebne jest tylko cokolwiek, co uruchomi aplikację, bez inwestowania w to czasu.

Użytkownik używany w testach

(to znaczy skąd bierze się przesunięcie w stronę Javy)

  • Znajomość Windowsa: prawie że zawodowa (w szczególności także Powershell)
  • Znajomość Javy: w zasadzie zawodowa (jakkolwiek głównie Maven, TestNG, JBoss, JPA, EJB, JSF itd., co w tym projekcie jest niezbyt przydatne)
  • Znajomość C/Cpp: raczej ograniczona do tego, co było na studiach; w przeciwieństwie do build.xml Anta czy pom.xml Mavena widok makefile'i nie napełnia mnie poczuciem, że wiem, co się dzieje
  • Znajomość SQL: okazyjnie MySQL, PostgreSQL, MS SQL server (ale brak prywatnej licencji na ostatnie)
  • Znajomość SPARQL i RDF: ograniczona do tego, co było na studiach

Zbiory trójek/czwórek używane w testach

  • LAK - 27 843 (według opisu) triples w jednym pliku, 98 472 triples fizycznie (zawiera sporo synonimów, które prawdopodobnie nie były liczone jako oddzielne stwierdzenia), ~55MB. Duża-ale-nie-za-duża baza, ostatecznie najwięcej używana w testach.
  • BTC 2010 (chunki 000, 042 i 054) - Bardzo dużo danych, ~2GB i ponoć ~10M stwierdzeń per chunk. W zamierzeniu miało służyć jako bardzo dużo danych, w praktyce format NQuads sprawia trudności (spodziewałem się, że informację o kontekście będzie się dało łatwo ignorować, ale jednak się nie da). Oprócz tego pliki zawierają błędy składniowe.
  • Pathway commons - zastępstwo dla BTC w roli 'bardzo dużo danych', 600MB i 5.7M stwierdzeń w pojedynczym pliku RDF/XML. RDF2RDF nie daje rady konwertować przy takich rozmiarach, nawet przy (znacznie) zwiększonym limicie na stertę, więc RDF/XML był jedynym używanym formatem.

Ogólny schemat oceny narzędzia/środowiska

  • Opis słownomuzyczny całego projektu, wszelkie ogólne uwagi i pierwsze wrażenia.
  • Dostępne bez kompilacji czegokolwiek narzędzia.
  • Szacowany czas potrzebny do wykonania pierwszego zapytania SPARQL przez przypadkowego studenta pierwszego semstru EISu (od momentu usłyszenia, że ma się ściągnąć i zainstalować narzędzie).
  • Obsługiwane formaty plików (sprawdzane zachowanie dla rdf/nt/ttl/n3/trig i dużego nq).
  • Zajęcie pamięci tuż po otwarciu (jeżeli dotyczy), najwyższe i/lub przeciętne zaobserwowane zajęcie pamięci podczas pracy, głównie na podstawie wskazań menedżera zadań. Uwaga: w wypadku aplikacji dla JVM w zasadzie bardziej zależy to od samego JVM niż od aplikacji, JVM ma tendencję do zajmowania takiej ilości pamięci, na jaką mu się pozwoli. Podstawowym sposobem regulacji limitu pamięci dla JVM jest limit na stertę, -Xmxn w linii poleceń podczas uruchamiania, np. -Xmx256m.
  • Czas załadowania LAK z pliku do bazy/pamięci (jeżeli dotyczy).
  • Czas załadowania fragmentów BTC z pliku do bazy/pamięci (jeżeli dotyczy). Jeżeli się da, to wszystkich razem (kolejne bez usuwania poprzednich), jeżeli nie, to każdy osobno.
  • Czas załadowania Common Pathways z bliku do bazy/pamięci (jeżeli dotyczy).
  • Czas wykonania poniższych zapytań na bazie LAK:
    • (a) Zapytanie zwracające całą bazę, czyli względnie sporo danych. Sprawdza sprawność w masowej produkcji wyjścia. W pewnym sensie jest nieuczciwe dla konsolowych kombinacji, ponieważ w dużej mierze zależy od sprawności shella (nawet mimo tego, że output jest przekierowany do pliku). Jednak z drugiej strony i tak te kombinacje muszą działać we współpracy z shellem, więc o ile może nie do końca mają wpływ na wynikowe czasy, o tyle jednak są to czasy, których należy się spodziewać używając ich.
SELECT ?a ?b ?c
WHERE {
  ?a ?b ?c
}
  • (b) Zapytanie zwracające kilka konkretnych trójek dotczących danej konferencji. Jako trywialne samo zapytanie powinno wykonywać się błyskawicznie, czas wykonania będzie raczej czasem dostępu do danych.
SELECT ?paper
WHERE {
  <http://data.linkededucation.org/resource/lak/conference/edm2014/paper/514> <http://purl.org/ontology/bibo/cites> ?paper.
}
  • © Zapytanie wymagające dość dalekiej i obszernej wycieczki po grafie i sprawdzające wydajność narzędzia w takim scenariuszu. W szczególności prawdopodobnie słabo wypadnie dla baz opartych o relacyjną bazę danych bądź o strukturze podobnej do relacyjnych baz danych (RDB są raczej kiepskie w przechowywaniu grafów).
SELECT ?details
WHERE {
  ?person <http://swrc.ontoware.org/ontology#affiliation> <http://data.linkededucation.org/resource/lak/organization/university-of-ljubljana> .
  ?paper1 <http://purl.org/dc/elements/1.1/creator> ?person .
  ?proceedings <http://data.semanticweb.org/ns/swc/ontology#hasPart> ?paper1 .
  ?paper2 <http://data.semanticweb.org/ns/swc/ontology#isPartOf> ?proceedings .
  ?paper2 <http://purl.org/ontology/bibo/cites> ?citation .
  ?citation <http://www.w3.org/2002/07/owl#sameAs> ?reference .
  ?reference <http://data.linkededucation.org/ns/linked-education.rdf#text> ?details .
}
  • Czas wykonania poniższego zapytania na pathways:
    • (d) Zapytanie sprawdzające, czy da się w ogóle zapytać o cokolwiek niecałkowicie trywialnego przy takiej ilości danych.
SELECT ?name
WHERE {
  ?prot <http://www.biopax.org/release/biopax-level3.owl#name> ?name .
  ?prot <http://www.biopax.org/release/biopax-level3.owl#entityReference> <http://identifiers.org/uniprot/O15514> .
}
  • Podsumowanie

Czasy ładowania do bazy i wykonywania zapytań dla okienkowych i webowych aplikacji są mierzone ze stoperem, subiektywnie, od momentu naciśnięcia przycisku typu uruchom bądź zatwierdzenia polecenia w konsoli, do momentu wypisania wszystkich wyników i odzyskania responsywności aplikacji/konsoli i/lub według wewnętrznych logów narzędzia. Dla konsolowych poleceń mierzone są na zasadzie Get-Time; [polecenie]; Get-Time (Powershell). Ze względu na spore opóźnienia konsoli przy większej ilości tekstu wszystkie konsolowe aplikacje były testowane z wyjściem przekierowanym do pliku.

Twinkle

Słownomuzycznie

Twinkle to proste narzędzie działające na JVM. Cała strona projektu mieści się na jednym ekranie. Jego dokumentacja praktycznie nie istnieje, ale tak naprawdę nie jest potrzebna. Dostępne są całe dwa download linki, z czego jeden to źródła. Drogą prostej eliminacji wystarczy z tych dwóch wybrać skompilowaną wersję, rozpakować, uruchomić i pozwolić swojej intuicji obsługiwać GUI. Od ręki można pisać zapytania do jednej z przykładowych baz, do dowolnych SPARQL endpointów lub do pliku. Jest to ogromna zaleta, zwłaszcza dla użytkowników, którzy mają raczej rozmyte pojęcie o całej kulturze RDF i o tym, czego tak właściwie oczekują od narzędzia oprócz tego, że chyba chcieliby napisać jakieś zapytanie. Czyli na przykład dla przeciętnego studenta. Odpytywanie RDB jako źródła jest już znacznie trudniejsze i wymaga przynajmniej minimalnego zorientowania w JDBC i znajomości Jeny, ale traktuję to jako poboczną funkcjonalność, która nie psuje ogólnego wizerunku jako prostego i intuicyjnego narzędzia. Gdyby ktokolwiek z jakiegokolwiek powodu chciał budować Twinkle ze źródeł, to jest budowany Antem i build.xml wygląda przyzwoicie (jakkolwiek nie próbowałem go uruchamiać), więc proces nie powinien sprawiać trudności.

Dostępne bez kompilacji czegokolwiek narzędzia

  • GUI
  • Zapytania do plików
  • Zapytania do baz umieszczonych w RDB (niesprawdzone)
  • Zapytania do dowolnych SPARQL endpointów

Pierwsze zapytanie

W związku z prostotą Twinkle wykonanie pierwszego zapytania na pliku lub SPARQL endpoincie powinno spokojnie zmieścić się w piętnastu minutach. Wykonanie zapytania na bazie po pierwsze wymaga już ustawionej bazy, po drugie zmian w znacznie mniej intuicyjnym pliku konfiguracyjnym (którego normalnie nie trzeba ruszać), po trzecie znajomości Jeny, po czwarte dokumentacja dotycząca SDB naprawdę została porzucona i jest w jeszcze gorszym stanie niż reszta, dlatego nie nastawiałbym się na zrobienie tego w ciągu jednego dnia (chyba że ktoś jest bardzo cierpliwy).

Formaty plików

Obsługiwane formaty plików to (sprawdzone doświadczalnie, brak dokumentacji na ten temat) rdf, nt, ttl i n3. Nie obsługuje trig od rdf2rdf i nq. Gubi się na niektórych kodowaniach plików, w szczególności źle odczytuje UCS-2 i UTF-8 z BOM. Działa dla ANSI/UTF-8 bez BOM.

Pamięć

Twinkle działa na JVM, w związku z czym te liczby powinny być traktowane bardzo orientacyjnie. Po starcie zajmuje około 100MB, przeciętnie podczas wykonywania zapytań całkowita zajęta pamięć waha się między 300 a 500MB. W skrajnych sytuacjach (np. próba zapytania na pathways) wzrasta i zatrzymuje się na około 1.2GB. Prawdopodobnie Twinkle jest poprawnie napisany, aby przy nieskończonej ilości czasu radzić sobie z dowolnie długimi plikami, przy próbie zapytania na pathways szybko osiągnął limit 1.2GB, po czym jeszcze bardzo długo działał na tych 1.2GB bez błędów OOM, więc prawdopodobnie kiedyś dałby radę skończyć.

Czasy wykonywania zapytań

Bezpośrednio z plików

rdf - nt - ttl - n3 - trig
a) 18s - 17s - 23s - 26s - N/A
b) 6s - 4.5s - 10s - 15s - N/A
c) 9s - 7.5s - 13s - 18s - N/A

d) N/A - brak odpowiedzi po godzinie

Podsumowanie

Narzędzie nie powala obfitością funkcjonalności ani dokumentacji, ale dla początkujących użytkowników bądź do prostych zadań sprawdza się nieźle. W szczególności na pochwałę zasługuje fakt, że prawdopodobnie poradziłby sobie w końcu z Pathways, w przeciwieństwie do Jeny, która zapychała pamięć i padała. Drugim pozytywnym zaskoczeniem jest brak problemów z podaniem (stricte podaniem) wyniku dla zapytania a), Twinkle jest w stanie go po prostu wyświetlić jak gdyby nigdy nic. Trzecią zaletą jest niewspomninana wcześniej prawdopodobna zdolność do zajmowania obliczeniami więcej niż jednego rdzenia. Nie badałem, ile korzyści to przynosi, być może to tylko podział między pojedynczym wątkiem obliczeniowym a kolejnymi przejściami GC i innymi pobocznymi zadaniami w JVM, ale jeśli jest to rzeczywiste rozbijanie problemu na wiele wątków, to jest to dosyć imponujące.

Twinkle do reszty rozwiązań ma się mniej więcej tak, jak Notepadpp do pełnych IDE. Gdybym był doktorantem i prowadził zajęcia, to nie miałbym wyrzutów sumienia każąc studentom robić coś w ramach laboratoriów w tej aplikacji (może Pan powoływać się na te słowa podczas zajęć pod warunkiem, że nie skomplikują się zbytnio względem tegorocznego stanu). Przygotowując pliki do odpytywania dla Twinkle najwyraźniej najlepiej w miarę możliwości korzystać z formatu .nt, ale różnice raczej nie są zbyt istotne.

Apache Jena

Słownomuzycznie

Ogólnie o projekcie

Apache Jena to pełnoprawny projekt Apache (jest wylistowany na stronie całej organizacji wśród <200 głównych projektów). O jego renomie świadczy między innymi fakt, że jego artefakty (dystrybucje) są dostępne w centralnym repozytorium Mavena - jest to spory plus, można bardzo łatwo pobierać je w niezawodny, powtarzalny i automatyczny sposób. Projekt obejmuje wiele aspektów związanych z Semantic Web i Linked Data, przede wszystkim szereg API spakowanych w biblioteki, ale także kilka konsolowych narzędzi takich jak używany w projekcie do odpytywania plików sparql.bat i używany do całej reszty Fuseki - serwer odpowiadający na zapytania SPARQL, posiadający przy okazji interfejs webowy. Niestety strona projektu kiepsko radzi sobie z jego rozległością, na przykład szukając czegoś związanego z Fuseki łatwo utonąć w przypadkowych innych częściach dokumentacji, które być może zawierają informację, której się potrzebuje, a być może nie. Ostatecznie do wszystkiego znajduje się jakiś tutorial gdzieś na stronie, ale trochę brakuje jednego, wyraźnego, logicznego podziału i w każdym dziale ścieżki prowadzącej za rączkę przez wszystkie atrakcje danej części Jeny. Tutorial do konfiguracji TDB w Fuseki jest w dziale Fuseki, natomiast tutorial do konfiguracji SDB w Fuseki jest w dziale SDB (choć jest to jeszcze wybaczalne z racji tego, że SDB ma już w zasadzie oficjalny status deprecated). Zgoda, są tutoriale 'getting started', ale te na głównej stronie dotyczą głównie API, trochę głębiej znajdą się także te dla Fuseki, wszystkie zawierają sporo podstawowych informacji. Niestety są napisane w stylu 'getting started (yet again)', to znaczy tak jakby były kierowane dla użytkowników, którzy kiedyś byli w miarę biegli w Jenie, ale już zdążyli trochę zapomnieć i teraz chcą sobie tylko odświeżyć swoją wiedzę. Są lakoniczne, całkowicie brakuje 'idiotoodpornego', regularnego przypominania kontekstu czy omówienia przyczyn, dla których wykonuje się aktualny krok. Nawet gdyby wszystko to było trywialne do wywnioskowania dla początkującego użytkownika (a czasem nie jest), to i tak odciąga to od głównego zagadnienia, jakim jest poznawanie narzędzia. Kolejność akapitów wydaje się być w większości przypadkowa, a ich treść nie płynie w jakiś logiczny i konsekwentny sposób od jednego do drugiego i żeby swobodnie zrozumieć większość z nich (to znaczy wiedzieć, jak mają się do reszty), trzeba mieć już jakieś ogólne pojęcie o całości. W dystrybucji są różne przykładowe pliki konfiguracyjne, ale niestety najbardziej interesujący mnie, z konfiguracją TDB dla Fuseki, zawiera błąd i nie działa bez modyfikacji.

Przykład, co nie podoba mi się w dokumentacji

Jako przykład lakoniczności tutoriali można wziąć choćby ten wyżej wspomniany, o integracji Fuseki z SDB. Stwierdza 'The Fuseki server needs the SDB jar files on its classpath.'. W porządku, wiem, co to znaczy classpath, wiem jak efektywnie dodać do niego pliki. Czym dokładnie są SDB jar files? Może znajdę je w paczce z Fuseki? Nie, wygląda na to, że tam ich nie ma, jedyny .jar w tej dystrybucji to ten główny, fuseki-server.jar. Może są w nim odpowiednie klasy, tak jak te od TDB? We fragmencie konfiguracji poniżej jest jakaś klasa com.hp.hpl.jena.sdb.SDB, sprawdzę, czy jest w tym .jarze. Nie, jednak jej nie ma, jest za to pakiet com.hp.hpl.jena.tdb, więc teraz już przynajmniej wiem dokładnie, dlaczego integracja z TDB działała od ręki, chociaż nie powinno mi to być do niczego potrzebne. Zajrzę w takim razie jeszcze raz na główną stronę o SDB. Faktycznie, jest napisane 'SDB is distributed from the Apache Jena project.'. W głównej dystrybucji Jeny w katalogu lib rzeczywiście jest jena-sdb-1.5.1.jar, a w nim szukana klasa. Gdybym wiedział od razu, że tamto jedno konkretne zdanie jest napisane akurat tam, to nie zajęłoby mi to dużo czasu, ale nie wiedziałem, nie zapamiętałem całej treści strony przy pierwszym czytaniu. Gdyby jednak powtórzyło się ono po prostu w tutorialu, bądź był tam dodany link, to całej sprawy by w ogóle nie było i nawet przez myśl by mi nie przeszło, żeby czegoś szukać czy że muszę czegoś szukać, mógłbym się za to w pełni skoncentrować na samym zadaniu i przedmiocie tutorialu, którym jest integracja Fuseki z SDB. A to dopiero pierwsza część problemu, pozostaje jeszcze zapewnić, żeby Fuseki widział ten .jar. Znów, nie jest to trudne, nie zajmuje to wiele czasu, ale jednak zajmuje czas i uwagę, a ilość takich drobnych szczegółów powoduje, że w efekcie większość procesu uczenia się nowego narzędzia to backtracking po różnych fragmentach dokumentacji.

Aplikacje konsolowe

Główna dystrybucja Jeny zawiera kilka konsolowych aplikacji, które pozwalają oddziaływać z bazą TDB lub wykonywać zapytania SPARQL. Do oddziaływania z bazami TDB używany był Fuseki, ale odpytywanie plików zostało sprawdzone, zwłaszcza że jest niedostępne w Fuseki.

Fuseki

Fuseki to kilka funkcjonalności Jeny upakowanych w prostą aplikację webową, która jest uruchamiana na zintegrowanym Jetty (tutaj plus za wkomponowanie serwera w paczkę praktycznie bez śladu dla użytkownika, chociaż właściwie to dokładnie do tego służy Jetty). Według JIRY gdzieś powinna znajdować się jego dystrybucja jako .war (standardowy format webowych aplikacji w Javie, teoretycznie całkowicie niezależny od serwera, na którym się go zdecyduje uruchomić), ale nie udało mi się jej nigdzie znaleźć. W wielu typowych scenariuszach nie jest to w ogóle potrzebne, a w wielu innych nie jest niezbędne, ale miłe byłoby, gdyby jednak gdzieś się znajdowała.

Niestety interfejs na powitalnej stronie (tzn. głównej stronie zwracanej przez serwer po jego uruchomieniu) posiada sporo wyeksponowanych treści, które nie powinny się tam znajdować, przynajmniej nie w takiej objętości (np. wylistowane linki do kilku standardów, każdy osobno, zamiast na przykład jednego, typu 'oficjalne standardy', do podstrony z nimi). Najbardziej interesujące (wczytaj coś do bazy, zapytaj o coś bazę, zapytaj o coś arbitralny SPARQL endpoint) są przez to trudniejsze do zauważenia. Interfejs nie pozwala odpytywać plików z lokalnego systemu plików, a URLe file: nie działają.

Dostępne bez kompilacji czegokolwiek narzędzia

  • Biblioteki TDB (aktualnie rekomendowana metoda przechowywania danych RDF)
  • Biblioteki SDB (aktualnie niepolecana metoda przechowywania danych RDF; to że nie trzeba niczego kompilować nie znaczy, że jest łatwo; wymaga zewnętrznych bibliotek)
  • Skrypty CLI do zarządzania TDB i SDB (tylko bash)
  • CLI do zapytań do plików/dowolnych SPARQL endpointów
  • Serwer HTTP:
    • Web UI
    • Zarządzanie bazami in-memory, TDB i SDB (ograniczone; nie takie proste do zestawienia w wypadku ostatniego)
  • Odpowiadanie na zapytania przez HTTP (niesprawdzone)

Pierwsze zapytanie

Mimo wszystkich opisanych powyżej problemów pierwsze zapytanie teoretycznie dałoby się wykonać w poniżej piętnaście minut, zakładając, że trafi się od razu na dystrybucję z Fuseki zamiast na przykład wsiąknąć w dokumentację API i że nie popełni się żadnego błędu typu brak –update podczas uruchomienia. Minimalnie świadome użytkowanie to prawdopodobnie kwestia rzędu godziny, zdolność do w miarę sprawnego znajdywania informacji na temat dokładnie tego, czego się chce (i wyczucie, czego rozsądnie jest chcieć, a czego nie) to kwestia dni.

Używanie SDB to jeszcze wyższa szkoła jazdy, na zwykłą nieprzystępność/dziurawość dokumentacji Jeny nakłada się fakt, że SDB jest obecnie zamiatane pod dywan oraz mnogość różnych baz danych i sterowników do nich. Atrakcje związane z ustawianiem SDB zawierają między innymi szukanie skryptów przygotowujących bazę (nie, nie są tam, gdzie dokumentacja każe się ich spodziewać, to znaczy w głównej dystrybucji Jeny), instalację cygwina, bo te skrypty są dostępne wyłącznie w bashu (bo przecież można ściągnąć cygwina) czy szybką przygodę z Jena Asemblerem (bo plik konfiguracyjny do SDB via Fuseki z dokumentacji nie zawiera nawet połowy rzeczy, które powinien zawierać). Zestawienie działającej bazy SDB to kilka godzin czystej frustracji (tylko po to, żeby potem okazało się, że faktycznie wydajność jest beznadziejna w porównaniu do TDB).

Formaty plików

Wszystkie sprawdzane formaty plików zostały odczytane w Fuseki, jednak NQuads ma ograniczone wsparcie w interfejsie. Pozwala wczytać dane tylko z jednego grafu naraz, w związku z czym nie da się po prostu wczytać całości pliku za jednym kliknięciem i trzeba znać wszystkie nazwy grafów, w ramach których posiada się dane. W szczególności jeżeli wybrana nazwa grafu do wczytania (domyślnie 'default') nie zgadza się z żadną z plików, to cały plik zostanie mozolnie przeczytany, ale żadne dane nie zostaną zapisane. Nie widzę żadnego sposobu zmiany tego zachowania za pomocą jakichś opcji w GUI, z tego powodu nie udało się zrobić niczego z danymi z BTC.

Pamięć

Konsolowe utility trzymało się raczej poniżej 300MB, w skrypcie domyślny limit sterty to 1024MB (czyli w praktyce można się spodziewać maksymalnie około 1.2GB zajętej pamięci z punktu widzenia systemu operacyjnego, ale ogólnie pamięć JVM to dość złożone zagadnienie). Fuseki po starcie trwającym 1-4s (w zależności od wybranego przechowywania danych i ewentualnie związanego z nim stanu plików) zajmuje około 60MB i trzyma się raczej poniżej 500MB, domyślny limit sterty to 1.2GB.

Czasy wczytywania plików i wykonywania zapytań

Bezpośrednio z plików (via CLI)

rdf - nt - ttl - n3 - trig
a) N/A - N/A - N/A - N/A - 595s
b) N/A - 6s - 7s - 8s - 9s
c) N/A - 8s - 9s - 10s - 12s
rdf - Failed to load data
query a - narzędzie formatuje tabelkę pod najdłuższą znajdującą się w niej wartość, bez łamania linii. Jako że w bazie znajdują się bardzo długie teksty, to zaskutkowało to bardzo długimi ciągami wypełniających spacji, dorównujących do najdłuższego tekstu w tabeli, a wynikowy plik miał 20GB. Wyrzucanie outputu do $null (odpowiednik /dev/null) daje niecałe dwie minuty zysku (z dziesięciu), więc zrezygnowałem z mierzenia tego dla pozostałych formatów.

In-memory base (via Fuseki)

load LAK rdf - nt - ttl - n3 - trig: 11s - 5.5s - 11s - 10s - 10s
load TBC: N/A (patrz wyżej)
load pathways: N/A
query a, output: plaintext /wyświetlany bezpośrednio w przeglądarce/) prawdopodobnie po około 70s przeglądarka wyświetla białą stronę lub zawiesza się; fuseki zawiesza się w jakiejś nieskończonej pętli i zajmuje CPU na 100%
query a, output: CSV /czas do wygenerowania pliku do pobrania/) 5s
query b) instant
query c) <0.5s
query d) N/A

TDB (via Fuseki)

natywna baza trójek, rekomendowana
!uwaga! na powitanie zajmuje ~200MB na dysku dla każdej bazy
load LAK rdf - nt - ttl - n3 - trig: 29s - 24s - 24s - 30s - 27s
load BTC: N/A
load pathways: przy domyślnym limicie sterty 1.2GB po ponad 15 minutach wyrzucił java.lang.OutOfMemoryError, po podbiciu limitu sterty do 3.6GB po 40 minutach znów wyrzucił java.lang.OutOfMemoryError, chociaż z nieco innym stosem (patrz tutaj)
query a, output: plaintext) po około 60s przeglądarka wyświetla białą stronę lub zawiesza się; fuseki zawiesza się w jakiejś nieskończonej pętli zajmując CPU na 100%
query a, output: CSV /do pobrania jako plik/) 9s
query b) instant
query c) 1s
query d) N/A (nie załadował)

Uwaga: Jeśli baza nie była całkiem nowa, to czasy wypełniania bazy były dość znacznie krótsze, nawet jeśli i tak była całkowicie pusta po

DELETE {?a ?b ?c}
WHERE {?a ?b ?c .}

SDB na PostgreSQL (via Fuseki)

load n3: N/A
Po ponad godzinie i piętnastu minutach baza dalej nie była załadowana, relacja 'triples' miała 81199 elementów. Prawdopodobnie całość skończyłaby się ładować w ciągu dwóch godzin, ale dwie godziny na niecałe 100k trójek to i tak raczej słaby wynik. Baza jako taka w ogóle działała, udało się załadować do niej malutki plik RDF utworzony na jednym z laboratoriów z SemWeb.

SDB na MySQL (via Fuseki)

W związku z 'osiągnięciami' SDB na Postgresie i skuteczności Sezame'a zrezygnowałem z powtarzania eksperymentu z SDB na MySQL.

Podsumowanie

Jena to ogromny projekt o wielu aspektach, z których najistotniejszego, czyli API, nawet nie dotknąłem. Niemniej jednak jeżeli jakość całości dokumentacji jest taka, jaką spotykałem do tej pory, to prawdopodobnie osiągnięcie efektywności i biegłości to kwestia dziesiątek, jeśli nie setek godzin. Najsensowniejszym rozwiązaniem, zarówno pod względem łatwości nauki i obsługi jak i wydajności, wydaje się być rekomendowane TDB. Nie wymaga żadnych dodatkowych bibliotek, jest zawarte zarówno w głównej dystrybucji Jeny jak i w Fuseki. Przykładowe konfiguracje są prawie poprawne. Niemniej jednak najwyraźniej albo nie potrafi działać na skończonej pamięci wobec dowolnego rozmiaru danych, albo zakłada masowe ilości pamięci jako minimum. Biorąc pod uwagę fakt, że 4GB to nie tak mało, to prawdopodobnie TDB po prostu ma złożoność pamięciową rosnącą bez ograniczenia razem z rozmiarem danych, co jest raczej słabe.

Sesame

Słownomuzycznie

Projekt jest dosyć typowym 'free OSS version + optional commercial support/commercial enterprise version', jak na przykład Ehcache, Sonar, JBoss/Wildfly czy Artifactory. Co za tym idzie twórcy dbają o przyciąganie nowych użytkowników, zarówno utrzymaniem jak i łatwością w użytkowaniu. Ogólnie dział wrażeń i uwag na temat Sesame będzie raczej krótki, ponieważ wszystko zadziałało od razu, w związku z czym nie miałem przerw 'bo coś nie działa i już nie wiem na razie, jak to poprawić', podczas których pisałem większość tekstu. Jedyny napotkany problem wiązał się z serwerem, a nie samą aplikacją. Domyślnie Wildfly nakłada limit 10MB na przyjmowane przez POST pliki, limit siłą rzeczy dotyczy także ewentualnych plików RDF mających zasilić bazę na serwerze. Podobne limity prawdopodobnie istnieją także na innych serwerach i warto na to zwrócić uwagę. W przypadku Widlfly'a (i prawdopodobnie także JBossa AS 7) można to zmienić w pliku konfiguracyjnym %JBOSS_HOME%\standalone\configuration\standalone.xml, w linii z http-listenerem. Należy dodać atrybut max-post-size o wystarczająco wysokiej wartości, np. <http-listener name=„default” socket-binding=„http” max-post-size=„1073741824”/>.

Jakby tego było mało Sezame interaktywnie wyświetla wyniki zapytań, to znaczy można klikać na poszczególne wartości i wtedy wyświetla wszystkie wartości z nią związane, co ułatwia na przykład ocenę, czy zapytanie zwróciło to, czego się spodziewaliśmy. W nagrodę Sezame dostał do przetestowania dodatkowe zapytanie, e), podobne do c), ale na bazie pathways.

SELECT ?prot2 ?name
WHERE {
  <http://purl.org/pc2/4/hprd9_5281861035176930245> <http://www.biopax.org/release/biopax-level3.owl#participant> ?prot1 .
  ?react <http://www.biopax.org/release/biopax-level3.owl#participant> ?prot1 .
  ?react <http://www.biopax.org/release/biopax-level3.owl#participant> ?prot2 .
  ?prot2 <http://www.biopax.org/release/biopax-level3.owl#name> ?name .
}

Dostępne bez kompilacji czegokolwiek narzędzia

  • Biblioteki do wszystkiego poniżej
  • Skrypty CLI (niesprawdzone, wersja Web UI działała zbyt dobrze)
  • Aplikacja webowa (dwuczęściowa, podział na backend i interfejs dla ludzi):
    • Web UI
    • Zarządzanie bazami in-memory, trwałymi oraz opartymi na RDB (wymaga zewnętrznych bibliotek w wypadku ostatniego)
  • Odpowiadanie na zapytania przez HTTP (niesprawdzone)

Pierwsze zapytanie

Zakładając, że ma się już serwer do deployowania aplikacji webowych Javy, bądź niczego się przypadkiem nie zepsuje podczas jego stawiania, pierwsze zapytanie powinno zmieścić się w piętnastu minutach, a po odrobinie przygotowania prawdopodobnie udałoby się nakręcić screencast „First SPARQL query in two minutes”. Po wychwyceniu z tutoriala informacji, że jedna część aplikacji to backend, a druga to UI dla użytkowników i należy uruchomić obie, a interfejs będzie pod /openrdf-workbench, można właściwie zignorować resztę (chociaż jest przystępnie napisana) i dać się ponieść intuicji.

Formaty plików

Sesame obsługuje wszystkie sprawdzane formaty, a oprócz tego na liście do wyboru są także binary rdf, rdf json, trix i json ld. W wypadku niektórych automatyczne rozpoznawanie typu zawodzi i trzeba podawać go explicite (wybierając go z wysuwanej listy), ale nie jest to problem.

Pamięć

Sesame nie dość, że jest aplikacją JVM, to jeszcze jest aplikacją uruchamianą na serwerze aplikacyjnym, w związku z czym mówienie o zajmowanej pamięci tym bardziej traci sens, zwłaszcza o minimalnej, ponieważ może ona monstrualnie zależeć od serwera. Niemniej jednak Sesame wczytując bazę pathways trzymał się cały czas równo poniżej 600MB mimo limitu na stertę 2GB. Daje to nadzieję na to, że jest w stanie pracować przy ograniczonej pamięci na danych o dowolnym rozmiarze. Przy tym samym limicie udało mu się upchnąć pathways do in memory (i to w dodatku ekspresowo) - zajmuje 2.3GB w systemie (jak wspominałem pamięć w JVM to skomplikowana sprawa), ale wewnętrznie w puli OldGen (czyli w uproszczeniu tych obiektów, które rzeczywiście trzeba przechowywać, czyli należących do faktycznej reprezentacji danych) po pełnym GC zajętych jest tylko 1.16GB. W związku z tym można przyjąć, że na ponad 5M trójek baza in-memory w Sesame potrzebuje około 1GB pamięci, czyli około 200B na każdą trójkę (a właściwie to czwórkę, bo tak są zapisywane).

Czasy wczytywania plików i wykonywania zapytań

In memory

load LAK rdf - nt - ttl - n3 - trig: 22s - 21s - 21s - 20s - 19s
load pathways: 311s
load BTC chunk 000: N/A (IRI included an unencoded space: [line 202033])
load BTC chunk 042: N/A (Expected '<', found: * [line 1041130])
load BTC chunk 054: N/A (IRI included an unencoded space: [line 455788])
query a) 7s
query b) instant
query c) ~1s

query d) instant
query e) instant

Native Java Store

load LAK rdf - nt - ttl - n3 - trig: 20s - 19s - 20s - 22s - 23s
load pathways: 41m
query a) 7s
query b) instant
query c) ~1s

query d) instant
query e) 2s

Podsumowanie

Za Sesame zabrałem się tuż po pierwszej próbie z Jeną SDB. Była to różnica jak ta między usiłowaniem załatwienia czegoś w dziekanacie tuż po godzinach zamknięcia a oddychaniem. Gdyby Sesame było ziemniakiem, to byłoby bardzo dobrym ziemniakiem. A tak na poważnie - Sezame jest naprawdę intuicyjnym, dobrze skalującym się, wydajnym, zasobooszczędnym narzędziem. In-memory store jest szybsze od native java store i ma możliwość okresowego zapisywania swojego stanu na dysk, więc wydaje się być poważną propozycją dla przechowywania nawet dość sporych baz, zawierających kilka milionów stwierdzeń, jeżeli tylko ilość dostępnej pamięci na to pozwala, a nie tylko zabawką do demonstracji, jak w większości takich przypadków.

Redland (stan z '06)

http://librdf.org/
http://download.librdf.org/binaries/win32/1.0.3/
„The binaries here are unsupported and old” - 21-Apr-2006

Słownomuzycznie

Przy uruchamianiu CLI utilities rappera/roqueta z linii poleceń wyskakuje jedynie generyczne powiadomienie „Program xxx przestał działać”. Przy uruchamianiu z Explorera (tzn. z GUI) można dowiedzieć się, że chodzi o brakujący MSVCR71.dll. Cytowany wcześniej komentarz na temat aktualności dystrybucji dla Windowsa najwyraźniej jest świętą prawdą, ta biblioteka jest częścią antycznego Visual C++ 2003 runtime/.NET 1.1. Na szczęście da się go jeszcze pobrać (http://www.microsoft.com/en-us/download/details.aspx?id=26) i po szybkiej instalacji (i ostrzeżeniach o problemach ze zgodnością) można skopiować świeżo zainstalowany Windows\Microsoft.NET\Framework\v1.1.4322\MSVCR71.dll do SysWOW64. Po wyeliminowaniu tego drobnego, aczkolwiek potencjalnie bardzo frustrującego problemu, oba prekompilowane narzędzia, roquet, owijka CLI na bibliotekę Rasqual (do zapytań) i rapper, owijka CLI na bibliotekę Raptor (do parsowania i transformacji plików RDF), uruchamiają się poprawnie. Niemniej jednak nie polecam takich przygód osobom nieprzywykłym do polowania na różne wersje .NETa. W szczególności ściąganie samego pliku MSVCR71.dll z pierwszej lepszej strony i wrzucanie go do SysWOW64 lub System32 naprawdę nie jest dobrym pomysłem.

Jedyne gotowe narzędzia w pakiecie to wcześniej wspomniane roquet i rapper, wszystko inne wymagałoby pisania własnego kodu i kompilacji, co przy względnie słabo znanym języku i zależnościach od bibliotek sprzed dziesięciu lat i starszych zdecydowanie nie jest zachęcającą perspektywą. W roquet można odpytywać pliki podając ich URL (działa file:), podobnie jak w Twinkle, i właśnie ta możliwość została przetestowana.

Dostępne bez kompilacji czegokolwiek narzędzia

  • CLI do parsowania i konwersji między formatami
  • CLI do odpytywania plików i dowolnych SPARQL endpointów

Formaty plików

Roquet otwierał wszystkie formaty, w których zapisana była baza LAK - rdf, nt, ttl, n3, trig, chociaż po pierwsze z bardzo różną szybkością, a po drugie w trig nie uznawał skrótu 'a' dla 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' i traktował go jako błąd.

Pamięć

Prawdopodobnie jedyną zaletą roqueta jest to, że podczas działania trzyma się jedynie około 100MB pamięci.

Czasy wczytywania plików i wykonywania zapytań

rdf - nt - ttl - n3 - trig:
query a) 71s - 79s - 600s - N/A - N/A
query b) 21s - 26s - 565s - 576s - N/A
query c) 127s - 141s - 650s - N/A - N/A
n3 - w związku z powalającą wydajnością dla ttl i n3 nawet nie próbowałem wykonywać wolniejszych zapytań na n3.
trig - roquet nie zezwala na użycie skrótu 'a' dla 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', w związku z czym nie odczytuje danego pliku.

Podsumowanie

W stanie out-of-the-box na Windowsa Redland jest w zasadzie bezużyteczny. Nie jest ani bezproblemowy w instalacji, ani nie posiada zbyt wielu funkcjonalności, ani nie jest szybki (~dwukrotnie wolniejszy od 'zabawki' Twinkle, w pesymistycznym przypadku ttl i n3 nawet ~50-krotnie). Bardzo możliwe, że w aktualniejszej wersji linuxowej działa znacznie lepiej, możliwe, że gdyby chcieć wcielać go do swojej aplikacji, to API ma potencjał, ale jako gotowe narzędzie dla Windowsa sprawdza się koszmarnie.

3store

Słownomuzycznie

Projekt 3store jest tu wspomniany chyba głównie z powodów historycznych. Po pierwsze jego wsparcie dla Windowsa jest zerowe - dystrybucja to paczka źródeł z bashowymi skryptami, które generują makefile, a dalej prawdopodobnie nie jest lepiej. Po drugie opierał się on na MySQL, a bazy danych RDF zdecydowanie odchodzą od RDB ze względu na ich kiepską wydajność w takich zastosowaniach. Po trzecie od dawna nie pojawiały się w nim żadne zmiany, na sourceforge ostatnie są z 2006. Niemniej jednak zdaje się, że w swoim czasie był bardzo mocnym rozwiązaniem i nadal pojawia się w wielu miejscach jak listy przykładowych baz trójek.

4store

Słownomuzycznie

4store jest do pewnego stopnia spadkobiercą 3store. Na pewno przejął jego niechęć do Windowsa, na stronie projektu jest napisane wprost, że nikt nie próbował go przenosić, a gdyby nawet ktoś spróbował, to prawdopodobnie miałby bardzo trudno. Posiada zdecydowanie lepszą dokumentację od 3store. Okres jego świetności (przynajmniej liczony ilością zmian w repozytorium) przypadał mniej więcej na lata 2009-2012, a teraz wygląda na to, że również powoli wygasa (chociaż jeszcze nie jest całkiem martwy).

Ostateczne podsumowanie

Wśród testowanych rozwiązań Sesame zdecydowanie zdeklasował konkurencję we wszystkich możliwych aspektach. Jedynie Twinkle broni się faktem, że jest ~10MB zabawką, a nie 100MB kombajnem, wymagającym jeszcze osobno serwera. Jeżeli tylko API jest tak dobrze przygotowane jak aplikacja, to jest to naprawdę świetny projekt.

Jeżeli chodzi o system operacyjny, to Windows niewątpliwie ogranicza liczbę dostępnych opcji w dziedzinie triple stores, a niektóre z pozostałych utrudnia, ale z drugiej strony nie wyklucza wszystkich możliwości i zostawia także te najlepsze.

pl/dydaktyka/semweb/2014/projects/triplestores.txt · ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0