La synchronisation de Duniter v1 occupe beaucoup de RAM

Bonjour à tous,

Ça fait maintenant depuis le 10 septembre que j’essaye de resynchroniser mon noeud duniter sans succès.
Il faut croire que mon raspi 4 n’y arrive plus…
Je passe par la GUI web (installation de duniter via Yunohost) et après 24h, parfois j’arrive à laisser plus de 24h mon ordi allumer, ça bloque quelque part entre 80 et 90 %. Je ne crois pas avoir dépassé 90 % en « Apply » une seule fois cette fois-ci.
Est-ce qu’il existe une autre façon de faire que via le GUI web qui a plus de succès?

Avec YunoHost, tu peux essayer en CLI :

sudo su - duniter -c "duniter --home \$HOME sync g1.duniter.org"

Ça devient de plus en plus dur avec les machines qui n’ont pas beaucoup de RAM.
Tu peux arrêter tes autres services (surtout ceux qui occupent beaucoup de RAM) le temps de la synchronisation pour essayer de faire passer.

2 Likes

Merci pour cette commande qu’il vaut mieux lancer dans un screen j’imagine pour se prémunir d’une perte de connexion ssh (How to Recover from an Accidental SSH Disconnection on Linux - RoseHosting)

Qu’est-ce que c’est « pas beaucoup de RAM »? 4Gb et en dessous?

Tout à fait, il est préférable d’utiliser un outil tel screen ou tmux pour cette longue opération.
Si la machine n’est pas dédiée au service Duniter, il y a moins que 4 Go disponible. De plus, ça commence à être difficile une synchro avec 2/3Go je trouve.

En tout cas, ta commande m’a permis d’arriver en moins de 24h à 90%/88% ce qui ne m’était pas encore arrivé avec le GUI web depuis la dernière mise à jour qui nous a obligé à redémarrer la sync.
Super, merci, j’y crois!

Bon ben je suis arrivé à 94%/92%, et ça a echoué avec l’erreur suivante :

Status: Getting chunck #2138/2273 from 534500 to 534749 on peer g1.bounceme.net
<--- Last few GCs --->

[3388:0x1d61848] 79175179 ms: Mark-sweep 659.6 (724.8) -> 657.6 (722.8) MB, 1822.8 / 0.0 ms  (average mu = 0.233, current mu = 0.046) allocation failure scavenge might not succeed
[3388:0x1d61848] 79175288 ms: Scavenge 659.5 (722.8) -> 657.9 (722.8) MB, 34.5 / 0.0 ms  (average mu = 0.233, current mu = 0.046) allocation failure 
[3388:0x1d61848] 79177947 ms: Mark-sweep 662.8 (725.8) -> 659.4 (724.7) MB, 1667.0 / 0.1 ms  (average mu = 0.323, current mu = 0.398) allocation failure GC in old space requested


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x56e126ed <JSObject>
    0: builtin exit frame: parse(this=0x56e0c039 <Object map = 0x5e285155>,0x3ab0438d <undefined>,0x83e04101 <Very long string[1414369]>,0x56e0c039 <Object map = 0x5e285155>)

    1: /* anonymous */ [0x876ff1bd] [/opt/duniter/node_modules/request/request.js:1145] [bytecode=0x50068925 offset=396](this=0x31e84e59 <Request map = 0x3deff991>)
    2: arguments adaptor frame: 1->0
    3: emit [0x56e2899d]...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
/usr/bin/duniter: line 15:  3388 Aborted                 $NODE "$DUNITER_DIR/bin/duniter" "$@"

Pour info, lancé juste après l’échec de la commande,

:~ $ free -h
               total        used        free      shared  buff/cache   available
Mem:           3.7Gi       448Mi       1.2Gi        14Mi       2.1Gi       3.2Gi
Swap:           99Mi        12Mi        87Mi

Je retente?

Il n’y a pas assez de mémoire, une solution est d’augmenter le swap (mais ça va ralentir considérablement). 4 Go de swap devrait suffire.

Ce qui m’étonne c’est que si Duniter a rempli la mémoire, il a forcément vidé le cache (le cache du système de fichiers est censé être moins prioritaire que les processus), or le cache occupe 2 Go juste après l’arrêt de Duniter. Soit il s’est rempli très rapidement après que Duniter a libéré la mémoire, soit quelque chose de bizarre s’est passé.

Il me semble que le cache était déjà à 2G pendant que Duniter tournait.

Bon du coup, j’ai fait une désinstallation/réinstallation.
J’ai

free -h
               total        used        free      shared  buff/cache   available
Mem:           3.7Gi       622Mi       1.4Gi        14Mi       1.7Gi       3.0Gi
Swap:           99Mi        10Mi        89Mi

et je relance.
On verra bien.

Le mieux serait de monitorer la mémoire au moment de la synchronisation.
Par exemple avec : free -hs 1

J’obtiens une erreur, au même moment, à 94/92% :

        GOT chunck #2138/2274 from 534500 to 534749 on peer duniter.coinduf.eu
<--- Last few GCs --->

[26748:0x2323848] 80442502 ms: Mark-sweep 656.7 (729.8) -> 647.5 (728.8) MB, 1664.1 / 3.1 ms  (average mu = 0.331, current mu = 0.331) allocation failure scavenge might not succeed
[26748:0x2323848] 80442788 ms: Scavenge 655.1 (728.8) -> 648.6 (728.8) MB, 29.9 / 2.2 ms  (average mu = 0.331, current mu = 0.331) allocation failure
[26748:0x2323848] 80442995 ms: Scavenge 655.1 (728.8) -> 649.4 (729.8) MB, 11.7 / 0.7 ms  (average mu = 0.331, current mu = 0.331) allocation failure


<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x4436c49c]
Security context: 0x427926ed <JSObject>
    1: put [0x300fd239] [/opt/duniter/node_modules/abstract-leveldown/abstract-leveldown.js:~95] [pc=0x92f2807c](this=0x31a2df51 <LevelDOWN map = 0x2437fa99>,key=0x32ef4525 <String[44]: 3t2EhtJRVQiKQMaTCSwRzhmSo5hfLzcN9ry9ifiigdtw>,value=0x323a7165 <Very long string[11584]>,options=0x323a7285 <Object map = 0x207842b9>,callback=0x323a72a1 <JSFunction (sfi = 0xaff0565...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
/usr/bin/duniter: line 15: 26748 Aborted                 $NODE "$DUNITER_DIR/bin/duniter" "$@"

Je veux bien monitorer la mémoire au moment de la synchronisation avec free -hs 1 .
Pour ça, je fais deux ‹ screen › c’est ça, un pour la commande

sudo su - duniter -c "duniter --home \$HOME sync g1.duniter.org"

et un pour free -hs 1
mais comment, une fois que j’arrive au bout de la synchro (si pas succès mais erreur), je peux récupérer le log de free -hs 1 ?

Petite question, avant de relancer sudo su - duniter -c "duniter --home \$HOME sync g1.duniter.org" il faut que j’arrête duniter et service duniter stop ne fonctionne pas du coup je l’arrête via la webgui de yunohost. C’est ok?

Tu peux utiliser la commande bash suivante, que j’ai concoctée pour journaliser l’utilisation de la RAM.

while true; do date >> /tmp/memory.log; free -h >> /tmp/memory.log; sleep 30; done

C’est pour vérifier que c’est bien le problème, bien que je soit certain que ça soit le problème.

Oui, il faut arrêter le service duniter : sudo systemctl stop duniter ou via l’interface d’admin de Duniter, oui.

Voila, l’erreur se reproduit à nouveau à 94/92% et le log de la ram est en dessous.

Progress:

Milestones:   [||||||||||||||||||||] 100 %
Download:     [||||||||||||||||||  ] 94 %
Apply:        [||||||||||||||||||  ] 92 %
Sandbox:      [                    ] 0 %
Peers:        [                    ] 0 %

Status: GOT chunck #2139/2278 from 534750 to 534999 on peer g1.soberaniadigital.net
<--- Last few GCs --->

[1541:0x3546848] 83164222 ms: Mark-sweep 657.8 (729.8) -> 649.2 (728.3) MB, 1663.1 / 1.5 ms  (average mu = 0.324, current mu = 0.256) allocation failure scavenge might not succeed
[1541:0x3546848] 83164441 ms: Scavenge 656.8 (728.3) -> 650.3 (728.8) MB, 10.2 / 0.7 ms  (average mu = 0.324, current mu = 0.256) allocation failure
[1541:0x3546848] 83164615 ms: Scavenge 656.9 (728.8) -> 651.1 (729.8) MB, 10.3 / 0.6 ms  (average mu = 0.324, current mu = 0.256) allocation failure


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x3e9126ed <JSObject>
    0: builtin exit frame: parse(this=0x3e90c039 <Object map = 0x2eb05155>,0x35b29169 <Very long string[11425]>,0x3e90c039 <Object map = 0x2eb05155>)

    1: /* anonymous */ [0x8ab0baf5] [/opt/duniter/app/lib/dal/indexDAL/leveldb/LevelDBTable.js:~72] [pc=0xb0eabc94](this=0x8ab0b9ad <ReadStream map = 0x2bb07599>,data=0x35b12165 <Object map = 0x2bb0567d>)
    2: emit [0x3e92899d] [events.js:~147] [pc=...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
/usr/bin/duniter: line 15:  1541 Aborted                 $NODE "$DUNITER_DIR/bin/duniter" "$@"

Voici le log de la ram depuis ce matin, l’erreur étant apparu plutôt en fin d’après-midi. Je peux affirmer que l’erreur n’était pas encore survenu à 16h. Après, je ne sais pas.

https://paste.yunohost.org/aroloxegen.sql

Ça semble avoir eu lieu au tour de 18h où l’on voit 1Gio se libérer :

Sun 23 Oct 2022 06:00:06 PM CEST
               total        used        free      shared  buff/cache   available
Mem:           3.7Gi       1.5Gi        87Mi        11Mi       2.1Gi       2.1Gi
Swap:           99Mi        99Mi          0B
Sun 23 Oct 2022 06:00:36 PM CEST
               total        used        free      shared  buff/cache   available
Mem:           3.7Gi       1.5Gi        70Mi        11Mi       2.1Gi       2.1Gi
Swap:           99Mi        99Mi          0B
Sun 23 Oct 2022 06:01:06 PM CEST
               total        used        free      shared  buff/cache   available
Mem:           3.7Gi       495Mi       1.1Gi        11Mi       2.2Gi       3.1Gi
Swap:           99Mi        99Mi          0B
Sun 23 Oct 2022 06:01:36 PM CEST
               total        used        free      shared  buff/cache   available
Mem:           3.7Gi       496Mi       1.1Gi        11Mi       2.2Gi       3.1Gi
Swap:           99Mi        99Mi          0B

mais il y avait encore 2 Go de disponible si je comprends bien.

En effet, je ne sais pas très bien comment est géré de la RAM. J’ai tenté de comprendre la colonne free avec un man free.

Du coup, Duniter v1 sur un raspi 4 avec 4 Go de ram sous Yunohost avec uniquement 3 apps, ynh-vpn, ynh-wifi et Lufi, c’est mort…?
Dommage, on va attendre Duniter v2 si je comprends bien :slight_smile:

Dire qu’à une époque ce même raspi faisait tourner en plus nextcloud et synapse et que duniter y tournait très bien. C’est quand même étrange tout ça je trouve.

La chaîne de bloc a évoluée entre-temps, elle est beaucoup plus grosse.
Il n’y a pas de travaux d’optimisations sur Duniter v1 pour qu’il occupe moins de RAM durant la sync.

Il y a toujours la possibilité de copier les données de confiance d’un nœud synchronisé sur les machines sur lesquels il n’y a pas assez de RAM pour réussir une synchronisation complète.

1 Like

Comment peut-on faire ça? Peux-tu m’indiquer un tuto stp?

Alors non, je pense que Moul ne parle pas de l’archive json, mais directement de la base de données. Je pourrais réfléchir à servir ces fichiers également mais pour l’instant ce n’est pas le cas.