Webanwendungen mit Apache HBase entwickeln

817 views

Published on

Webanwendungen mit Apache HBase entwickeln

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
817
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
2
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

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

×