SlideShare a Scribd company logo
1 of 41
Download to read offline
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

More Related Content

What's hot

Advanced Flink Training - Design patterns for streaming applications
Advanced Flink Training - Design patterns for streaming applicationsAdvanced Flink Training - Design patterns for streaming applications
Advanced Flink Training - Design patterns for streaming applicationsAljoscha Krettek
 
FIDO2 Specifications Overview
FIDO2 Specifications OverviewFIDO2 Specifications Overview
FIDO2 Specifications OverviewFIDO Alliance
 
Windows Server and Docker - The Internals Behind Bringing Docker and Containe...
Windows Server and Docker - The Internals Behind Bringing Docker and Containe...Windows Server and Docker - The Internals Behind Bringing Docker and Containe...
Windows Server and Docker - The Internals Behind Bringing Docker and Containe...Docker, Inc.
 
PURL and vers: The Mostly Universal Package URL and Version Ranges Identifier...
PURL and vers: The Mostly Universal Package URL and Version Ranges Identifier...PURL and vers: The Mostly Universal Package URL and Version Ranges Identifier...
PURL and vers: The Mostly Universal Package URL and Version Ranges Identifier...Michael Herzog
 
PHP unserialization vulnerabilities: What are we missing?
PHP unserialization vulnerabilities: What are we missing?PHP unserialization vulnerabilities: What are we missing?
PHP unserialization vulnerabilities: What are we missing?Sam Thomas
 
Building a Streaming Pipeline on Kubernetes Using Kafka Connect, KSQLDB & Apa...
Building a Streaming Pipeline on Kubernetes Using Kafka Connect, KSQLDB & Apa...Building a Streaming Pipeline on Kubernetes Using Kafka Connect, KSQLDB & Apa...
Building a Streaming Pipeline on Kubernetes Using Kafka Connect, KSQLDB & Apa...HostedbyConfluent
 
Building secure applications with keycloak
Building secure applications with keycloak Building secure applications with keycloak
Building secure applications with keycloak Abhishek Koserwal
 
WebAuthn and Security Keys
WebAuthn and Security KeysWebAuthn and Security Keys
WebAuthn and Security KeysFIDO Alliance
 
Rainbird: Realtime Analytics at Twitter (Strata 2011)
Rainbird: Realtime Analytics at Twitter (Strata 2011)Rainbird: Realtime Analytics at Twitter (Strata 2011)
Rainbird: Realtime Analytics at Twitter (Strata 2011)Kevin Weil
 
Getting Data into Splunk
Getting Data into SplunkGetting Data into Splunk
Getting Data into SplunkSplunk
 
When to Use MongoDB...and When You Should Not...
When to Use MongoDB...and When You Should Not...When to Use MongoDB...and When You Should Not...
When to Use MongoDB...and When You Should Not...MongoDB
 
Abusing Symlinks on Windows
Abusing Symlinks on WindowsAbusing Symlinks on Windows
Abusing Symlinks on WindowsOWASP Delhi
 
Technical Considerations for Deploying FIDO Authentication
Technical Considerations for Deploying FIDO Authentication Technical Considerations for Deploying FIDO Authentication
Technical Considerations for Deploying FIDO Authentication FIDO Alliance
 
Mongodb basics and architecture
Mongodb basics and architectureMongodb basics and architecture
Mongodb basics and architectureBishal Khanal
 
Service workers
Service workersService workers
Service workersjungkees
 
Schema Design
Schema DesignSchema Design
Schema DesignMongoDB
 
How Retail Banks Use MongoDB
How Retail Banks Use MongoDBHow Retail Banks Use MongoDB
How Retail Banks Use MongoDBMongoDB
 
Importing Data into Neo4j quickly and easily - StackOverflow
Importing Data into Neo4j quickly and easily - StackOverflowImporting Data into Neo4j quickly and easily - StackOverflow
Importing Data into Neo4j quickly and easily - StackOverflowNeo4j
 
Introduction to memcached
Introduction to memcachedIntroduction to memcached
Introduction to memcachedJurriaan Persyn
 

What's hot (20)

Advanced Flink Training - Design patterns for streaming applications
Advanced Flink Training - Design patterns for streaming applicationsAdvanced Flink Training - Design patterns for streaming applications
Advanced Flink Training - Design patterns for streaming applications
 
FIDO2 Specifications Overview
FIDO2 Specifications OverviewFIDO2 Specifications Overview
FIDO2 Specifications Overview
 
Windows Server and Docker - The Internals Behind Bringing Docker and Containe...
Windows Server and Docker - The Internals Behind Bringing Docker and Containe...Windows Server and Docker - The Internals Behind Bringing Docker and Containe...
Windows Server and Docker - The Internals Behind Bringing Docker and Containe...
 
PURL and vers: The Mostly Universal Package URL and Version Ranges Identifier...
PURL and vers: The Mostly Universal Package URL and Version Ranges Identifier...PURL and vers: The Mostly Universal Package URL and Version Ranges Identifier...
PURL and vers: The Mostly Universal Package URL and Version Ranges Identifier...
 
PHP unserialization vulnerabilities: What are we missing?
PHP unserialization vulnerabilities: What are we missing?PHP unserialization vulnerabilities: What are we missing?
PHP unserialization vulnerabilities: What are we missing?
 
Building a Streaming Pipeline on Kubernetes Using Kafka Connect, KSQLDB & Apa...
Building a Streaming Pipeline on Kubernetes Using Kafka Connect, KSQLDB & Apa...Building a Streaming Pipeline on Kubernetes Using Kafka Connect, KSQLDB & Apa...
Building a Streaming Pipeline on Kubernetes Using Kafka Connect, KSQLDB & Apa...
 
Building secure applications with keycloak
Building secure applications with keycloak Building secure applications with keycloak
Building secure applications with keycloak
 
WebAuthn and Security Keys
WebAuthn and Security KeysWebAuthn and Security Keys
WebAuthn and Security Keys
 
Rainbird: Realtime Analytics at Twitter (Strata 2011)
Rainbird: Realtime Analytics at Twitter (Strata 2011)Rainbird: Realtime Analytics at Twitter (Strata 2011)
Rainbird: Realtime Analytics at Twitter (Strata 2011)
 
Getting Data into Splunk
Getting Data into SplunkGetting Data into Splunk
Getting Data into Splunk
 
When to Use MongoDB...and When You Should Not...
When to Use MongoDB...and When You Should Not...When to Use MongoDB...and When You Should Not...
When to Use MongoDB...and When You Should Not...
 
Abusing Symlinks on Windows
Abusing Symlinks on WindowsAbusing Symlinks on Windows
Abusing Symlinks on Windows
 
Technical Considerations for Deploying FIDO Authentication
Technical Considerations for Deploying FIDO Authentication Technical Considerations for Deploying FIDO Authentication
Technical Considerations for Deploying FIDO Authentication
 
Mongodb basics and architecture
Mongodb basics and architectureMongodb basics and architecture
Mongodb basics and architecture
 
Service workers
Service workersService workers
Service workers
 
Schema Design
Schema DesignSchema Design
Schema Design
 
How Retail Banks Use MongoDB
How Retail Banks Use MongoDBHow Retail Banks Use MongoDB
How Retail Banks Use MongoDB
 
Importing Data into Neo4j quickly and easily - StackOverflow
Importing Data into Neo4j quickly and easily - StackOverflowImporting Data into Neo4j quickly and easily - StackOverflow
Importing Data into Neo4j quickly and easily - StackOverflow
 
WebAuthn
WebAuthnWebAuthn
WebAuthn
 
Introduction to memcached
Introduction to memcachedIntroduction to memcached
Introduction to memcached
 

Viewers also liked

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
 

Viewers also liked (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
 

Similar to 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
 
1 24 - user data management
1 24 - user data management1 24 - user data management
1 24 - user data managementMongoDB
 
Webinar: User Data Management with MongoDB
Webinar: User Data Management with MongoDBWebinar: User Data Management with MongoDB
Webinar: User Data Management with MongoDBMongoDB
 
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
 

Similar to 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)
 
1 24 - user data management
1 24 - user data management1 24 - user data management
1 24 - user data management
 
Webinar: User Data Management with MongoDB
Webinar: User Data Management with MongoDBWebinar: User Data Management with MongoDB
Webinar: User Data Management with MongoDB
 
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...
 

Recently uploaded

DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 

Recently uploaded (20)

DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 

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