Datomic La base qui détonne (aka database as a value)
Identité Base de données NoSQL Distribuée ("cloud"!) ACID Annoncée début 2012 Version 0.8.XXXX Rich Hickey et Relevance (Clojure!) Licence privative
Distribuée et ACID? Théorème de CAP "On ne peut garantir les trois contraintes en même temps." => Vous ne pouvez assurer la disponibilité ET la consistance que si vous n'êtes pas distribué. A B Autorise-t'on les écritures en cas de partition?
Un choix structurant RDBMS MongoDB HBase Redis MemcacheDB BigTable Voldemort Riak Couchbase Dynamo Cassandra
Le choix Datomic "Favor ACID transactions instead of unlimited write scalability" Séparation des écritures et du requêtage Des écritures ACID Isolées par sérialisation sur un composant unique lequel assure la Cohérence par la maj de toutes les structures requêtables joignables
+ 2 astuces Les requêtes sont jouées via des index en mémoire sur le client sur des données immuables Un client isolé des écritures travaille au pire sur des données dépassées mais toujours "vraies"
L'architecture Datomic Client Peer Lib Client Client Requêtage JVM Comm Index Cache Transactor Service de stockage
Décomposition de la BD Trois axes Stockage Structuration, contrôle et indexation Requêtage Tendance Des systèmes de stockage distribués, redondés,... Au détriment du reste
Le focus de Datomic Utiliser les stockages existants RDBMS, DynamoDB, Riak, Couchbase, Infinispan (La Durabilité est fonction de leur paramétrage) Pour apporter du neuf L'ACIDité en écriture et la disponibilité en lecture Des schémas souples mais de données typées La dimension temps
Le modèle de données Un stockage, orienté colonne, de "faits" appelés datoms : entité attribut valeur transaction (db timestamp) Add/Retract ~ triplet RDF + temps + rétractation
La transaction Référencée par chaque datom C'est une liste d'ajouts ou de retraits à la base de faits : [:db/add entity-id attribute value] [:db/retract entity-id attribute value] Elle définit le temps et l'atomicité.
Le schéma C'est une déclaration d'attributs avec nom type (string, long,..., uri, instant, uuid, ref) cardinalité doc unique index, fulltext iscomponent, nohistory
Batexemple : le schéma [{:db/id #db/id[:db.part/db] :db/ident :comic/name :db/valuetype :db.type/string :db/cardinality :db.cardinality/one :db.install/_attribute :db.part/db} {:db/ident :issue/comic :db/valuetype :db.type/ref :db/cardinality :db.cardinality/one} {:db/ident :issue/name :db/valuetype :db.type/string :db/cardinality :db.cardinality/one} {:db/ident :issue/number :db/valuetype :db.type/long :db/cardinality :db.cardinality/one}
Batexemple : quelques données [ {:db/id #db/id[:db.part/user -1 :comic/name "Batman"]} {:db/id #db/id[:db.part/user] :issue/comic #db/id[:db.part/user -1] :issue/number 1 :issue/name "Knife Trick"} {:db/id #db/id[:db.part/user] :issue/comic #db/id[:db.part/user -1] :issue/number 2 :issue/name "Trust Fall"} ]
L'API Java Obtention d'un Peer String uri = "datomic:mem://comics"; Peer.createDatabase(uri); Connection conn = Peer.connect(uri); Ecriture (schéma, ou données) List transaction = Util.readAll(reader).get(0); ListenableFuture lf = conn.transact(transaction).get(); conn.transact(list(map(":db/id", tempid(":db.part/user"), ":issue/name", "The Thirteenth Hour",...)
Le requêtage Inspiré de DataLog [:find variables... :where clauses...] Batexemple : Database db = conn.db(); String query = "[:find?comic :in $?comicname :where [?comic :comic/name?comicname]]" Collection<List<Object>> res = Peer.q(query, db, "Knife Trick");
Souplesse sur la source de données On peut dériver les sources de données Peer.q(query, db.asof(lasttuesday)); ou since ou filter (predicate) ou with (transaction) pour faire du "what-if?" Ou travailler sur de simples collections : Peer.q(query, acollectionoflistswithtestdata);
That's All Folks! A retenir? Des idées séduisantes Perspectives Architecture à plusieurs transactors? Changement de modèle économique? (Vente d'un support autour d'un source ouvert!)
Références http://www.datomic.com http://nathanmarz.com/blog/how-to-beat-the-cap-theorem.html http://codahale.com/you-cant-sacrifice-partition-tolerance http://en.wikipedia.org/wiki/datalog http://www.infoq.com/articles/architecture-datomic http://www.infoq.com/articles/datomic-information-model https://github.com/jeffbrown/groovy-datomic