• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
JPA avec Cassandra, grâce à Achilles
 

JPA avec Cassandra, grâce à Achilles

on

  • 1,233 views

 

Statistics

Views

Total Views
1,233
Views on SlideShare
847
Embed Views
386

Actions

Likes
1
Downloads
11
Comments
0

13 Embeds 386

http://blog.ippon.fr 225
http://cloud.feedly.com 59
http://feeds.feedburner.com 51
http://www.newsblur.com 19
http://www.feedly.com 18
http://reader.nunux.org 3
http://localhost 2
http://www.feedspot.com 2
http://feedly.com 2
http://127.0.0.1 2
http://www.nexxea.com 1
http://digg.com 1
http://leed.burgaud.name 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    JPA avec Cassandra, grâce à Achilles JPA avec Cassandra, grâce à Achilles Presentation Transcript

    • https://github.com/doanduyhai/AchillesJPA avec Cassandra ?Mission pas impossible !1
    • https://github.com/doanduyhai/Achilles• Développeur Java freelance full-stack• Bidouilleur Cassandra, créateur d’Achilles• En mission chez• doanduyhai.wordpress.com• @doanduyhai2Duy Hai DOAN
    • https://github.com/doanduyhai/AchillesAchillesPrésentation3
    • https://github.com/doanduyhai/AchillesAchilles• Framework de persistance JPA pour C*• Support des annotations/opérations JPA• Extensions spécifiques à C*• 2 implémentations : Thrift & CQL3*4
    • https://github.com/doanduyhai/AchillesPourquoi Achilles ?• Voulez-vous écrire ça ?5
    • https://github.com/doanduyhai/AchillesPourquoi Achilles ?• ou ça ?6
    • https://github.com/doanduyhai/AchillesPourquoi Achilles?• Librairies trop bas niveau (Hector, Thrift)• Virage vers SQL avec CQL3 par Datastax• Object mapper nécessaire pour lierentités/requêtes• Concepts JPA: bien connus et maîtrisés7
    • https://github.com/doanduyhai/AchillesMapping d’entités• Annotations JPA– @Entity, @Table– @Id, @EmbededId, @Column, @JoinColumn– @OneToOne, @OneToMany …• Spécifiques à Cassandra– @WideRow– @Consistency– @Key (composite)– @Lazy8
    • https://github.com/doanduyhai/Achilles 9Mapping d’entités@Entitypublic class UserBean@Idprivate Long id;@Columnprivate String name;@Lazy@Columnprivate List<Long> friendIds;@Columnprivate WideMap<UUID, String> tweets;@ManyToOne@JoinColumnprivate UserBean referer;
    • https://github.com/doanduyhai/AchillesTypes spécifiques Cassandra• WideMap<K,V>: miroir d’une column family– KeyValue<K,V>: représente une colonne– KeyValueIterator<K,V>: itérateur• Counter: compteur distribué10puissancealfred batgirl catwoman lois_lane robin1 6 7 1 8WideMap<String,Integer>KeyValue<String,Integer>
    • https://github.com/doanduyhai/Achilles 11Entity Manager• find(Entity.class,pk)– retourne entité « managed » (proxy)• getReference(Entity.class,pk)*– retourne proxy sans chargement initial– peut servir pour du direct-update• persist(entity)– écrase/met à jour toute valeur existante– persist(User(fn,ln,age)) puis persist(User(fn,ln)) ?
    • https://github.com/doanduyhai/AchillesEntity Manager• merge(entity)– dirty check + flush à C*– retourne entité « managed » si transient– entité retournée == entité mergée• remove(entity)– effacer + cascade delete des types de C*• refresh(entity)– recharge l’entité– identique à find()12
    • https://github.com/doanduyhai/AchillesPersistance avec Thrift• Persistance des champs « simples »1310firstname lastname ageDuyHai DOAN 32• Persistance des listes100 1 2 3Java Cassandra Scala Angular JS
    • https://github.com/doanduyhai/Achilles 14Persistance avec Thrift• Persistance des Sets101265231 68754 546546#Cassandra #Achilles #Tatami• Persistance des Maps10113131 6543213 51313 65465464{language:Java} {database:Cassandra} … …
    • https://github.com/doanduyhai/AchillesDirty check• Interception seulement sur getter (internal calls )• Pas d’update atomique des collections/maps• Dirty check des collections/maps coûteux en ThriftImpl– (read + delete) + write pour mettre à jour (pas de slicedelete)– optimisation possible pour Set & Map– list.add(2,peter) ???– faible cardinalité conseillée (10 -20)15friends0 1 2 3 4bob alice john helen richard
    • https://github.com/doanduyhai/AchillesLazy Loading• @Lazy, typiquement collections/maps• Champs chargés à l’appel du getter• Chargement complet des collections/maps parslice query• Champs de jointure toujours lazy, par choix deconception16
    • https://github.com/doanduyhai/AchillesJointures• Besoin de cohérence forte au détriment de laperformance• Join collections/maps ->– Optimisation avec MultiGet Slice Query auchargement• 1 lecture pour n clés primaires dans la collection/map• 1 multiget slice query pour charger les n jointures (nlectures côté C*)– Batch mutation pour sauvegarder– Jointure possible sur les WideMap17
    • https://github.com/doanduyhai/AchillesCascading• No cascade• PERSIST– écrase l’entité existante• MERGE– écrase les colonnes existantes si modifiées• REFRESH -> rien• REMOVE -> interdit/non supporté/mal• ALL -> tout sauf REMOVE18
    • https://github.com/doanduyhai/AchillesWideMap API19@Entity@Table(name=«user»)class User@Idprivate Long userId;@Columnprivate String firstname;…..@Column(table=« tweet »)WideMap<UUID,String> tweets;10067e6162-3b6f-… 54947df8-0e9e-… 38400000-8cf0-…Hello world! #IppEvent avec #Achilles Ceci est un tweet...10firstname lastname ageJulien DUBOIS ???
    • https://github.com/doanduyhai/AchillesWideMap API• insert(K key, V value, int ttl)• V get(K key)• remove(K key)• List<KeyValue<K, V>> find(K start, K end, int count)• List<KeyValue<K, V>> findBoundsExclusive(K start, K end,int count)• List<KeyValue<K, V>> findReverse(K start, K end, int count)• List<KeyValue<K,V>> findFirst(int count)• List<KeyValue<K,V>> findLast(int count)• KeyValueIterator<K,V> iterator(int count)• ...20
    • https://github.com/doanduyhai/AchillesWideRow• Entité avec une primary Key + WideMap• Représente directement une column family21@Entity@WideRowpublic class TweetLine@Idprivate Long id;@Columnprivate WideMap<UUID, String> tweets;10uuid1 uuid2 uuid3 uuid4 uuid5Test Hellow World Démo Achilles CQL3 Ipp Event
    • https://github.com/doanduyhai/AchillesCounter API• get()• incr(), incr(n)• decr(), decr(n)• Pas de suppression de compteur, c’est mal• WideMap<xxx,Counter> possible -> column familycounter dédiée22@Idprivate Long userId;@ColumnCounter tweetsCount;"User:10"tweetsCount friendsCount followersCount150 1000 420"Tweet:067e6162-3b6f"likesCount retweetCount5000 15000
    • https://github.com/doanduyhai/AchillesUsage23user.getTweets().insert(uuid, «content »);List<KeyValue<UUID,String>> first10 = user.getTweets().findFirst(10);List<String> last10Tweets = user.getTweets().findLastValues(10);user.setTweets(xxx);• WideMapLong tweetCount = user.getTweetCount().get();user.getTweetCount().incr(3);user.setTweetCount(xxx);• Counter
    • https://github.com/doanduyhai/AchillesDémoComment faire un clone de Twitteravec Achilles24
    • https://github.com/doanduyhai/AchillesCompromis• La lecture des tweets doit être très très rapide• L’envoi des tweets doit être relativementrapide• La suppression des tweets peut être lente25
    • https://github.com/doanduyhai/AchillesScénario 1• Modéliser un utilisateur• Modéliser la liste des amis/suiveurs• Implémenter un compteur d’amis/suiveurs• Implémenter la fonctionnalité « A suit B »• Donner la liste des amis/suiveurs d’unutilisateur• Donner les détails sur un utilisateur26
    • https://github.com/doanduyhai/AchillesScénario 2• Modéliser un « Tweet »• Implémenter l’envoi de tweet• Dupliquer le tweet– dans la liste des tweets propres à l’utilisateur– dans la timeline de l’utilisateur– dans la timeline de tous ses suiveurs27
    • https://github.com/doanduyhai/AchillesScénario 3• Supprimer un tweet– de la liste des tweets de l’utilisateur– de la timeline de l’utilisateur– de la timeline de tous ses suiveurs28
    • https://github.com/doanduyhai/AchillesScénario 4• Implémenter la gestion des hashtags• Créer une tag-line pour les tags• Gérer l’effacement du tweet de la taglinelorsque le tweet est effacé29
    • https://github.com/doanduyhai/AchillesScénario 5• Donner la possibilité de mettre un tweet en« favori » -> favoriteline• Détecter les personnes citées dans les tweets(@login) -> mentionline• Gérer l’effacement de la favoriteline et de lamentionline lorsque le tweet est effacé30
    • https://github.com/doanduyhai/AchillesClés Composite• Interface marqueur MultiKey• Annotation dédiée @Key(order=x)31@JoinColumnprivate WideMap<UserIndex, User> user;public class UserIndex implements MultiKey{@Key(order=1)private String login;@Key(order=2)private Long id;}
    • https://github.com/doanduyhai/AchillesConsistency Level• Par annotation32@Consistency(read=ONE,write=QUORUM)public class User@Column@Consistency(read=ONE,write=QUORUM)private Counter tweetsCount;@Column@Consistency(read=ONE,write=THREE)private WideMap<UUID,String> tweets;• Au runtime– persist(tweet,QUORUM)– merge(user,ALL)– tweetWideMap.insert(uuid1, «a tweet», ONE)
    • https://github.com/doanduyhai/AchillesTTL33• Sur les opérations JPA– persist(entity, ttl)– persist(entity, ttl, writeCL)– merge(entity, ttl)– merge(entity, ttl, writeCL)• Sur les WideMap– user.getTweets().insert(uuid, «content», ttl)• Pas de TTL sur les counters (pas de tombstones)
    • https://github.com/doanduyhai/AchillesLe futureQue nous réserve Achilles dansquelques mois ?34
    • https://github.com/doanduyhai/AchillesProjection• Support complet de CQL3– @NamedQuery, query data mapper– Prepared statement (perf)– Batches « atomiques »– Row key composite (clustering)• Interceptors (@PrePersist,@PreRemove…)• Listeners• Bean Validation (JSR 303)• Secondary index• Callable, Future<>…35
    • https://github.com/doanduyhai/AchillesRetour d’expérience CQL3• PreparedStatement (select fn,ln,age from User where userId=?)– Stocké côté serveur (100.000 max) et par Node– Seules les valeurs sont envoyées à l’exécution– Valeurs nulles possible -> effacer le champ– Pas possible de binder CL, TTL, Timestamp,possible dans C* 2.0– Pas de batch de PS, possible dans C* 2.0– Pas de IN (?) binding pour faire du MultiGet36
    • https://github.com/doanduyhai/Achilles 37Retour d’expérience CQL3• List/Set/Map démystifié– Nouveaux serializers:• ColumnToCollectionType• ListType, SetType,MapType– List: index = timeUUID généré• insertion rapide avec append/prepend• ré-écriture + décalage si insertion par index• read-before-write pour enlever un élément quelconque– Set: valeur stockée directement dans ColumnName– Map: columnName contient la clé
    • https://github.com/doanduyhai/AchillesRetour d’expérience CQL3CREATE TABLE users (user_id int PRIMARY KEY,emails set<text>,top_places list<text>,todo map<int, text>);INSERT INTO users(user_id,emails,top_places,todo)VALUES(1,{ddoan@test.com,dhdoan@gmail.com},[Paris,Chatillon’],{1:Demo Achilles, 2:Implement CQL3});RowKey: 1=> (column=, value=, timestamp=1362010585307000)=> (column=emails:64646f616e40746573742e636f6d,value=, timestamp=1362010585307000)=> (column=emails:6468646f616e40676d61696c2e636f6d,value=, timestamp=1362010585307000)=> (column=todo:00000001,value=44656d6f20416368696c6c6573, timestamp=1362010585307000)=> (column=todo:00000002,value=496d706c656d656e742043514c33,timestamp=1362010585307000)=> (column=top_places:16ae51c0813c11e289730dd4d81b4c6b,value=5061726973, timestamp=….)=> (column=top_places:16ae51c1813c11e289730dd4d81b4c6b,value=43686174696c6c6f6e, timestamp=…)38
    • https://github.com/doanduyhai/AchillesAchilles est open-source donc …39We need you !!!github.com/doanduyhai/Achilles