Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro

8,425 views

Published on

Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro

  1. 1. n(ot) o(nly) SQLDes alternatives aux bases de données relationnelles<br />Olivier Mallassi<br />(27 Janvier 2011)<br />http://www.flickr.com/photos/fabbriciuse/2093103013/sizes/l/<br />
  2. 2. @omallassi<br />Architecte @OCTO<br />http://blog.octo.com<br />noSQL User Group @Paris<br />#nosqlfr<br />2<br />
  3. 3. noSQL, kezako?<br />La fin du langage SQL?<br />La fin des transactions ACID?<br />La fin des SGBDR?<br />Non, <br />Juste un sigle qui regroupe des alternatives <br />aux SGBDR<br />Objectifs <br />Proposer une vision synthétique du <br />monde NoSQL<br />Fournir un premier guide de lecture<br />3<br />http://www.flickr.com/photos/nuagedenuit/155699074/sizes/o/<br />
  4. 4. Au commencement était…<br />4<br />
  5. 5. Au commencement était…<br />…le fichier séquentiel (indexé)…<br />… et COBOL<br />Une interrogation (limitée) séquentielle ou par index<br />5<br />SELECT BookFile ASSIGN TO "BOOKS.DAT" ORGANIZATION IS INDEXED <br />ACCESS MODE IS DYNAMIC RECORD KEY IS BookNumber<br />ALTERNATE RECORD KEY IS AuthorNumber WITH DUPLICATES<br />FILE STATUS IS BookErrorStatus.<br />…<br />© OCTO 2011<br />
  6. 6. Vers 1970les premiers modèles relationnels<br />6<br /> Un référentiel unique de données structurées et couplées<br /> Un système centralisé<br /> Une donnée unique (structure, valeur, consistance…) pour toutes les utilisations<br /> On modélise les données puis on développe des applications<br />© OCTO 2011<br />
  7. 7. Puis vinrent…<br />7<br />Objectif : stocker et rechercher <br />dans le web en temps réel<br />Objectif : vendre la plus grande variété<br />d’articles (livres, bricolage…)<br />Des enjeux communs <br />Performance (malgré les volumétries)<br />Disponibilité (>99,99%)<br />Résilience <br />Scalabilité horizontale<br /><ul><li>Enjeux :
  8. 8. Agréger de gros volumes de données</li></ul> BigTable + Map/Reduce<br /><ul><li>Enjeux
  9. 9. Débit important en écriture tout en assurant la disponibilité
  10. 10. Derniers incidents majeurs : 2004
  11. 11. <40 minutes d’indisponibilité par an</li></ul> Dynamo<br />© OCTO 2011<br />
  12. 12. NoSQL aujourd’huiUn foisonnement de solutions…<br />© OCTO 2011<br />8<br />Key/Value<br />Graph<br />Document<br />ColumnOriented<br />
  13. 13. Hadoople modèle Google<br />9<br />
  14. 14. Hadoopun écosystème riche et complexe<br />© OCTO 2011<br />10<br />Un « stack » complexe <br />Le cauchemar de la compatibilité des versions<br />Des « leaders » différents : Cloudera, Apache…<br />Des équipes distinctes : Hadoop, Hive, Sqoop…<br />Pig<br />Dataflowlanguage & compiler<br />Hive<br />SQL LikequeriesDSL<br />Oozie<br />Workflow for interdependentHadoop Jobs<br />MapReduce<br />Framework permettant de « cruncher » des données en parallèle<br />Sqoop<br />Intégration RDBMS & Hadoop<br />Hbase<br />Base de données pour des accès aléatoires read/write<br />Zookeeper<br />Service de coordination<br />HDFS<br />Un système de fichiers distribués<br />Write-once, readmany<br />Flume, Chukwa, Scribe<br />Collection de données fiable et résiliente<br />
  15. 15. HadoopDistributed File System<br />Un système de fichier distribué<br />Permet de stocker des fichiers plus volumineux que ce que peut contenir un disque dur…<br />Répartir les données sur plusieurs machines physiques<br />Répliquer ces données pour assurer le « fail-over »  N * le volume de données<br />11<br />core-site.xml<br />hdfs-site.xml<br />masters, slaves<br /><ul><li>Taille des blocs : </li></ul>dfs.block.size (64MB par défaut)<br /><ul><li>Config. des réplicas (par défaut 3)</li></ul>dfs.replication : le nombre de réplica<br />dfs.replication.min : le nombre de réplica à assurer pour valider une écriture<br />© OCTO 2011<br />
  16. 16. Opérations sur HDFS<br />Des opérations standards (via CLI, Java…)<br />Manipulation de fichiers/répertoires<br />Copie de fichier<br />Copie de fichiers « locaux » sur le HDFS<br />…<br />Une gestion des permissions<br />dfs.permissions = true<br />Intégration possible avec Kerberos<br />© OCTO 2011<br />12<br />$HADOOP_HOME/bin/hadoopfs -rm /chukwa/logs/*.*<br />$HADOOP_HOME/bin/hadoopfs -mkdir /tmp/myfolder<br />/bin/hadoopfs -put /home/user/cash-flow/cashflow-clean.txt /data<br />/bin/bin/hadoopfs –copyFromLocal /myfile.txt /user/myfile.txt<br />/bin/bin/hadoopfs –copyToLocal /myfile.txt /user/myfile.txt<br />
  17. 17. HDFSFailover & résilience de l’infrastructure<br />La résilience de la donnée est assurée par réplication de bloc<br />dfs.replication & dfs.replication.min<br />En cas de perte d’un nœud, une re-replication<br />est programmée<br />Quid de la résilience à la panne matérielle?<br />La réplication utilise la notion de « distance »<br />À l’écriture, on cherche le datanode le « plus proche »<br />La notion de distance est en fait lié à la topologie réseau<br />© OCTO 2011<br />13<br />Hdfs-site.xml<br /><configuration><br /> <property><br /> <name>dfs.replication</name><br /> <value>1</value><br /> </property><br />
  18. 18. MapReduce<br />Le système de requêtage : MapReduce<br />Traiter des volumes de données plus faibles<br />Paralléliser ces traitements « plus » unitaires<br />Co-localiser traitements / données<br />© OCTO 2011<br />14<br />masters<br />slaves<br />core-site.xml<br />hdfs-site.xml<br />mapred-site.xml<br />hadoop-metrics.properties<br />log4j.properties<br />hadoop-env.sh<br />
  19. 19. HadoopfilesystemUn niveau d’abstraction sur le stockage physique<br />© OCTO 2011<br />15<br />Hadoop<br />Local File System<br />HDFS<br />S3<br />FTP<br />Core-site.xml<br /><property><br /> <name>fs.default.name</name><br /> <value>file:///</value><br /></property><br />core-site.xml<br />…<br /><configuration><br /> <property><br /> <name>fs.default.name</name><br /> <value>hdfs://localhost:9000</value><br /> </property><br /></configuration><br />core-site.xml<br /><property><br /> <name>fs.default.name</name><br /><value>s3://BUCKET</value><br /></property><br /><property><br /><name>fs.s3.awsAccessKeyId</name><br /><value>ID</value> </property> <property><br /><name>fs.s3.awsSecretAccessKey</name><br /><value>SECRET</value><br />
  20. 20. MapReduceOverview<br />© OCTO 2011<br />16<br />
  21. 21. MapReducePrincipes de l’algorithme<br />© OCTO 2011<br />17<br />Objectif : réaliser la somme des deals sur un axe d’agrégation<br />GEDEQSWAP John 15/09/2010 EUR 10200 CreditSG<br />GEDSWAPTION John 14/09/2010 EUR 11000 CreditHSBC<br />…<br />GEDSWAPTION John 17/09/2010 EUR 5500 CreditHSBC<br />IRDIRS Simon 13/09/2010 USD 10000 DebitSG<br />IRDIRS Simon 14/09/2010 USD 11000 CreditBankofAmerica<br />(K1, V1)<br />Map<br />agrégation par devise<br />EUR 10200<br />USD -10000<br />EUR 11000<br />EUR 5500<br />USD 11000<br />List(K2, V2)<br />Shuffle & Sort<br />EUR 10200,11000, 5500<br />USD -10000,11000<br />K2,list(V2)<br />Reduce<br />somme sur l’axe d’agrégation<br />Itération sur l’ensemble des K2<br />EUR 26700<br />USD 1000<br />List(K3, V3)<br />
  22. 22. MapReduceImplémentation en Java<br />© OCTO 2011<br />18<br />Objectif : réaliser la somme des deals sur un axe d’agrégation<br />import org.apache.hadoop.mapred;<br /> public static class MapextendsMapReduceBaseimplements Mapper {<br /> public voidmap(LongWritablekey, Text value, OutputCollector output, Reporter reporter) throwsIOException {<br /> String line = value.toString();<br /> String[] lineAsArray = line.split("t");<br /> String currentCurrency = lineAsArray[4];<br /> String amountAsString = lineAsArray[5];<br /> String sens = lineAsArray[6];<br />DoubleWritable data = null;<br /> if("Debit".equals(sens)){<br /> data = new DoubleWritable(Double.parseDouble("-" + amountAsString));<br /> }<br />else if("Credit".equals(sens)) {<br /> data = new DoubleWritable(Double.parseDouble(amountAsString));<br /> }<br />output.collect(new Text(currentCurrency), data);<br /> }<br /> }<br />OutputCollector<K2,V2><br />Key = K1<br />Value = V1<br />Map<br />agrégation par devise<br />Shuffle & Sort<br />/The reduce is called once per key in the output map of the map() function<br /> public static class Reduce extends MapReduceBase implements Reducer {<br /> public void reduce(Text key, Iterator values, OutputCollector output, Reporter reporter) throws IOException {<br /> double sum = 0;<br /> while (values.hasNext()) {<br /> double amount = values.next().get();<br /> sum += amount;<br /> }<br />output.collect(key, new DoubleWritable(sum));<br /> }<br />}<br />Reduce<br />somme sur l’axe d’agrégation<br />Itération sur l’ensemble des K2<br />
  23. 23. Détail du main()<br />Script de lancement <br />Dd <br />dd<br />MapReduceLancement<br />© OCTO 2011<br />19<br />public class CurrencyAggregateextendsConfiguredimplementsTool {<br />@Override<br />public intrun(String[] args) throws Exception{<br />JobConfconf = new JobConf(CurrencyAggregate.class);<br />conf.setJobName("CurrencyAggregate");<br /> //output of the Mapper<br />conf.setOutputKeyClass(Text.class);<br />conf.setOutputValueClass(DoubleWritable.class);<br />conf.setMapperClass(Map.class);<br />conf.setReducerClass(Reduce.class);<br />conf.setInputFormat(TextInputFormat.class);<br />conf.setOutputFormat(TextOutputFormat.class);<br />FileInputFormat.setInputPaths(conf, new Path(args[0]));<br />FileOutputFormat.setOutputPath(conf, new Path(args[1]));<br />JobClient.runJob(conf);<br /> return 0;<br /> }<br />public staticvoid main(String[] args) throws Exception {<br />intexitCode = ToolRunner.run(new CurrencyAggregate(), args);<br />System.exit(exitCode);<br />}<br />$HADOOP_HOME/bin/hadoop jar ./Currency.jar org.CurrencyAggregate /tmp/cashflow-clean.txt /tmp/output10<br />
  24. 24. DSL, DSL…<br />© OCTO 2011<br />20<br />
  25. 25. Hadoopun écosystème riche et complexe<br />© OCTO 2011<br />21<br />Pig<br />Dataflowlanguage & compiler<br />Hive<br />SQL LikequeriesDSL<br />Oozie<br />Workflow for interdependentHadoop Jobs<br />MapReduce<br />Framework permettant de « cruncher » des données en parallèle<br />Sqoop<br />Intégration RDBMS & Hadoop<br />Hbase<br />Base de données pour des accès aléatoires read/write<br />Zookeeper<br />Service de coordination<br />HDFS<br />Un système de fichiers distribués<br />Write-once, readmany<br />Flume, Chukwa, Scribe<br />Collection de données fiable et résiliente<br />
  26. 26. Pig, HiveGénéralités<br />© OCTO 2011<br />22<br />
  27. 27. Pig, HiveStructuration des données<br />Pig ne gère pas de schémas <br />En dehors d’une requête<br />© OCTO 2011<br />23<br />Hive organise les données en table…<br />…un schéma est donc maintenu<br />metastore<br />Ce metastore peut être stocké dans MySQL (par défaut Derby)<br />« Table » ou « External Table »<br />External Table : hive de gère pas la données<br />Intéressant si<br />Multiple schémas sur les même données, <br />Modification des données indépendamment de Hive (ajout, drop…)<br />records = LOAD ‘input/sample.txt’<br />AS (year:character, temperature:int, quality:int);<br />CREATE TABLE cash_flow (BookID STRING, ProductID STRING, TraderID STRING, DueDateBIGINT, Currency STRING, Amount DOUBLE, Direction STRING, Counterparty STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY 't' LINES TERMINATED BY 'n' STORED AS TEXTFILE;<br />LOAD DATA INPATH '/data/cashflow-clean.txt'<br />OVERWRITE INTO TABLE cash_flow;<br />CREATE TABLE…PARTITIONED BY (date STRING, country, STRING);<br />CREATE TABLE…. CLUSTERED BY (id) INTO 4 BUCKETS;<br />
  28. 28. Pig, Hive Accès<br />© OCTO 2011<br />24<br />grunt> A = load 'passwd' using PigStorage(':');<br />hive> CREATE TABLE pokes (fooINT, bar STRING); <br />$HIVE_HOME/bin/hive -e 'select a.col from tab1 a' -hiveconfhive.exec.scratchdir=/home/my/hive_scratch -hiveconfmapred.reduce.tasks=32 <br />$PIG_HOME/pig –x mapreduce script.pig <br />HIVE_HOME/bin/hive -f /home/my/hive-script.sql <br />PigServerpigServer = new PigServer("mapreduce");<br />pigServer.registerQuery("A = load '" + inputFile + "' usingPigStorage(':');");<br />pigServer.registerQuery("B = foreach A generate $0 as id;");<br />//run<br />pigServer.store("B", "id.out");<br />Connection con = DriverManager.getConnection("jdbc:hive://localhost:10000/default", "", "");<br />Statementstmt = con.createStatement();<br />String sql = "select * from " + tableName;<br />ResultSetres = stmt.executeQuery(sql);<br />while (res.next()) {<br /> System.out.println(String.valueOf(res.getInt(1)) + "t" + res.getString(2));<br />}<br />
  29. 29. Pig, Hiverequêtage<br />© OCTO 2011<br />25<br />select Currency, sum(Amount) from cash_flow where Direction='Credit' AND DueDate &lt; = unix_timestamp('2010-09-15 00:00:00') group by Currency<br />Ou<br />SELECT cash_flow_simple.*,user_simple.*<br />FROM cash_flow_simple<br />JOIN user_simple ON (cash_flow_simple.TraderID=user_simple.UserID);<br />records = LOAD ‘input/sample.txt’<br />AS (year:character, temperature:int, quality:int);<br />filtered_records = FILTER records BY temperature != 9999 AND (quality = 0 OR quality == 1);<br />grouped_records = GROUP filtered_records BY years;<br />max_temp = FOREACHgrouped_recordsGENERATE group, MAX(filtered_records.temperature);<br />STORE max_tempINTO ‘/output/file’<br />//créé une table avec 2 colonnes.<br />CREATE TABLE target<br />AS<br />SELECT col1, col2 FROM source<br />;<br />
  30. 30. Alimentation du HDFS<br />© OCTO 2011<br />26<br />
  31. 31. Un fonctionnement similaire <br />Quelques limitations<br />Intégration Scribe / HDFS complexe (compilation)<br />Flume, Chukwa proposent plus de connecteurs (fichiers…) que Scribe (Thrift)<br />Flume, Scribe, Chukwale même principe<br />© OCTO 2011<br />27<br />
  32. 32. Exemple de configurations Scribe<br />Flume, Scribe, Chukwale même principe<br />© OCTO 2011<br />28<br />port=1464<br />max_msg_per_second=2000000<br />check_interval=3<br /># DEFAULT - forward all messages to Scribe on port 1463<br /><store><br />category=default<br />type=buffer<br />target_write_size=20480<br />max_write_interval=1<br />buffer_send_rate=1<br />retry_interval=30<br />retry_interval_range=10<br /><primary><br />type=network<br />remote_host=localhost<br />remote_port=1463<br /></primary><br /><secondary><br />type=file<br />fs_type=std<br />file_path=/tmp/scribetest2<br />base_filename=thisisoverwritten<br />max_size=3000000<br /></secondary><br /></store><br />port=1463<br />max_msg_per_second=2000000<br />check_interval=1<br />max_queue_size=100000000<br />num_thrift_server_threads=2<br /># DEFAULT - write all messages to hadoophdfs<br /><store><br />category=default<br />type=buffer<br />target_write_size=20480<br />max_write_interval=1<br />buffer_send_rate=1<br />retry_interval=30<br />retry_interval_range=10<br /><primary><br />type=file<br />fs_type=hdfs<br />file_path=hdfs://localhost:9000/scribedata<br />create_symlink=no<br />use_hostname_sub_directory=yes<br />base_filename=thisisoverwritten<br />max_size=1000000000<br />rotate_period=daily<br />rotate_hour=0<br />rotate_minute=5<br />add_newlines=1<br /></primary><br /><secondary><br />type=file<br />fs_type=std<br />file_path=/tmp/scribe-central-hdfs<br />...<br /></store><br />
  33. 33. Sqoopde RDBMS vers HDFS et vice-versa<br />Une brique visant à <br />Importer de la donnée d’un RDBMS vers Hadoop (voire Hive)<br />Exporter de la donnée du HDFS vers RDBMS<br />© OCTO 2011<br />29<br />Hive<br />HadoopMapReduce<br />HDFS<br />
  34. 34. SqoopImport / Export<br />Import<br />Export <br />Fonctionne selon la même logique que l’import<br />Les données sont mappées dans l’ordre naturel<br />© OCTO 2011<br />30<br />$ sqoop import --connectjdbc:mysql://localhost/hadoopguide --table comments -m 1<br />$ sqoop import –-connectjdbc:mysql://localhost/hadoopguide --table comments -m 1 –hive-import<br />$ sqoop export --connectjdbc:mysql://localhost/hadoopguide --table comments -m 1 –table comments –export-dir /user/omallassi/comments –input-fields-terminated-by ‘0001’<br />
  35. 35. HBaseet Zookeeper<br />© OCTO 2011<br />31<br />
  36. 36. HBaseLe modèle de données<br />Une base de données distribuée « column-oriented »…<br />…Permettant des accès temps réel et aléatoire en lecture et en écriture<br />En somme, permettant de gérer de la donnée « mutable » contrairement au HDFS<br />© OCTO 2011<br />32<br />Séparation entre « columnfamiliy » et « columnfamilu qualifier » est :<br />
  37. 37. HBaseLe modèle de données<br />Une base de données distribuée « column-oriented »…<br />33<br />Columnfamily<br />Row<br />Cell<br />© OCTO 2011<br />
  38. 38. HBaseVue d’ensemble de l’architecture<br />Un modèle Master/Slave <br />HMaster<br />Gère la localisation des données (HRegion)<br />HRegionServer<br />Les tables sont splittées en HRegion<br />Automatiquement au fur et à mesure de l’insertion de données<br />Les « splits » sont gérés dans Zookeeper. Un accès est réalisé lorsqu’un client se connecte pour localiser la donnée (le « split »)<br />Gestion des écritures par HLog et memstore<br />© OCTO 2011<br />34<br />hbase-default.xml<br />hbase-site.xml<br />regionservers<br />http://www.larsgeorge.com/2009/10/hbase-architecture-101-storage.html<br />
  39. 39. HBasemanipuler les schémas, données…<br />Via CLI<br />© OCTO 2011<br />35<br />Les objets existent dans l’API JAva<br />Il est possible de définir des propriétés (TTL, versions #<br />create 'cash_flow', {NAME => 'bookid', TTL => '10'}…<br />HTableDescriptor<br />HColumnDescriptor<br />Htable<br />…<br />create 'cash_flow', 'bookId', 'productId', 'traderId', 'DueDate', 'currency', 'amount', 'direction', 'counterparty‘<br />Lecture de la donnée « 5 »<br />
  40. 40. HBasemanipuler les schémas, données…<br />© OCTO 2011<br />36<br />Les objets existent dans l’API JAva<br />…<br />conf = new HBaseConfiguration(); <br />admin = new HBaseAdmin(conf); tableDesc = new HTableDescriptor(GRADES_TABLE_NAME); <br />tableDesc.addFamily(new HColumnDescriptor(COURSE_FAMILY)); <br />admin.createTable(tableDesc); <br />HTable table = new HTable(conf, “tableName”); <br />table.put(writeid, courseColumn, new IntWritable(grade)); <br />Get g = new Get(row1);<br />Resultsres = table.get(g);<br />…<br />Créer une HTable<br />Insert une donnée<br />Lecture de la donnée « 5 »<br />
  41. 41. Hashmap distribuéele modèle Amazon : Dynamo, S3, SimpleDB, Cassandra, Riak, Voldemort…<br />© OCTO 2011<br />37<br />
  42. 42. Rappelez vous…<br />38<br />Objectif : stocker et rechercher <br />dans le web en temps réel<br />Objectif : vendre la plus grande variété<br />d’articles (livres, bricolage…)<br />Des enjeux communs <br />Performance (malgré les volumétries)<br />Disponibilité (>99,99%)<br />Résilience <br />Scalabilité horizontale<br /><ul><li>Enjeux :
  43. 43. Agréger de gros volumes de données</li></ul> BigTable + Map/Reduce<br /><ul><li>Enjeux
  44. 44. Débit important en écriture tout en assurant la disponibilité
  45. 45. Derniers incidents majeurs : 2004
  46. 46. <40 minutes d’indisponibilité par an</li></ul> Dynamo<br />© OCTO 2010<br />
  47. 47. Des enjeux différents de ceux de Google<br />Un objectif « simple » : être capable d’accepter une demande d’achat…<br />…quelque soit la panne !<br />© OCTO 2011<br />39<br />Enjeux: reporting(induit une modélisation riche), <br />Indisponibilité temporaire acceptable<br />Enjeux: disponibilité en écriture, tolérance à la panne<br />Le modèle RDBMS atteint ces limites en terme de <br /><ul><li>Débit en écriture
  48. 48. Disponibilité
  49. 49. Gestion du « capacity planning » </li></ul>Le modèle RDBMS est adapté<br /><ul><li>Massivement en lecture
  50. 50. Besoin de reporting
  51. 51. …</li></li></ul><li>Des gènes différents, centrés sur la disponibilité qui imposent des « trade-offs »<br />40<br />© OCTO 2011<br />Trade-off : « weforfeit ‘C’ and ‘I’ for availibility, gracefuldegradation and performance »<br /><ul><li>De ACID vers BASE (WeakConsistency, Best Effort, Stale State…)</li></li></ul><li>« Event Sourcing »Le pattern…<br />vision « stock » ou « mouvements »?<br />41<br />09/2010 400 Credit<br />13/09/2010 10000 Debit<br />15/09/2010 10200 Credit<br />14/09/2010 11000 Credit<br />15/09/2010 5500 Debit<br />16/09/2010 5500 Debit<br />15/09/2010 11000 Debit<br />16/09/2010 5500 Credit<br />17/09/2010 5500 Credit<br />13/09/2010 10000 Debit<br />15/09/2010 10200 Credit<br />13/09/2010 20000 Debit<br />14/09/2010 11000 Credit<br />15/09/2010 3900 Credit<br />16/09/2010 0 Credit<br />17/09/2010 5500 Credit<br />© OCTO 2011<br />
  52. 52. « Event Sourcing »Le pattern…<br />Des enjeux distincts en écriture et en lecture<br />42<br />Source d’évènements, collecte<br /><ul><li>Durable
  53. 53. Hautement disponible</li></ul>-…<br />Des représentations adaptées aux usages, restitution<br /><ul><li>RDBMS
  54. 54. Graph
  55. 55. …</li></ul>© OCTO 2011<br />
  56. 56. Hashmap distribuéeModèle de données<br />Modèle de données : une Map<br />Cassandra offre un modèle de données « plus riche » en reprenant le modèle « column-oriented » de BigTable : un Map de Map<br />Sans aller jusqu’au stockage physique en colonne<br />Propose des index secondaires (v.0.7) : <br />43<br />get users where state = 'UT' and birth_date > 1970;<br />© OCTO 2011<br />
  57. 57. Hashmap distribuéeen termes d’API<br />© OCTO 2010<br />44<br />Voldemort<br />StoreClientFactoryfactory = new SocketStoreClientFactory(numThreads,<br />numThreads, maxQueuedRequests, maxConnectionsPerNode,<br />maxTotalConnections, bootstrapUrl);<br />try {<br />StoreClient<String, Object> client = factory.getStoreClient("author");<br />Map<String, Object> authorMap = new HashMap<String, Object>();<br />authorMap.put("key", "key" + i);<br />authorMap.put("firstName", "firstName" + i);<br />authorMap.put("lastName", "lastName" + i);<br />client.put("key" + i, authorMap);<br />
  58. 58. Hashmap distribuée Un peu de configuration…<br />© OCTO 2010<br />45<br />Voldemort<br /><store><br /><name>author</name><br /> <persistence>bdb</persistence><br /> <routing>client</routing><br /><replication-factor>2</replication-factor><br /><required-reads>1</required-reads><br /> <required-writes>1</required-writes><br /> <key-serializer><br /><type>json</type><br /> <schema-info>"string"</schema-info><br /> </key-serializer><br /> <value-serializer><br /> <type>json</type><br /> <schema-info version="0">{"key":"string", "firstName":"string", "lastName":"string"}</schem..<br /> </value-serializer><br /> </store><br />~ une table dans le monde relationnel<br />Voldemort : un paramétrage fin par type de donnée<br />- Nombre de nœud en réplication<br />- Nombre de nœud en écriture<br />- Nombre de nœud en lecture<br />Format de la valeur : json, java-serialization, protobuf, thrift…<br />
  59. 59. Hashmap distribuée en termes d’API<br />© OCTO 2010<br />46<br />Cassandra (0.6.x)<br />TTransporttr = new TSocket("192.168.216.128", 9160);<br />TProtocol proto = new TBinaryProtocol(tr);<br />tr.open();<br />Cassandra.ClientcassandraClient = new Cassandra.Client(proto);<br />Map<String, List<ColumnOrSuperColumn>> insertClientDataMap = new HashMap<String, <br />List<ColumnOrSuperColumn>>();<br />List<ColumnOrSuperColumn> clientRowData = new ArrayList<ColumnOrSuperColumn>();<br />ColumnOrSuperColumncolumnOrSuperColumn = new ColumnOrSuperColumn();<br />columnOrSuperColumn.setColumn(new Column("fullName".getBytes(UTF8), aCustomer.getName().getBytes(UTF8), timestamp));<br />clientRowData.add(columnOrSuperColumn);<br />insertClientDataMap.put("customers", clientRowData);<br />cassandraClient.batch_insert("myBank", aCustomer.getName(),insertClientDataMap, ConsistencyLevel.DCQUORUM);<br />Il existe des APIs proposant des services de plus haut niveau : Hector, Pelops, HectorSharp, Fauna…<br />Mécanismes de pool, client fail over…<br />
  60. 60. Hashmap distribuée Un peu de configuration…<br />© OCTO 2010<br />47<br />Cassandra (0.6.x)<br /><Storage><br /> <ClusterName>Test Cluster</ClusterName><br /> <Keyspaces><br /><Keyspace Name="users"><br /> <ColumnFamilyCompareWith="UTF8Type" Name="info"/></Keyspace><br /> </Keyspaces><br /> <Partitioner>org.apache.cassandra.dht.RandomPartitioner</Partitioner><br /><Seeds><br /> <Seed>10.1.112.252</Seed><br /> <Seed…<br /> </Seeds><br /> <!-- ~ Address to bind to and tell othernodes to connect to.--><br /> <ListenAddress>10.1.123.119</ListenAddress><br /> <!-- TCP port, for commands and data --><br /> <StoragePort>7000</StoragePort><br /> <!-- UDP port, for membership communications (gossip) --><br /> <ControlPort>7001</ControlPort><br /> <!-- The address to bind the Thrift RPC service to. --><br /> <ThriftAddress>10.1.123.119</ThriftAddress><br /> <!-- Thrift RPC port (the port clients connect to). --><br /> <ThriftPort>9160</ThriftPort><br />Définition du cluster<br />~Database / schéma dans le monde relationnel<br />~Table dans le monde relationnel<br />Liste des serveurs faisant partis du cluster <br />(gestion du « gossipprotocol »)<br />Paramètres d’accès pour les clients Thrift<br />
  61. 61. Hashmap distribuée Partitionnement<br />Le partitionnement et l’association clé/serveur sont assurés via « consistent hashing »<br />48<br />Client<br />md5(key) = 3<br />#2<br />«3»<br />© OCTO 2011<br />
  62. 62. Hashmap distribuée Gestion de la consistence<br />49<br />© OCTO 2011<br />Consistence faible<br />Consistance forte<br />Client<br />(Write)<br />Client<br />(Read)<br />Client<br />(Write)<br />Client<br />(Read)<br />Quorum basedprotocol : N/2 + 1 ou W + R > N<br />Trade off entre consistance, latence, tolérance à la panne en fonction de la donnée<br />#2<br />«3»<br />#2<br />«3»<br />
  63. 63. Pendant l’écriture, le coordinateur envoie un « hintedhandoff » à un des réplicas en ligne<br />Quand le nœud est de nouveau disponible, le nœud #3 dépile ses « hintedhandoffs »<br />Tolérance à la panne, disponibilité en écritureHintedHandoff<br />50<br />© OCTO 2011<br />Client<br />(Write)<br />#2<br />«3»<br />#4<br /><=8<br />Envoyer « 3 » à #4 dès que « up »<br />
  64. 64. Quelques métriquesTemps de réponse<br />Benchmark réalisé par Yahoo! <br />Infrastructure : 6 boxes {2x4 core 2.5GHz, 8GB RAM, <br />6 HDD (SAS RAID1+0), GB eth}<br />120M records (1K) ~ 20GB data per server<br />100+ client threads <br />© OCTO2011<br />51<br />50/50 Read/update<br />95/5 Read/update<br />Source : « Yahoo! Cloud Serving Benchmark », Brian F. Cooper<br />http://www.brianfrankcooper.net/pubs/ycsb-v4.pdf<br />
  65. 65. Quelques métriquesElasticité<br />© OCTO2011<br />52<br />95/5 Read/update<br />Passage de 2 à 6 serveurs<br />Benchmark réalisé par Yahoo! <br /><ul><li>Infrastructure : 6 boxes {2x4 core 2.5GHz, 8GB RAM, </li></ul>6 HDD (SAS RAID1+0), GB eth}<br /><ul><li>120M records (1K) ~ 20GB data per server
  66. 66. 100+ client threads </li></ul>Source : « Yahoo! Cloud Serving Benchmark », Brian F. Cooper<br />http://www.brianfrankcooper.net/pubs/ycsb-v4.pdf<br />
  67. 67. Quelques métriquesDifférence entre les versions<br />© OCTO2011<br />53<br />50/50 Read/update<br />95/5 Read/update<br />Benchmark réalisé par Yahoo! <br />Infrastructure : 6 boxes {2x4 core 2.5GHz, 8GB RAM, <br />6 HDD (SAS RAID1+0), GB eth}<br />120M records (1K) ~ 20GB data per server<br />100+ client threads <br />Source : « Yahoo! Cloud Serving Benchmark », Brian F. Cooper<br />http://www.brianfrankcooper.net/pubs/ycsb-v4.pdf<br />
  68. 68. Et enfin…Les bases graphes, géographiques…<br />© OCTO 2011<br />54<br />
  69. 69. Les bases « graph »<br />© OCTO2011<br />55<br />
  70. 70. Les bases « graph »en termes d’API<br />© OCTO2011<br />56<br />Neo4j<br />Transaction tx = myDb.beginTx();<br />try<br />{<br />Nodearchitect = myDb.createNode();<br />Nodesmith = myDb.createNode();<br />smith.setProperty(« version », « 1.0 »);<br /> Relationship relation = smith.createRelationshipTo(architect, …<br />relation.setProperty…<br />tx.success();<br />}<br />finally<br />tx.finish();<br />Requêtage : algorithmes de parcours de graphes<br />for ( Nodeperson : persons.query( "name:*sson AND title:Hacker" ) ) { } <br />RelationshipIndex friendships = graphDb.index().forRelationships( "friendships" );<br />// "type" isn't a reserved key and isn't indexed automatically<br />Relationship relationship = friendships.get( "type", "knows", morpheus, trinity ).getSingle();<br />
  71. 71. En bref…<br />© OCTO 2011<br />57<br />
  72. 72. NoSQL aujourd’huiUn foisonnement de solutions…<br />58<br />Key/Value<br />Graph<br />Document<br />ColumnOriented<br />© OCTO 2011<br />
  73. 73. …Organisées en grandes catégoriesbasées sur la modélisation de la donnée<br />59<br />{attr1, …}<br />Une classification qui a des limites<br />Ne prend pas en compte les patterns précédents (Cassandra & HBase)<br />Les trade-offs sur ACID (durabilité…)<br />© OCTO 2011<br />
  74. 74. D’après le théorème de CAP…(1)<br />© OCTO 2011<br />60<br />Le théorème CAP  statue qu'il est impossible sur un système distribué de garantir en même temps les trois contraintes suivantes :<br />- Cohérence : tous les nœuds du système voient exactement les mêmes données au même moment ;<br />- Disponibilité (Availability en anglais) : le temps de réponse doit toujours être le plus court possible ;<br />- Tolérance au partitionnement (Partition Tolerance en anglais) : aucune panne moins importante qu'une coupure totale du réseau ne doit empêcher le système de répondre correctement.<br />D'après ce théorème, un système distribué ne peut garantir à un instant T que deux de ces contraintes mais pas les trois.<br />A<br />Réplication asynchrone<br />Dynamo & Amazon Dynamo derivatives : <br />Cassandra, Voldemort, Riak<br />RDBMS : <br />MySQL, Postgres…<br />Réplication synchrone<br />C<br />P<br />Neo4j, BigTable & Bigtablederivatives : <br />HBase…<br />(1) Eric Brewer – 2000<br />CAP Theorem<br />
  75. 75. Pour conclure…Des systèmes qui challengent les règles établies<br />© OCTO2011<br />61<br /><ul><li>Performance, débit en écriture
  76. 76. Stockage et Manipulation de gros volume de données
  77. 77. Disponibilité et Tolérance aux pannes
  78. 78. Elasticitédes infrastructure de stockage
  79. 79. Souplessede modélisation</li></li></ul><li>Pour conclure…Au-delà du buzz<br />NoSQL reste un domaine d’innovation…même s’il existe des déploiements en production<br />« le diable est dans le détail »<br />NoSQL appliqué au monde de la « Business Intelligence »<br />NoSQL nous demandera peut-être de penser différemment nos systèmes <br />Event Sourcing…<br />NoSQL nous rappelle qu’il est important de travailler sur l’utilisation qui est faite de la donnée<br />Toutes les données n’ont pas besoin d’être consistantes dans tous les contextes d’utilisation<br />NoSQL parle de collaboration :stockage « polyglote »<br />Ce n’est pas un remplacement des SGBDR<br />NoSQL parle d’alternatives et challenge 40 années de suprématie des bases relationnelles…<br />© OCTO2011<br />62<br />
  80. 80. © OCTO 2011<br />63<br />

×