On observe depuis 1 semaine des passages de plus en plus fréquents du CPU de synapse à 100% et le serveur s'effondre progressivement. Il y a effectivement eu quelques vagues de spam suite au FOSDEM, mais on en est au stade où le trafic normal nous met par terre rapidement.
On a déjà creusé et j'ouvre cette issue pour capitaliser les réflexions et essayer d'identifier une piste de sortie correcte.
Edited
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items
...
Show closed items
Linked items
0
Link issues together to show that they're related.
Learn more.
D'abord, les problèmes semblent souvent s'accumuler après une salve d'events, puis le serveur ne parvient plus à suivre la fédération pendant de nombreuses heures.
Exemple :
Toutefois, ce n'est pas le cas sytématiquement, par exemple :
Il y a donc probablement un état de fond qui affaiblit fortement le serveur (index mal optimisé, trop gros, etc.) et des épiphénomènes qui le mettent au tas.
Quelques requêtes pour explorer les coupables en nombre d'événéments.
Nombre d'événements par room et par heure, soit par heure de réception, soit par heure d'émission
select count(event_id), type, room_id, (received_ts/3600000)*3600 as ts from events where received_ts > 1643921432000 group by type, room_id, ts
select count(event_id), type, room_id, (origin_server_ts/3600000)*3600 as ts from events where origin_server_ts > 1643921432000 group by type, room_id, ts
Sur ces données, un simple sort pointe assez rapidement le coupable.
Evolution de l'écart entre émission et réception
select received_ts, received_ts - origin_server_ts from events where origin_server_ts > 1644477071000
Matérialise le lag, mais aussi les salves d'events provenant de serveurs qui rejoignent la fédération après un temps. Exemple :
Plus que le simple monitoring de l'état du synapse ou des lags fédération, la taille de la queue de traitement des messages inbound semble être le meilleur critère pour identifier une difficulté. Un monitoring sur ce critère pourrait servir d'early alert (bien qu'on n'ait pas encore de solution pour rétablir) :
De même, pour matcher l'origine des défauts, on s'attache à observer les événements reçus dans ces périodes où la file de fédération commence à s'allonger, et le CPU monter en charge.
Matcher sur les performances d'envoi est bien moins pertinent, puisque l'état du serveur semble décourager les envois de messages, voire les pousser en erreur. Le taux d'erreur à l'envoi pourrait aider mais n'est qu'indirectement corrélé.
Pour profile synapse, on utilise py-spy installé sur l'hôte et qui ptrace directement le processus conteneurisé.
En temps normal, y compris sous charge élevée, l'essentiel de la charge est sur les fonctions d'accès à la bdd. Il y a probablement beaucoup d'optimisation de ce côté, notamment en maximisant l'emploi du cache. A creuser plus tard. Lorsque le serveur est vraiment indisponible, le profile devient intéressant :
Le flamegraph a confirmé ce que les taux de requêtes donnaient déjà pas mal : le get_users_in_room effondre pas mal en requête BDD.
Il avait un hit ratio en cache à 25% environ, et était trigger principalement par une super-transaction get_users_in_same_room, qui avait un hit ratio à 30% elle-même. On a commencé par pousser le cache size de ces deux transactions d'un facteur 5 et 4 respectivement. Le hit ratio est >95% pour les deux dorénavant pour quelques dizaines de Mo de RAM.
La charge CPU associée a chuté, on a pu rattraper la fédération. Cela a aussi mis en avant une nouvelle transaction qui mange des ressources. Peu fréquente, elle est excessivement longue d'exécution (plusieurs secondes voire dizaines de secondes par transaction). On observe comment ça se comporte à la prochaine salve de messages.
Après quelques heures de recul, effectivement la charge générale sur le serveur a diminué : il consomme 3 à 4 fois moins d'accès bdd en général, et 2 fois moins de CPU. En revanche même s'il met moins de temps à absorber s'en remettre, il continue de s'effondrer sur des événements spécifiques.
Le scénario est globalement le suivant :
le serveur reçoit "quelque chose" (events entrants, sortants, on ne sait pas bien encore exactement)
il monte immédiatement en charge CPU
il cesse de traiter la fédération en contrepartie, ou beaucoup plus lentement
la charge CPU descend mais la fédération reste très en retard, jusqu'à 1h ou 2h plus tard
le retard est absorbé d'un coup, sans surcharge CPU énorme
On n'a pas de profil CPU pendant ces périodes pour l'instant. On va voir pour setup un profil toutes les 15 minutes à exploiter plus tard.