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

Uma Black Friday sem catástrofes, TDC Floripa 2020

Uma Black Friday sem catástrofes, TDC Floripa 2020

A última Black Friday exigiu muitos preparos e melhorias nas APIs e microserviços do Olist para aguentarem os milhões de vendas e acessos que esperávamos no e-commerce. Nessa palestra vou compartilhar o que fizemos para dar conta da Black Friday com tranquilidade, em relação a monitoramentos e performance.

O Olist é uma empresa que permite que logistas e marcas vendam seus produtos nos grandes e-commerces brasileiros, e possui uma arquitetura robusta com mais de uma centena de microserviços.

More Decks by Jessica Pauli de C Bonson

Other Decks in Technology

Transcript

  1. Jéssica Pauli de C Bonson • +-8 anos de exp

    em pesquisa/desenvolvimento • graduação/mestrado em Ciências da Computação • foco em dev backend, machine learning e big data Jogos RPG Canto Hobbies:
  2. Maior loja nos principais marketplaces do Brasil. Arquitetura em microsserviços

    e serverless. Python. Go. PostgreSQL. AWS. Heroku. 20+ APIs 120+ serviços 3m+ produtos 30k+ logistas 10m+ anúncios 200k+ pedidos em maio/2020
  3. Techstack • Python 3 • Django Rest Framework (DRF) •

    Heroku • Postgres • AWS (API Gateway, SQS, SNS, S3, IAM, Lambda, RDS, Athena, ...) • Outros: Redis, Javascript, Go, Lambda, ElasticSearch, ...
  4. Exemplo Para 100 Books, onde cada um tem uma FK

    para um Publisher... queryset = Book.objects.all() for book in queryset: print(str({'name': book.name, 'publisher': book.publisher.name}))
  5. Exemplo Para 100 Books, onde cada um tem uma FK

    para um Publisher... queryset = Book.objects.all() for book in queryset: print(str({'name': book.name, 'publisher': book.publisher.name})) # 101 queries
  6. Exemplo: select_related Para 100 Books, onde cada um tem uma

    FK para um Publisher... queryset = Book.objects.all() for book in queryset: print(str({'name': book.name, 'publisher': book.publisher.name})) # 101 queries queryset = Book.objects.select_related('publisher').all() for book in queryset: print(str({'name': book.name, 'publisher': book.publisher.name})) # 1 query
  7. Exemplo Para 10 Stores, onde cada uma tem 10 Books,

    em uma relação many-to-many... queryset = Store.objects.all() for store in queryset : books = [book.name for book in store.books.all()] print(str({'name': store.name, 'books': books}))
  8. Exemplo Para 10 Stores, onde cada uma tem 10 Books,

    em uma relação many-to-many... queryset = Store.objects.all() for store in queryset : books = [book.name for book in store.books.all()] print(str({'name': store.name, 'books': books})) # 11 queries
  9. Exemplo: prefetch_related Para 10 Stores, onde cada uma tem 10

    Books, em uma relação many-to-many... queryset = Store.objects.all() for store in queryset: books = [book.name for book in store.books.all()] print(str({'name': store.name, 'books': books})) # 11 queries queryset = Store.objects.prefetch_related('books') for store in queryset: books = [book.name for book in store.books.all()] print(str({'name': store.name, 'books': books})) # 2 queries
  10. Exemplo: prefetch_related com filtro Para 10 Stores, onde cada uma

    tem 10 Books, em uma relação many-to-many... queryset = Store.objects.prefetch_related('books') for store in queryset: books = [book.name for book in store.books.filter(price__range=(250, 300))] print(str({'name': store.name, 'books': books}))
  11. Exemplo: prefetch_related com filtro Para 10 Stores, onde cada uma

    tem 10 Books, em uma relação many-to-many... queryset = Store.objects.prefetch_related('books') for store in queryset: books = [book.name for book in store.books.filter(price__range=(250, 300))] print(str({'name': store.name, 'books': books})) # 12 queries
  12. queryset = Store.objects.prefetch_related( Prefetch('books', queryset=Book.objects.filter(price__range=(250, 300)))) for store in queryset:

    books = [book.name for book in store.books.all()] print(str({'name': store.name, 'books': books})) # 2 queries Exemplo: prefetch_related com filtro
  13. django-rest-framework-rapidjson ou drf-ujson-renderer /seller-orders/ Antes: Time per request: 1030.060 [ms]

    (mean) Depois: Time per request: 973.138 [ms] (mean) /orders/ Antes: Time per request: 12512.722 [ms] (mean) Depois: Time per request: 1837.474 [ms] (mean)
  14. Melhorias de Banco de Dados • Adicionar/Remover índices no BD

    • Reestruturar relações no BD • Ativar full text search do Postgres • Réplica de leitura do BD • Dumps de dados antigos de histórico para NoSQL • Particionamento
  15. Melhorias de Arquitetura • Usar cache • Usar código assíncrono

    • Evitar ponto único de falha • Dividir APIs e serviços que ficarem muito grandes • Evitar contadores em paginação • Implementar padrão circuit-breaker • Conteinerização