Laurea in Informatica nel 2006 a Catania
~ 3 anni di esperienza nello sviluppo di Software Enterprise
Cofondatore del Catania Ruby User Group,
cataniarb.org
Smanetta progetti open source su
github.comConsideriamo le prestazioni dei database relazionali
di applicazioni web su grande scala. Non appena
raggiungono una massa critica ed hanno successo:
Soddisfare velocemente una mole elevata di
richieste per unita' di tempo diventa cruciale
Nel tempo si sono consolidate varie tecniche
per aumentare il Request Rate dei RDBMS:
Per ottenere cio' sono stati implementati diversi
middleware che ottengono risultati non sempre
soddisfacenti ed hanno il loro prezzo da pagare
Proviamo ad andare a monte per discutere
i costi/benefici dei RDBMS
Versatilita' espressiva: fornisce SQL, un linguaggio
comprensibile per esprimere e manipolare
il modello di dati di un applicativo
Ma, dietro le quinte, la versatilita' ha dei costi:
Purtroppo il modello relazionale risulta inadeguato
per modellare domini di dati gerarchici.
Es.: alberi, grafi.
Esempio: dati gerarchici implementati in SQL
http://dev.mysql.com/tech-resources/articles/
hierarchical-data.html
Inoltre, non essendoci un matching tra la
rappresentazione dei dati fornita dal database
e quella impiegata dall'applicativo
Es. ActiveRecord in RoR:
acts_as_nested_set,
acts_as_a_list, acts_as_a_ordered_list
Del resto sarebbe comodo dotarsi proprio a
livello applicativo di un'interfaccia uniforme
e disaccoppiata ad Abstract Data Types
Es. Code
di messaggi per elaborazioni asincrone,
deque,
code con priorita', etc…
Consiste praticamente in una tabella hash. E' piu'
semplice concettualmente rispetto ad un RDBMS
Alcuni dei piu' noti sono CouchDB,
Tokyo Cabinet,
Voldemort e da poco meno di due mesi
anche
Redis
Concepito da antirez, al secolo
Salvatore Sanfilippo, uno dei
migliori Hacker della comunita'
italiana di programmatori
Grazie alla sua notevole esperienza,
fissato l'obiettivo, Salvatore e'
capace di valutare e prendere scelte
progettuali con ottimi risultati
Disaccoppiare una Struttura Dati dalla
memoria dell'elaboratore che la usa
Fornire operazioni che consentano
l'implementazione delle principali ADT.
Consentire gli approcci relazionali
a condizione che facciano uso
esclusivamente di chiavi surrogate
Su un singolo Xeon L5420 64 bit, CPU @ 2.5 Ghz, Linux 2.6,
50 client con 100.000 req/s sull'interfaccia di loopback
Si usa il glob style per i pattern
Un valore e' l'elemento associato ad una certa chiave.
Quando esiste, un elemento puo' essere:
una stringa, un insieme o una lista.
require 'rubygems'
require 'redis'
r = Redis.new
r['user:michelangelo:id'] = '1000' # SET user:michelangelo:id 1000
r['user:michelangelo:id'] # GET user:michelangelo:id
r['user:michel:id'] = '1001' # SET user:michel:id 1001
r['user:michel:id'] # GET user:michel:id
# Osserva che il : fa da separatore per namespacing delle chiavi
# poteva anche essere un / , - , etc..
git clone git://github.com/antirez/redis.git
cd redis; make; ./redis-server &
sudo gem install ezmobius-redis-rb; irb
r.delete 'user_id' # DEL user_id
r.set('user_id', 0) # SET user_id 0
r['user_id'] # => 0
r.incr('user_id', 1000) # INCRBY user_id integer
r['user_id'] # => 1000
r.incr('user_id') # INCR user_id
r['user_id'] # => 1001
r.incr('user_id') # incrementiamo il contatore globale
r['user_id'] # => 1002
r['user:alessandro:id'] = r['user_id'] # SET user:alessandro:id 1002
r['user:alessandro:id'] # => 1002
r.delete 'user:alessandro:id' # DEL user:alessandro:id
r.decr('user_id') # DECR user_id
r['user_id'] # => 1001
r.set_add 'user:michelangelo:barcamp2009:tags', 'redis'
r.set_add 'user:michelangelo:barcamp2009:tags', 'storage'
r.set_add 'user:michelangelo:barcamp2009:tags', 'data structure'
r.set_add 'user:michelangelo:barcamp2009:tags', 'web 3.0'
r.set_members 'user:michelangelo:barcamp2009:tags'
# => #<Set: {"data structure", "redis", "storage", "web 3.0"}>
r.set_add 'user:michel:barcamp2009:tags', 'semantic web'
r.set_add 'user:michel:barcamp2009:tags', 'ontology'
r.set_add 'user:michel:barcamp2009:tags', 'rdf/owl'
r.set_add 'user:michel:barcamp2009:tags', 'web 3.0'
r.set_members 'user:michel:barcamp2009:tags'
# => <Set: {"rdf/owl", "semantic web", "ontology", "web 3.0"}>
p 'intersezione'
r.set_intersect 'user:michelangelo:barcamp2009:tags', 'user:michel:barcamp2009:tags'
# => #<Set: {"web 3.0"}>
r.delete 'coda' # inizializza il buffer della coda di messaggi
# produttore
r.push_tail 'coda', 'vino' # => "OK"
r.push_tail 'coda', 'acqua' # => "OK"
# consumatore
r.pop_head 'coda' # => "vino"
# arriva l'antipasto :)
r.push_tail 'coda', 'pane' # => "OK"
r.push_tail 'coda', 'olive' # => "OK"
r.push_tail 'coda', 'caponata' # => "OK"
# consumatore
r.pop_head 'coda' # => "acqua"
r.pop_head 'coda' # => "pane"
# il condimento arriva in ritardo..
r.push_tail 'coda', 'olio' # => "OK"
r.pop_head 'coda' # => "olive"
r.pop_head 'coda' # => "caponata"
r.pop_head 'coda' # => "olio"
r.pop_head 'coda' # => nil non e' rimasto piu' nulla :)
Sono attualmente disponibili client per i seguenti ambienti o
linguaggi di programmazione:
Antirez's face antirez @ flikr.com
Lamborghini Diablo apulloa @ sbcglobal.net
Lamborghini Diablo Engine jclo3313 @ flikr.com
JQuery Slideshow Plugin T. J. Van Slyke