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

Uma Black Friday sem Catástrofes, Python Brasil 2020

Uma Black Friday sem Catástrofes, Python Brasil 2020

A Black Friday exige muitos preparos e melhorias na arquitetura do Olist para aguentarmos os milhões de vendas e acessos no e-commerce. Nessa palestra vou compartilhar o que fizemos para dessa data com tranquilidade e o que planejamos para que a desse ano também seja um sucesso.

Jessica Pauli de C Bonson

November 02, 2020
Tweet

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 Jogar RPG Canto Livros Hobbies:
  2. Maior loja nos principais marketplaces do Brasil. Arquitetura em microsserviços

    e serverless. Python. Go. PostgreSQL. AWS. Kubernetes. 20+ APIs 120+ serviços 3m+ produtos 30k+ logistas 10m+ anúncios 230k+ pedidos por mês
  3. Techstack • Python 3 • Django Rest Framework (DRF) •

    Postgres • AWS (API Gateway, SQS, SNS, S3, IAM, Lambda, RDS, Athena, ...) • Heroku => EKS • 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 /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. • 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 • Migração para AWS
  15. • 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 • Migração para AWS
  16. • 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 • Migração para AWS
  17. • 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 • Migração para AWS
  18. • 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 • Migração para AWS
  19. • 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 • Migração para AWS
  20. • 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 • Migração para AWS
  21. • Usar cache e retries • Usar código assíncrono •

    Cuidado com queries em properties de models • Evitar ponto único de falha • ElasticSearch • Dividir APIs e serviços que ficarem muito grandes • Evitar contadores em paginação • Payload SNS mínimo • Implementar padrão circuit-breaker e throttling • Conteinerização
  22. • Usar cache e retries • Usar código assíncrono •

    Cuidado com queries em properties de models • Evitar ponto único de falha • ElasticSearch • Dividir APIs e serviços que ficarem muito grandes • Evitar contadores em paginação • Payload SNS mínimo • Implementar padrão circuit-breaker e throttling • Conteinerização
  23. • Usar cache e retries • Usar código assíncrono •

    Cuidado com queries em properties de models • Evitar ponto único de falha • ElasticSearch • Dividir APIs e serviços que ficarem muito grandes • Evitar contadores em paginação • Payload SNS mínimo • Implementar padrão circuit-breaker e throttling • Conteinerização
  24. • Usar cache e retries • Usar código assíncrono •

    Cuidado com queries em properties de models • Evitar ponto único de falha • ElasticSearch • Dividir APIs e serviços que ficarem muito grandes • Evitar contadores em paginação • Payload SNS mínimo • Implementar padrão circuit-breaker e throttling • Conteinerização
  25. • Usar cache e retries • Usar código assíncrono •

    Cuidado com queries em properties de models • Evitar ponto único de falha • ElasticSearch • Dividir APIs e serviços que ficarem muito grandes • Evitar contadores em paginação • Payload SNS mínimo • Implementar padrão circuit-breaker e throttling • Conteinerização
  26. • Usar cache e retries • Usar código assíncrono •

    Cuidado com queries em properties de models • Evitar ponto único de falha • ElasticSearch • Dividir APIs e serviços que ficarem muito grandes • Evitar contadores em paginação • Payload SNS mínimo • Implementar padrão circuit-breaker e throttling • Conteinerização
  27. • Usar cache e retries • Usar código assíncrono •

    Cuidado com queries em properties de models • Evitar ponto único de falha • ElasticSearch • Dividir APIs e serviços que ficarem muito grandes • Evitar contadores em paginação • Payload SNS mínimo • Implementar padrão circuit-breaker e throttling • Conteinerização
  28. • Usar cache e retries • Usar código assíncrono •

    Cuidado com queries em properties de models • Evitar ponto único de falha • ElasticSearch • Dividir APIs e serviços que ficarem muito grandes • Evitar contadores em paginação • Payload SNS mínimo • Implementar padrão circuit-breaker e throttling • Conteinerização
  29. • Usar cache e retries • Usar código assíncrono •

    Cuidado com queries em properties de models • Evitar ponto único de falha • ElasticSearch • Dividir APIs e serviços que ficarem muito grandes • Evitar contadores em paginação • Payload SNS mínimo • Implementar padrão circuit-breaker e throttling • Conteinerização
  30. • Usar cache e retries • Usar código assíncrono •

    Cuidado com queries em properties de models • Evitar ponto único de falha • ElasticSearch • Dividir APIs e serviços que ficarem muito grandes • Evitar contadores em paginação • Payload SNS mínimo • Implementar padrão circuit-breaker e throttling • Conteinerização
  31. • Usar cache e retries • Usar código assíncrono •

    Cuidado com queries em properties de models • Evitar ponto único de falha • ElasticSearch • Dividir APIs e serviços que ficarem muito grandes • Evitar contadores em paginação • Payload SNS mínimo • Implementar padrão circuit-breaker e throttling • Conteinerização