SlideShare uma empresa Scribd logo
1 de 64
Baixar para ler offline
BUILDING TO SCALE

                            David Cramer
                           twitter.com/zeeg



Tuesday, February 26, 13
The things we build will not
                    and can not last




Tuesday, February 26, 13
Who am I?




Tuesday, February 26, 13
Tuesday, February 26, 13
Tuesday, February 26, 13
Tuesday, February 26, 13
What do we mean by scale?




Tuesday, February 26, 13
DISQUS
                 Massive traffic with a long tail


                                                  Sentry
                                 Counters and event aggregation




                 tenXer
                 More stats than we can count



Tuesday, February 26, 13
Does one size fit all?




Tuesday, February 26, 13
Practical Storage




Tuesday, February 26, 13
Postgres is the foundation of DISQUS




Tuesday, February 26, 13
MySQL powers the tenXer graph store




Tuesday, February 26, 13
Sentry is built on SQL




Tuesday, February 26, 13
Databases are not the problem




Tuesday, February 26, 13
Compromise




Tuesday, February 26, 13
Scaling is about Predictability




Tuesday, February 26, 13
Augment SQL with [technology]




Tuesday, February 26, 13
Tuesday, February 26, 13
Simple solutions using Redis
                           (I like Redis)




Tuesday, February 26, 13
Counters




Tuesday, February 26, 13
Counters are everywhere




Tuesday, February 26, 13
Counters in SQL
                           UPDATE table SET counter = counter + 1;




Tuesday, February 26, 13
Counters in Redis
                                  INCR counter 1
                             >>> redis.incr('counter')




Tuesday, February 26, 13
Counters in Sentry

                           event ID 1   event ID 2   event ID 3




                           Redis INCR   Redis INCR   Redis INCR




                                        SQL Update




Tuesday, February 26, 13
Counters in Sentry

                ‣
                     INCR event_id in Redis
                ‣
                     Queue buffer incr task
                      ‣
                           5 - 10s explicit delay


                ‣
                     Task does atomic GET event_id and DEL
                     event_id (Redis pipeline)
                ‣
                     No-op If GET is not > 0
                ‣
                     One SQL UPDATE per unique event per
                     delay



Tuesday, February 26, 13
Counters in Sentry (cont.)


                     Pros
                ‣
                     Solves database row lock contention
                ‣
                     Redis nodes are horizontally scalable
                ‣
                     Easy to implement


                     Cons
                ‣
                     Too many dummy (no-op) tasks




Tuesday, February 26, 13
Alternative Counters

                             event ID 1      event ID 2      event ID 3




                           Redis ZINCRBY   Redis ZINCRBY   Redis ZINCRBY




                                            SQL Update




Tuesday, February 26, 13
Sorted Sets in Redis




                           > ZINCRBY events ad93a 1
                           {ad93a: 1}

                           > ZINCRBY events ad93a 1
                           {ad93a: 2}

                           > ZINCRBY events d2ow3 1
                           {ad93a: 2, d2ow3: 1}



Tuesday, February 26, 13
Alternative Counters


                ‣
                     ZINCRBY events event_id in Redis
                ‣
                     Cron buffer flush


                ‣
                     ZRANGE events to get pending updates
                ‣
                     Fire individual task per update
                      ‣
                           Atomic ZSCORE events event_id and
                           ZREM events event_id to get and flush
                           count.



Tuesday, February 26, 13
Alternative Counters (cont.)



                     Pros
                ‣
                     Removes (most) no-op tasks
                ‣
                     Works without a complex queue due to no
                     required delay on jobs


                     Cons
                ‣
                     Single Redis key stores all pending updates




Tuesday, February 26, 13
Activity Streams




Tuesday, February 26, 13
Streams are everywhere




Tuesday, February 26, 13
Streams in SQL


                           class Activity:
                               SET_RESOLVED = 1
                               SET_REGRESSION = 6

                               TYPE = (
                                   (SET_RESOLVED, 'set_resolved'),
                                   (SET_REGRESSION, 'set_regression'),
                               )

                               event      =   ForeignKey(Event)
                               type       =   IntegerField(choices=TYPE)
                               user       =   ForeignKey(User, null=True)
                               datetime   =   DateTimeField()
                               data       =   JSONField(null=True)




Tuesday, February 26, 13
Streams in SQL (cont.)




                       >>> Activity(event, SET_RESOLVED, user, now)
                       "David marked this event as resolved."

                       >>> Activity(event, SET_REGRESSION, datetime=now)
                       "The system marked this event as a regression."

                       >>> Activity(type=DEPLOY_START, datetime=now)
                       "A deploy started."

                       >>> Activity(type=SET_RESOLVED, datetime=now)
                       "All events were marked as resolved"




Tuesday, February 26, 13
Stream == View == Cache




Tuesday, February 26, 13
Views as a Cache



                      TIMELINE = []
                      MAX = 500

                      def on_event_creation(event):
                          global TIMELINE

                           TIMELINE.insert(0, event)
                           TIMELINE = TIMELINE[:MAX]

                      def get_latest_events(num=100):
                          return TIMELINE[:num]



Tuesday, February 26, 13
Views in Redis



                  class Timeline(object):
                      def __init__(self):
                          self.db = Redis()

                           def add(self, event):
                               score = float(event.date.strftime('%s.%m'))
                               self.db.zadd('timeline', event.id, score)

                           def list(self, offset=0, limit=-1):
                               return self.db.zrevrange(
                                   'timeline', offset, limit)




Tuesday, February 26, 13
Views in Redis (cont.)




                  MAX_SIZE = 10000

                  def add(self, event):
                      score = float(event.date.strftime('%s.%m'))

                           # increment the key and trim the data to avoid
                           # data bloat in a single key
                           with self.db.pipeline() as pipe:
                               pipe.zadd(self.key, event.id, score)
                               pipe.zremrange(self.key, event.id, MAX_SIZE, -1)




Tuesday, February 26, 13
Queuing




Tuesday, February 26, 13
Introducing Celery




Tuesday, February 26, 13
RabbitMQ or Redis




Tuesday, February 26, 13
Asynchronous Tasks




                      # Register the task
                      @task(exchange=”event_creation”)
                      def on_event_creation(event_id):
                          counter.incr('events', event_id)


                      # Delay execution
                      on_event_creation(event.id)




Tuesday, February 26, 13
Fanout

                      @task(exchange=”counters”)
                      def incr_counter(key, id=None):
                          counter.incr(key, id)


                      @task(exchange=”event_creation”)
                      def on_event_creation(event_id):
                          incr_counter.delay('events', event_id)
                          incr_counter.delay('global')


                      # Delay execution
                      on_event_creation(event.id)




Tuesday, February 26, 13
Object Caching




Tuesday, February 26, 13
Object Cache Prerequisites




                ‣
                     Your database can't handle the read-load


                ‣
                     Your data changes infrequently


                ‣
                     You can handle slightly worse performance




Tuesday, February 26, 13
Distributing Load with Memcache


                           Memcache 1        Memcache 2        Memcache 3




                           Event   ID   01   Event   ID   02   Event   ID   03
                           Event   ID   04   Event   ID   05   Event   ID   06
                           Event   ID   07   Event   ID   08   Event   ID   09
                           Event   ID   10   Event   ID   11   Event   ID   12
                           Event   ID   13   Event   ID   14   Event   ID   15




Tuesday, February 26, 13
Querying the Object Cache

                      def make_key(model, id):
                          return '{}:{}'.format(model.__name__, id)

                      def get_by_ids(model, id_list):
                          model_name = model.__name__
                          keys = map(make_key, id_list)

                           res = cache.get_multi()

                           pending = set()
                           for id, value in res.iteritems():
                               if value is None:
                                   pending.add(id)

                           if pending:
                               mres = model.objects.in_bulk(pending)

                               cache.set_multi({make_key(o.id): o for o in mres})

                               res.update(mres)

                           return res



Tuesday, February 26, 13
Pushing State




                      def save(self):
                          cache.set(make_key(type(self), self.id), self)


                      def delete(self):
                          cache.delete(make_key(type(self), self.id)




Tuesday, February 26, 13
Redis for Persistence


                             Redis 1           Redis 2           Redis 3




                           Event   ID   01   Event   ID   02   Event   ID   03
                           Event   ID   04   Event   ID   05   Event   ID   06
                           Event   ID   07   Event   ID   08   Event   ID   09
                           Event   ID   10   Event   ID   11   Event   ID   12
                           Event   ID   13   Event   ID   14   Event   ID   15




Tuesday, February 26, 13
Routing with Nydus


                      # create a cluster of Redis connections which
                      # partition reads/writes by (hash(key) % size)

                      from nydus.db import create_cluster

                      redis = create_cluster({
                          'engine': 'nydus.db.backends.redis.Redis',
                          'router': 'nydus.db...redis.PartitionRouter',
                          'hosts': {
                              {0: {'db': 0} for n in xrange(10)},
                          }
                      })


                               github.com/disqus/nydus

Tuesday, February 26, 13
Planning for the Future




Tuesday, February 26, 13
One of the largest problems for
         Disqus is network-wide moderation




Tuesday, February 26, 13
Be Mindful of Features




Tuesday, February 26, 13
Sentry's Team Dashboard




                ‣
                     Data limited to a single team
                ‣
                     Simple views which could be materialized
                ‣
                     Only entry point for "data for team"


Tuesday, February 26, 13
Sentry's Stream View




                ‣
                     Data limited to a single project
                ‣
                     Each project could map to a different DB



Tuesday, February 26, 13
Preallocate Shards




Tuesday, February 26, 13
redis-1


                           DB0   DB1    DB2      DB3   DB4




                           DB5   DB6    DB7      DB8   DB9




Tuesday, February 26, 13
redis-1


                           DB0   DB1    DB2      DB3   DB4




             When a physical machine becomes
            overloaded migrate a chunk of shards
                    to another machine.

                                       redis-2


                           DB5   DB6    DB7      DB8   DB9




Tuesday, February 26, 13
Takeaways




Tuesday, February 26, 13
Enhance your database
                          Don't replace it




Tuesday, February 26, 13
Queue Everything




Tuesday, February 26, 13
Learn to say no
                            (to features)




Tuesday, February 26, 13
Complex problems do not
               require complex solutions




Tuesday, February 26, 13
QUESTIONS?



Tuesday, February 26, 13

Mais conteúdo relacionado

Mais de it-people

«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...
«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...
«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...it-people
 
«Тотальный контроль производительности» Михаил Юматов, ЦИАН
«Тотальный контроль производительности» Михаил Юматов, ЦИАН«Тотальный контроль производительности» Михаил Юматов, ЦИАН
«Тотальный контроль производительности» Михаил Юматов, ЦИАНit-people
 
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банкit-people
 
«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co
«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co
«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Coit-people
 
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНСit-people
 
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...it-people
 
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologiesit-people
 
«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System
«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System
«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn Systemit-people
 
«(Без)опасный Python», Иван Цыганов, Positive Technologies
«(Без)опасный Python», Иван Цыганов, Positive Technologies«(Без)опасный Python», Иван Цыганов, Positive Technologies
«(Без)опасный Python», Иван Цыганов, Positive Technologiesit-people
 
«Python of Things», Кирилл Борисов, Яндекс
«Python of Things», Кирилл Борисов, Яндекс«Python of Things», Кирилл Борисов, Яндекс
«Python of Things», Кирилл Борисов, Яндексit-people
 
«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...
«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...
«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...it-people
 
«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician
«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician
«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognicianit-people
 
«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...
«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...
«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...it-people
 
ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...
ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...
ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...it-people
 
ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...
ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...
ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...it-people
 
"Как повысить мотивацию удаленных разработчиков и повысить значимость каждой ...
"Как повысить мотивацию удаленных разработчиков и повысить значимость каждой ..."Как повысить мотивацию удаленных разработчиков и повысить значимость каждой ...
"Как повысить мотивацию удаленных разработчиков и повысить значимость каждой ...it-people
 
"Профессиональное выгорание менеджера проекта" Орлов Александр, Школа менедже...
"Профессиональное выгорание менеджера проекта" Орлов Александр, Школа менедже..."Профессиональное выгорание менеджера проекта" Орлов Александр, Школа менедже...
"Профессиональное выгорание менеджера проекта" Орлов Александр, Школа менедже...it-people
 
"Как поднять цену в разы и не потерять в продажах?" Калаев Дмитрий, ФРИИ
"Как поднять цену в разы и не потерять в продажах?" Калаев Дмитрий, ФРИИ"Как поднять цену в разы и не потерять в продажах?" Калаев Дмитрий, ФРИИ
"Как поднять цену в разы и не потерять в продажах?" Калаев Дмитрий, ФРИИit-people
 
"Как работать из 20 разных городов с ощущением, что находитесь в 1 комнате" З...
"Как работать из 20 разных городов с ощущением, что находитесь в 1 комнате" З..."Как работать из 20 разных городов с ощущением, что находитесь в 1 комнате" З...
"Как работать из 20 разных городов с ощущением, что находитесь в 1 комнате" З...it-people
 
"Коммуникация в распределенной команде" Жаринов Андрей, Яндекс
"Коммуникация в распределенной команде" Жаринов Андрей, Яндекс"Коммуникация в распределенной команде" Жаринов Андрей, Яндекс
"Коммуникация в распределенной команде" Жаринов Андрей, Яндексit-people
 

Mais de it-people (20)

«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...
«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...
«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...
 
«Тотальный контроль производительности» Михаил Юматов, ЦИАН
«Тотальный контроль производительности» Михаил Юматов, ЦИАН«Тотальный контроль производительности» Михаил Юматов, ЦИАН
«Тотальный контроль производительности» Михаил Юматов, ЦИАН
 
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
 
«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co
«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co
«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co
 
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
 
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
 
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
 
«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System
«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System
«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System
 
«(Без)опасный Python», Иван Цыганов, Positive Technologies
«(Без)опасный Python», Иван Цыганов, Positive Technologies«(Без)опасный Python», Иван Цыганов, Positive Technologies
«(Без)опасный Python», Иван Цыганов, Positive Technologies
 
«Python of Things», Кирилл Борисов, Яндекс
«Python of Things», Кирилл Борисов, Яндекс«Python of Things», Кирилл Борисов, Яндекс
«Python of Things», Кирилл Борисов, Яндекс
 
«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...
«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...
«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...
 
«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician
«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician
«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician
 
«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...
«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...
«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...
 
ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...
ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...
ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...
 
ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...
ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...
ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...
 
"Как повысить мотивацию удаленных разработчиков и повысить значимость каждой ...
"Как повысить мотивацию удаленных разработчиков и повысить значимость каждой ..."Как повысить мотивацию удаленных разработчиков и повысить значимость каждой ...
"Как повысить мотивацию удаленных разработчиков и повысить значимость каждой ...
 
"Профессиональное выгорание менеджера проекта" Орлов Александр, Школа менедже...
"Профессиональное выгорание менеджера проекта" Орлов Александр, Школа менедже..."Профессиональное выгорание менеджера проекта" Орлов Александр, Школа менедже...
"Профессиональное выгорание менеджера проекта" Орлов Александр, Школа менедже...
 
"Как поднять цену в разы и не потерять в продажах?" Калаев Дмитрий, ФРИИ
"Как поднять цену в разы и не потерять в продажах?" Калаев Дмитрий, ФРИИ"Как поднять цену в разы и не потерять в продажах?" Калаев Дмитрий, ФРИИ
"Как поднять цену в разы и не потерять в продажах?" Калаев Дмитрий, ФРИИ
 
"Как работать из 20 разных городов с ощущением, что находитесь в 1 комнате" З...
"Как работать из 20 разных городов с ощущением, что находитесь в 1 комнате" З..."Как работать из 20 разных городов с ощущением, что находитесь в 1 комнате" З...
"Как работать из 20 разных городов с ощущением, что находитесь в 1 комнате" З...
 
"Коммуникация в распределенной команде" Жаринов Андрей, Яндекс
"Коммуникация в распределенной команде" Жаринов Андрей, Яндекс"Коммуникация в распределенной команде" Жаринов Андрей, Яндекс
"Коммуникация в распределенной команде" Жаринов Андрей, Яндекс
 

Último

The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 

Último (20)

The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 

Building to Scale with Redis, Memcache, and Asynchronous Tasks

  • 1. BUILDING TO SCALE David Cramer twitter.com/zeeg Tuesday, February 26, 13
  • 2. The things we build will not and can not last Tuesday, February 26, 13
  • 3. Who am I? Tuesday, February 26, 13
  • 7. What do we mean by scale? Tuesday, February 26, 13
  • 8. DISQUS Massive traffic with a long tail Sentry Counters and event aggregation tenXer More stats than we can count Tuesday, February 26, 13
  • 9. Does one size fit all? Tuesday, February 26, 13
  • 11. Postgres is the foundation of DISQUS Tuesday, February 26, 13
  • 12. MySQL powers the tenXer graph store Tuesday, February 26, 13
  • 13. Sentry is built on SQL Tuesday, February 26, 13
  • 14. Databases are not the problem Tuesday, February 26, 13
  • 16. Scaling is about Predictability Tuesday, February 26, 13
  • 17. Augment SQL with [technology] Tuesday, February 26, 13
  • 19. Simple solutions using Redis (I like Redis) Tuesday, February 26, 13
  • 22. Counters in SQL UPDATE table SET counter = counter + 1; Tuesday, February 26, 13
  • 23. Counters in Redis INCR counter 1 >>> redis.incr('counter') Tuesday, February 26, 13
  • 24. Counters in Sentry event ID 1 event ID 2 event ID 3 Redis INCR Redis INCR Redis INCR SQL Update Tuesday, February 26, 13
  • 25. Counters in Sentry ‣ INCR event_id in Redis ‣ Queue buffer incr task ‣ 5 - 10s explicit delay ‣ Task does atomic GET event_id and DEL event_id (Redis pipeline) ‣ No-op If GET is not > 0 ‣ One SQL UPDATE per unique event per delay Tuesday, February 26, 13
  • 26. Counters in Sentry (cont.) Pros ‣ Solves database row lock contention ‣ Redis nodes are horizontally scalable ‣ Easy to implement Cons ‣ Too many dummy (no-op) tasks Tuesday, February 26, 13
  • 27. Alternative Counters event ID 1 event ID 2 event ID 3 Redis ZINCRBY Redis ZINCRBY Redis ZINCRBY SQL Update Tuesday, February 26, 13
  • 28. Sorted Sets in Redis > ZINCRBY events ad93a 1 {ad93a: 1} > ZINCRBY events ad93a 1 {ad93a: 2} > ZINCRBY events d2ow3 1 {ad93a: 2, d2ow3: 1} Tuesday, February 26, 13
  • 29. Alternative Counters ‣ ZINCRBY events event_id in Redis ‣ Cron buffer flush ‣ ZRANGE events to get pending updates ‣ Fire individual task per update ‣ Atomic ZSCORE events event_id and ZREM events event_id to get and flush count. Tuesday, February 26, 13
  • 30. Alternative Counters (cont.) Pros ‣ Removes (most) no-op tasks ‣ Works without a complex queue due to no required delay on jobs Cons ‣ Single Redis key stores all pending updates Tuesday, February 26, 13
  • 33. Streams in SQL class Activity: SET_RESOLVED = 1 SET_REGRESSION = 6 TYPE = ( (SET_RESOLVED, 'set_resolved'), (SET_REGRESSION, 'set_regression'), ) event = ForeignKey(Event) type = IntegerField(choices=TYPE) user = ForeignKey(User, null=True) datetime = DateTimeField() data = JSONField(null=True) Tuesday, February 26, 13
  • 34. Streams in SQL (cont.) >>> Activity(event, SET_RESOLVED, user, now) "David marked this event as resolved." >>> Activity(event, SET_REGRESSION, datetime=now) "The system marked this event as a regression." >>> Activity(type=DEPLOY_START, datetime=now) "A deploy started." >>> Activity(type=SET_RESOLVED, datetime=now) "All events were marked as resolved" Tuesday, February 26, 13
  • 35. Stream == View == Cache Tuesday, February 26, 13
  • 36. Views as a Cache TIMELINE = [] MAX = 500 def on_event_creation(event): global TIMELINE TIMELINE.insert(0, event) TIMELINE = TIMELINE[:MAX] def get_latest_events(num=100): return TIMELINE[:num] Tuesday, February 26, 13
  • 37. Views in Redis class Timeline(object): def __init__(self): self.db = Redis() def add(self, event): score = float(event.date.strftime('%s.%m')) self.db.zadd('timeline', event.id, score) def list(self, offset=0, limit=-1): return self.db.zrevrange( 'timeline', offset, limit) Tuesday, February 26, 13
  • 38. Views in Redis (cont.) MAX_SIZE = 10000 def add(self, event): score = float(event.date.strftime('%s.%m')) # increment the key and trim the data to avoid # data bloat in a single key with self.db.pipeline() as pipe: pipe.zadd(self.key, event.id, score) pipe.zremrange(self.key, event.id, MAX_SIZE, -1) Tuesday, February 26, 13
  • 41. RabbitMQ or Redis Tuesday, February 26, 13
  • 42. Asynchronous Tasks # Register the task @task(exchange=”event_creation”) def on_event_creation(event_id): counter.incr('events', event_id) # Delay execution on_event_creation(event.id) Tuesday, February 26, 13
  • 43. Fanout @task(exchange=”counters”) def incr_counter(key, id=None): counter.incr(key, id) @task(exchange=”event_creation”) def on_event_creation(event_id): incr_counter.delay('events', event_id) incr_counter.delay('global') # Delay execution on_event_creation(event.id) Tuesday, February 26, 13
  • 45. Object Cache Prerequisites ‣ Your database can't handle the read-load ‣ Your data changes infrequently ‣ You can handle slightly worse performance Tuesday, February 26, 13
  • 46. Distributing Load with Memcache Memcache 1 Memcache 2 Memcache 3 Event ID 01 Event ID 02 Event ID 03 Event ID 04 Event ID 05 Event ID 06 Event ID 07 Event ID 08 Event ID 09 Event ID 10 Event ID 11 Event ID 12 Event ID 13 Event ID 14 Event ID 15 Tuesday, February 26, 13
  • 47. Querying the Object Cache def make_key(model, id): return '{}:{}'.format(model.__name__, id) def get_by_ids(model, id_list): model_name = model.__name__ keys = map(make_key, id_list) res = cache.get_multi() pending = set() for id, value in res.iteritems(): if value is None: pending.add(id) if pending: mres = model.objects.in_bulk(pending) cache.set_multi({make_key(o.id): o for o in mres}) res.update(mres) return res Tuesday, February 26, 13
  • 48. Pushing State def save(self): cache.set(make_key(type(self), self.id), self) def delete(self): cache.delete(make_key(type(self), self.id) Tuesday, February 26, 13
  • 49. Redis for Persistence Redis 1 Redis 2 Redis 3 Event ID 01 Event ID 02 Event ID 03 Event ID 04 Event ID 05 Event ID 06 Event ID 07 Event ID 08 Event ID 09 Event ID 10 Event ID 11 Event ID 12 Event ID 13 Event ID 14 Event ID 15 Tuesday, February 26, 13
  • 50. Routing with Nydus # create a cluster of Redis connections which # partition reads/writes by (hash(key) % size) from nydus.db import create_cluster redis = create_cluster({ 'engine': 'nydus.db.backends.redis.Redis', 'router': 'nydus.db...redis.PartitionRouter', 'hosts': { {0: {'db': 0} for n in xrange(10)}, } }) github.com/disqus/nydus Tuesday, February 26, 13
  • 51. Planning for the Future Tuesday, February 26, 13
  • 52. One of the largest problems for Disqus is network-wide moderation Tuesday, February 26, 13
  • 53. Be Mindful of Features Tuesday, February 26, 13
  • 54. Sentry's Team Dashboard ‣ Data limited to a single team ‣ Simple views which could be materialized ‣ Only entry point for "data for team" Tuesday, February 26, 13
  • 55. Sentry's Stream View ‣ Data limited to a single project ‣ Each project could map to a different DB Tuesday, February 26, 13
  • 57. redis-1 DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7 DB8 DB9 Tuesday, February 26, 13
  • 58. redis-1 DB0 DB1 DB2 DB3 DB4 When a physical machine becomes overloaded migrate a chunk of shards to another machine. redis-2 DB5 DB6 DB7 DB8 DB9 Tuesday, February 26, 13
  • 60. Enhance your database Don't replace it Tuesday, February 26, 13
  • 62. Learn to say no (to features) Tuesday, February 26, 13
  • 63. Complex problems do not require complex solutions Tuesday, February 26, 13