Duniter dev: ressources pour la synchro et espace disque

Il y a encore quelques jours je pouvais faire une synchro en limitant la RAM de mon instance à 2Go. Aujourd’hui même avec 4Go ça ne passe pas les 28% d’avancement.

Ça veut dire que les raspberry pi dotés de 4Go ou moins ne pourront plus servir de noeud. C’est un peu dommage, je trouve.

Je ne suis pas certain que la bande passante nécessaire pour une synchro était si problématique. Sur mon serveur de base j’avais réussi à synchroniser en 90minutes (mon record sur cette machine) avec mon dernier patch. Ça semble parfaitement acceptable. Surcharger la RAM et la CPU pour gagner à peine quelques minutes sur des machines de course n’est peut-être pas une bonne idée.

Ben non qui à dit qu’on allait rester comme ça ? J’essaye un truc, je vois que ça bouffe beaucoup de ressources, je réadapte :wink:

D’une part ce serait beaucoup plus que quelques minutes, d’autres part ça réduit aussi considérablement l’espace de stockage occupé par les chunk, donc ça réduit la taille de la db.
Je compte garder la compression, faut juste changer l’algo de compression, c’est lz4 qui bouffe beaucoup trop de RAM.

1 Like

J’ai fait quelques tests complémentaires, et en particulier un test de synchro depuis mon PC perso (16 Go de RAM), juste après reboot afin d’éviter les effets de bord. Ça se termine là :

2021-05-18T07:45:58+00:00 - info: GOT chunck #1368/3028 from 342000 to 342249 on peer gtest.jytou.fr

Avec la mémoire complètement saturée :

mai 18 09:46:01 pinibrem15 kernel: oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=docker-7fb9c3662c6f809030b63b6e74106ea6a6165456ef0ad61faa31fdc0f3c6d6eb.scope,mems_allowed=0,global_oom,task_memcg=/>
mai 18 09:46:01 pinibrem15 kernel: Out of memory: Killed process 3819 (node) total-vm:17543136kB, anon-rss:14934656kB, file-rss:0kB, shmem-rss:0kB, UID:1111 pgtables:41700kB oom_score_adj:0

À noter également l’empreinte stockage qui augmente de deux ordres de grandeur :

  • Avant, l’espace disque était < 2Go à la fin de la synchro
  • Lors de ce test interrompu vers 45%, on est monté à 23 Go. L’augmentation semble croître proportionnellement au cours de l’avancement, au point que j’anticipe dans les 100Go au total.

Tout cet espace est occupé par gva_v1_sled.

Hope this helps…

Chez moi la db gva fait 46 Go (sync complète et terminée), donc c’est beaucoup moins que 100, mais ça reste trop. Je vais voir ce que ça change en passent à deflate pour les chunk, mais mon humble avis ça restera trop, car sled prend trop d’espaces disque, c’est censé être fortement amélioré par la v1, mais elle n’est pas encore sortie.

J’espère que sled v1 sera sorti d’ici l’automne (avant la sortie de Duniter 2.0), si d’ici l’automne je ne vois toujours rien venir je migrerai sous RocksDB. En attendant les testeurs de la version de dev doivent prévoir de l’espace disque.

Avec deflate en level 3 je suis à 51Go, soit plus encore qu’avec lz4. En fait je pense que l’erreur c’est de stocker les chunk compréssés dans la db, sled semble réagir très mal à ça, autant en espace disque qu’en temps d’ouverture de la db.
Il faut que je stocke les chunk compressés dans des fichiers directement, ça occupera beaucoup moins d’espace disque et ça ne ralentira plus l’ouverture de la db.

3 Likes

Ok alors en fait le problème d’espace disque ne viens pas de sled ni de lz4 mais de mon code de création des chunks de blocks. J’ai un “current chunk” que je compresse tous les N blocs, et j’oubliais de vider ce “current chunk” à chaque cycle. Donc chaque chunk répétais le contenu de tout les précédents, ce qui donne 5.3 Go de données au lieu de 117 Mo :laughing:

EDIT: et c’est aussi pour ça que trop de ressources était prises en mémoire, avec ce bug le dernier chunk contenais toute la blockchain, forcément toute la blockchain à compresser d’un bloc ça pique.
Du coup faudrait peut-être que je réessaye lz4 car il n’étais en fait pas la cause du problème.

Bon, sled prend quand même beaucoup plus d’espaces que les données qu’on y insère, mais c’est un problème connu (carrément indiqué même dans leur README), et que la v1 est censée résoudre.

4 Likes

La v1 était pas censé sortir en Janvier 2021 ?
Il me semble t’entendre dire ça l’année dernière, mais je dois me tromper.

Si c’est bien ça, ils ont du retard

1 Like

'font chier tous ces gens à avoir du retard sur leurs deadlines …

Avec le correctif, les chunk compressés pèsent 112Mo pour la Ğ1 et 155Mo pour la ĞT, c’est beaucoup plus cohérent comme taille :slight_smile:

dex migrate se joue en moins de 10 minutes chez moi, je n’ai pas regardé quelle RAM ça prend.

Pour tester, assurez-vous d’être sur le commit 0b787134 ou supérieur :slight_smile:

EDIT: j’utilise l’algo deflate, utilisé notamment par le format gzip (mais pas que) qui est en réalité le nom d’un format et non pas d’un l’algo de compression :wink:
J’ai réglé la compression sur 3, le minimum étant 1 (très rapide mais taux de compression faible) et le max étant 9 (taux de compression maximal mais temps de compression très long).
Avec 3 j’ai déjà une bonne augmentation du temps de sync et une taille des chunk très raisonnable, donc je ne vais pas augmenter, peut-être même réduire à 2 je verrais.

3 Likes

Je confirme c’est beaucoup mieux ! Merci :+1:

C’est passé avec une limitation de RAM à 2,5Go. Pas encore testé avec 2Go, mais 2.5Go c’est parfaitement acceptable.

UPDATE : La limite basse pour la RAM semble être 2.2Go.

4 Likes

La branche dev est censée fonctionner sur un Raspberry Pi 4 actuellement ? Les commandes reset et sync m’affichent :

 $ ./target/release/duniter reset data

<--- Last few GCs --->


<--- JS stacktrace --->


#
# Fatal process OOM in insufficient memory to create an Isolate
#

J’essaie de modifier la mémoire allouée pour Node à travers NODE_OPTIONS=--max_old_space_size=2048 mais cela ne semble pas faire effet.

Une idée ?

En théorie oui, en pratique je n’ai pas testé depuis un moment, j’attendais de recevoir ma box pour rebrancher mon rpi4, mais je ne l’ai toujours pas reçue.

Cette option est déjà setté automatiquement avec la valeur 4096 :slight_smile:

Hélas non, il faudrait que je teste sur mon rpi4 pour pouvoir diagnostiquer

Ah OK, mais c’est trop. Comment puis-je mettre une autre valeur ?

On a remarqué que les nœuds de dev crashait souvent et qu’on était obligé de les restart très régulièrement. Depuis que j’ai setté statiquement max_old_space_size=4096 ça semble avoir résolu le problème.
Je ne pense pas que ce soit trop, car la plupart des utilisateurs de Duniter disposent bien d’au moins 4 Go, et souvent plus.

D’après des tests récents de @Pini , la synchro demande à minima 2,2 Go, sachant que ça ne va qu’empirer avec le grossissement de l’historique tant qu’on aura pas de système de master block, je compte indiquer dans les prérequis minimal du Duniter 2.0 qu’il faudra disposer d’au moins 4 Go de RAM.

Vu l’ampleur de ce que doit gérer Duniter et la charge grandissante autant en historique de données qu’en utilisateurs, il me semble irréaliste d’espérer que l’on puisse maintenir à moyen/long terme la possibilité de faire fonctionner un nœud Duniter avec moins de 4 Go de RAM, en tous les cas je ne compte pas m’engager là-dessus.

Là maintenant ce n’est pas possible, je peux exposer l’option afin que l’on puisse facilement tester d’autres valeurs pour trouver celle qui va bien, je ferai ça dimanche :slight_smile:

Question: ces 4Go sont-ils nécessaires uniquement pour la synchro, ou également pour la résolution de forks ?

J’ai resynchronisé mon noeud (1Go de RAM) en faisant la synchro sur le laptop (8Go) puis en copiant le dossier duniter_default.

Par ailleurs, je pense mettre en place un backup recurrent de duniter_default pour pouvoir repartir d’un état à -1mois en cas de fork non résolu.

Dans ces cas d’usage (pas de synchro complète sur le noeud), les 4Go s(er)ont-ils tout de même nécessaires ?

Ce serait l’idéal de faire ça. Malheureusement, chez moi, un reset data + sync en ram est plus rapide qu’une sync sur HDD…

Si j’ai bien compris, une sync sur une blockhain existante mais bloquée, ne va recharger que les blocs divergeants, non ? C’est censé être plus court en temps que de recharger toute la blockchain ?

Ou bien y a t-il un paramètre que j’ignore pour dire “sync uniquement les x derniers blocs” ?

Sur une machine qui a exactement 4Go de RAM, ça empêche le programme de démarrer visiblement (erreur ci-dessus).

OK j’ai trouvé dans le code, j’ai modifié à 4000 et ça passe. Mais entre 4000 et 4096 c’est assez aléatoire, parfois ça passe parfois non. Je suppose que c’est lié à l’activité système.

edit : bon, mais la synchro ne passe pas pour autant, ça bloque à “Milestone: 99%”. Pourtant la mémoire n’est pas saturée.

edit 2 : en fait ça plante dès que le processus tente de dépasser les 2Go de mémoire réellement utilisée (pas virtuelle).

De ce que j’ai cru comprendre par mon experience :

  • souvent (1x/semaine) un bloc est considéré comme invalide, reste en mémoire et bloque toute résolution de fork. Redémarrer Duniter fait la job, j’ai une tâche cron qui redémarre tous les jours.

  • parfois, un bloc est considéré invalide même après redémarrage, reset, etc. Dans ce cas, une sync sans reset data n’a jamais fonctionné chez moi. En revanche, remplacer les donnees par une archive de donnees plus anciennes a fonctionné, Duniter est allée chercher les blocs manquantes comme une grande.

2 Likes

Pourtant lorsque je bride mon instance Docker de dev à 2.5 Go de RAM la synchro complète fonctionne.

Je n’ai pas encore remarqué ça. Mais il est vrai que j’ai rarement laissé tourner une de mes instances plus d’une semaine sans redémarrage. Je vais surveiller en les maintenant up autant que possible.

Sait-on jusqu’à quelle ancienneté ce mécanisme peut fonctionner ?