41 points par xguru 2023-11-13 | 1 commentaires | Partager sur WhatsApp

Enseignements

  • Utiliser des technologies connues et éprouvées
  • Keep it Simple
  • Ne pas chercher à être trop créatif (choisir une architecture extensible en ajoutant les mêmes nœuds)
  • Limiter les options
  • Sharding de base de données > clustering
  • S’amuser ! (même les ingénieurs juniors pouvaient contribuer au code dès leur première semaine)

Mars 2010 : bêta fermée, 1 ingénieur

  • 1 MySQL + 1 serveur web (Django + Python) + 1 ingénieur (en incluant les 2 cofondateurs). Hébergé sur Rackspace

Janvier 2011 : 10 000 utilisateurs (MAU), 2 ingénieurs

  • Stack de serveurs web AWS EC2 (EC2 + S3 + CloudFront)
  • Django + Python
  • 4 serveurs web pour la redondance
  • NGINX comme reverse proxy et load balancer
  • 1 MySQL avec 1 secondaire en lecture seule
  • MongoDB pour les compteurs
  • 1 task queue et 2 task processors (travaux asynchrones)

Octobre 2011 : 3,2 millions de MAU, 3 ingénieurs

  • Croissance fulgurante pendant 10 mois, avec un nombre d’utilisateurs qui doublait tous les 1,5 mois
  • Le lancement de l’app iPhone en mars 2011 a été l’un des moteurs de cette croissance
  • Avec cette croissance rapide, les problèmes techniques sont devenus plus fréquents
  • Pinterest a alors commis une erreur : « l’architecture est devenue excessivement complexe »
  • Alors qu’il n’y avait que 3 ingénieurs, 5 technologies de base de données différentes étaient utilisées pour les données
  • Tout en shardant MySQL manuellement, l’équipe utilisait aussi Cassandra et Membase (aujourd’hui Couchbase) pour clusteriser les données
  • Leur « stack trop complexe »
    • Stack de serveurs web (EC2 + S3 + Cloudnfront)
      • Début de migration du backend vers Flask (Python)
    • 16 serveurs web
    • 2 moteurs d’API
    • 2 proxys NGINX
    • 5 bases MySQL shardées manuellement + 9 secondaires en lecture seule
    • 4 nœuds Cassandra
    • 15 nœuds Membase (3 clusters séparés)
    • 8 nœuds Memcache
    • 10 nœuds Redis
    • 3 routeurs de tâches + 4 task processors
    • 4 nœuds Elastic Search
    • 3 clusters Mongo
  • Le clustering s’est mal passé
    • En théorie, le clustering permet d’étendre automatiquement le datastore, d’assurer la haute disponibilité et le load balancing, tout en éliminant les SPOF
    • Malheureusement, en pratique, le clustering était trop complexe, les mécanismes de mise à niveau étaient difficiles, et il introduisait un gros SPOF
    • Chaque base de données possédait un algorithme de gestion de cluster qui assurait le routage entre bases
      • Lorsqu’un problème survenait dans la base, il fallait ajouter une nouvelle base et la gérer
      • Mais un bug dans l’algorithme de gestion de cluster de Pinterest a corrompu les données sur tous les nœuds, interrompu le rééquilibrage des données et provoqué plusieurs problèmes impossibles à corriger
  • La solution de Pinterest ?
    • Supprimer du système toutes les technologies de clustering (Cassandra, Membase)
    • Miser entièrement sur MySQL + Memcached, plus éprouvés

Janvier 2012 : 11 millions de MAU, 6 ingénieurs

  • Environ 12 millions d’utilisateurs et 2,1 millions de DAU
  • À ce stade, l’équipe a pris le temps de simplifier l’architecture
  • Suppression du clustering et de Cassandra, remplacés par MySQL, Memcache et le sharding
  • Stack simplifiée
    • Amazon EC2 + S3 + Akamai (à la place de CloudFront)
    • AWS ELB (Elastic Load Balancing)
    • 90 Web Engines + 50 API Engines (avec Flask)
    • 66 bases MySQL + 66 secondaries
    • 59 instances Redis
    • 51 instances Memcache
    • 1 Redis Task Manager + 25 Task Processors
    • Apache Solr shardé (à la place d’Elasticsearch)
    • Supprimés : Cassandra, Membase, Elasticsearch, MongoDB, NGINX

Comment Pinterest a shardé sa base manuellement

Le sharding de base de données est une méthode qui consiste à diviser un ensemble de données unique en plusieurs bases de données
Avantages : haute disponibilité, load balancing, algorithmes simples pour le placement des données, ajout facile de capacité en divisant la base, recherche des données facilitée

  • Comme des problèmes étaient apparus lors du premier sharding, le sharding manuel a été mis en place progressivement sur plusieurs mois
  • Ordre de transition
    1. 1 base + clés étrangères + jointures
    2. 1 base + dénormalisation + cache
    3. 1 base + read slaves + cache
    4. Plusieurs bases shardées par fonction + read slaves + cache
    5. Bases shardées par ID + backup slaves + cache
  • Suppression des jointures de tables et des requêtes complexes au niveau de la couche base de données, avec beaucoup plus de cache
  • Comme il fallait énormément d’efforts pour maintenir les contraintes d’unicité à travers l’ensemble des bases, des données comme les noms d’utilisateur et les e-mails ont été conservées dans une énorme base non shardée
  • Toutes les tables ont fini par être placées sur des shards

Octobre 2012 : 22 millions de MAU, 40 ingénieurs

  • L’architecture a été conservée telle quelle, avec simplement l’ajout de plusieurs systèmes identiques
    • Amazon EC2 + S3 + CDNs (EdgeCast, Akamai, Level 3)
    • 180 serveurs web + 240 moteurs d’API (Flask)
    • 88 bases MySQL + 88 secondaries chacune
    • 110 instances Redis
    • 200 instances Memcache
    • 4 Redis Task Managers + 80 Task Processors
    • Apache Solr shardé
  • Début de la migration des disques durs vers les SSD
  • Enseignement clé : des choix limités et éprouvés (limited, proven choices) étaient préférables
  • Le fait de s’en tenir à EC2 et S3 a réduit l’éventail des options de configuration, diminué les casse-têtes et renforcé la simplicité
  • En contrepartie, de nouvelles instances pouvaient être prêtes en quelques secondes. Autrement dit, il était possible d’ajouter 10 instances Memcache en quelques minutes seulement

Structure de base de données de Pinterest

  • IDs
    • Comme Instagram, Pinterest avait une structure d’ID unique à cause du sharding
    • Composition de l’ID 64 bits
      • Shard ID : indique de quel shard il s’agit. 16 bits
      • Type : type d’objet (comme un Pin) 10 bits
      • Local ID : position dans la table. 38 bits
    • La structure de lookup de cet ID n’était qu’un simple dictionnaire Python
  • Tables
    • Il y avait des tables d’objets et des tables de mapping
    • Les tables d’objets servaient pour les pins, boards, commentaires, utilisateurs, etc. : local ID mappé vers un MySQL Blob (JSON)
    • Les tables de mapping servaient aux données relationnelles entre objets, comme associer un board à un utilisateur ou un like à un pin : full ID mappé vers full ID et horodatage
    • Toutes les requêtes passaient par des recherches de PK (clé primaire) ou d’index pour l’efficacité. Toutes les jointures ont été supprimées

1 commentaires

 
xguru 2023-11-13

Comment Instagram a conquis 14 millions d’utilisateurs avec seulement 3 ingénieurs
C’est un article de la même série, et le contenu s’enchaîne aussi.
« Garder les choses simples. Utiliser des technologies connues et éprouvées »