41 pontos por xguru 2023-11-13 | 1 comentários | Compartilhar no WhatsApp

Lições

  • Usar tecnologias bem conhecidas e comprovadas
  • Keep it Simple
  • Não pensar de forma criativa demais (decidir por uma arquitetura escalável adicionando nós idênticos)
  • Limitar as opções
  • Sharding de banco de dados > clustering
  • Divirta-se! (até engenheiros juniores podiam contribuir com código desde a primeira semana)

Março de 2010: beta fechada, 1 engenheiro

  • 1 MySQL + 1 servidor web (Django + Python) + 1 engenheiro (incluindo 2 cofundadores). Hospedado na Rackspace

Janeiro de 2011: 10 mil usuários (MAU), 2 engenheiros

  • Stack de servidores web na AWS EC2 (EC2 + S3 + CloudFront)
  • Django + Python
  • 4 servidores web para redundância
  • NGINX como proxy reverso e balanceador de carga
  • 1 MySQL com 1 secundário somente leitura
  • MongoDB para contadores
  • 1 fila de tarefas e 2 processadores de tarefas (trabalhos assíncronos)

Outubro de 2011: 3,2 milhões de MAU, 3 engenheiros

  • Crescimento acelerado por 10 meses, com a base de usuários dobrando a cada 1,5 mês
  • Um dos fatores que impulsionou o crescimento foi o lançamento do app para iPhone em março de 2011
  • Com o crescimento rápido, os problemas técnicos passaram a acontecer com mais frequência
  • O Pinterest cometeu um erro nessa época: "tornou a arquitetura excessivamente complexa"
  • Havia apenas 3 engenheiros, mas 5 tecnologias de banco de dados diferentes em uso
  • Faziam sharding manual do MySQL ao mesmo tempo em que usavam Cassandra e Membase (hoje Couchbase) para clusterizar os dados
  • Sua "stack complexa demais"
    • Stack de servidores web (EC2 + S3 + Cloudnfront)
      • Começaram a migrar o backend para Flask (Python)
    • 16 servidores web
    • 2 engines de API
    • 2 proxies NGINX
    • 5 bancos MySQL com sharding manual + 9 secundários somente leitura
    • 4 nós de Cassandra
    • 15 nós de Membase (3 clusters separados)
    • 8 nós de Memcache
    • 10 nós de Redis
    • 3 roteadores de tarefas + 4 processadores de tarefas
    • 4 nós de Elastic Search
    • 3 clusters de Mongo
  • O clustering deu errado
    • Em teoria, o clustering deveria escalar automaticamente o datastore, oferecer alta disponibilidade e balanceamento de carga, além de eliminar SPOF
    • Infelizmente, na prática o clustering era complexo demais, o mecanismo de upgrade era difícil e havia grandes SPOFs
    • Cada banco tinha um algoritmo de gerenciamento de cluster para rotear de banco para banco
      • Quando surgia um problema no banco, um novo banco era adicionado e precisava ser gerenciado, mas
      • Um bug no algoritmo de gerenciamento de cluster do Pinterest corrompeu os dados em todos os nós, interrompeu o rebalanceamento de dados e causou alguns problemas irrecuperáveis
  • Qual foi a solução do Pinterest?
    • Remover do sistema todas as tecnologias de clustering (Cassandra, Membase)
    • Apostar tudo em MySQL + Memcached (mais comprovados)

Janeiro de 2012: 11 milhões de MAU, 6 engenheiros

  • Cerca de 12 milhões e 2,1 milhões de DAU
  • Nesse momento, dedicaram tempo para simplificar a arquitetura
  • Removeram clustering e Cassandra, substituindo por MySQL, Memcache e sharding
  • Stack simplificada
    • Amazon EC2 + S3 + Akamai (no lugar do CloudFront)
    • AWS ELB (Elastic Load Balancing)
    • 90 Web Engines + 50 API Engines (usando Flask)
    • 66 bancos MySQL + 66 secundários
    • 59 instâncias de Redis
    • 51 instâncias de Memcache
    • 1 Redis Task Manager + 25 Task Processors
    • Apache Solr com sharding (no lugar do Elasticsearch)
    • Removidos: Cassanda, Membase, Elasticsearch, MongoDB, NGINX

Como o Pinterest fez sharding manual do banco de dados

Sharding de banco de dados é uma forma de dividir um único conjunto de dados em vários bancos de dados
Vantagens: alta disponibilidade, balanceamento de carga, algoritmo simples para alocação de dados, facilidade para dividir o banco e adicionar capacidade, facilidade para encontrar dados

  • Como houve problemas no início do sharding, eles fizeram o processo manualmente e de forma gradual ao longo de vários meses
  • Ordem da transição
    1. 1 banco + Foreign Keys + Joins
    2. 1 banco + Denormalized + Cache
    3. 1 banco + Read Slaves + Cache
    4. Vários bancos funcionalmente shardados + Read Slaves + Cache
    5. Bancos shardados por ID + Backup Slaves + Cache
  • Removeram joins de tabela e consultas complexas da camada de banco de dados e adicionaram muito cache
  • Como era necessário muito esforço para manter restrições de unicidade em todo o banco, dados como nome de usuário e e-mail eram mantidos em um enorme banco não shardado
  • Todas as tabelas foram colocadas em shards

Outubro de 2012: 22 milhões de MAU, 40 engenheiros

  • Mantiveram a mesma arquitetura e apenas adicionaram mais alguns sistemas idênticos
    • Amazon EC2 + S3 + CDNs (EdgeCast, Akamai, Level 3)
    • 180 servidores web + 240 API engines (Flask)
    • 88 bancos MySQL + 88 secundários cada
    • 110 instâncias de Redis
    • 200 instâncias de Memcache
    • 4 Redis Task Managers + 80 Task Processors
    • Apache Solr com sharding
  • Começaram a migrar de discos rígidos para SSD
  • Lição importante: escolhas limitadas e comprovadas (limited, proven choices) funcionaram melhor
  • Ao insistir em EC2 e S3, limitaram as opções de configuração, reduziram dores de cabeça e aumentaram a simplicidade
  • Mas as novas instâncias passaram a poder ficar prontas em poucos segundos. Ou seja, era possível adicionar 10 instâncias de Memcache em apenas alguns minutos

Estrutura de banco de dados do Pinterest

  • IDs
    • Assim como o Instagram, tinham uma estrutura de ID única por causa do sharding
    • Composição do ID de 64 bits
      • Shard ID: qual shard é. 16 bits
      • Type: tipo de objeto (como Pin). 10 bits
      • Local ID: posição na tabela. 38 bits
    • A estrutura de lookup desse ID era simplesmente um dicionário Python
  • Tabelas
    • Havia tabelas de entidades e tabelas de mapeamento
    • As tabelas de objetos eram para pins, boards, comentários, usuários etc. ID local mapeado para MySQL Blob (JSON)
    • As tabelas de mapeamento eram para dados relacionais entre objetos, como mapear boards para usuários ou curtidas para pins. ID completo mapeado para ID completo e timestamp
    • Todas as consultas eram feitas por PK (chave primária) ou lookup por índice para eficiência. Todos os joins foram removidos

1 comentários

 
xguru 2023-11-13

Como o Instagram conquistou 14 milhões de usuários com apenas 3 engenheiros
É um texto da mesma série que este, e o conteúdo também se conecta.
"Manter as coisas simples. Usar tecnologias bem conhecidas e comprovadas"