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.

Webanwendungen mit Apache HBase entwickeln

859 views

Published on

Webanwendungen mit Apache HBase entwickeln

Published in: Technology
  • Be the first to comment

Webanwendungen mit Apache HBase entwickeln

  1. 1. Webanwendungen mit Apache HBase entwickeln Roman Roelofsen Managing Director (aka Alpha Geek) Weigle Wilczek GmbH Twitter: romanroe JAX, 19. April 2012 1
  2. 2. ¨ WeigleWilczek - Uber Uns IT-Beratung, Software-Entwicklung Typische Anwendungen ”Web-Anwendungen” Lagerverwaltung Kennzahlenanalyse, Dashboards Kein Facebook, Twitter, etc. 2
  3. 3. Typischer Stack JVM Jetty/Tomcat/WebSphere Guice/Spring Diverse Web-Frameworks Diverse RDBMS (MySQL, PostreSQL, ...) Ein paar Exoten MongoDB Prevayler 3
  4. 4. Probleme mit RDBMS Schlechte horizontale Skalierung Option A) Partitionierung nach Funktion Option B) Partitionierung nach PK, Hash, etc. Vertikale Skalierung ist teuer 4
  5. 5. Warum NoSQL? Buzzword! (== Spaß, meistens jedenfalls) Partitionierungsf¨higkeiten sind wirtschaftlich interessant a Skaliert die Abfragezeit mit der Serveranzahl? Kosten f¨r Redundanz k¨nnen berechnet werden u o memcached, etc. wird uberfl¨ssig (weniger Administration) u ¨ NoSQL-Architekturen passen gut zum Cloud-Trend Apache Hadoop wird (in den USA) sehr gehyped → Evaluierung 5
  6. 6. Warum NoSQL? 6
  7. 7. Warum NoSQL? 7
  8. 8. Warum NoSQL? 8
  9. 9. Auswahl NoSQL Sammelbegriff f¨r viele Datenbanken u Dokumenten-Datenbank Graph-Datenbank Key/Value Datenbank Objekt-Datenbank Google’s BigTable, Amazon’s Dynamo ... 9
  10. 10. Google’s BigTable Verteilte Key/Value Datenbank Basiert auf Google File System Fehlertolerant Skalierbar L¨uft auf ”billiger” Hardware a Erlaubt Parallelisierung (MapReduce & Co.) 10
  11. 11. Apache Hadoop Stack Hadoop Verteiltes Dateisystem (HDFS) Hive Abfragen MapReduce Implementierung f¨r das HDFS u HBase BigTable-Implementierung MediaGuardian Innovation Awards: Innovator of the Year Wikipedia: ”...Hervorgehoben wurde, dass Hadoop so vielseitige und weitreichende Anwendungen erm¨glicht, dass es o sich als Beginn einer neuen Datenrevolution erweisen k¨nne.” o 11
  12. 12. Exkurs: HBase vs. Cassandra HBase Vorteile Konsistenz Read-Performance > Write-Performance Cassandra Vorteile Write-Performance > Read-Performance Wichtig f¨r Business-Anwendungen u Konsistenz Read-Performance Abfragen 12
  13. 13. HBase - Datendesign Key/Value Datenbank java.util.Map Row Map<ROW_ID, DATA> 13
  14. 14. HBase - Datendesign Key/Value Datenbank java.util.Map Row Map<ROW_ID, DATA> Column Family Map<ROW_ID, Map<FAMILY_ID, DATA>> 14
  15. 15. HBase - Datendesign Key/Value Datenbank java.util.Map Row Map<ROW_ID, DATA> Column Family Map<ROW_ID, Map<FAMILY_ID, DATA>> Column Map<ROW_ID, Map<FAMILY_ID, Map<COLUMN_ID, DATA>>> 15
  16. 16. HBase - Datendesign Key/Value Datenbank java.util.Map Row Map<ROW_ID, DATA> Column Family Map<ROW_ID, Map<FAMILY_ID, DATA>> Column Map<ROW_ID, Map<FAMILY_ID, Map<COLUMN_ID, DATA>>> Alle Werte sind byte[] Map<byte[], Map<byte[], Map<byte[], byte[]>>> 16
  17. 17. HBase - Datendesign 17
  18. 18. HBase - Datendesign Zeilen IDs werden Byte-Lexikographisch sortiert Innerhalb einer Zeile werden Spalten Byte-Lexikographisch sortiert Zeilen- und Spaltenabschnitte k¨nnen leicht ”gescannt” o werden Wichtige Eigenschaft, um Indizes zu simulieren bzw. Abfragen zu erm¨glichen o 18
  19. 19. HBase - Column Families Column Families werden in unterschiedlichen Dateien gespeichert 19
  20. 20. HBase - Horizontale Skalierung IDs werden in Regionen aufgeteilt Regionen werden auf Region Servers gespeichert Regionen und Region Server werden je nach Auslastung neu angeordnet 20
  21. 21. HBase - Versionierung Jede ”Zelle” wird mit einem Timestamp gespeichert und automatisch versioniert 21
  22. 22. HBase - Versionierung Jede ”Zelle” wird mit einem Timestamp gespeichert und automatisch versioniert Map<byte[], Map<byte[], Map<byte[], Map<Long, byte[]>>>> 22
  23. 23. HBase - Versionierung Jede ”Zelle” wird mit einem Timestamp gespeichert und automatisch versioniert Map<byte[], Map<byte[], Map<byte[], Map<Long, byte[]>>>> Default: 3 Versionen Timestamp wird beim Schreiben vom Server gesetzt, kann aber vom Client uberschrieben werden ¨ 23
  24. 24. HBase API Grundlagen 24
  25. 25. HBase - Getting Started Standalone Mode Zur Entwicklung kann HBase im Standalone Modus gestartet werden HDFS wird dann nicht verwendet HBase und ZooKeeper laufen in der selben JVM Shell bin/hbase shell hbase(main):001:0> status 1 servers, 0 dead, 0.0000 average load 25
  26. 26. Exkurs: Ubuntu 11.10 und HBase /etc/hosts 127.0.0.1 localhost #127.0.1.1 servername 192.168.178.44 localhost 26
  27. 27. HBase API - Tabellen anlegen Tabellen m¨ssen explizit angelegt werden u Shell create ’person’, ’cfamily1’ 27
  28. 28. HBase API - Tabellen anlegen Tabellen m¨ssen explizit angelegt werden u Shell create ’person’, ’cfamily1’ Java Configuration c = new Configuration(); HBaseAdmin admin = new HBaseAdmin(c); HTableDescriptor person = new HTableDescriptor("person"); person.addFamily(new HColumnDescriptor("cfamily1")); admin.createTable(person); 28
  29. 29. HBase API - Daten speichern Shell put ’person’, ’id_1’, ’cfamily1:firstname’, ’John’ put ’person’, ’id_1’, ’cfamily1:lastname’, ’McCarthy’ 29
  30. 30. HBase API - Daten speichern Shell put ’person’, ’id_1’, ’cfamily1:firstname’, ’John’ put ’person’, ’id_1’, ’cfamily1:lastname’, ’McCarthy’ Java Configuration c = new Configuration(); HTable person = new HTable(c, "person"); Put put = new Put(Bytes.toBytes("id_1")); put.add(Bytes.toBytes("cfamily1"), Bytes.toBytes("firstname"), Bytes.toBytes("John")); put.add(Bytes.toBytes("cfamily1"), Bytes.toBytes("lastname"), Bytes.toBytes("McCarthy")); person.put(put); 30
  31. 31. HBase API - Daten lesen Shell hbase(main):001:0> scan ’person’ ROW COLUMN+CELL id_1 column=cfamily1:firstname, timestamp=123, value=John id_1 column=cfamily1:lastname, timestamp=123, value=McCarthy 1 row(s) in 0.1100 seconds 31
  32. 32. HBase API - Daten lesen Java Configuration c = new Configuration(); HTable person = new HTable(c, "person"); Get get = new Get(Bytes.toBytes("id_1")); get.addColumn(Bytes.toBytes("cfamily1"), Bytes.toBytes("firstname")); get.addColumn(Bytes.toBytes("cfamily1"), Bytes.toBytes("lastname")); Result result = person.get(get); byte[] firstname = result.getValue(Bytes.toBytes("cfamily1"), Bytes.toBytes("firstname")); .. 32
  33. 33. HBase API - Daten l¨schen o Shell delete ’person’, ’id_1’, ’cfamily1:firstname’ 33
  34. 34. HBase API - Daten l¨schen o Shell delete ’person’, ’id_1’, ’cfamily1:firstname’ Java Configuration c = new Configuration(); HTable person = new HTable(c, "person"); Delete delete = new Delete(Bytes.toBytes("id_1")); delete.setTimestamp(1); person.delete(delete); 34
  35. 35. HBase API - Scanner Java Configuration c = new Configuration(); HTable person = new HTable(c, "person"); Scan s = new Scan( Bytes.toBytes("id_1"), Bytes.toBytes("id_5")); s.addFamily(Bytes.toBytes("cfamily1")); ResultScanner rs = person.getScanner(s); // while.... Result r = rs.next(); r.getValue(Bytes.toBytes("cfamily1"), Bytes.toBytes("firstname")); ... 35
  36. 36. HBase und Web-Anwendungen 36
  37. 37. Web-Anwendungen Mehrere Threads im Server API muss (sollte) Thread-safe sein Synchronisation beim Datenbankzugriff notwendig Locking, Isolierung, ... Multi-User Umgebung Gemeinsame Updates w¨ren w¨nschenswert a u Viele Views auf die selben Daten Anzahl Reads > Anzahl Writes Viele, kurzlebige Ausf¨hrungen u 37
  38. 38. Atomare Operationen, Isolierung Atomare Operationen sind: Put, Get, Delete, ... Keine Gruppierung m¨glich! o Jeder Aufruf ist direkt ein RPC-call 38
  39. 39. Atomare Operationen, Isolierung Atomare Operationen sind: Put, Get, Delete, ... Keine Gruppierung m¨glich! o Jeder Aufruf ist direkt ein RPC-call Client-side Buffer table.setAutoFlush(false) Put-Operationen werden im Client gepuffert Explizit senden mit table.flushCommits() Implizit basierend auf Heap-Verbrauch 39
  40. 40. Atomare Operationen, Isolierung Batch-Support List<Row> ops = new LinkedList<Row>(); Put put1 = new Put(Bytes.toBytes("id1"); put1.add(Bytes.toBytes("cf"), Bytes.toBytes("col"), Bytes.toBytes("abc")); ops.add(put1); Put put2 = new Put(Bytes.toBytes("id2"); put2.add(Bytes.toBytes("cf"), Bytes.toBytes("col"), Bytes.toBytes("def")); ops.add(put12; Object[] result = new Object[ops.size()]; table.batch(ops, result); 40
  41. 41. Atomare Operationen, Isolierung Reihenfolge im Batch-Betrieb ist nicht explizit und wird vom Client optimiert Daher sollten keine Put- und Delete-Operationen f¨r die u selben Rows gemischt werde Egal wie und wann, andere Clients sehen Zwischenschritte 41
  42. 42. Compare and Swap HBase erlaubt atomare compare-and-swap Operationen Put update = new Put(Bytes.toBytes("id1")); update.add( Bytes.toBytes("cfamily1"), Bytes.toBytes("firstname"), Bytes.toBytes("Max")); boolean wasUpdated = person.checkAndPut( Bytes.toBytes("id1"), Bytes.toBytes("cfamily1"), Bytes.toBytes("version"), Bytes.toBytes("3"), update); Erm¨glicht Optimistic-Locking o 42
  43. 43. Synchronisation uber Locks m¨glich o ¨ Mehrere Operationen k¨nnen nicht als eine, atomare o Operation durchgef¨hrt werden u Andere Clients werden immer Zwischenschritte sehen Wenn Clients sich auf gemeinsame Locks einigen, ist zumindest eine Synchronisation m¨glich o RowLock id1lock = person.lockRow(Bytes.toBytes("id1")); ... ... person.unlockRow(id1lock); 43
  44. 44. Synchronisation uber Locks m¨glich o ¨ Probleme Welche Rows eignen sich als gemeinsamer Lock? Gefahr von Deadlocks 44
  45. 45. Thread-Sicherheit der API HTable Das Erstellen einer HTable-Instanz kann mehrere Sekunden dauern Instanzen sollten daher immer wiederverwendet werden 45
  46. 46. Thread-Sicherheit der API HTable Das Erstellen einer HTable-Instanz kann mehrere Sekunden dauern Instanzen sollten daher immer wiederverwendet werden Problem: Instanzen sind nicht Thread-safe 46
  47. 47. Thread-Sicherheit der API HTable Das Erstellen einer HTable-Instanz kann mehrere Sekunden dauern Instanzen sollten daher immer wiederverwendet werden Problem: Instanzen sind nicht Thread-safe L¨sung: HTablePool o HTablePool pool = new HTablePool(c, Integer.MAX_VALUE); HTable table = pool.getTable("person"); ... table.close(); 47
  48. 48. ”Transaction per View” RDBMS + Web-Anwendung F¨r jeden Request wird eine Transaction erstellt u RuntimeExceptions f¨hren zu einem Rollback, u ... sonst Commit 48
  49. 49. ”Transaction per View” RDBMS + Web-Anwendung F¨r jeden Request wird eine Transaction erstellt u RuntimeExceptions f¨hren zu einem Rollback, u ... sonst Commit HBase + Web-Anwendung Jeder Request braucht eigene HTable-Instanzen 49
  50. 50. ”Transaction per View” RDBMS + Web-Anwendung F¨r jeden Request wird eine Transaction erstellt u RuntimeExceptions f¨hren zu einem Rollback, u ... sonst Commit HBase + Web-Anwendung Jeder Request braucht eigene HTable-Instanzen Problem: Wir wissen vorher nicht, auf welche Tabellen zugegriffen wird 50
  51. 51. ”Transaction per View” RDBMS + Web-Anwendung F¨r jeden Request wird eine Transaction erstellt u RuntimeExceptions f¨hren zu einem Rollback, u ... sonst Commit HBase + Web-Anwendung Jeder Request braucht eigene HTable-Instanzen Problem: Wir wissen vorher nicht, auf welche Tabellen zugegriffen wird L¨sung: Proxy Objekt + Thread-local HTable-Zuordnung o 51
  52. 52. Row IDs erzeugen ID Erzeugung ist nicht atomar GET aktueller Wert +1 PUT neuer Wert 52
  53. 53. Row IDs erzeugen ID Erzeugung ist nicht atomar GET aktueller Wert +1 PUT neuer Wert Counter HTable table = new HTable(conf, "IDs"); long counter1 = table.incrementColumnValue( Bytes.toBytes("person_ids"), Bytes.toBytes("family"), Bytes.toBytes("next_id"), 1); 53
  54. 54. Primary Keys 54
  55. 55. Secondary Keys 55
  56. 56. Secondary Keys - Backrefs 56
  57. 57. Secondary Keys und Scanner - St¨dtenamen a Java Configuration c = new Configuration(); HTable person = new HTable(c, "personFK"); Scan s = new Scan( Bytes.toBytes("FK:Stadt:A"), Bytes.toBytes("FK:Stadt:L")); ResultScanner rs = person.getScanner(s); ... 57
  58. 58. Secondary Keys und Scanner - Postleitzahlen Java Configuration c = new Configuration(); HTable person = new HTable(c, "personFK"); Scan s = new Scan( Bytes.toBytes("FK:PLZ:50667"), Bytes.toBytes("FK:PLZ:51150")); ResultScanner rs = person.getScanner(s); ... 58
  59. 59. Secondary Keys und Scanner - Alter? Configuration c = new Configuration(); HTable person = new HTable(c, "personFK"); Scan s = new Scan( Bytes.toBytes("FK:Alter:2"), Bytes.toBytes("FK:Alter:51")); ResultScanner rs = person.getScanner(s); ... 59
  60. 60. Secondary Keys und Scanner - Alter? Configuration c = new Configuration(); HTable person = new HTable(c, "personFK"); Scan s = new Scan( Bytes.toBytes("FK:Alter:2"), Bytes.toBytes("FK:Alter:51")); ResultScanner rs = person.getScanner(s); ... Problem: IDs werden Byte-Lexikographisch sortiert 2 3 51 6 7 60
  61. 61. Secondary Keys und Scanner - Alter? Padding 2 → 0002 12 → 0012 42 → 0042 135 → 0135 61
  62. 62. Secondary Keys und Scanner - Alter? Padding 2 → 0002 12 → 0012 42 → 0042 135 → 0135 Probleme Maximale Zahlenl¨nge muss bekannt sein a 62
  63. 63. Secondary Keys und Scanner - Alter? Wie w¨re eine andere Zahlendarstellung? (Additionssystem) a 2→2 12 → 92 42 → 99992 135 → 99999999999995 63
  64. 64. Secondary Keys und Scanner - Alter? Wie w¨re eine andere Zahlendarstellung? (Additionssystem) a 2→2 12 → 92 42 → 99992 135 → 99999999999995 Probleme Sehr ineffizient bzgl. Platzbedarf Zahl ist nicht lesbar 64
  65. 65. Secondary Keys und Scanner - Alter? L¨sung: Additionssystem und Stellenwertsystem kombinieren o 2 → 1#2 12 → 2#12 42 → 2#42 135 → 3#135 65
  66. 66. Fazit 1/6 Entweder man macht es so, wie HBase es will, oder man l¨sst a es bleiben! Bitte keine O/H(Base) Mapper! 66
  67. 67. Fazit 2/6 Kostenargumente sind schwer dem Kunden zu verkaufen, wenn Oracle und Co. schon im Einsatz ist, Lizenzen vorhanden sind, etc. 67
  68. 68. Fazit 3/6 HBase kann sehr gut mehrere Rechner nutzen Jedoch muss man diese Eigenschaft nutzen, um uberhaupt ¨ erst eine gute Performance zu erhalten 68
  69. 69. Fazit 4/6 HBase (& Co.): Imperativ SQL: Deklarativ 69
  70. 70. Fazit 5/6 Es ist nicht leicht, im Team stabile Tests zu erstellen Man vermisst jdbc:h2:mem:testdb 70
  71. 71. Fazit 6/6 Die Vorteile von HBase wurden durch Verzicht erm¨glicht o 71
  72. 72. Wir stellen ein! Wir suchen professionelle Java-Geeks! Wir bieten eine gesunde Mischung aus Programmierer Berater Kicker-Profi Bitte bei mir melden! roelofsen@weiglewilczek.com 72
  73. 73. Vielen Dank f¨r Ihre Aufmerksamkeit! u Fragen? 73

×