Artikel top billede

(Foto: Computerworld)

Programmering med NoSQL - del 2

NoSQL adskiller sig væsentligt fra relationelle databaser som MySQL og DB2. For det første er der ofte tale om distribuerede databaser, og for det andet bruges SQL ikke som søgesprog. I dette afsnit kommer du til at stifte bekendtskab med et eksempel på en NoSQL-database: Keyspace.

Af Kenneth Geisshirt, Alt om Data

Denne artikel er oprindeligt bragt på Alt om Data. Computerworld overtog i november 2022 Alt om Data. Du kan læse mere om overtagelsen her.

Keyspace er en distribueret database. Det betyder, at du skal have den kørende på flere servere samtidig. Ved at bruge flere servere kan du lade dine applikationer skalere op, i takt med at du får flere forespørgsler.

Men som første afsnit i denne serie afslører, har distribuerede systemer og databaser en pris: Du kan ikke få konsistens, tilgængelighed og tolerance mod nedbrud på en gang.

Du er nødt til at vælge to af tre egenskaber. Keyspace-udviklerne har valgt, at konsistens og tilgængelighed er de vigtigste egenskaber. Det betyder, at Keyspace vil undlade at bruge servere for at vedblive med at være konsistent.

Selve programmet er skrevet i C++, og Keyspace kan i princippet afvikles under Linux (og andre Unix-lignende systemer), Windows og Mac OS X. Programmet frigives som open source-software, og du kan frit downloade og bruge det.

Der er tale om en NoSQL-database. Det betyder, at data ikke gemmes i tabeller (relationer) som i relationsdatabaser som MySQL.

I Keyspace kan du gemme nøgle/værdipar. Nøglerne skal være entydige, da du ellers ikke kan genfinde værdien, som hører til en nøgle. Omvendt er der ingen krav om strukturen af værdierne.

Som udgangspunkt er både nøglerne og værdierne tekststrenge, og som du vil se i dette afsnit, kan du bruge JSON til at konvertere et php-objekt til en streng, inden objektet gemmes i Keyspace.

Alle instanser i en Keyspace-klynge har samme data. Data kopieres automatisk rundt mellem alle serverne, og det betyder, at der ikke er et enkelt følsomt sted i klyngen, du vil kunne tilgå data, selvom en vilkårlig server er gået ned.

Endvidere er Keyspace udviklet med ydeevne i tankerne, for eksempel viser visse benchmarks, at Keyspace kan håndtere over 100.000 operationer i sekundet på tre Linux-servere.

Kodeeksemplerne i dette afsnit er skrevet i php, men skal afvikles på en kommandolinje i stedet for en webserver. Du kan forholdsvis let skrive eksemplerne om, så al udskrivning sker i html og ikke blot primitive printlinjer.

Ideen med koden er at vise, hvordan kernen i et dokumenthåndteringssystem kan skrives. Kun en type dokument er vist, men det er let at generalisere til andre typer.

Paxos’ algoritme

Keyspace er, som allerede omtalt, en distribueret database, hvor konsistens og tilgængelighed er de to valgte parametre.

Arkitekturen under Keyspace er, at data er tilgængelig på alle instanser af database hele tiden. Dette omtales som stærk konsistens. Det er svært at sikre i et distribueret system, hvis du ikke gør noget særligt for det.

For 20 år siden udviklede Leslie Lamport (amerikansk datalog) en algoritme til at sikre stærk konsistens i distribuerede systemer. Denne algoritme går under navnet Paxos’ algoritme, og Keyspace bruger en modificeret udgave af denne algoritme. Paxos er en del af det græske øhav, og navnet kommer fra det latinske ord for fred.

Både Google, Microsoft og IBM bruger Paxos’ algoritme i nogle af deres produkter. Ideen er, at en instans er master, eller rettere en instans har en »lease«. Endvidere replikeres data til de andre instanser fra masteren. Masteren har en lease i syv sekunder ad gangen (det er standardværdien, men du kan ændre den).

Lige inden denne lease udløber, vil masteren forlænge den i yderligere syv sekunder. Er masteren gået ned, vil den ikke forlænge, og derved vil ingen instanser have en lease.

I den situation vil alle instanser forhandle om, hvem der skal have en lease og derved være master i de næste syv sekunder. Konsekvensen er, at en Keyspace-klynge højst kan være uden master i syv sekunder, og i den tid vil data ikke blive kopieret.

Det vil altid være muligt at hente en konsistent værdi fra Keyspace-klyngen, men der kan være, korte, pauser i at gemme data. Disse pauser vil applikationen ikke se, da det er pakket ind i klientbiblioteket.

Installation

Der findes ingen binære pakker af Keyspace til hverken Linux, Windows eller Mac OS X. Det er dog ikke svært at få Keyspace installeret under Ubuntu Linux, men der er en række trin, som du skal igennem. Først skal du gøre Ubuntu Linux klar til Keyspace. Eftersom du skal installere direkte fra kildeteksten og ikke fra en binær pakke, kræver det, at du har et mindre udviklingsmiljø klar.

For at oversætte Keyspace er en C++-oversætter nødvendig. Endvidere skal du have udviklerversion til Berkeley DB installeret. Alt dette klarer du med kommandoen sudo apt-get install g++ make libdb4.6++-dev.

I skrivende stund er version 1.9.0 seneste udgave af Keyspace. Du kan downloade Keyspace fra den officielle hjemmeside med kommandoen wget http://scalien.com/releases/keyspace/keyspace-1.9.0.tgz.

Med kildeteksten downloadet kan du pakke de komprimerede filer ud med tar xzf keyspace-1.9.0.tgz og skifte til folderen med Keyspace (cd keyspace-1.9.0). Endelig er du klar til at oversætte og installerede Keyspace. Det gør du med kommandoerne make og sudo make install.

Det er muligt at tilgå Keyspaces data ved hjælp af http-forespørgsler. Men i mange situationer skal Keyspace bruges i en applikation. Keyspace understøtter en lang række programmeringssprog, herunder php.

Som ved installationen af Keyspace er der en række trin for at få php-understøttelse til at virke. Du skal være sikker på, at dit php-miljø på applikationsserveren er klar til at sende forespørgsler til Keyspace.

Under Ubuntu Linux skal du derfor udføre kommandoen sudo apt-get install php-config php5-dev. Derved installerer du en række pakker (både php-config og php5-dev tiltrækker en række andre pakker), som gør det muligt at oversætte nye php-moduler.

Når dit php-miljø er klar, kan du oversætte Keyspace-modulet med kommandoen make phplib. For at bruge Keyspace i dine php-applikationer kan du med fordel kopiere php-modulet og tilhørende php-filer over i folderen med din applikation. Kommandoen cp bin/php/* /srv/web/app kopierer de relevante filer over i folderen /srv/web/app.

Som det sidste er du nødt til at rette lidt i php-fortolkerens konfigurationsfil. Under Ubuntu Linux finder du den som /etc/php5/cli/php.ini eller /etc/php5/apache2/php.ini afhængig af, om du ønsker at afvikle din applikation fra en kommandolinje (Command Line Interface) eller som web-applikationer under Apache. Du skal rette to linjer.

Først skal extension_dir sættes til værdien “/”, hvilket betyder, at php-moduler kan være placeret i samme folder som applikationen.

Som det andet skal du have php-fortolkeren til at aktivere Keyspace-modulet. Det gør du ved at sætte enable_dl til on (teknisk set er et php-modul et dynamic library og enable_dl viser, om sådanne moduler er slået til eller ej).

Konfiguration

Keyspace-udviklerne har gjort det let for brugere af Keyspace. Med kildeteksten til Keyspace følger der også en konfiguration, som kan bruges i testsituationer. Eftersom Keyspace er en distribueret database, er det egentlig et krav, at du har mere end en server. Men under udvikling og test af applikationer kan du nøjes med én computer.

Tricket er, at tcp-portene for de tre instanser af Keyspace er forskellige, mens tcp-portene i et produktionsmiljø vil være de samme på alle serverne, mens ip-adresserne vil være forskellige.

Ønsker du hjælp til at bygge konfigurationsfilerne op, kan du bruge programmet keyspace-config. Det er et lille tekstbaseret værktøj, som stiller dig en række spørgsmål og til slut genererer en række konfigurationsfiler.Programmet vil i øvrigt generere en tegning af arkitekturen, i ASCII-art.

Det er også muligt at skrive konfigurationsfilerne i hånden, idet der er tale om flade tekstfiler. Dokumentationen til Keyspace finder du på Keyspaces hjemmeside, hvor alle parametre er godt dokumenteret.

For at starte Keyspace op i testkonfigurationen (tre instanser på én server) kan du bruge kommandoen: for i in $(seq 0 2) ; do script/safe_keyspaced bin/keyspaced test/$i/keyspace.conf test/$1 ; done. Der er tale om en løkke skrevet i BASH, og i hver iteration startes en instans af Keyspace op.

Når du er kommet så langt, at Keyspace er startet op, kan du med en browser tjekke, om det virker. Kører Keyspace på din desktop-computer, kan du tjekke Keyspace ved at gå til følgende to url’er i din browser: http://localhost:8080/ og http://localhost:8081/.

Gem en fil

Med php-modul og støttekode på plads kan du skrive applikationer i php, som bruger Keyspace. Php-udgaven af klientbibliotektet til Keyspace har en klasse ved navn KeyspaceClient, og du skal sørge for at oprette et objekt i denne klasse for at gøre dig i stand til at sende forespørgsler til din Keyspace-klynge.

Argumentet til constructor er et array af ip-adresser/tcp-porte, som udgør klyngen. I boksen ’gem_billede.php’ finder du et eksempel på, hvordan en fil (her et billede) gemmes i Keyspace. Variablen client er det omtalte objekt.
Metoden ’set’ tildeler en værdi til en nøgle. I eksemplet i boksen ’gem_billede.php’ finder du metoden i anvendelse to gange.

Eftersom Keyspace gemmer et nøgle/værdipar, er du nødt til at have en entydig nøgle. Et trick er at oprette en nøgle, hvis værdi er et indeks. Ved at tælle dette indeks 1 op, hver gang du gemmer noget i din database, har du hele tiden en brugbar nøgle.

Metoden ’add’ bruges til at tælle værdien af en nøgle 1 op, du skal her huske at tildele værdien et heltal første gang. Eksemplet her er noget komprimeret. Du skal huske at adskille den initiale tildeling af en værdi til din indeksnøgle fra resten af applikationerne.

Som eksemplet er vist her, vil du nulstille indeks, hver gang du gemmer et nyt billede. Det er værd at bemærke, at Keyspace bruger strenge til værdier til nøglerne. I eksemplet finder du derfor, at billedet først konverteres til almindelige tegn som bogstaver og tal. Det er egentlig ikke strengt nødvendigt, men det sikrer, at du kan læse data senere.

I stedet for at gemme et php-array eller -objekt konverteres data til en JSON-streng. JSON bruges meget i web-applikationer til kommunikationen mellem browser og server, men da alle kendte programmeringssprog i dag understøtter JSON, er det en fordel at bruge JSON som et slags neutralt format. Fordelen er, at det er muligt at bruge andre programmeringssprog end php sammen med dine data i Keyspace-klyngen.

Oversigt

Med en masse data i databasen vil du sikkert gerne have en oversigt over, hvad der findes. Med metoden ’listKeys’ kan du søge efter nøgler, som begynder med et præfiks (prefix), fra en bestemt nøgle (startKey, første som standard) og kun et antal nøgler (count, uendelig som standard).

Ved at kombinere startKey og count kan du generere websider med oversigter med for eksempel 25 resultater for hver side.

I boksen ’oversigt.php’ kan du se, hvordan listKeys kan bruges. Vil du gerne have værdierne med tilbage i søgeresultatet, kan du bruge metoden ’listKeyValues’.

Disse to metoder bruger masteren til at udføre søgningen. Er det ikke vigtigt for dig (og det er det nok ikke, da du har valgt en distribueret database som Keyspace), kan du i stedet for bruge metoderne ’dirtyListKeys’ og ’dirtyListKeyValues’.

Hent en fil

Ud fra oversigten af nøgler vil dine brugere vælge en fil/billede. Der findes naturligvis også metoder til at hente værdier ud fra nøgler. Metoden ’get’ kan hente værdien til en given nøgle.

I boksen ’hent_billede.php’ kan du se hvordan. Som en lille krølle på halen skal værdien opsættes til et php-objekt ved hjælp af json_decode, og selve billedfilen skal konverteres.

Næste gang

I dette afsnit er du blevet introduceret til Keyspace, som er en distribueret database. Data gemmes uden egentlig struktur, som du ellers kender det fra relationelle databaser.

I næste afsnit rykker vi videre til en anden NoSQL-database, nemlig CouchDB. Det er en database, som nyder stor udbredelse, idet en lang række open source-projekter og kommercielle produkter og websites bruger CouchDB som grundlæggende database.

@include_once(”keyspace.php”);

$client = new KeyspaceClient(array(”127.0.0.1:7080”,
”127.0.0.1:7081”,
”127.0.0.1:7082”));
$date = new DateTime();
$handle = fopen(”/tmp/kneth.jpg”, ”r”);
$imgfile = fread($handle, filesize(”/tmp/kneth.jpg”));
fclose($handle);
$client->set(”billede_index”, ”0”);
$idx = $client->add(”billede_index”, 1);
$a = json_encode(array(”title”=>”billede”, ”timestamp”=>$date->getTimeStamp(), ”data”=>base64_encode($imgfile)));
$client->set(”billede_”.$idx, $a);

Boks – oversigt.php
@include_once(”keyspace.php”);

$client = new KeyspaceClient(array(”127.0.0.1:7080”,
”127.0.0.1:7081”,
”127.0.0.1:7082”));

$a = $client->listKeys(array(”prefix” => ”billede”));
foreach ($a as $i) {
print ”$in”;
}
Boks – hent_billede.php
@include_once(”keyspace.php”);

$client = new KeyspaceClient(array(”127.0.0.1:7080”,
”127.0.0.1:7081”,
”127.0.0.1:7082”));

$billede = json_decode($client->get(”billede_1”));
print $billede->title.” dateret ”.date(”d M Y”, $billede->timestamp).”n”;
$data = base64_decode($billede->data);
$handle = fopen(”test.jpg”, ”w”);
fwrite($handle, $data);
fclose($handle);

[themepacific_accordion]
[themepacific_accordion_section title="Fakta"]

Mere info

[/themepacific_accordion_section]
[/themepacific_accordion]