Yleistä

Cassandra on alkujaan Facebookin kehittämä avoimen lähdekoodin NoSQL-tietokanta, joka on avain/arvopareihin perustuvan ja perinteisen taulukkomuotoisen tietokannan välimuoto. Se on suunniteltu erittäin suurien tietomäärien käsittelyyn, jotka on hajautettu useille erillisille palvelimille. Nykyisen Cassandran ylläpidosta ja kehityksestä vastaa Apache Software Foundation.

Tietomalli

Cassandran tietomalli koostuu sarakkeista (column), riveistä (row), sarakeryhmistä (column family) ja tiloista (key space). Käytännössä Cassandran tietomalli voidaan nähdä moniulotteisena assosiatiivisena taulukkona. Kyselyiden tekoon käytetään SQL:ää muistuttavaa CQL (Cassanda Query Language) -kyselykieltä. Kuvassa 1 on esitetty Cassandran tietomalli.


Kuva 1. Cassandran tietomalli.

  • Sarake - tietomallin perusyksikkö. Koostuu nimestä, arvosta ja aikaleimasta. Yleensä aikaleima sivuutetaan ja puhutaan nimi-arvoparista. Arvon muotoa/tyyppiä ei ole millään tavalla määritelty, vaan se on täysin sovelluksen valittavissa. SQL-tietokannasta poiketen sarakkeiden määrää ei määritellä etukäteen, vaan sovellus voi luoda niitä dynaamisesti niin paljon kuin haluaa.
  • Rivi - kokoelma sarakkeita. Jokaisella rivillä on nimi, joka toimii rivin uniikkina avaimena, jonka muuttaminen ei rivin luomisen jälkeen ole mahdollista. Rivin sisällä sarakkeet on tallennettu sarakkeen nimen mukaiseen järjestykseen. Kullakin rivillä voi olla vaihteleva määrä sarakkeita ja ainoastaan kunkin rivin käytössä olevat sarakkeet tallennetaan fyysisesti.

    Esimerkki 1. Rivi.
    RiviID-> { 
      sarake1=arvo, 
      sarake2=arvo, 
      sarake3=arvo
    }
    
    Second Foundation-> {
      author="Asimov", 
      publishedDate="..",
      tag1="sci-fi", 
      tag2="Asimov"
    }
  • Sarakeryhmä - kokoelma rivejä. Sarakeryhmä rinnastetaan usein perinteisen relaatiotietokannan tauluun. Relaatiotietokannan tauluista poiketen samaan sarakeryhmään kuuluvat rivit voivat sisältää eri määrän sarakkeita, jonka lisäksi uusia sarakkeita voidaan lisätä vain osalle sarakeryhmän riveistä.

    Esimerkki 2. Sarakeryhmä.
    Sarakeryhmä-> { 
      rivi1-> { sarake1=arvo, sarake2=arvo, sarake3=arvo },
      rivi2-> { sarake1=arvo, sarake2=arvo, sarake4=arvo, sarake5=arvo }
    }
    
    Books->{
      Foundation->{author="Asimov", publishedDate=".."},
      Second Foundation->{author="Asimov", publishedDate="..", tag1="sci-fi", tag2="Asimov"}
    } 
  • Tila - sarakeperheiden ryhmä. Sarakeperheiden looginen ryhmä, jolla on oma nimiavaruutensa.

    Esimerkki 3. Tila.
    Tila-> {
      Sarakeryhmä1-> { 
        rivi1-> { sarake1=arvo, sarake2=arvo, sarake3=arvo },
        rivi2-> { sarake1=arvo, sarake2=arvo }
      },
      Sarakeryhmä2-> { 
        rivi1-> { sarake1=arvo, sarake2=arvo, sarake3=arvo },
        rivi2-> { sarake1=arvo, sarake2=arvo }
      }
    }
    
    Space-> {
      Books->{
        Foundation-> { author="Asimov", publishedDate=".." },
        Second Foundation-> { author="Asimov", publishedDate="..", tag1="sci-fi", tag2="future" },
        I Robot-> { author="Asimov", rank=7, price=14, tag1="sci-fi", tag2="robots" }
       },
     Tags2BooksIndex->{
       sci-fi-> { 1311031405918="Foundation", 1311031405919="I Robot" }
       future-> { 1311031405920="Foundation" }
      }
    }
  • Supersarake - sarake, joka sisältää kokoelman alasarakkeita.

    Esimerkki 4. Supersarake.
    RiviID-> { 
      Super sarake1-> { sarake1=arvo, sarale2=arvo }
    }
    
    Cath-> {
      username-> { firstname="Cath", lastname="Yoon" }
    }
  • Supersarakeryhmä - sarakeryhmä, joka sisältää kokoelman supersarakkeita.

    Esimerkki 5. Supersarakeryhmä.
    Super sarakeryhmä-> { 
      RiviID-> { 
        Super sarake1-> { sarake1=arvo, sarale2=arvo }, 
        Super sarake2-> { sarake1=arvo, sarake3=arvo }
      }
    }
    
    UserList-> { 
      Cath-> {
        username-> { firstname="Cath", lastname="Yoon" },
        address-> { city="Seoul", postcode="1234" }
       }
       Terry-> {
        username-> { firstname="Terry", lastname="Cho"},
        account-> { bank="hana", accounted="12342 }
      }
    }

Suhde relaatiokantoihin

Sarakeryhmissä sijaitseva tieto on tallennettu kaksiulotteiseen assosiatiiviseen taulukkoon, jonka sisältämiin yksittäisiin tietoihin päästään käsiksi rivin ja sarakkeen nimen kautta. Tässä suhteessa perinteinen relaatiotietokanta ja Cassandra toimivat samalla periaatteella, mutta monilla muissa osa-alueilla on useita merkittäviä eroavaisuuksia.

  • Relaatiotietokannan samassa taulussa olevilla riveillä on kaikilla samat sarakkeet ja tietyn sarakkeen sisältämä tieto on vertailukelpoista eri rivien kesken. Kaikien rivien kaikilla sarakkeilla on pakko olla jokin arvo, vähintään null. Cassandrassa sarakkeiden määrä ja sisältö voivat vaihdella samaan sarakeryhmään kuuluvien rivien välillä, jonka vuoksi sarakkeisiin on tallennettu varsinaisen datan lisäksi myös sarakkeen nimi. Ainoastaan käytössä olevat sarakkeet tallennetaan fyysisesti, joka tekee tietomallista harvan. Käytännössä tämä siis tarkoittaa sitä, että mikäli rivi ei sisällä jonkun sarakkeen tallentamaa arvoa, saraketta ei tallenneta lainkaan. 
  • Relaatiotietokannassa sarakkeiden nimet edustavat varsinaista dataa kuvaavaa metadataa ja ne eivät koskaan sisällä varsinaista dataa. Cassandrassa sarakkeiden nimet voivat puolestaan sisältää myös varsinaista dataa. Esimerkiksi yksittäisen ihmisen kaikki puhelinnumerot voitaisiin Cassandrassa tallentaa ihmisen perustietojen kanssa samalle riville siten, että puhelinnumero-sarakkeen nimen perään lisätään juokseva numero aina uutta puhelinnumeroa lisättäessä. Näin ihmisellä voisi olla phone1-, phone2- ja phone3-sarakkeet. Sarakkeiden määrää ei ole määritelty tai rajoitettu, joten sarakkeita lisätään ja poistetaan tarpeen mukaan.
  • Cassandra järjestelee rivien sisältämät sarakkeet niiden nimen mukaisessa järjestyksessä, kun tietokannasta noudetaan rivi. Cassandra mahdollistaa myös hakujen tekemisen sarakkeiden nimien osilla. Edeltävään puhelinnumero-esimerkkiin liittyen haku voitaisiin kohdistaa kaikkiin phone-alkuisiin sarakkeisiin, jolloin kaikki phone-sarakkeet olisivat haun piirissä. Haun rajaaminen tietylle välille sarakkeen nimen perusteella on myös mahdollista, esim. phone1-2.
  • Relaatiotietokannat mahdollistavat monipuolisten liitosten ja yhdistelmien käytön kyselyitä tehtäessä, jonka ansiosta kyseilyillä ei ole merkittävää roolia tietokannan rakenteen suunnittelussa. Cassandra ei puolestaan tue liitoksia (JOIN) tai monia muita SQL-kielen hakumenetelmiä, jonka vuoksi hakuihin kohdistuvat vaatimukset vaikuttavat suoraan tietokannan rakenteeseen ja sen suunnitteluun. Käytännössä relaatiot pitää siis rakentaa sarakkeita hyödyntäen.
  • Cassandrassa rivien avainten muuttaminen ole enää rivien luomisen jälkeen mahdollista. Käytännössä tämä estää esimerkiksi käyttäjätunnuksen tai sähköpostiosoitteen käytön käyttäjätietoon liittyvänä avaimena, koska kyseisiä tietoja on voitava myös muuttaa jälkeenpäin.
  • Useimmat relaatiotietokannat toteuttavat transaktiomallin (ACID), jolla on halutut tiedon oikeellisuuden säilytysominaisuudet. Cassandra ei tue ACID transaktioita, vaan tietokannan konsistenttina pitäminen on sovelluksen vastuulla. ACID-ominaisuuksia löyhentämällä tähdätään parempaan skaalautuvuuteen, saatavuuteen ja suorituskykyyn.
  • Cassandra ei tue vierasavaimia, koska niitä on hankalaa ja tehotonta ylläpitää, kun tiedot on hajautettu ja ositettu jo avaimen perusteella. Tämän seurauksena sarakeperheisiin voi jäädä orpoja rivejä.

Arkkitehtuuri

Cassandra on hajautettu järjestelmä ja sen arkkitehtuuri on esitetty kuvassa 2.

Kuva 2. Cassandran arkkitehtuuri.

Cassandra klusteri koostuu useista erillisistä solmuista (node), joiden välille järjestelmään tallennettu tieto on hajautetettu. Tietojen hajauttamisessa käytetään hyväksi tallennavan tiedon avaimesta laskettavaa tiivistearvoa. Klusterin solmut tallentavat kukin määrätyn alueen järjestelmän tiivistearvoavaruudesta, joten tiivistearvon perusteella tiedetään mihin solmuun tieto on tallennettu. Käytännössä tiedon hajauttaminen ei kuitenkaan näy käyttäjälle millään tavalla, sillä yksittäisen tiedon käsitteleminen onnistuu minkä tahansa klusteriin kuuluvan solmun kautta, sillä solmut osaavat reitittää pyynnöt eteenpäin sille solmulle, jonne käsiteltävä tieto on tallennettu.

Cassandra mahdollistaa tietojen replikoinnin useille eri palvelimille sijoitetuille solmuille, joka parantaa järjestelmän vikasietoisuutta ja luotettavuutta huomattavasti. Lisäksi myös solmujen kyky reitittää pyyntöjä eteenpäin parantaa osaltaan luotettavuutta merkittävästi, sillä järjestelmä ei kaadu yksittäisten solmujen vikaantumiseen. Vikaantuneet solmut pystytään myös vaihtamaan lennossa sekä uusia solmuja lisäämään klusteriin ilman järjestelmän alasajoa tai uudelleenkäynnistämistä. Järjestelmä on myös hyvin skaalautuva, sillä sekä luku- että kirjoitusoperaatioiden nopeus kasvaa lineaarisesti uuden palvelinkapasiteetin lisäämisen myötä.

  • No labels