SlideShare une entreprise Scribd logo
1  sur  41
Télécharger pour lire hors ligne
Redis Analytics

         @JeffSeibert
        CEO, Crashlytics


2      CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
3   CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
4   CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Crashlytics for Mac
Strings
    Lists
    Hashes
    Sets
    Sorted Sets

8                 CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Strings                              Activity Tracking

    Lists
    Hashes                               Event Tracking

    Sets
    Sorted Sets                          Leader boards


9                 CRASHLYTICS CONFIDENTIAL         © 2012. All rights reserved
Active User Tracking




10         CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Active User Tracking




      CREATE TABLE accounts (
        id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
        name varchar(255),
        email varchar(255),
        ...

           last_active_at datetime
      );




11                         CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Active User Tracking




      CREATE TABLE events (
         id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
         type varchar(32),
         account_id int(11),
         happened_at datetime
      );




12                      CRASHLYTICS CONFIDENTIAL    © 2012. All rights reserved
Active User Tracking




     accounts::active

       0       0        0        0               1        0       0                    1


        SETBIT key                offset value                (>= 2.2)           O(1)
      > SETBIT “accounts::active” 4      1
      > SETBIT “accounts::active” 7      1


14                             CRASHLYTICS CONFIDENTIAL           © 2012. All rights reserved
Active User Tracking
     accounts::active::2012-10

       1      1    1      0               1        0   1                    1

     accounts::active::2012-10-22

       0      0    1      0               1        0   0                    1

     accounts::active::2012-10-22-00

       0      0    0      0               1        0   0                    1

15                      CRASHLYTICS CONFIDENTIAL       © 2012. All rights reserved
Active User Tracking

     def record_active(obj, t=Time.now.utc)
       key = "#{obj.class.name.downcase.pluralize}::active::"

       key << t.year.to_s
       key << "-" << '%02d' % t.month
       REDIS.setbit key, obj.id, 1                     # accounts::active::2012-10

       key << "-" << '%02d' % t.day
       REDIS.setbit key, obj.id, 1                     # accounts::active::2012-10-22

       key << "-" << '%02d' % t.hour
       REDIS.setbit key, obj.id, 1                     # accounts::active::2012-10-22-00
     end




16                                    CRASHLYTICS CONFIDENTIAL             © 2012. All rights reserved
Active User Tracking
     ‣   We want to know…
         • How many users were active today? This month?

            BITCOUNT key                                      (>= 2.6)           O(N)
          > BITCOUNT “accounts::active::2012-10-22”
          (integer) 3
          > BITCOUNT “accounts::active::2012-10”
          (integer) 5


         • Was user X active today? This month?
            GETBIT key                            index       (>= 2.2)           O(1)
          > GETBIT “accounts::active::2012-10-22” 6
          (integer) 0
          > GETBIT “accounts::active::2012-10”    6
          (integer) 1


17                                 CRASHLYTICS CONFIDENTIAL       © 2012. All rights reserved
Active User Tracking
     ‣   Graphs and Heatmaps
         • Monthly actives over time?

          > BITCOUNT   “accounts::active::2012-07”
          > BITCOUNT   “accounts::active::2012-08”
          > BITCOUNT   “accounts::active::2012-09”
          > BITCOUNT   “accounts::active::2012-10”
          ...


         • Over time, when was user X active?
          > GETBIT   “accounts::active::2012-10-22”             6
          > GETBIT   “accounts::active::2012-10-21”             6
          > GETBIT   “accounts::active::2012-10-20”             6
          > GETBIT   “accounts::active::2012-10-19”             6
          ...


18                                   CRASHLYTICS CONFIDENTIAL       © 2012. All rights reserved
Active User Tracking
     ‣   Advanced Data-Mining: WAU
         • Computing weekly active users:

               BITOP op destkey srckey [srckeys...]              (>= 2.6)           O(N)
         •   > BITOP OR “accounts::active::2012-W42” 
                 “accounts::active::2012-10-21” 
                 “accounts::active::2012-10-20” 
                 “accounts::active::2012-10-19” 
                 “accounts::active::2012-10-18” 
                 “accounts::active::2012-10-17” 
                 “accounts::active::2012-10-16” 
                 “accounts::active::2012-10-15”
             > BITCOUNT “accounts::active::2012-W42”




19                                    CRASHLYTICS CONFIDENTIAL       © 2012. All rights reserved
Active User Tracking
     ‣   Advanced Data-Mining: Retention
         • What % of users active last week are active this week?

               BITOP op destkey srckey [srckeys...]              (>= 2.6)           O(N)
         •   > BITOP AND “accounts::active::2012-W41+W42” 
                 “accounts::active::2012-W41” 
                 “accounts::active::2012-W42”
             > BITCOUNT “accounts::active::2012-W41”
             > BITCOUNT “accounts::active::2012-W41+W42”




20                                    CRASHLYTICS CONFIDENTIAL       © 2012. All rights reserved
Active User Tracking
     ‣   Advanced Data-Mining: Churn
         • Locate accounts that have been inactive for 3 months

               BITOP op destkey srckey [srckeys...]              (>= 2.6)           O(N)
         •   > BITOP OR “accounts::active::2012-Q3” 
                 “accounts::active::2012-09” 
                 “accounts::active::2012-08” 
                 “accounts::active::2012-07”
             > BITOP NOT “accounts::churned::2012-Q3” 
                 “accounts::active::2012-Q3”
             > BITCOUNT “accounts::churned::2012-Q3”




21                                    CRASHLYTICS CONFIDENTIAL       © 2012. All rights reserved
Active User Tracking

     def record_boolean(obj, topic=:active, t=Time.now.utc)
       key = "#{obj.class.name.downcase.pluralize}::#{topic}::"

       key << t.year.to_s
       key << "-" << '%02d' % t.month
       REDIS.setbit key, obj.id, 1                     # accounts::active::2012-10

       key << "-" << '%02d' % t.day
       REDIS.setbit key, obj.id, 1                     # accounts::active::2012-10-22

       key << "-" << '%02d' % t.hour
       REDIS.setbit key, obj.id, 1                     # accounts::active::2012-10-22-00
     end




22                                    CRASHLYTICS CONFIDENTIAL             © 2012. All rights reserved
Event Tracking




23      CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Event Tracking




     apps::crashes

       0      0      0     0               ?        0   0                    0




24                       CRASHLYTICS CONFIDENTIAL       © 2012. All rights reserved
Event Tracking

     apps::crashes {
       0 => 34,
       1 => 546457,
       2 => 1
     }



       HINCRBY key             field increment           (>= 2.0)           O(1)
     > HINCRBY “apps::crashes” “0”   1
     > HINCRBY “apps::crashes” “2”   1




25                            CRASHLYTICS CONFIDENTIAL       © 2012. All rights reserved
Event Tracking

     app::0::crash::by_day {
       2012-10-22 => 34,
       2012-10-21 => 46,
       2012-10-20 => 29,
       ...
     }



     > HINCRBY “app::0::crash::by_day” “2012-10-22” 1




26                            CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Event Tracking

     def record_event(obj, topic=:crash, specificity=:day, t=Time.now.utc)
       key = "#{obj.class.name.downcase}::#{obj.id}::#{topic}::by_#{specificity}"
       # e.g. app::0::crash::by_day

       field = t.year.to_s
       field << "-" << '%02d' % t.month    # 2012-10
       REDIS.hincrby key, field, 1 if specificity == :month

       field << "-" << '%02d' % t.day      # 2012-10-22
       REDIS.hincrby key, field, 1 if specificity == :day

       field << "-" << '%02d' % t.hour     # 2012-10-22-00
       REDIS.hincrby key, field, 1 if specificity == :hour
     end




27                                 CRASHLYTICS CONFIDENTIAL        © 2012. All rights reserved
Event Tracking
     ‣   We want to…
         • Power a graph of crashes over the last week

            HMGET key                     field1 [...]    (>= 2.0)           O(N)
          > HMGET “app::0::crash::by_day” “2012-10-22” 
                    “2012-10-21” “2012-10-20” “2012-10-19” 
                    “2012-10-18” “2012-10-17” “2012-10-16”
          1) ...


         • “Zoom” the graph to see more detail

         > HMGET “app::0::crash::by_hour” “2012-10-22-00” 
                   “2012-10-22-01” “2012-10-22-02” “2012-10-22-03” 
                   “2012-10-22-04” “2012-10-22-05” “2012-10-22-06” ...
         1) ...



28                                 CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Grouped Event Tracking

      “How often has app X crashed
         on each type of iPad?”




29            CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Grouped Event Tracking

     app::0::crash::iPad1,1 {                      device_models [
       2012-10-22 => 34,                             “iPad1,1”,
       2012-10-21 => 46,                             “iPad2,1”,
       2012-10-20 => 29,                             ...
       ...                                         ]
     }

     app::0::crash::iPad2,1 {
       2012-10-22 => 12,
       2012-10-21 => 17,
       2012-10-20 => 11,
       ...
     }


30                      CRASHLYTICS CONFIDENTIAL           © 2012. All rights reserved
Grouped Event Tracking

     app::0::crash::2012-10-22 {
       ALL => 46,
       iPad1,1 => 34,
       iPad2,1 => 12,
       ...
     }


       HGETALL key                                        (>= 2.0)          O(N)
     > HGETALL “app::0::crash::2012-10-22”
     (multi-bulk)




31                             CRASHLYTICS CONFIDENTIAL        © 2012. All rights reserved
Grouped Event Tracking

     def record_grouped_event(obj, group, topic=:crash, t=Time.now.utc)
       key = "#{obj.class.name.downcase}::#{obj.id}::#{topic}::"

       key = t.year.to_s
       key << "-" << '%02d' % t.month      # app::0::crash::2012-10
       REDIS.hincrby key, group, 1
       REDIS.hincrby key, 'ALL', 1

       field << "-" << '%02d' % t.day      # app::0::crash::2012-10-22
       REDIS.hincrby key, group, 1
       REDIS.hincrby key, 'ALL', 1

       field << "-" << '%02d' % t.hour     # app::0::crash::2012-10-22-00
       REDIS.hincrby key, group, 1
       REDIS.hincrby key, 'ALL', 1
     end




32                                 CRASHLYTICS CONFIDENTIAL           © 2012. All rights reserved
MongoDB
     > Account.first.id
     => BSON::ObjectId('507db04798a3340ada000002')




33                      CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Sequential ID Generation

     sequential_ids::accounts {
       10 5084bfbb98a33406f0000002,
       9 5084bfa798a33406f0000001,
       8 507db04798a3340ada000002,
       ...
     }


       ZADD key                        score member (>= 1.2) O(log(N))
     > ZADD “sequential_ids::accounts” 10    507db04798a3340ada000002
     (integer) 1




34                             CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Sequential ID Generation

     sequential_ids::accounts {
       10 5084bfbb98a33406f0000002,
       9 5084bfa798a33406f0000001,
       8 507db04798a3340ada000002,
       ...
     }


       ZCARD key                                          (>= 1.2) O(1)
     > ZCARD “sequential_ids::accounts”
     (integer) 9

       ZADD key                        score member (>= 1.2) O(log(N))
     > ZADD “sequential_ids::accounts” 10    5084bfbb98a33406f0000002
     (integer) 1



35                             CRASHLYTICS CONFIDENTIAL    © 2012. All rights reserved
Sequential ID Generation

     sequential_ids::accounts {
       10 5084bfbb98a33406f0000002,
       9 5084bfa798a33406f0000001,
       8 507db04798a3340ada000002,
       ...
     }


       ZSCORE key                        member          (>= 1.2) O(1)
     > ZSCORE “sequential_ids::accounts” 5084bfbb98a33406f0000002
     (integer) 10




36                             CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Sequential ID Generation

     def sequential_id(obj)
       key = "sequential_keys::#{obj.class.name.downcase.pluralize}"
       id = obj.id.to_s

       # Lua script to atomically determine the score of an id.
       # If needed, adds it to the set with the next available score.
       # In the general case, O(1). On add, O(log(N)). Requires Redis >= 2.6
       monotonic_zadd = <<LUA
         local sequential_id = redis.call('zscore', KEYS[1], ARGV[1])
         if not sequential_id then
           sequential_id = redis.call('zcard', KEYS[1])
           redis.call('zadd', KEYS[1], sequential_id, ARGV[1])
         end

           return sequential_id
     LUA

       REDIS.eval(monotonic_zadd, [key], [id]).to_i
     end



37                                   CRASHLYTICS CONFIDENTIAL          © 2012. All rights reserved
Redis Analytics Wish List




38           CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Redis Analytics Wish List
     ‣   MSETBIT, MGETBIT, MBITCOUNT, HMINCRBY
         • Can already be addressed with scripting
     ‣ Native support for (insertion-)ordered sets
     ‣ Per-hash-key expiration policies




39                              CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Q&A
       @JeffSeibert
      CEO, Crashlytics



40   CRASHLYTICS CONFIDENTIAL   © 2012. All rights reserved
Scaling Crashlytics: Building Analytics on Redis 2.6

Contenu connexe

Tendances

Event-Driven Messaging and Actions using Apache Flink and Apache NiFi
Event-Driven Messaging and Actions using Apache Flink and Apache NiFiEvent-Driven Messaging and Actions using Apache Flink and Apache NiFi
Event-Driven Messaging and Actions using Apache Flink and Apache NiFiDataWorks Summit
 
[오픈소스컨설팅] Open Stack Ceph, Neutron, HA, Multi-Region
[오픈소스컨설팅] Open Stack Ceph, Neutron, HA, Multi-Region[오픈소스컨설팅] Open Stack Ceph, Neutron, HA, Multi-Region
[오픈소스컨설팅] Open Stack Ceph, Neutron, HA, Multi-RegionJi-Woong Choi
 
Creating modern java web applications based on struts2 and angularjs
Creating modern java web applications based on struts2 and angularjsCreating modern java web applications based on struts2 and angularjs
Creating modern java web applications based on struts2 and angularjsJohannes Geppert
 
Understanding container security
Understanding container securityUnderstanding container security
Understanding container securityJohn Kinsella
 
Experience lessons from architecture of zalo real time system
Experience lessons from architecture of zalo real time systemExperience lessons from architecture of zalo real time system
Experience lessons from architecture of zalo real time systemZalo_app
 
Kolla talk at OpenStack Summit 2017 in Sydney
Kolla talk at OpenStack Summit 2017 in SydneyKolla talk at OpenStack Summit 2017 in Sydney
Kolla talk at OpenStack Summit 2017 in SydneyVikram G Hosakote
 
Designing microservices platforms with nats
Designing microservices platforms with natsDesigning microservices platforms with nats
Designing microservices platforms with natsChanaka Fernando
 
PayPal datalake journey | teradata - edge of next | san diego | 2017 october ...
PayPal datalake journey | teradata - edge of next | san diego | 2017 october ...PayPal datalake journey | teradata - edge of next | san diego | 2017 october ...
PayPal datalake journey | teradata - edge of next | san diego | 2017 october ...Deepak Chandramouli
 
REST: From GET to HATEOAS
REST: From GET to HATEOASREST: From GET to HATEOAS
REST: From GET to HATEOASJos Dirksen
 
Deep Learning on Apache Spark at CERN’s Large Hadron Collider with Intel Tech...
Deep Learning on Apache Spark at CERN’s Large Hadron Collider with Intel Tech...Deep Learning on Apache Spark at CERN’s Large Hadron Collider with Intel Tech...
Deep Learning on Apache Spark at CERN’s Large Hadron Collider with Intel Tech...Databricks
 
「Photon OS + Docker」VLAN 環境の構築
「Photon OS + Docker」VLAN 環境の構築「Photon OS + Docker」VLAN 環境の構築
「Photon OS + Docker」VLAN 環境の構築Fuva Brain
 
Metal³ – Metal Kubed, Bare Metal Provisioning for Kubernetes | Kim Bảo Long
Metal³ – Metal Kubed, Bare Metal Provisioning for Kubernetes | Kim Bảo LongMetal³ – Metal Kubed, Bare Metal Provisioning for Kubernetes | Kim Bảo Long
Metal³ – Metal Kubed, Bare Metal Provisioning for Kubernetes | Kim Bảo LongVietnam Open Infrastructure User Group
 
Protecting Apps from Hacks in Kubernetes with NGINX
Protecting Apps from Hacks in Kubernetes with NGINXProtecting Apps from Hacks in Kubernetes with NGINX
Protecting Apps from Hacks in Kubernetes with NGINXNGINX, Inc.
 
OpenStack Architecture
OpenStack ArchitectureOpenStack Architecture
OpenStack ArchitectureMirantis
 
State of the ATT&CK May 2023
State of the ATT&CK May 2023State of the ATT&CK May 2023
State of the ATT&CK May 2023Adam Pennington
 
Container Security
Container SecurityContainer Security
Container SecuritySalman Baset
 
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.7.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.7.0対応)FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.7.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.7.0対応)fisuda
 
Developer’s guide to contributing code to Kafka with Mickael Maison and Tom B...
Developer’s guide to contributing code to Kafka with Mickael Maison and Tom B...Developer’s guide to contributing code to Kafka with Mickael Maison and Tom B...
Developer’s guide to contributing code to Kafka with Mickael Maison and Tom B...HostedbyConfluent
 

Tendances (20)

Event-Driven Messaging and Actions using Apache Flink and Apache NiFi
Event-Driven Messaging and Actions using Apache Flink and Apache NiFiEvent-Driven Messaging and Actions using Apache Flink and Apache NiFi
Event-Driven Messaging and Actions using Apache Flink and Apache NiFi
 
[오픈소스컨설팅] Open Stack Ceph, Neutron, HA, Multi-Region
[오픈소스컨설팅] Open Stack Ceph, Neutron, HA, Multi-Region[오픈소스컨설팅] Open Stack Ceph, Neutron, HA, Multi-Region
[오픈소스컨설팅] Open Stack Ceph, Neutron, HA, Multi-Region
 
Creating modern java web applications based on struts2 and angularjs
Creating modern java web applications based on struts2 and angularjsCreating modern java web applications based on struts2 and angularjs
Creating modern java web applications based on struts2 and angularjs
 
Understanding container security
Understanding container securityUnderstanding container security
Understanding container security
 
Experience lessons from architecture of zalo real time system
Experience lessons from architecture of zalo real time systemExperience lessons from architecture of zalo real time system
Experience lessons from architecture of zalo real time system
 
Openstack 101
Openstack 101Openstack 101
Openstack 101
 
Kolla talk at OpenStack Summit 2017 in Sydney
Kolla talk at OpenStack Summit 2017 in SydneyKolla talk at OpenStack Summit 2017 in Sydney
Kolla talk at OpenStack Summit 2017 in Sydney
 
Designing microservices platforms with nats
Designing microservices platforms with natsDesigning microservices platforms with nats
Designing microservices platforms with nats
 
PayPal datalake journey | teradata - edge of next | san diego | 2017 october ...
PayPal datalake journey | teradata - edge of next | san diego | 2017 october ...PayPal datalake journey | teradata - edge of next | san diego | 2017 october ...
PayPal datalake journey | teradata - edge of next | san diego | 2017 october ...
 
REST: From GET to HATEOAS
REST: From GET to HATEOASREST: From GET to HATEOAS
REST: From GET to HATEOAS
 
Kubernetes Security
Kubernetes SecurityKubernetes Security
Kubernetes Security
 
Deep Learning on Apache Spark at CERN’s Large Hadron Collider with Intel Tech...
Deep Learning on Apache Spark at CERN’s Large Hadron Collider with Intel Tech...Deep Learning on Apache Spark at CERN’s Large Hadron Collider with Intel Tech...
Deep Learning on Apache Spark at CERN’s Large Hadron Collider with Intel Tech...
 
「Photon OS + Docker」VLAN 環境の構築
「Photon OS + Docker」VLAN 環境の構築「Photon OS + Docker」VLAN 環境の構築
「Photon OS + Docker」VLAN 環境の構築
 
Metal³ – Metal Kubed, Bare Metal Provisioning for Kubernetes | Kim Bảo Long
Metal³ – Metal Kubed, Bare Metal Provisioning for Kubernetes | Kim Bảo LongMetal³ – Metal Kubed, Bare Metal Provisioning for Kubernetes | Kim Bảo Long
Metal³ – Metal Kubed, Bare Metal Provisioning for Kubernetes | Kim Bảo Long
 
Protecting Apps from Hacks in Kubernetes with NGINX
Protecting Apps from Hacks in Kubernetes with NGINXProtecting Apps from Hacks in Kubernetes with NGINX
Protecting Apps from Hacks in Kubernetes with NGINX
 
OpenStack Architecture
OpenStack ArchitectureOpenStack Architecture
OpenStack Architecture
 
State of the ATT&CK May 2023
State of the ATT&CK May 2023State of the ATT&CK May 2023
State of the ATT&CK May 2023
 
Container Security
Container SecurityContainer Security
Container Security
 
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.7.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.7.0対応)FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.7.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.7.0対応)
 
Developer’s guide to contributing code to Kafka with Mickael Maison and Tom B...
Developer’s guide to contributing code to Kafka with Mickael Maison and Tom B...Developer’s guide to contributing code to Kafka with Mickael Maison and Tom B...
Developer’s guide to contributing code to Kafka with Mickael Maison and Tom B...
 

En vedette

Kicking ass with redis
Kicking ass with redisKicking ass with redis
Kicking ass with redisDvir Volk
 
Redis in Practice
Redis in PracticeRedis in Practice
Redis in PracticeNoah Davis
 
Redis data design by usecase
Redis data design by usecaseRedis data design by usecase
Redis data design by usecaseKris Jeong
 
High-Volume Data Collection and Real Time Analytics Using Redis
High-Volume Data Collection and Real Time Analytics Using RedisHigh-Volume Data Collection and Real Time Analytics Using Redis
High-Volume Data Collection and Real Time Analytics Using Rediscacois
 
Redis Use Patterns (DevconTLV June 2014)
Redis Use Patterns (DevconTLV June 2014)Redis Use Patterns (DevconTLV June 2014)
Redis Use Patterns (DevconTLV June 2014)Itamar Haber
 
Redis data modeling examples
Redis data modeling examplesRedis data modeling examples
Redis data modeling examplesTerry Cho
 
Everything you always wanted to know about Redis but were afraid to ask
Everything you always wanted to know about Redis but were afraid to askEverything you always wanted to know about Redis but were afraid to ask
Everything you always wanted to know about Redis but were afraid to askCarlos Abalde
 

En vedette (7)

Kicking ass with redis
Kicking ass with redisKicking ass with redis
Kicking ass with redis
 
Redis in Practice
Redis in PracticeRedis in Practice
Redis in Practice
 
Redis data design by usecase
Redis data design by usecaseRedis data design by usecase
Redis data design by usecase
 
High-Volume Data Collection and Real Time Analytics Using Redis
High-Volume Data Collection and Real Time Analytics Using RedisHigh-Volume Data Collection and Real Time Analytics Using Redis
High-Volume Data Collection and Real Time Analytics Using Redis
 
Redis Use Patterns (DevconTLV June 2014)
Redis Use Patterns (DevconTLV June 2014)Redis Use Patterns (DevconTLV June 2014)
Redis Use Patterns (DevconTLV June 2014)
 
Redis data modeling examples
Redis data modeling examplesRedis data modeling examples
Redis data modeling examples
 
Everything you always wanted to know about Redis but were afraid to ask
Everything you always wanted to know about Redis but were afraid to askEverything you always wanted to know about Redis but were afraid to ask
Everything you always wanted to know about Redis but were afraid to ask
 

Similaire à Scaling Crashlytics: Building Analytics on Redis 2.6

ATT&CK Updates- Defensive ATT&CK
ATT&CK Updates- Defensive ATT&CKATT&CK Updates- Defensive ATT&CK
ATT&CK Updates- Defensive ATT&CKMITRE ATT&CK
 
Desenvolvimento web com Ruby on Rails (parte 5)
Desenvolvimento web com Ruby on Rails (parte 5)Desenvolvimento web com Ruby on Rails (parte 5)
Desenvolvimento web com Ruby on Rails (parte 5)Joao Lucas Santana
 
Webinar: User Data Management with MongoDB
Webinar: User Data Management with MongoDBWebinar: User Data Management with MongoDB
Webinar: User Data Management with MongoDBMongoDB
 
1 24 - user data management
1 24 - user data management1 24 - user data management
1 24 - user data managementMongoDB
 
Introducing Stitch
Introducing Stitch Introducing Stitch
Introducing Stitch MongoDB
 
DevTalks 2021 Cloud Engineering @Crowdstrike
DevTalks 2021 Cloud Engineering @CrowdstrikeDevTalks 2021 Cloud Engineering @Crowdstrike
DevTalks 2021 Cloud Engineering @CrowdstrikeCosmin Bratu
 
Audience Intel presentation 2014
Audience Intel presentation 2014Audience Intel presentation 2014
Audience Intel presentation 2014David Mitchell
 
5 Key Audit Procedures for Rock-Solid Trial Balances
5 Key Audit Procedures for Rock-Solid Trial Balances5 Key Audit Procedures for Rock-Solid Trial Balances
5 Key Audit Procedures for Rock-Solid Trial Balanceseprentise
 
MongoDB Days UK: No Compromises SQL Connectivity for MongoDB
MongoDB Days UK: No Compromises SQL Connectivity for MongoDBMongoDB Days UK: No Compromises SQL Connectivity for MongoDB
MongoDB Days UK: No Compromises SQL Connectivity for MongoDBMongoDB
 
PayPal Real Time Analytics
PayPal  Real Time AnalyticsPayPal  Real Time Analytics
PayPal Real Time AnalyticsAnil Madan
 
IOOF IT System Modernisation
IOOF IT System ModernisationIOOF IT System Modernisation
IOOF IT System ModernisationMongoDB
 
Google Analytics blog support
Google Analytics blog supportGoogle Analytics blog support
Google Analytics blog supportmassiveans
 
Build 2017 - P4152 - Microsoft Graph - Delta Query and Webhooks
Build 2017 - P4152 - Microsoft Graph - Delta Query and WebhooksBuild 2017 - P4152 - Microsoft Graph - Delta Query and Webhooks
Build 2017 - P4152 - Microsoft Graph - Delta Query and WebhooksWindows Developer
 
Building Applications with DynamoDB
Building Applications with DynamoDBBuilding Applications with DynamoDB
Building Applications with DynamoDBAmazon Web Services
 
Nyss Open legislation
Nyss Open legislationNyss Open legislation
Nyss Open legislationGraylinKim
 
Webinar: User Data Management with MongoDB
Webinar: User Data Management with MongoDBWebinar: User Data Management with MongoDB
Webinar: User Data Management with MongoDBMongoDB
 
The database is half done
The database is half doneThe database is half done
The database is half doneconfluent
 
Ivanti for msp
Ivanti for mspIvanti for msp
Ivanti for mspIvanti
 
Uncover the Root Cause of Kafka Performance Anomalies, Daniel Kim & Antón Rod...
Uncover the Root Cause of Kafka Performance Anomalies, Daniel Kim & Antón Rod...Uncover the Root Cause of Kafka Performance Anomalies, Daniel Kim & Antón Rod...
Uncover the Root Cause of Kafka Performance Anomalies, Daniel Kim & Antón Rod...HostedbyConfluent
 

Similaire à Scaling Crashlytics: Building Analytics on Redis 2.6 (20)

ATT&CK Updates- Defensive ATT&CK
ATT&CK Updates- Defensive ATT&CKATT&CK Updates- Defensive ATT&CK
ATT&CK Updates- Defensive ATT&CK
 
Desenvolvimento web com Ruby on Rails (parte 5)
Desenvolvimento web com Ruby on Rails (parte 5)Desenvolvimento web com Ruby on Rails (parte 5)
Desenvolvimento web com Ruby on Rails (parte 5)
 
Webinar: User Data Management with MongoDB
Webinar: User Data Management with MongoDBWebinar: User Data Management with MongoDB
Webinar: User Data Management with MongoDB
 
1 24 - user data management
1 24 - user data management1 24 - user data management
1 24 - user data management
 
Introducing Stitch
Introducing Stitch Introducing Stitch
Introducing Stitch
 
DevTalks 2021 Cloud Engineering @Crowdstrike
DevTalks 2021 Cloud Engineering @CrowdstrikeDevTalks 2021 Cloud Engineering @Crowdstrike
DevTalks 2021 Cloud Engineering @Crowdstrike
 
Audience Intel presentation 2014
Audience Intel presentation 2014Audience Intel presentation 2014
Audience Intel presentation 2014
 
5 Key Audit Procedures for Rock-Solid Trial Balances
5 Key Audit Procedures for Rock-Solid Trial Balances5 Key Audit Procedures for Rock-Solid Trial Balances
5 Key Audit Procedures for Rock-Solid Trial Balances
 
MongoDB Days UK: No Compromises SQL Connectivity for MongoDB
MongoDB Days UK: No Compromises SQL Connectivity for MongoDBMongoDB Days UK: No Compromises SQL Connectivity for MongoDB
MongoDB Days UK: No Compromises SQL Connectivity for MongoDB
 
Andy lib解説
Andy lib解説Andy lib解説
Andy lib解説
 
PayPal Real Time Analytics
PayPal  Real Time AnalyticsPayPal  Real Time Analytics
PayPal Real Time Analytics
 
IOOF IT System Modernisation
IOOF IT System ModernisationIOOF IT System Modernisation
IOOF IT System Modernisation
 
Google Analytics blog support
Google Analytics blog supportGoogle Analytics blog support
Google Analytics blog support
 
Build 2017 - P4152 - Microsoft Graph - Delta Query and Webhooks
Build 2017 - P4152 - Microsoft Graph - Delta Query and WebhooksBuild 2017 - P4152 - Microsoft Graph - Delta Query and Webhooks
Build 2017 - P4152 - Microsoft Graph - Delta Query and Webhooks
 
Building Applications with DynamoDB
Building Applications with DynamoDBBuilding Applications with DynamoDB
Building Applications with DynamoDB
 
Nyss Open legislation
Nyss Open legislationNyss Open legislation
Nyss Open legislation
 
Webinar: User Data Management with MongoDB
Webinar: User Data Management with MongoDBWebinar: User Data Management with MongoDB
Webinar: User Data Management with MongoDB
 
The database is half done
The database is half doneThe database is half done
The database is half done
 
Ivanti for msp
Ivanti for mspIvanti for msp
Ivanti for msp
 
Uncover the Root Cause of Kafka Performance Anomalies, Daniel Kim & Antón Rod...
Uncover the Root Cause of Kafka Performance Anomalies, Daniel Kim & Antón Rod...Uncover the Root Cause of Kafka Performance Anomalies, Daniel Kim & Antón Rod...
Uncover the Root Cause of Kafka Performance Anomalies, Daniel Kim & Antón Rod...
 

Dernier

Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 

Dernier (20)

Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 

Scaling Crashlytics: Building Analytics on Redis 2.6

  • 1.
  • 2. Redis Analytics @JeffSeibert CEO, Crashlytics 2 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 3. 3 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 4. 4 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 5.
  • 7.
  • 8. Strings Lists Hashes Sets Sorted Sets 8 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 9. Strings Activity Tracking Lists Hashes Event Tracking Sets Sorted Sets Leader boards 9 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 10. Active User Tracking 10 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 11. Active User Tracking CREATE TABLE accounts ( id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, name varchar(255), email varchar(255), ... last_active_at datetime ); 11 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 12. Active User Tracking CREATE TABLE events ( id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, type varchar(32), account_id int(11), happened_at datetime ); 12 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 13.
  • 14. Active User Tracking accounts::active 0 0 0 0 1 0 0 1 SETBIT key offset value (>= 2.2) O(1) > SETBIT “accounts::active” 4 1 > SETBIT “accounts::active” 7 1 14 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 15. Active User Tracking accounts::active::2012-10 1 1 1 0 1 0 1 1 accounts::active::2012-10-22 0 0 1 0 1 0 0 1 accounts::active::2012-10-22-00 0 0 0 0 1 0 0 1 15 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 16. Active User Tracking def record_active(obj, t=Time.now.utc) key = "#{obj.class.name.downcase.pluralize}::active::" key << t.year.to_s key << "-" << '%02d' % t.month REDIS.setbit key, obj.id, 1 # accounts::active::2012-10 key << "-" << '%02d' % t.day REDIS.setbit key, obj.id, 1 # accounts::active::2012-10-22 key << "-" << '%02d' % t.hour REDIS.setbit key, obj.id, 1 # accounts::active::2012-10-22-00 end 16 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 17. Active User Tracking ‣ We want to know… • How many users were active today? This month? BITCOUNT key (>= 2.6) O(N) > BITCOUNT “accounts::active::2012-10-22” (integer) 3 > BITCOUNT “accounts::active::2012-10” (integer) 5 • Was user X active today? This month? GETBIT key index (>= 2.2) O(1) > GETBIT “accounts::active::2012-10-22” 6 (integer) 0 > GETBIT “accounts::active::2012-10” 6 (integer) 1 17 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 18. Active User Tracking ‣ Graphs and Heatmaps • Monthly actives over time? > BITCOUNT “accounts::active::2012-07” > BITCOUNT “accounts::active::2012-08” > BITCOUNT “accounts::active::2012-09” > BITCOUNT “accounts::active::2012-10” ... • Over time, when was user X active? > GETBIT “accounts::active::2012-10-22” 6 > GETBIT “accounts::active::2012-10-21” 6 > GETBIT “accounts::active::2012-10-20” 6 > GETBIT “accounts::active::2012-10-19” 6 ... 18 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 19. Active User Tracking ‣ Advanced Data-Mining: WAU • Computing weekly active users: BITOP op destkey srckey [srckeys...] (>= 2.6) O(N) • > BITOP OR “accounts::active::2012-W42” “accounts::active::2012-10-21” “accounts::active::2012-10-20” “accounts::active::2012-10-19” “accounts::active::2012-10-18” “accounts::active::2012-10-17” “accounts::active::2012-10-16” “accounts::active::2012-10-15” > BITCOUNT “accounts::active::2012-W42” 19 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 20. Active User Tracking ‣ Advanced Data-Mining: Retention • What % of users active last week are active this week? BITOP op destkey srckey [srckeys...] (>= 2.6) O(N) • > BITOP AND “accounts::active::2012-W41+W42” “accounts::active::2012-W41” “accounts::active::2012-W42” > BITCOUNT “accounts::active::2012-W41” > BITCOUNT “accounts::active::2012-W41+W42” 20 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 21. Active User Tracking ‣ Advanced Data-Mining: Churn • Locate accounts that have been inactive for 3 months BITOP op destkey srckey [srckeys...] (>= 2.6) O(N) • > BITOP OR “accounts::active::2012-Q3” “accounts::active::2012-09” “accounts::active::2012-08” “accounts::active::2012-07” > BITOP NOT “accounts::churned::2012-Q3” “accounts::active::2012-Q3” > BITCOUNT “accounts::churned::2012-Q3” 21 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 22. Active User Tracking def record_boolean(obj, topic=:active, t=Time.now.utc) key = "#{obj.class.name.downcase.pluralize}::#{topic}::" key << t.year.to_s key << "-" << '%02d' % t.month REDIS.setbit key, obj.id, 1 # accounts::active::2012-10 key << "-" << '%02d' % t.day REDIS.setbit key, obj.id, 1 # accounts::active::2012-10-22 key << "-" << '%02d' % t.hour REDIS.setbit key, obj.id, 1 # accounts::active::2012-10-22-00 end 22 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 23. Event Tracking 23 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 24. Event Tracking apps::crashes 0 0 0 0 ? 0 0 0 24 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 25. Event Tracking apps::crashes { 0 => 34, 1 => 546457, 2 => 1 } HINCRBY key field increment (>= 2.0) O(1) > HINCRBY “apps::crashes” “0” 1 > HINCRBY “apps::crashes” “2” 1 25 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 26. Event Tracking app::0::crash::by_day { 2012-10-22 => 34, 2012-10-21 => 46, 2012-10-20 => 29, ... } > HINCRBY “app::0::crash::by_day” “2012-10-22” 1 26 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 27. Event Tracking def record_event(obj, topic=:crash, specificity=:day, t=Time.now.utc) key = "#{obj.class.name.downcase}::#{obj.id}::#{topic}::by_#{specificity}" # e.g. app::0::crash::by_day field = t.year.to_s field << "-" << '%02d' % t.month # 2012-10 REDIS.hincrby key, field, 1 if specificity == :month field << "-" << '%02d' % t.day # 2012-10-22 REDIS.hincrby key, field, 1 if specificity == :day field << "-" << '%02d' % t.hour # 2012-10-22-00 REDIS.hincrby key, field, 1 if specificity == :hour end 27 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 28. Event Tracking ‣ We want to… • Power a graph of crashes over the last week HMGET key field1 [...] (>= 2.0) O(N) > HMGET “app::0::crash::by_day” “2012-10-22” “2012-10-21” “2012-10-20” “2012-10-19” “2012-10-18” “2012-10-17” “2012-10-16” 1) ... • “Zoom” the graph to see more detail > HMGET “app::0::crash::by_hour” “2012-10-22-00” “2012-10-22-01” “2012-10-22-02” “2012-10-22-03” “2012-10-22-04” “2012-10-22-05” “2012-10-22-06” ... 1) ... 28 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 29. Grouped Event Tracking “How often has app X crashed on each type of iPad?” 29 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 30. Grouped Event Tracking app::0::crash::iPad1,1 { device_models [ 2012-10-22 => 34, “iPad1,1”, 2012-10-21 => 46, “iPad2,1”, 2012-10-20 => 29, ... ... ] } app::0::crash::iPad2,1 { 2012-10-22 => 12, 2012-10-21 => 17, 2012-10-20 => 11, ... } 30 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 31. Grouped Event Tracking app::0::crash::2012-10-22 { ALL => 46, iPad1,1 => 34, iPad2,1 => 12, ... } HGETALL key (>= 2.0) O(N) > HGETALL “app::0::crash::2012-10-22” (multi-bulk) 31 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 32. Grouped Event Tracking def record_grouped_event(obj, group, topic=:crash, t=Time.now.utc) key = "#{obj.class.name.downcase}::#{obj.id}::#{topic}::" key = t.year.to_s key << "-" << '%02d' % t.month # app::0::crash::2012-10 REDIS.hincrby key, group, 1 REDIS.hincrby key, 'ALL', 1 field << "-" << '%02d' % t.day # app::0::crash::2012-10-22 REDIS.hincrby key, group, 1 REDIS.hincrby key, 'ALL', 1 field << "-" << '%02d' % t.hour # app::0::crash::2012-10-22-00 REDIS.hincrby key, group, 1 REDIS.hincrby key, 'ALL', 1 end 32 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 33. MongoDB > Account.first.id => BSON::ObjectId('507db04798a3340ada000002') 33 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 34. Sequential ID Generation sequential_ids::accounts { 10 5084bfbb98a33406f0000002, 9 5084bfa798a33406f0000001, 8 507db04798a3340ada000002, ... } ZADD key score member (>= 1.2) O(log(N)) > ZADD “sequential_ids::accounts” 10 507db04798a3340ada000002 (integer) 1 34 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 35. Sequential ID Generation sequential_ids::accounts { 10 5084bfbb98a33406f0000002, 9 5084bfa798a33406f0000001, 8 507db04798a3340ada000002, ... } ZCARD key (>= 1.2) O(1) > ZCARD “sequential_ids::accounts” (integer) 9 ZADD key score member (>= 1.2) O(log(N)) > ZADD “sequential_ids::accounts” 10 5084bfbb98a33406f0000002 (integer) 1 35 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 36. Sequential ID Generation sequential_ids::accounts { 10 5084bfbb98a33406f0000002, 9 5084bfa798a33406f0000001, 8 507db04798a3340ada000002, ... } ZSCORE key member (>= 1.2) O(1) > ZSCORE “sequential_ids::accounts” 5084bfbb98a33406f0000002 (integer) 10 36 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 37. Sequential ID Generation def sequential_id(obj) key = "sequential_keys::#{obj.class.name.downcase.pluralize}" id = obj.id.to_s # Lua script to atomically determine the score of an id. # If needed, adds it to the set with the next available score. # In the general case, O(1). On add, O(log(N)). Requires Redis >= 2.6 monotonic_zadd = <<LUA local sequential_id = redis.call('zscore', KEYS[1], ARGV[1]) if not sequential_id then sequential_id = redis.call('zcard', KEYS[1]) redis.call('zadd', KEYS[1], sequential_id, ARGV[1]) end return sequential_id LUA REDIS.eval(monotonic_zadd, [key], [id]).to_i end 37 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 38. Redis Analytics Wish List 38 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 39. Redis Analytics Wish List ‣ MSETBIT, MGETBIT, MBITCOUNT, HMINCRBY • Can already be addressed with scripting ‣ Native support for (insertion-)ordered sets ‣ Per-hash-key expiration policies 39 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved
  • 40. Q&A @JeffSeibert CEO, Crashlytics 40 CRASHLYTICS CONFIDENTIAL © 2012. All rights reserved