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