1 points par GN⁺ 2024-07-14 | 1 commentaires | Partager sur WhatsApp
  • Lichess, confronté à une forte charge de requêtes qui retardait les vérifications RAID périodiques de son serveur de tablebases Syzygy à 7 pièces, est passé d’un parcours complet des blocs à une vérification de l’intégrité à la lecture
  • Pour déplacer une tablebase de 17 TiB sans longue interruption, un nouveau serveur a été préparé, puis validé en rejouant de vrais journaux de requêtes sur une configuration avec 32 GiB de RAM, 2×201 GiB de NVMe et 6×5,46 TiB de HDD
  • En rejouant 1 million de requêtes enregistrées en production avec 12 clients parallèles, le principal goulet d’étranglement s’est révélé être non pas la réponse moyenne, mais la latence de queue perceptible par les utilisateurs
  • Côté implémentation, pread(2) s’est avéré plus avantageux que mmap pour la gestion des erreurs et la latence de queue, tandis que les indications d’accès aléatoire comme POSIX_FADV_RANDOM et MADV_RANDOM ont globalement eu l’effet inverse
  • Les préfixes de tables ont été placés sur le SSD limité, et les probes internes aux requêtes ont été parallélisés afin de réduire les accès aux disques lents ; il a ensuite été vérifié que les gains mesurés en benchmark se traduisaient aussi dans les temps de réponse en production

Passage d’une vérification RAID complète à une vérification à la lecture

  • Le serveur de tablebases Syzygy à 7 pièces de Lichess avait du mal à terminer les vérifications périodiques d’intégrité RAID pendant les périodes de forte demande de tablebases
  • La nouvelle configuration utilise dm-integrity on LVM pour ne pas vérifier périodiquement tous les blocs de données, mais les vérifier à chaque lecture
  • Pour migrer la tablebase de 17 TiB sans plusieurs heures d’interruption, un nouveau serveur a été configuré séparément
    • Avant la bascule réelle, il a été possible d’exécuter un benchmark contrôlé sur l’ensemble de la tablebase
    • Le service a ensuite basculé vers le nouveau serveur et l’ancien a été retiré

Configuration du nouveau serveur

  • La RAM est restée identique à l’ancienne configuration, soit 32 GiB
  • Côté stockage, 2×201 GiB de NVMe, absents de l’ancien serveur, ont été ajoutés ; le reste de l’espace des disques de 476 GiB a été réservé à l’OS et à l’espace de travail
  • Les HDD sont passés de 5 disques à 6×5,46 TiB de HDD
  • Le système d’exploitation est Debian bookworm, avec un noyau de la série Linux 6.1.0-21-amd64
  • Les ordonnanceurs d’E/S par défaut sélectionnés étaient none pour les NVMe et mq-deadline pour les HDD

Configuration et supervision du RAID 5

  • Le RAID 5 convient bien à un serveur de tablebases, car il permet de récupérer après la panne d’un seul disque et de répartir les lectures aléatoires sur plusieurs disques
  • La configuration initiale était la suivante
lvcreate --type raid5 --raidintegrity y --raidintegrityblocksize 512 --name tables --size 21T vg-hdd
  • Les performances des premiers tests étaient correctes, mais sans supervision, un problème où certains disques ne participaient pas au même niveau aurait pu passer inaperçu
  • Si --stripes est omis, tous les volumes physiques ne sont pas utilisés par défaut
  • La supervision de l’activité de lecture par disque a été nécessaire pour détecter une mauvaise configuration RAID

Les goulets d’étranglement vus dans les vrais journaux de requêtes

  • Dans des conditions normales, le serveur reçoit 10 à 35 requêtes par seconde
  • 1 million de requêtes ont été enregistrées en production, puis, dans le scénario choisi, 12 clients parallèles les ont soumises séquentiellement
  • Les tables sont ouvertes de manière différée, et les caches applicatifs et OS se remplissent progressivement
    • Les 800 000 premiers temps de réponse ont été exclus comme phase de chauffe
    • Les temps de réponse des 200 000 requêtes suivantes ont ensuite été analysés
  • Le temps de réponse moyen est suffisamment rapide, mais la latence de queue élevée est devenue le principal axe d’optimisation
  • Le graphique ECDF montre la proportion de requêtes plus rapides que chaque temps de réponse, avec un axe des x en échelle logarithmique
  • Le graphique ajoute 30 ms à chaque temps de réponse afin de tenir compte du ping time de 30 ms côté client
    • Ce traitement évite que l’axe des x logarithmique n’accentue excessivement des écarts de quelques millisecondes dans les faibles valeurs

pread(2) plus avantageux que mmap

  • shakmaty-syzygy, l’implémentation des tablebases Syzygy, fournit une interface permettant de remplacer la manière d’ouvrir et de lire les fichiers de tables
  • Les deux principaux candidats étaient les suivants
    • mmap : mappe les fichiers de tables en mémoire, et les lectures disque se produisent de façon transparente lors de l’accès à la zone mémoire correspondante
    • pread(2) : effectue un appel système à chaque lecture et signale les erreurs de lecture via la valeur de retour
  • Avec mmap, aucun appel système supplémentaire n’est nécessaire après le mapping, mais comme la lecture ressemble à un accès mémoire ordinaire, les erreurs doivent être traitées via un mécanisme out-of-band, comme des signaux
  • Dans l’implémentation du serveur, la seule gestion d’erreurs plus robuste suffisait déjà à justifier l’usage de pread, et les benchmarks ont aussi montré que, dans les scénarios étudiés, les performances de pread étaient meilleures
  • L’une des causes possibles est qu’un accès à un seul bloc de données mappé en mémoire peut entraîner deux lectures disque lorsqu’il traverse une limite de page
  • Il n’est pas nécessaire d’appliquer immédiatement pread aux moteurs d’échecs
    • Dans les matchs entre moteurs, l’usage des tablebases suppose généralement que toutes les tables WDL puissent être placées sur un stockage suffisamment rapide
    • Dans ce cas, les temps de réponse habituels seraient trop faibles pour apparaître sur le graphique concerné, et le mapping mémoire, qui réduit l’overhead des appels système, est préférable

Effet inverse des indications d’accès aléatoire

  • posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM) et l’indication équivalente pour les mappings mémoire ont finalement eu, dans la plupart des cas, l’effet inverse
  • POSIX_FADV_RANDOM indique à l’OS que les accès au fichier sont aléatoires et que le read-ahead automatique a peu de chances d’être utile, afin de réduire la pression sur le cache de pages
  • Les motifs d’accès aux tablebases lorsque les utilisateurs analysent des finales peuvent être moins aléatoires que prévu
  • Dans les moteurs d’échecs, les probes peuvent être plus dispersés entre différentes finales possibles, ce qui pourrait donner des résultats différents

Préfixes de tables à placer sur le SSD limité

  • Un probe de table commence par encoder la position en un index entier à partir des informations d’encodage présentes dans l’en-tête de la table
  • Il faut ensuite trouver le bloc de données compressé qui contient le résultat correspondant à cet index
  • Syzygy fournit une sparse block length list pointant près de la bonne entrée, puis une block length list permet de trouver le bloc de données concerné
  • Les tailles des sections de tables sont les suivantes
Table section WDL DTZ Total
Headers and sparse block length lists 38 GiB 9 GiB 47 GiB
Block length lists 274 GiB 64 GiB 339 GiB
Compressed data blocks 8433 GiB 8458 GiB 16891 GiB
  • L’espace SSD pourrait aussi être utilisé comme couche de cache adaptative pour mettre en cache les entrées de listes et les blocs de données chauds
  • Avec l’objectif de réduire la latence de queue, une approche adaptée consiste à considérer le pire cas et à placer les sparse block length lists et block length lists sur SSD
  • Cette disposition permet de limiter les lectures sur disques lents à au plus 1 par probe de table, que les données soient chaudes ou froides
  • Sur ce serveur, l’espace SSD n’était pas suffisant pour un miroir RAID 1 ; la redondance a donc été abandonnée au profit d’un RAID 0, au motif qu’il s’agissait d’une optimisation sélective

Parallélisation des probes au sein des requêtes

  • Une requête de tablebase typique dans un moteur d’échecs demande une seule valeur WDL
  • Dans l’interface utilisateur, l’objectif est d’afficher les valeurs DTZ pour tous les coups
  • En incluant la résolution des captures dans Syzygy, une requête moyenne génère 23 probes WDL et 70 probes DTZ
  • L’implémentation initiale parallélisait le traitement des requêtes elles-mêmes, mais exécutait séquentiellement les probes à l’intérieur de chaque requête
  • Une parallélisation plus fine crée de l’overhead dans les faibles plages de latence, mais réduit fortement la latence de queue
  • Même si le disque ne peut pas physiquement traiter de nombreuses lectures parallèles, il devient plus probable que l’ordonnanceur d’E/S planifie les lectures de manière à terminer chaque requête plus vite
  • Cette approche aide à mieux organiser l’ordre des accès disque liés afin de réduire le temps d’attente jusqu’à ce que la tête de disque atteigne le secteur de la requête suivante

Vérification en production et données brutes

  • Les graphiques de temps de réponse ont permis de vérifier que les optimisations du scénario de benchmark apportaient aussi un gain en production réelle
  • Les données brutes sont publiées dans lila-tablebase-bench

1 commentaires

 
GN⁺ 2024-07-14
Avis sur Hacker News
  • Lichess est un service qu’on admire en silence, comme un bon vin. C’est vraiment excellent pour la communauté des échecs, et en l’utilisant tous les jours, je suis constamment impressionné par ses fonctionnalités et ses performances.
    C’est encore plus étonnant quand on sait qu’il s’agit d’une équipe de 1 à 2 personnes avec un budget limité.

    • Il ne faut pas oublier non plus que c’est gratuit et open source, que ça ne demande pas d’argent et que ça ne le fera jamais. Beaucoup de gens font des dons, les dépenses sont publiques, et il y a aussi une appli.
    • J’aimerais que davantage de logiciels open source destinés aux utilisateurs finaux soient aussi conviviaux, bien conçus et bien maintenus que Lichess.
    • Je ressens la même chose. La nouvelle appli mobile bêta est plus propre, et même avec du retour haptique, c’est super.
    • J’aimerais un jour créer quelque chose d’aussi précieux et cool que Lichess.
  • J’ai trouvé intéressante la partie qui montrait une ECDF avec 30 ms ajoutées à chaque temps de réponse.
    Ajouter une constante peut sembler artificiel, mais en pratique, c’est une manière de regarder les résultats du point de vue d’un client ayant un ping de 30 ms, et ça évite que l’axe x en échelle logarithmique exagère les différences de quelques millisecondes dans les faibles valeurs. C’est peut-être une technique standard, mais ça ressemble à une astuce assez maligne.

  • Je me demande si la réduction des coûts était vraiment nécessaire, ou s’il y avait une autre raison de ne pas simplement mettre 20 To de SSD dans une seule machine et en finir là. Un SSD de 4 To coûte environ 300 dollars, et les disques SFF HP ou Dell ne sont pas beaucoup plus chers.
    Ils étaient probablement surtout intéressés par les tests et l’optimisation en eux-mêmes ; d’un point de vue produit, ils auraient sans doute consacré ce temps limité à d’autres projets.

    • Lichess est une organisation à but non lucratif avec beaucoup de bénévoles, donc l’équilibre entre le temps passé et le coût du matériel est probablement différent de celui de la plupart des entreprises commerciales.
    • Lichess est une organisation à but non lucratif qui fonctionne uniquement grâce aux dons et au bénévolat. Il n’y a qu’un seul salarié, la personne qui a créé l’association, et il semble se verser beaucoup moins que ce qu’il pourrait gagner ailleurs vu son niveau.
      Le fait que l’organisation soit basée en France peut aussi avoir un effet sur les coûts, je ne sais pas lequel, mais ça mérite d’être mentionné.
    • Ce travail a réduit le temps de réponse maximal d’un ordre de grandeur à un chiffre. Si le projet a pris une semaine, deux au maximum, et que le temps de réponse de certains utilisateurs est passé de 15 s à 1,5 s, ça en valait largement la peine.
      Pour mieux justifier de consacrer du temps ailleurs, il faudrait soit un projet avec une expérience utilisateur encore pire, soit une organisation commerciale qui admet qu’il y a de l’argent à gagner ailleurs et qu’elle ne se soucie pas vraiment de la souffrance de ses clients.
    • En dehors de l’IT, il doit y avoir très peu d’industries où des ingénieurs considéreraient ça comme « tester et optimiser pour le plaisir ».
      Ça ressemble plutôt au résultat d’une combinaison entre du matériel trop puissant et bon marché, et des gens paresseux qui veulent juste dire « ça suffit pour aujourd’hui ». On dit bien qu’il faut être fier de son travail, non ?
    • Du point de vue produit, ça se tient, mais Lichess n’est pas une entreprise commerciale avec un produit : c’est réellement géré comme une organisation à but non lucratif, donc il faut changer de perspective pour comprendre leurs décisions.
  • Il y a quelques choix discutables dans cette optimisation. La raison donnée est qu’il y avait trop d’activité d’entrée-sortie pour que le contrôle RAID puisse se terminer.
    D’après l’article seul, on ne sait pas clairement si un contrôle RAID des 17 Tio de données s’est déjà réellement terminé. À la place, ils ont désactivé les contrôles RAID périodiques et sont passés à une vérification des erreurs page par page lors de la lecture des données, mais les deux méthodes ne sont pas équivalentes, et pour des données importantes il faudrait utiliser les deux.
    Si l’on ne découvre la corruption qu’au moment où l’on essaie de lire les données, une corruption ancienne peut rester présente, et l’on peut dépasser la période de rétention des sauvegardes sans pouvoir restaurer l’original. Il y a aussi, en arrière-plan, le passage à RAID 0 : c’est certes le choix le plus rapide, mais cela suppose une confiance assez importante dans la capacité de cette configuration NVMe à supporter cette charge.
    J’espère que les sauvegardes sont bien faites. Une bonne solution serait de lancer un serveur temporaire, de restaurer la sauvegarde et d’effectuer une vérification complète des données ; en cas de succès, cela validerait aussi la procédure de sauvegarde/restauration et l’intégrité des fichiers. Même ainsi, il faut conserver assez de marge sur le serveur principal pour terminer les contrôles RAID, et il vaut mieux éviter RAID 0 pour des raisons de performance.

    • C’est vrai que les deux méthodes ne sont pas équivalentes, mais c’est suffisant pour ce cas d’usage. S’ils détectent une corruption de données, ils peuvent jeter le fichier et le retélécharger ou le régénérer.
      C’est un jeu de données librement disponible, simplement assez volumineux. https://en.wikipedia.org/wiki/Endgame_tablebase l’explique mieux. C’est pour ça qu’ils ne font pas non plus de sauvegardes.
  • Il existe aussi lishogi, mais il est encore trop petit pour avoir besoin de ce genre d’optimisation.
    Parmi les variantes des échecs, le shogi est la plus intéressante, pas autant le xiangqi.

  • Je me demande si lichess veut dire lich au féminin, comme baron/baroness.

    • Les titres de noblesse ne sont pas un très bon point de comparaison. C’est l’un des rares cas où il existe réellement une racine réservée au masculin ; pour la plupart des mots, la racine est neutre, et même lorsqu’il existe une forme masculine ou féminine, il faut un affixe.
      À proprement parler, un lich masculin serait « werlich », un lich féminin « wiflich », et le pluriel prendrait « -en ». Cela dit, le genre est généralement sans importance pour les morts-vivants, donc la forme neutre est très largement la plus utilisée.
      « lichess » est un mélange bizarre de racines allemandes et françaises, ce qui fait qu’il ne se distingue pas naturellement des autres mots anglais.
    • Libre chess, c’est-à-dire des échecs libres et open source.
  • Ce n’est pas une comparaison totalement équitable, mais la qualité d’ingénierie de l’équipe Lichess force vraiment l’admiration. Son principal concurrent s’est vanté de migrer vers GCP tout en subissant des pannes répétées à mesure que sa popularité augmentait, et je pense qu’il a environ 100 fois plus de personnel.
    Le point faible de Lichess était l’appli mobile, mais la v2 réécrite en Flutter est déjà assez bonne, même si elle est encore en bêta.
    Et il faut aussi se rappeler que Thibault ne se verse même pas 60 000 dollars par an.

    • Je ne pense pas qu’il devrait se sentir coupable d’augmenter son salaire. Le passer à 200 000 dollars et rendre sa vie plus confortable ne pourrait qu’être bénéfique au projet sur le long terme.
    • Lichess est un excellent service pour les joueurs d’échecs occasionnels comme moi qui veulent jouer rapidement une partie contre quelqu’un d’autre. Il n’y a presque jamais d’attente.
      Je me demande toutefois comment se prononce Lichess : « Lie chess », « Le chess » ou « League chess » ?
    • Lichess me semble être un bon exemple de ce que Wikipedia aurait pu être en termes d’efficacité, à la fois côté code et côté organisation.
    • Je pense que tu surestimes beaucoup le nombre de développeurs chez Chess.com.