Alt om ingenting og litt i mellom En blogg av Knut-Olav

Bigdata RDF-server erfaringer

23. juni 2014 · Comments Off

I jobbsammenheng jobber jeg mye med modellering av data i RDF.

Vi har lenge lagret RDF-grafer som filer på disk, men har den siste tida undersøkt flere RDF-databaser.

Felles for de fleste grafdatabaser er at de trives best i RAM.
Store installasjoner som skryter av å lagre milliarder av tripler består enten av servere med masse minne, eller av mange maskiner i et kluster som tilsammen innehar mye minne – da snakker vi størrelsesorden hundrevis av GB RAM.

Tidligere tester av RDF-databaser

Vi har tidligere testet Jena Fuseki og OpenLink Virtuoso, men begge har sine irriterende problemer.

Jena Fuseki TDB

Jena Fuseki med TDB blir fort ubrukelig når databasen blir større enn Java heap-size, og den feiler ofte med OutOfMemoryError.
Testet med 4 GB Java-heap.

OpenLink Virtuoso

OpenLink Virtuoso har vi testet i versjon 6 og versjon 7.
Versjon 6, som følger med i pakkesystemet til Ubuntu, støttet ikke SPARQL UPDATE.
Versjon 7 feiler når vi prøver å laste inn grafer som inneholder mange blank nodes, selv om vi klarte å hacke oss til en løsning ved å splitte opp insertene i mindre deler.
Generelt sett har Virtuoso flere irriterende problemer, blant annet at den ikke forstår “INSERT DATA” fra SPARQL UPDATE – her måtte vi bruke “INSERT INTO”.

Bigdata

Jeg har i noen dager testet Bigdata, en server for lagring og spørring over RDF-data.

Bigdata-serveren er en Java-applikasjon som kjører i en standard Servlet applikasjons-container.

Innlasting av data

Datagrunnlaget er oppdelt i 525K (525.000) grafer – dokumenter i RDF/TURTLE-format.

Grafene inneholder mange blank nodes, ressurser som ikke er navngitte og globalt identifisérbare med IRI.
Grunnen til at vi bruker blank nodes er fordi vi konstruerer ressurser sammensatt av data fra kildesystemer som ikke tilordner ID-er til disse konseptene.
Dersom vi skulle konstruert ID-er for disse ressursene må vi bruke mye energi og mange kodelinjer for å holde de ID-ene stabile, for å tilordne de samme ID-ene ved neste eksport fra kildesystemet – da er det mye enklere å konstruerer blank nodes.

Innlasting av data ble gjort graf for graf i form av SPARQL UPDATE-meldinger over HTTP, hver delt i to seksjoner – først sletting av eksisterende tripler i grafen, for så innsetting av nye tripler i samme graf.

Sletting av grafer er en viktig funksjon i vårt tilfelle, da vi ønsker å bytte ut alle tripler fra en eventuell gammel versjon av grafen med tripler fra en ny versjon.
Utskiftingen av hele grafer ønsker vi å gjøre som en atomisk operasjon for å unngå at en graf fremstår som tom før nye data lastes inn.

Serveroppsett

Jeg startet med å kjøre Bigdata i en Jetty-container på en server med 4 GB RAM og 100 GB disk – dbdev01.
Med unntak av lokasjonen til journal-fila (databasen til Bigdata), kjørte jeg med standardinnstillinger og 2 GB Java-heap.

Datamengder

Mot denne lastet jeg inn ca 450K (450.000) grafer.
Dette utgjorde i overkant av 84M (84.000.000) tripler.

Journal-fila vokste til 14 GB.

Ytelse ved innlasting av data

I starten klarte jeg å laste inn ca 10 grafer per sekund.
Det er ikke spesielt imponerende hastighet, men siden dette var en test så lot jeg prosessen fortsette.
Etter ett døgn var hastigheten nede i 2-3 grafer per sekund.
Etter to døgn var hastigheten nede i 1-2 grafer per sekund.

Å gjøre SPARQL-spørringer mot databasen samtidig som importen pågikk var bortimot ubrukelig, selv enkle spørringer som å hente ut navn på 60 ressurser.
Samtidig sakt importhastigheten ned til ca 1 graf per 10 sekunder.

Da var 450.000 grafer importert, 85% av datasettet vårt, som for tiden øker med ca 100.000 grafer per år.
Dette skalerer ikke.
Bestemte meg for å avbryte importen.

Ny server med mer minne

Jeg fikk en ny server til rådighet, med 32 GB RAM og 100 GB disk – dbdev02.
Serveren kjørte allerede noen tjenester, så jeg hadde ca 28 GB RAM ledig.
Ellers var det lite last på serveren.

Jeg kopierte journal-fila på 14GB fra dbdev01 til dbdev02, og starta opp Bigdata på begge servere, samme konfigurasjon, og med 1 GB Java heap.

Ytelsestester spørringer

Gjorde samme tester mot begge serverne.

Test #1

Første spørringen mot serveren er en SPARQL-spørring med datofiltrering og dybde på 5 (Vedlegg 1).
Resultatet fra spørringen er ca 80K (80.000) løsninger, i SPARQL RESULTS XML-format på 75 MB.

Ved kald, nyoppstartet Bigdata var dbdev02 (24s) vesentlig raskere enn dbdev01 (2m31s).

Ved gjentatte utføringer av samme spørring var begge servere nokså like raske, også etter kjøring av andre relativt enklere spørringer i mellomtiden.

Test #2

En annen spørring som ga store utslag var med dybde på 4, uten filtrering og med LIMIT 100.000 (Vedlegg 2).
Resultatet fra spørringen er ca 53K (53.000) løsninger, i SPARQL RESULTS XML-format på 22 MB.
Resultatet var altså mindre enn den angitte begrensningen på 100K.

dbdev02 (1m19s) var mye raskere enn dbdev01 (12m23s).
Dette var med varm database.

Innlasting av data mot 32 GB minne

En ny test av import av data, som inkluderer overskriving av gamle grafer, denne gang gjort mot dbdev02 med 32 GB minne, viser en importhastighet på ca 5 grafer i sekundet.

Analyse av testresultatene

Den største forskjellen er rett etter Bigdata nettopp har starta opp.
Mange av spørringene som ga store utslag etter kald oppstart returnerte omtrent like raskt etter gjentagende spørringer.
Dataene i resultatet blir muligens cachet et sted.

Minne

dbdev01 har etter noen spørringer lite ledig RAM, mens dbdev02 har mye ledig RAM.
Det kan tyde mot at Bigdata har det bedre når mye av datafila ligger i minnet.

Diskytelse

Hjelper nok også om disken er rask.
Virker som at disken er raskere på dbdev02 enn dbdev01.
En test lokalt på hver server viser at kopiering av fil på 1 GB tok 14.5s på dbdev01 og 6.2s på dbdev02.
Ingen prosesser på noen av boksene som bruker nevneverdig mye disk-IO når Bigdata idler.

Swapping

Kanskje swapping på dbdev01 kan være årsak, selv om swap-aktiviteten for tiden er lav.

Munin-graf over minne for dbdev02 viser en økning på 16GB i cache (fil-cache) etter oppstart av Bigdata.
Null swapping.

Munin-graf over minne for dbdev01 er fullstendig mongo, går opp og ned som en jojo i den perioden Bigdata har kjørt (2 dager).
Viser også mye swapping, spesielt under inserts.

Konklusjon

Bigdata trives veldig godt med mye RAM og bruker operativsystemets filcache for å få rask aksess til dataene.

Bigdata feiler ikke like dramatisk som Jena Fuseki TDB når minnet går fullt.
Selv om vi endte opp med å teste Bigdata med mer minne enn vi testet med Jena Fuseki TDB, så taklet Bigdata med 4 GB minne mye større datasett enn Jena Fuseki TDB klarte med det samme.

Det er ikke så viktig med stor Java heap under innlasting av data.
Heap-størrelsen øker når det gjøres spørringer, så større heap har kanskje en positiv effekt ved mange og tunge spørringer.

Den nye innlastingstesten viser at Bigdata er mye raskere på innlasting av data dersom den har nok minne til databasen.

Vedlegg

Vedlegg 1: SPARQL Test #1

SPARQL-spørring som lister ut avspilt musikk i en tidsperiode på én måned:

PREFIX dct: <http://purl.org/dc/terms/>
PREFIX ebuccdm: <http://www.ebu.ch/metadata/ontologies/ebuccdm#>
PREFIX digas: <http://id.nrk.no/2013/digas/class/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT * WHERE {
  GRAPH ?g {
    ?part a digas:Music .
    ?timeline ebuccdm:hasTimelineTrackPart ?part .
    ?prog ebuccdm:hasTimelineTrack ?timeline .
    ?trans ebuccdm:playsOut ?prog .

    ?part dct:title ?partTitle .
    ?prog dct:title ?progTitle .
    ?trans ebuccdm:publicationStartDateTime ?startTime .
    FILTER ( ?startTime >= "2014-01-01T00:00:00+01:00"^^xsd:dateTime ) .
    FILTER ( ?startTime < "2014-02-01T00:00:00+01:00"^^xsd:dateTime ) .
  }
}
ORDER BY ?startTime

Vedlegg 2: SPARQL Test #2

SPARQL-spørring som lister ut medvirkende på programmer med en begrensning på 100.000 resultater:

PREFIX nrk: <http://gluon.nrk.no/dataordbok.xml#>
PREFIX dct: <http://purl.org/dc/terms/>
PREFIX ebuccdm: <http://www.ebu.ch/metadata/ontologies/ebuccdm#>

SELECT ?obj ?title ?contactName ?roleName
WHERE {
    ?obj a nrk:programme .
    ?obj dct:title ?title .
    ?obj ebuccdm:hasContributor ?contributor .
    ?contributor ebuccdm:contactName ?contactName .
    ?contributor ebuccdm:hasRole ?role .
    ?role ebuccdm:roleName ?roleName .
} LIMIT 100000

HTC One – trådløst nettverk funnet…

5. juli 2013 · 2 Kommentarer

Ja, så koble deg til det da!! Et av de mest irriterende problemene med HTC One er trådløst nettverkstilkoblingen. Eller mangel av det. Når jeg aktiverer trådløst nettverk tar det gjerne et halvt minutt før den finner nettverket til basestasjonen ved siden av meg. Av og til kobler den seg til, men av og til klager den på autentiseringsproblemer… på et åpent usikra nettverk… WTF?

Når jeg har brukt telefonen litt og har lagt den fra meg for en kort periode før jeg tar den ibruk igjen, så hender det at den forteller meg at alt er i skjønneste orden… men hvor er Internett? Nettleseren har ikke skjønt det ennå, men det er faktisk ingen kobling mot det trådløse nettverket. Løsning: skru av og på trådløst på telefonen… og vente 30 sekunder.

Irriterende! Ellers grei telefon!

Synd det er så gammel Android på den, 4.1.2. Jeg kjører nyere Android på min gamle HTC Desire! Blir nok roota i løpet av sommeren! God sommer :D

Tilkoblingsparametere for å styre Denon AVR 2807

10. oktober 2012 · Comments Off

Jeg har koblet stue-PC-en til receiveren i hjemmekinoanlegget som er en Denon AVR 2807. Den er koblet til med en USB-til-seriell-kabel, slik at jeg kan styre receiveren ved å sende kommandoer til den, men dette skrev jeg om for mange år siden.

Det jeg derimot glemte å skrive var hvordan man skulle koble opp mot den for å sende kommandoer, noe jeg så klart har glemt siden den gang og trøblet litt med i kveld.

Det jeg sleit mest med er at alle terminalklientene jeg testet har aktiv maskinvarebasert flytkontroll, noe som ikke fungerer mot denne receiveren. Så det må skrus av.

Dette kan gjøres via minicom eller kermit. Beskrivelse finnes blant annet hos Gumstix Developer Center.

Etter at flow control er skrudd av kan minicom kjøres:

minicom -b 9600 -D /dev/ttyUSB0 -8 -o

Et tips hvis du bruker minicom er å aktivere “Add linefeed” i konfigurasjonen av “Screen and keyboard”.

FreeBSD top of network connections

2. oktober 2012 · Comments Off

To view the active connections in FreeBSD, which might be a very good debugging/overview tool for a router, one can use ipfstat -t.

This will output something like this:

Source IP             Destination IP         ST   PR   #pkts    #bytes       ttl
10.1.1.100,1052       199.47.216.148,80     4/4  tcp   37860   6446150 119:59:07
10.1.1.100,17500      255.255.255.255,17500 0/0  udp   11681   1740469      1:55
10.1.1.100,17500      10.1.1.255,17500      0/0  udp   11681   1740469      1:55

Finding which Windows process uses what IP socket

2. oktober 2012 · Comments Off

To find out which application uses what IP port on a Windows, both open listening sockets and open connections, you can use netstat with some options and then grep for the port number, or findstr as it’s called in Windows world.

netstat -ano | findstr “:xxxx”

This outputs something like this:

Aktive tilkoblinger

  Prot. Lokal adresse          Ekstern adresse          Tilstand           PID
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING       1232
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:17500          0.0.0.0:0              LISTENING       3500
  TCP    10.1.1.100:139         0.0.0.0:0              LISTENING       4
  TCP    10.1.1.100:1051        10.1.1.1:443           CLOSE_WAIT      3500
  TCP    10.1.1.189:1052        199.47.216.148:80      ESTABLISHED     3500

In the right column you’ll find the PID of the process using the socket. Open task manager, make sure the PID column is visible (might need to add it to the view, then look around in the drop down menus).

Windows Task Manager shows process PID of Dropbox

Windows Task Manager shows process PID of Dropbox

Source: http://www.windowsnetworking.com/kbase/WindowsTips/WindowsServer2008/AdminTips/Network/DeterminingwhatserviceorapplicationownsaTCPport.html

KMail – Use GSSAPI for authentication to IMAP account

21. september 2012 · Comments Off

On a freshly installed Debian testing with KDE desktop, i set up KMail to read email from our corporate MS Exchange server using the IMAP protocol.

The curiosity in me wanted to check out GSSAPI for authentication, but the IMAP server replied with SASL(-4): no mechanism available: no worthy mechs found.

Of course, I need the krb5-user package and run the kinit command to retrieve a valid Kerberos session ticket. What wasn’t so obvious was the need for the package libsasl2-modules-gssapi-mit. Voila! Got me some emails :D

Redshift – a Linux tool for late nights

6. september 2012 · Comments Off

Redshift is a nice Linux tool for adjusting the color temperature of the screen according to time of the day.

At night this tool makes the screen a bit warmer, so your eyes wont “hurt” so much of the otherwise so bright display of your desktop background, browser or editor.

You provide the tool with your approximately geo coordinates and some value for upper and lower limit of color temperature, then it will automatically and continuously change color temperature all through day and night.

Example command for running this tool, if your’re in Norway:

$ redshift -l 60.0:10.0 -t 5700:3600 -g 0.8 -m vidmode -v

MIME Multipart, boundary og linjeskift

3. august 2012 · Comments Off

MIME Multipart-meldinger er kresne og er vanskelige å håndkode.
Det er allikevel mulig å håndkode dem hvis man har god nok teksteditor (som kan vise kontrolltegn som linjeskift) og god tålmodighet og tunga rett i munnen.

MIME-meldinger krever CRLF-endinger på linjene før og etter boundary-kodene og etter hver MIME-header.
I eksempelet nedenfor representeres hvert linjeskift som LF.

MIME-meldingseksempel

De steder hvor det står ^M brukes CR, som oftest rett før linjeskiftet.


--part-boundary-1^M
Content-Type: text/plain; charset=utf-8; name=litt-tekst.txt^M
Content-ID:
^M
Content-Disposition: attachment; name="litt-tekst.txt"; filename="litt-tekst.txt"^M
^M
Dette er noe tekst i en fil som heter some-text.txt
Denne fila bruker UNIX-linjeendinger, altså LF og ikke CRLF,
og det er helt i orden, siden innholdet av denne tekstfila er utenfor kontekst av MIME.

Dette er siste linje i fila^M
--part-boundary-1^M
Content-Type: image/png; name=lite-bilde.png^M
content-transfer-encoding: base64^M
^M
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAAL
EwAACxMBAJqcGAAAAAd0SU1FB9wIAwwLKSOxKhgAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRo
IEdJTVBXgQ4XAAAAMklEQVQoz2P8z4AD/Mcuw8RAIhjGGv7/J0UDbtUMDAws+KQZGUnxAzbVuDXg
UD1SYxoAH7UJHx3uIsQAAAAASUVORK5CYII=
^M
--part-boundary-1--^M

Store og små bokstaver i navn på MIME-headere har ingen betydning.

Blokk og separatorkoder (boundary)

I denne meldingen bruker vi separatorkoden (boundary) part-boundary-1.
Separatorene i fila prefikses med --, som viser til start på en MIME Part-blokk.
En slik blokk varer fram til neste separator av samme kode.
Siste separator appendes med -- i tillegg til prefiksen, som betyr at det ikke er flere blokker.

En blokk i en multipart kan også være en multipart, men blokker under denne separeres med egen separatorkode.

Teste meldingen mot en server

For å teste opplasting med HTTP til en web servlet kan man bruke curl.
Vi lagrer multipart-meldingen på fil melding.multipart.
For at serveren skal kunne forstå multipart-meldingen må Content-Type-headeren spesifiseres som multipart/related og boundary satt til part-boundary-1.

Eksempel på kommando:


$ curl -X POST \
    -H "Content-Type: multipart/related; boundary=\"part-boundary-1\"" \
    --data-binary @melding.multipart \
    "http://localhost:8080/multipartServlet"

Forskjellige biblioteker og krav til CRLF

Det er noe forskjeller i hvordan forskjellige kodebiblioteker tolker multipart-meldinger.
Noen tillater linjeendinger med bare LF (uten CR), mens andre er strengere og krever CRLF.

Servlet 3 sin multipart-parser er streng og krever CRLF.
Samme er tilfellet med CXF sin SOAP-Attachment-parser.

Telia MMS MMSC-parser er derimot mer tilgivende.

Ansvarsfraskrivelse…

Det er ikke sikkert jeg har forstått dette 100% ennå.
Det kan være at mitt håndkoda eksempel over inneholder noen skrivefeil.
Jeg hadde Java i tankene da jeg skrev dette, og det er Java jeg har arbeidet med for behandling av MIME-meldinger da jeg forsket på feilscenariene jeg har hatt med linjeendinger.

Mer om MIME-meldinger

RFC 1341 og spesielt seksjonen 7.2 om multipart gir mer informasjon om strukturen til MIME multiparts.

Cryptic error message from Courier IMAP server – Permission Denied

2. juli 2012 · Comments Off

I have debugged this error message for the last couple of days.

Jul  1 23:11:56 lance imapd: LOGIN, user=knut-olav@hoven.ws, ip=[::ffff:AAA.BBB.CCC.DDD], port=[48700], protocol=IMAP
Jul  1 23:11:56 lance imapd: knut-olav@hoven.ws: Permission denied

The solution was pretty simple.

The /tmp folder had bad permissions. This server was only meant for hosting email services, so bad permissions on /tmp folder was actually not an issue earlier.

I guess the wrong permissions were caused by my custom XEN node setup using multiple partitions, including a partition just for /tmp.

Debugging was quite hard

Authentication was successful, as I got a different error message when authenticating with a known bad password.

I debugged it using strace. It wasn’t easy, as courier imap forks out child processes for each connection, which I had to strace as well.

# strace /usr/sbin/couriertcpd -address=0 -maxprocs=40 -maxperip=20 -nodnslookup -noidentlookup 143 /usr/lib/courier/courier/imaplogin /usr/bin/imapd Maildir

Connect to port 143 using telnet.
Log in using this command:

i login MY_EMAIL_USERNAME MY_PASSWORD

Then find the imap process PID. Look for a process running as user vmail:

$ ps axuw|grep imapd
#...
vmail      362  0.0  1.0   4616  1344 ?        S    01:46   0:00 /usr/bin/imapd /var/spool/mail/vmail/hoven.ws/knut-olav/Maildir/
#...

In this case, the PID is 362. Then attach strace to it using strace -p 362, as sudo.

From the telnet interface, I entered a couple of commands like these:

2 select "INBOX"
5 UID fetch 1:10 (UID RFC822.SIZE FLAGS BODY.PEEK[HEADER.FIELDS (From To Cc Bcc Subject Date Message-ID Priority X-Priority References Newsgroups In-Reply-To Content-Type)])

Then I found this somewhere down into the strace output:

open("/tmp/tmpfWsezjv", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied)
write(2, "ERR: knut-olav@hoven.ws: Permiss"..., 43) = 43

Fixing the problem
chmod 1777 /tmp

As I wrote earier… a simple solution.

Bringing an old Dreambox DM-7000 back to life

18. september 2011 · Comments Off

A long time ago, in a … no, really, I can’t remember how long ago it was… but a long time ago I bought a Dreambox DM-7000-C, a 4 headed satellite dish and got a lot of channels. That was a fun time. But time changes fast and finally I got about zero channels. My last attempt to use the Dreambox with a legal Canal Digital (Conax) card failed, and so the Dreambox got stuffed away in a closet.

I came across it one day this summer and decided to give it another try. After all, it was VERY fast in changing channels. And I don’t have to wait two minutes on the Dreambox for the EPG to show either. I browsed the Internet for what firmware to use, and thought that since the box is very old, some final recommended image could be easily found… but no.

Dreambox on top of a Canal Digital box

The Dreambox might be a lot bigger than the box from Canal Digital, but it's a lot faster too!

The world of Dreambox is kind of cloudy, with lots of forums of users with completely different experiences of what works like a dream and what “just sucks”, and of course a lot of broken links. After a while I came up with a list of possible candidates: Peter Pan, Pli jade, OpenPLi, SifTeam, EDG Nemesis and Gemini Project. I was only looking for images compatible with my DM-7000.

Peter Pan Neverland was the “nordic image” of choice, but is now outdated, last version from 13.01.2007.

I saw a forum post of one recommending SifTeam and after some research on my own I found out that they provided the newest image for my box, version 1.9.4c from 04.06.2010. I decided to give it a try, but had to scratch it since it froze to often.

Gemini Project seemed to be more focused on stuffing addons into the firmware such as web servers, SSH server, print server, you name it, than actually provide me with useful information about softcams and stuff needed for watching TV. Actually, to be open to you, I don’t like Gemini Project at all, after they injected a virus into their firmwares that bricked DM-500 clones (in norwegian).

I couldn’t find any information about EDG Nemesis other than the version number and that they have released version 5.0 beta in 08.11.2010. Since no changelog was provided, I decided to drop trying it.

PLi Jade seemed at first to be very old, a version from 27.06.2009, but there is a version called OpenPLi which provides daily builds. I kind of like the idea, but I very much doubt that they work on it daily. I still haven’t figured out when the last change actually was made. This is the version I decided to settle on. It runs smoothly, no crashes, the EPG works and after installing CCcam softcam it reads my Canal Digital card too and I “got the picture”.

A good source for Dreambox images can be found at the website of Dreambox Tool.

Ok, there it is. This is as far as I came on “the project” today, and it remains to see if the card gets updated entitlements or not. I guess the next thing I need is to set up some “bouquets” for easy access to the favourites.