Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Realtime Database for high traffic production application

Sota Sugiura
September 01, 2018

Realtime Database for high traffic production application

2018/9/1
GDG DevFest Tokyo 2018

Sota Sugiura

September 01, 2018
Tweet

More Decks by Sota Sugiura

Other Decks in Technology

Transcript

  1. Mercari channel • Live e-commerce • Working on Mercari app

    • You can buy/sell anything through streaming https://www.mercari.com/jp/mercari-channel/
  2. Note • Today, Iʼll share some techniques • I believe

    itʼll help you to use Realtime Database
  3. Fully managed • 1 JSON data in 1 database •

    Multiple databases per 1 Firebase Project • Make project and ship it
  4. // Set the configuration for your app const config =

    { apiKey: "apiKey", authDomain: "projectId.firebaseapp.com", databaseURL: "https://databaseName.firebaseio.com", storageBucket: "bucket.appspot.com" }; firebase.initializeApp(config); // Get a reference to the database service const database = firebase.database(); Initializing
  5. Read Write ・Using SDK to read data ・Techniques not to

    read all data ・Updating data with REST API ・Managing frequency of query
  6. Little hack • SDK gets one data when connecting •

    But sometimes itʼs unnecessary • So filtering data by timestamp
  7. REST API • Two ways to write data • REST

    API or WebSocket(w/SDK) • In our case, REST API matched
  8. Cache auth token • Cache auth token on cache store

    • In case of sending request to REST API, it will work • OAuth2 authentication will be overhead
  9. keep-alive with chocon • We use chocon for using keep-alive

    • PHP process canʼt use it • Realtime Database instances are in US • 1 request means RTT to the Pacific Ocean • https://github.com/kazeburo/chocon
  10. Frequency managing • We donʼt need to send these kinds

    of data every time • Likes, Audience count, Notifications • So we manage frequency of sending such data
  11. Mercari API Like count=1 count=1 Like Like Like count=2 count=3

    count=4 Check frequency before sending data N query/sec
  12. Motivation • We donʼt need to update UI 1000 times

    • The most important point is experience • Actually, spec is limited for 1 instance • 1000 update per sec
  13. Rule • Settings for 1 database • Written in JSON

    • Validation • Permission/Authorization
  14. { "rules": { ".write": false, "lives": { "$live_id": { "messages":

    { "$message_id": { ".validate": "newData.hasChildren(['user', 'text'])" } }, "notifications": { "buy_item": { ".validate": "newData.hasChildren(['text'])" } } } } } } Sample rule
  15. Our strategy • Only writing data from our server •

    Controlling read permission by using flag data on database
  16. Only writing from server • Pros • Not need to

    be careful about permission for client • Cons • Server needs to handle high traffic
  17. { "rules": { ".write": false, "lives": { "$live_id": { "messages":

    { "$message_id": { ".validate": "newData.hasChildren(['user', 'text'])" } }, "notifications": { "buy_item": { ".validate": "newData.hasChildren(['text'])" } } } } } } Read only Rule
  18. { "rules": { ".write": false, "lives": { "$live_id": { "messages":

    { "$message_id": { ".validate": "newData.hasChildren(['user', 'text'])" } }, "notifications": { "buy_item": { ".validate": "newData.hasChildren(['text'])" } } } } } } Read only Rule
  19. { "rules": { ".write": false, "lives": { "$live_id": { "messages":

    { "$message_id": { ".validate": "newData.hasChildren(['user', 'text'])" } }, "notifications": { "buy_item": { ".validate": "newData.hasChildren(['text'])" } } } } } } Read only Rule Tips: Admin user can ignore all rules
  20. Controlling permission dynamically • Rule can refer data on schema

    • It means we can manage permission by data
  21. { "rules": { ".write": false, "lives": { "$live_id": { "messages":

    { "$message_id": { ".validate": "newData.hasChildren(['user', 'image', 'text'])" } }, "notifications": { "buy_item": { ".validate": "newData.hasChildren(['text'])" } } } }, "alive_lives": { ".write": false, ".read": false } } }
  22. { "rules": { ".write": false, "lives": { "$live_id": { "messages":

    { "$message_id": { ".validate": "newData.hasChildren(['user', 'image', 'text'])" } }, "notifications": { "buy_item": { ".validate": "newData.hasChildren(['text'])" } } } }, "alive_lives": { ".write": false, ".read": false } } } Data for client Data for managing permission
  23. { "rules": { ".write": false, "lives": { "$live_id": { ".read":

    "root.child('alive_lives').child($live_id).val() === true", "messages": { "$message_id": { ".validate": "newData.hasChildren(['user', 'image', 'text'])" } }, "notifications": { "buy_item": { ".validate": "newData.hasChildren(['text'])" } } } }, "alive_lives": { ".write": false, ".read": false } } }
  24. { "rules": { ".write": false, "lives": { "$live_id": { ".read":

    "root.child('alive_lives').child($live_id).val() === true", "messages": { "$message_id": { ".validate": "newData.hasChildren(['user', 'image', 'text'])" } }, "notifications": { "buy_item": { ".validate": "newData.hasChildren(['text'])" } } } }, "alive_lives": { ".write": false, ".read": false } } }
  25. { "lives": { "1": { ... }, "2": { ...

    } }, "alive_lives": { "1": true, "2": false } } alive_lives[ʻ1ʼ] is true So it can be read
  26. { "lives": { "1": { ... }, "2": { ...

    } }, "alive_lives": { "1": true, "2": false } } alive_lives[ʻ1ʼ] is false So it canʼt be read
  27. Easier to control permission • Updating rule every time will

    be overhead • So adding data to manage permission is good technique
  28. KPI of Mercari channel • Over 1500 streamers/day • Over

    30K viewers/day • 5-6M yen sales per 1 stream ※not strict numbers
  29. Again, limitation of database • There is limitation for each

    database • 1000 query/sec • 1M connection
  30. For scalability • We use over 15+ database instances in

    production • Client switch DB by data from Mercari API • For now, Cloud Firestore can be good choice for this problem
  31. Stackdriver • Monitoring tool provided by Google • Some metrics

    of Realtime Database • Aggregating all instances data to 1 dashboard
  32. Metrics • Connection count • Database load • Network usage

    • etc… https://cloud.google.com/monitoring/api/metrics_gcp#gcp-firebasedatabase
  33. Notice Operation ・Notice to some problem ・Investigation ・Fix bug ・Make

    service maintenance Problem ・Some incident of Cloud service ・System alert
  34. Notice Operation ・Notice to some problem ・Investigation ・Fix bug ・Make

    service maintenance Problem ・Some incident of Cloud service ・System alert
  35. Notice Operation ・Notice to some problem ・Investigation ・Fix bug ・Make

    service maintenance Problem ・Some incident of Cloud service ・System alert
  36. Alert channel • All information will be passed to Slack

    channel • Channel includes all team members
  37. Small technique • Official alert including both incident and recovery

    informations • There is a staff who can't read English • So we customized feed bot
  38. Notice Operation ・Notice to some problem ・Investigation ・Fix bug ・Make

    service maintenance Problem ・Some incident of Cloud service ・System alert
  39. Maintenance mode • System flag to manage maintenance mode •

    Team member can edit • If the effect of incident is too large for customers, we'll edit it
  40. Cloud Firestore vs Realtime Database • You SHOULD check this

    article • https://firebase.googleblog.com/2017/10/ cloud-firestore-for-rtdb-developers.html