SlideShare uma empresa Scribd logo
1 de 41
Baixar para ler 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

Mais conteúdo relacionado

Mais procurados

[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30Chris Ohk
 
weather-data-processing-using-python
weather-data-processing-using-pythonweather-data-processing-using-python
weather-data-processing-using-pythonmarc_kth
 
Why and How to Use Virtual DOM
Why and How to Use Virtual DOMWhy and How to Use Virtual DOM
Why and How to Use Virtual DOMDaiwei Lu
 
PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)Win Yu
 
Lab1-DB-Cassandra
Lab1-DB-CassandraLab1-DB-Cassandra
Lab1-DB-CassandraLilia Sfaxi
 
Java entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfiJava entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfiENSET, Université Hassan II Casablanca
 
Mastering the Sling Rewriter
Mastering the Sling RewriterMastering the Sling Rewriter
Mastering the Sling RewriterJustin Edelson
 
Introduction à React JS
Introduction à React JSIntroduction à React JS
Introduction à React JSAbdoulaye Dieng
 
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...ENSET, Université Hassan II Casablanca
 
Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)
Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)
Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)Svetlin Nakov
 
Introduction to JPA and Hibernate including examples
Introduction to JPA and Hibernate including examplesIntroduction to JPA and Hibernate including examples
Introduction to JPA and Hibernate including examplesecosio GmbH
 

Mais procurados (20)

[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
 
Clean code
Clean codeClean code
Clean code
 
Clean code
Clean codeClean code
Clean code
 
Clean code
Clean code Clean code
Clean code
 
Clean code
Clean codeClean code
Clean code
 
weather-data-processing-using-python
weather-data-processing-using-pythonweather-data-processing-using-python
weather-data-processing-using-python
 
Why and How to Use Virtual DOM
Why and How to Use Virtual DOMWhy and How to Use Virtual DOM
Why and How to Use Virtual DOM
 
PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)
 
Lab1-DB-Cassandra
Lab1-DB-CassandraLab1-DB-Cassandra
Lab1-DB-Cassandra
 
Java entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfiJava entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfi
 
Mastering the Sling Rewriter
Mastering the Sling RewriterMastering the Sling Rewriter
Mastering the Sling Rewriter
 
Support Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFISupport Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFI
 
Introduction à React JS
Introduction à React JSIntroduction à React JS
Introduction à React JS
 
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...
 
Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)
Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)
Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)
 
react-slides.pptx
react-slides.pptxreact-slides.pptx
react-slides.pptx
 
Mise en oeuvre des framework de machines et deep learning v1
Mise en oeuvre des framework de machines et deep learning v1 Mise en oeuvre des framework de machines et deep learning v1
Mise en oeuvre des framework de machines et deep learning v1
 
Hibernate notes
Hibernate notesHibernate notes
Hibernate notes
 
Introduction to JPA and Hibernate including examples
Introduction to JPA and Hibernate including examplesIntroduction to JPA and Hibernate including examples
Introduction to JPA and Hibernate including examples
 
React js
React jsReact js
React js
 

Destaque

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
 

Destaque (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
 

Semelhante a 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
 

Semelhante a 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...
 

Último

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 

Último (20)

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 

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