data modeling for scale with riak data types
play

Data Modeling for Scale with Riak Data Types Sean Cribbs - PowerPoint PPT Presentation

Data Modeling for Scale with Riak Data Types Sean Cribbs @seancribbs #riak #datatypes QCon NYC 2014 I work for Basho We make Visit our booth! Riak is Eventually Consistent key-value + indexes + search + MapReduce Eventual Consistency 1


  1. Data Modeling for Scale with Riak Data Types Sean Cribbs @seancribbs #riak #datatypes QCon NYC 2014

  2. I work for Basho We make Visit our booth!

  3. Riak is Eventually Consistent key-value + indexes + search + MapReduce

  4. Eventual Consistency 1 2 Replicated Loose coordination 3 Convergence

  5. Eventual is Good ✔ Fault-tolerant ✔ Highly available ✔ Low-latency

  6. Consistency? 1 A 2 No clear winner! Throw one out? 3 Keep both? B

  7. Consistency? 1 A 2 No clear winner! Throw one out? 3 Keep both? B Cassandra

  8. Consistency? 1 A 2 No clear winner! Throw one out? 3 Keep both? B Cassandra Riak

  9. Con f icts! A! B!

  10. Semantic Resolution • Your app knows the domain - use business rules to resolve • Amazon Dynamo’s shopping cart

  11. Semantic Resolution • Your app knows the domain - use business rules to resolve • Amazon Dynamo’s shopping cart “Ad hoc approaches have proven brittle and error-prone”

  12. Convergent Replicated Data Types

  13. Convergent Replicated Data Types useful abstractions

  14. Convergent Replicated Data Types multiple independent copies useful abstractions

  15. resolves automatically toward a single value Convergent Replicated Data Types multiple independent copies useful abstractions

  16. How CRDTs Work • A partially-ordered set of values • A merge function • An identity value • In f ation operations

  17. How CRDTs Work • A partially-ordered set of values • A merge function • An identity value • In f ation operations What CRDTs Enable • Consistency without coordination • Fluent , rich interaction with data

  18. This research is supported in part by European FP7 project 609 551 SyncFree http://syncfree.lip6.fr/ (2013--2016).

  19. by @joedevivo

  20. Forget CRDTs Do Data Modeling

  21. Data Modeling for Riak • Identify needs for both read and write • Design around key as index • Denormalize relationships if possible • Weigh data size against coherence

  22. Riak Data Types

  23. Riak Data Types Counter :: int increment decrement

  24. Riak Data Types Counter :: int increment decrement Set :: { bytes } add* remove

  25. Riak Data Types Map :: bytes → DT Counter :: int update* increment remove decrement Set :: { bytes } add* remove

  26. Riak Data Types Map :: bytes → DT Counter :: int update* increment remove decrement Set :: { bytes } add* remove

  27. Riak Data Types Map :: bytes → DT Counter :: int update* increment remove decrement Set :: { bytes } Register :: bytes add* assign remove

  28. Riak Data Types Map :: bytes → DT Counter :: int update* increment remove decrement Set :: { bytes } Register :: bytes add* assign remove Flag :: boolean enable* disable

  29. MADDATA

  30. Counters

  31. Ad Network • Impressions - when someone sees an ad • Click-through - when someone clicks on an ad • Hourly rollups ad-metrics/<campaign>/<type>-<hour>

  32. Ad Network $ riak-admin bucket-type create ad-metrics \ '{"props":{"datatype":"counter"}}' ad-metrics created $ riak-admin bucket-type activate ad-metrics ad-metrics has been activated $ riak-admin bucket-type list ad-metrics (active)

  33. Ad Network from riak import RiakClient from rogersads import RIAK_CONFIG from time import strftime client = RiakClient(**RIAK_CONFIG) metrics = client.bucket_type('ad-metrics') def record_metric(campaign, metric_type): key = metric_type + strftime('-%Y%m%d-%H') counter = metrics.bucket(campaign).new(key) counter.increment() counter.store()

  34. Ad Network 3000 2250 1500 750 0 9 10 11 12 13 14 15 16

  35. Sets

  36. PartyOn • RSVPs - guest lists • Connections - friends lists per-user • Likes - expressing interest

  37. PartyOn $ riak-admin bucket-type create partyon-sets \ '{"props":{"datatype":"set"}}' partyon-sets created $ riak-admin bucket-type activate partyon-sets partyon-sets has been activated $ riak-admin bucket-type list partyon-sets (active)

  38. PartyOn • RSVPs partyon-sets/rsvps/<eventid> • Connections partyon-sets/friends/<userid> • Likes partyon-sets/likes/<eventid>

  39. PartyOn from riak.datatypes import Set sets = client.bucket_type('partyon-sets') rsvps = sets.bucket('rsvps') friends = sets.bucket('friends') likes = sets.bucket('likes')

  40. PartyOn def rsvp_get(event): return rsvps.get(event) # Returns a Set def rsvp_add(event, user): guests = rsvps.new(event) guests.add(user) guests.store(return_body= True ) return guests.context def rsvp_remove(event, user, context): guests = Set(rsvps, event, context=context) guests.remove(user) guests.store()

  41. Maps (and the rest)

  42. GameNet • User pro f les - demographic data users/profiles/<userid> • Achievements - trophies per game users/trophies/<userid> • Game state - progress and stats users/<gameid>/<userid>

  43. GameNet $ riak-admin bucket-type create users \ '{"props":{"datatype":"map"}}' users created $ riak-admin bucket-type activate users users has been activated $ riak-admin bucket-type list users (active)

  44. GameNet users = client.bucket_type('users') def update_profile(user, fields): profile = users.bucket('profiles').get(user) for field in fields: if field in USER_FLAGS: if fields[field]: profile.flags[field].enable() else : profile.flags[field].disable() else : value = fields[field] profile.registers[field].assign(value) profile.store()

  45. GameNet def add_trophy(user, game, trophy): trophies = users.bucket('trophies').get(user) trophies.sets[game].add(trophy) trophies.store() def get_trophies(user, game): trophies = users.bucket('trophies').get(user) return trophies.sets[game].value

  46. GameNet def build_structure(user, game, structure, gold, wood, stone): gamestate = users.bucket(game).get(user) gamestate.sets['structures'].add(structure) gamestate.counters['gold'].decrement(gold) gamestate.counters['wood'].decrement(wood) gamestate.counters['stone'].decrement(stone) gamestate.store(return_body= True ) return gamestate.value

  47. GameNet client.create_search_index('asteroids') users.bucket('asteroids').set_property('search_index', 'asteroids') def find_asteroids_opponents(min_score=0): query = "score_counter:[{} to *]". format (min_score) results = client.fulltext_search( 'asteroids', query, fl=['userid_register', 'score_counter']) return results['docs']

  48. Bene f ts • Richer interactions , familiar types • Write mutations , not state • No merge function to write • Same reliability and predictability of vanilla Riak

  49. Caveats • Value size still matters • Updates not idempotent (yet) • Cross-key atomicity not possible (yet)

  50. Future • Riak 2.0 due out this summer - betas available now! • Richer querying, lighter storage requirements, more types

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend