Duniter dev: ressources pour la synchro et espace disque

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 ?

Si tu as un OOM kill dès que ça dépasse 2Go, c’est plus cohérent avec mes derniers essais (minimum requis 2,2 Go), et c’est peut-être que ta RAM est déjà bien occupée par ailleurs. As-tu configuré du swap pour donner un peu de marge ?

1 Like

Je viens de regarder la date du dernier démarrage de mon container docker Duniter Ğ1, pensant que c’était il y a longtemps, car il tourne comme une horloge, mais ô surprise, il a rebouté cette nuit !

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

<--- Last few GCs --->

[7:0x562be7030960] 372327370 ms: Scavenge 1308.2 (1378.9) -> 1304.6 (1386.9) MB, 3.7 / 0.0 ms  (average mu = 0.373, current mu = 0.392) allocation failure 
[7:0x562be7030960] 372327451 ms: Scavenge 1312.7 (1386.9) -> 1305.2 (1386.9) MB, 3.1 / 0.0 ms  (average mu = 0.373, current mu = 0.392) allocation failure 
[7:0x562be7030960] 372327496 ms: Scavenge 1313.1 (1386.9) -> 1305.9 (1386.9) MB, 3.2 / 0.0 ms  (average mu = 0.373, current mu = 0.392) allocation failure 


<--- JS stacktrace --->

Aborted (core dumped)

Le container se relance automatiquement en cas d’erreur. Ici on voit un problème de mémoire. Pourtant j’ai 8go. Je vais installer un outil de monitoring pour comprendre ce qui se passe…

2 Likes

On pourrait le penser, mais je ne crois pas :

oom_2gb

Il semble que ce soit effectivement la synchro qui demande le plus de RAM. Très probablement qu’actuellement Duniter consomme très peu de RAM hors-synchro, mais je ne garantis pas qu’il en restera ainsi :slight_smile:

Ça fait bien longtemps que la sync partielle ne fonctionne plus, et je n’ai pas les compétences pour diagnostiquer ça. Je peux coder de la sync partielle pour les DB Rust, mais tant que la db leveldb restera (et elle restera encore bien après duniter 2.0), je ne serai pas en capacité d’avoir une sync entièrement partielle.

D’accord je vais donc baisser la valeur par défaut. Entre temps je viens d’exposer l’option --max-old-space-size dans mon dernier commit, tu peut donc testes d’autres valeurs sans recompiler :slight_smile:

Ha tiens c’est curieux :thinking:

En théorie aussi loin que possible. Le nœud rattrape les blocs petit à petit via WS2P, j’ai déjà rattrapé plus de 20000 blocs comme ça, mais ça prend plusieurs heures.


Je testerai sur mon raspberry pi 4 avec 4Go de RAM dès que j’aurais enfin reçu ma box. Je ferai de mon mieux pour que Duniter fonctionne dessus, et corrigerai ce qu’il y a à corriger, mais tant que je suis en partage de connexion via mon tel c’est compliqué :sweat_smile:

2 Likes

Bon je pense avoir trouvé : pour l’instant Raspbian est en 32bits, ce qui empêche l’utilisation de plus de 2GB par process.

Je vais essayer une Raspbian x64, c’est encore en beta mais pour ce que je veux faire ça ira très bien.

1 Like