Comprendre la persistance dans Apache Spark

Temps de lecture: 4 minutes

Dans ce blog, nous allons essayer de comprendre le concept de Persistance dans Apache Spark dans un terme très profane avec des exemples basés sur des scénarios.
Remarque: Les scénarios ne sont destinés qu’à votre compréhension facile.

Architecture Spark

Remarque : La mémoire cache peut être partagée entre les exécuteurs.

Qu’est-ce que cela signifie par persistance / mise en cache d’un RDD ?

La persistance RDD Spark est une technique d’optimisation qui enregistre le résultat de l’évaluation RDD dans la mémoire cache. En l’utilisant, nous enregistrons le résultat intermédiaire afin de pouvoir l’utiliser davantage si nécessaire. Cela réduit les frais généraux de calcul.

Lorsque nous persistons un RDD, chaque nœud stocke les partitions de celui-ci qu’il calcule en mémoire et les réutilise dans d’autres actions sur ce RDD (ou un RDD dérivé de celui-ci). Cela permet aux actions futures d’être beaucoup plus rapides (souvent de plus de 10 fois). La mise en cache est un outil clé pour les algorithmes itératifs et une utilisation interactive rapide.

Vous pouvez marquer un RDD à conserver en utilisant les méthodes persist() ou cache(). La première fois qu’il est calculé dans une action, il sera conservé en mémoire cache sur les nœuds. Le cache de Spark est tolérant aux pannes – si une partition d’un RDD est perdue, elle sera automatiquement recalculée à l’aide des transformations qui l’ont créée à l’origine.

Disons que j’ai cette transformation –

RDD3 => RDD2 => RDD1 => Text FileRDD4 => RDD3RDD5 => RDD3

RDD3 est créé à partir de RDD2 et RDD2 est créé à partir de RDD1. Chaque fois que nous effectuons une transformation sur RDD3, RDD2 et RDD1 doivent être recalculés encore et encore.

RDD4.collect()RDD5.collect()

Ici, toute la chaîne de transformation doit être calculée deux fois.

Mais nous pouvons conserver ce RDD3 dans la mémoire cache du nœud de travail de sorte que chaque fois que nous l’utilisons, RDD2 et RDD1 n’ont pas besoin d’être recalculés.

RDD3.cache()RDD4.collect()//The first action which involves RDD3 will store it in cache memoryRDD5.collect()

Ici, pour calculer RDD5, Spark lira RDD3 à partir de la mémoire cache et générera le résultat. Par conséquent, RDD2 et RDD1 ne seront pas recalculés pour RDD5

Remarque: rdd.cache() est identique à rdd.persist()

Niveaux de persistance

Emplacement de stockage

rdd.persister (niveau de stockage.MEMORY_ONLY) ou rdd.persist() rdd.persister (niveau de stockage.MEMORY_AND_DISK)

– DISK_ONLY – Stocke toutes les partitions du disque
rdd.persister (niveau de stockage.DISK_ONLY)

– DISK_ONLY – Disons que j’ai un RDD (nommé RDD1) et que le calcul de ce RDD est très compliqué (long, créé après l’application d’un algorithme ML) et que le RDD est de taille énorme et que la mémoire cache disponible dans le nœud de travail est moindre, nous ne pouvons donc pas enregistrer le RDD dans la mémoire cache. Dans ce cas, nous pouvons enregistrer le RDD sur le DISQUE.

Vous vous demandez peut-être à quoi sert de stocker sur disque?

Définitivement, si nous stockons le RDD sur le disque, les E / S se produiront, ce qui prend du temps. Mais nous devons nous assurer que les E / S prennent beaucoup de temps ou que le recalcul du RDD prend plus de temps. Maintenant, si nous pouvons découvrir que les E / S prennent moins de temps que le recalcul du RDD, alors dans ce cas, il vaut mieux stocker le RDD sur le disque.

Ainsi, chaque fois que RDD1 est requis la prochaine fois dans la transformation suivante, Spark effectuera une opération d’E / S et l’amènera à la mémoire de l’exécuteur.

RDD1.persister (niveau de stockage.DISK_ONLY)

Maintenant, supposons que 3 RDD soient mis en cache en mémoire et que lorsque RDD4 arrive, LRU n’expulse aucun RDD de la mémoire cache du nœud de travail. Et il peut y avoir des problèmes de MOO.

Mais si nous utilisons le niveau de persistance MEMORY_AND_DISK avec RDD4, RDD4 sera stocké sur le disque, s’il ne trouve pas assez d’espace dans la mémoire cache.

RDD4.persister (niveau de stockage.MEMORY_AND_DISK)

De plus, si un énorme RDD est mis en cache en mémoire et qu’il n’y a pas assez de mémoire cache, les partitions restantes qui ne peuvent pas tenir dans la mémoire cache sont déversées sur le disque si nous utilisons MEMORY_AND_DISK.

Encore une fois, le défi ici est les opérations d’E / S.

Remarque: Les données persistantes sur le disque sont stockées à l’emplacement tmp.

Format de mémoire

Sérialisation – Nous pouvons choisir de sérialiser les données stockées dans la mémoire cache.

MEMORY_ONLY_SER et MEMORY_AND_DISK_SER

La persistance du RDD sous une forme sérialisée (binaire) permet de réduire la taille du RDD, laissant ainsi de la place pour que plus de RDD soient persistés dans la mémoire cache. Ces deux formats de mémoire sont donc peu encombrants.

Mais le problème avec cela est qu’ils sont moins rapides car nous devons supporter le coût du temps nécessaire à la désérialisation des données.

C’est donc au développeur de choisir si les performances sont importantes ou si le stockage est important. Certainement, l’impact sur les performances ne serait pas beaucoup, mais ce serait une minute.

Réplication de partition

Stocke la partition sur deux nœuds.

DISK_ONLY_2
MEMORY_AND_DISK_2
MEMORY_ONLY_2
MEMORY_AND_DISK_SER_2
MEMORY_ONLY_SER_2

Ces options stockent également une copie répliquée du RDD dans la mémoire cache d’un autre nœud de travail.

Les données répliquées sur le disque seront utilisées pour recréer la partition, c’est-à-dire cela aide à recalculer le RDD si l’autre nœud de travail tombe en panne.

Désinscription du RDD

– Pour arrêter de persister et supprimer de la mémoire ou du disque
– Pour modifier le niveau de persistance d’un RDD
rdd.unpersist()

Donc, c’est ainsi que nous pouvons travailler avec notre mémoire cache dans Apache Spark.

Tout cela vient de ce blog, j’espère que cela vous a plu et que cela vous a aidé!! Restez connecté pour plus de futurs blogs. Merci!!

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.