web-dev-qa-db-fra.com

Y a-t-il une limite à la taille d'une chaîne en JSON avec Node.js?

Une section de mon application Node.js implique de recevoir une chaîne en entrée de l'utilisateur et de la stocker dans un fichier JSON. JSON lui-même n'a évidemment aucune limite à cela, mais y a-t-il une limite supérieure sur la quantité de texte que Node peut traiter en JSON?

Notez que j'utilise pas en utilisant MongoDB ou toute autre technologie pour l'insertion réelle - il s'agit de la chaîne de caractères native et de l'enregistrement dans un fichier .json en utilisant fs.

23
Hydrothermal

V8 (le nœud du moteur JavaScript est construit) jusqu'à ce que très ait récemment limite stricte sur la taille du tas d'environ 1,9 Go .

Le nœud v0.10 est bloqué sur une ancienne version de V8 (3.14) en raison de la rupture des modifications de l'API V8 autour des modules complémentaires natifs. Node 0.12 mettra à jour vers la dernière version V8 (3.26), qui cassera de nombreux modules natifs, mais ouvre la porte à l'augmentation de la limite de tas de 1,9 Go.

Ainsi, en l'état, un processus à nœud unique ne peut pas conserver plus de 1,9 Go de code JavaScript, objets, chaînes, etc. combinés . Cela signifie que la longueur maximale d'une chaîne est inférieure à 1,9 Go.

Vous pouvez contourner ce problème en utilisant Buffers, qui stockent les données en dehors du tas V8 (mais toujours dans le tas de votre processus). Une construction de nœud 64 bits peut à peu près remplir tous vos RAM tant que vous n'avez jamais plus de 1,9 Go de données dans les variables JavaScript.


Cela dit, vous ne devriez jamais vous approcher de cette limite. Lorsque vous traitez avec autant de données, vous devez les traiter comme un flux. Vous ne devriez jamais avoir plus de quelques mégaoctets (tout au plus) en mémoire à la fois. La bonne nouvelle est que le nœud est particulièrement bien adapté au traitement des données en streaming.

Vous devriez vous poser quelques questions:

  • Quel type de données recevez-vous réellement de l'utilisateur?
  • Pourquoi voulez-vous le stocker au format JSON?
  • Est-ce vraiment une bonne idée de remplir des gigaoctets en JSON? (La réponse est non.)
  • Qu'adviendra-t-il des données plus tard, après leur stockage? Votre code le lira-t-il? Autre chose?

La question que vous avez posée est en fait assez vague en ce qui concerne ce que vous essayez réellement d'accomplir. Pour des conseils plus spécifiques, mettez à jour votre question avec plus d'informations.

Si vous vous attendez à ce que les données ne soient jamais aussi grandes, jetez simplement une limite raisonnable de 10 Mo ou quelque chose sur l'entrée, mettez-les en mémoire tampon et utilisez JSON.stringify.

Si vous prévoyez de traiter des données plus volumineuses, vous devez diffuser directement l'entrée sur le disque. Regardez dans transformer les flux si vous devez traiter/modifier les données avant qu'elles ne soient envoyées sur le disque. Par exemple, il y a modules qui traitent du streaming JSON .

27
josh3736

La taille de chaîne maximale dans nodeJS "Vanilla" (v0.10.28) est d'environ 1 Go.

Si vous êtes pressé, vous pouvez tester la taille de chaîne maximale prise en charge avec une chaîne à doublage automatique. Le système testé dispose de 8 Go de RAM, pour la plupart inutilisés.

x = 'x';
while (1){ 
     x = ''+x+x; // string context
     console.log(x.length);
}

2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
536870912
FATAL ERROR: JS Allocation failed - process out of memory
Aborted (core dumped)

Dans un autre test, je suis arrivé à 1 000 000 000 avec un seul caractère à la fois pour la boucle.

Maintenant, un critique pourrait dire, "attendez, qu'en est-il de JSON. La question concerne JSON!" et je crierais IL N'Y A AUCUN OBJET JSON DANS JAVASCRIPT les types JS sont Object, Array, String, Number, etc .... et comme JSON est une représentation String, cette question se résume à quelle est la chaîne la plus longue autorisée. Mais juste pour vérifier, ajoutons un appel JSON.stringify pour traiter la conversion JSON.

Code

x = 'x';
while (1){ 
     x = ''+x+x; // string context
     console.log(JSON.stringify({a:x}).length);
}

Attentes: la taille de la chaîne JSON commencera supérieure à 2, car le premier objet va se stringifier en '{"a": "xx"}' pour 10 caractères. Il ne commencera pas à doubler jusqu'à ce que la chaîne x dans la propriété a s'agrandisse. Il échouera probablement autour de 256M car il fait probablement une deuxième copie en stringification. Rappelons qu'une stringification est indépendante de l'objet d'origine.

Résultat:

10
12
16
24
40
72
136
264
520
1032
2056
4104
8200
16392
32776
65544
131080
262152
524296
1048584
2097160
4194312
8388616
16777224
33554440
67108872
134217736
268435464

Comme prévu ...

Maintenant, ces limites sont probablement liées au code C/C++ qui implémente JS dans le projet nodeJS, qui à l'heure actuelle, je crois, est le même code V8 utilisé dans Chrome navigateurs.

Il existe des preuves dans des articles de blog de personnes recompilant nodeJS pour contourner les limites de mémoire dans les anciennes versions. Il existe également un certain nombre de commutateurs de ligne de commande nodejs. Je n'ai testé l'effet de rien de tout cela.

9
Paul

C'est une bonne question, mais je pense que la limite supérieure dont vous devez vous inquiéter n'implique pas la taille maximale de la chaîne JSON.

À mon avis, la limite dont vous devez vous soucier est de combien de temps souhaitez-vous bloquer le thread de demande pendant le traitement de la demande de l'utilisateur.

Toute taille de chaîne supérieure à 1 Mo prendra quelques secondes à l'utilisateur pour télécharger et 10 mégaoctets pourraient prendre quelques minutes. Après avoir reçu la demande, le serveur mettra quelques centaines de millisecondes en secondes pour analyser une structure de données conduisant à une très mauvaise expérience utilisateur (l'analyse JSON est très coûteuse)

La bande passante et les temps de traitement du serveur éclipseront toute limite que JSON peut avoir sur la taille des chaînes.

1
Martin Konecny