Entendendo a persistência no Apache Spark

tempo de leitura: 4 minutos

neste blog, tentaremos entender o conceito de persistência no Apache Spark em um termo muito leigo com exemplos baseados em cenários.
Nota: Os cenários são destinados apenas para sua fácil compreensão.

Arquitetura Spark

Nota: A memória Cache pode ser compartilhada entre executores.

o que isso significa persistindo/armazenando em cache um RDD?

Spark RDD persistence é uma técnica de otimização que salva o resultado da avaliação RDD na memória cache. Usando isso, salvamos o resultado intermediário para que possamos usá-lo ainda mais, se necessário. Reduz a sobrecarga de computação.

quando persistimos um RDD, cada nó armazena as partições dele que ele calcula na memória e as reutiliza em outras ações naquele RDD (ou RDD derivado dele). Isso permite que ações futuras sejam muito mais rápidas (geralmente em mais de 10x). O Cache é uma ferramenta chave para algoritmos iterativos e uso interativo rápido.

você pode marcar um RDD para ser persistido usando os métodos persist() ou cache() nele. A primeira vez que é calculado em uma ação, ele será mantido na memória cache nos nós. O cache do Spark é tolerante a falhas-se qualquer partição de um RDD for perdida, ela será automaticamente recomputada usando as transformações que o criaram originalmente.

Vamos dizer que eu tenho essa transformação–

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

RDD3 é criado a partir de RDD2 e RDD2 é criado a partir de RDD1. Cada vez que fazemos uma transformação no RDD3, então RDD2 e RDD1 precisam ser recomputados repetidamente.

RDD4.collect()RDD5.collect()

aqui, toda a cadeia de transformação precisa ser calculada duas vezes.

mas podemos persistir este RDD3 na memória cache do nó de trabalho para que cada vez que o usarmos, RDD2 e RDD1 não precisem ser computados novamente.

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

aqui, para calcular RDD5 Spark irá ler RDD3 a partir da memória cache e gerar o resultado. Portanto, RDD2 e RDD1 não serão recomputados para RDD5

Nota: rdd.cache () é o mesmo que rdd.persist()

níveis de persistência

local de armazenamento

rdd.persist(StorageLevel.MEMORY_ONLY) ou rdd.persist () rdd.persist(StorageLevel.MEMORY_AND_DISK)

– DISK_ONLY – armazena todas as partições no disco
rdd.persist(StorageLevel.DISK_ONLY)

– MEMORY_ONLY – padrão) – este é o mais simples e recomendado de usar. Ele armazena todas as partições do RDD na memória cache.

– DISK_ONLY-digamos que eu tenha UM RDD (chamado RDD1) e o cálculo desse RDD é muito complicado (demorado, criado após a aplicação de um algoritmo ML) e o RDD é enorme em tamanho e a memória cache disponível no nó Worker é menor, então não podemos salvar o RDD na memória cache. Nesse caso, podemos salvar o RDD no disco.

você pode se perguntar Qual é o ponto de armazenar no disco?

definitivamente, se armazenarmos o RDD no disco, ocorrerá E / S, O que consome tempo. Mas precisamos garantir que se a E / S leva muito tempo ou o re-cálculo do RDD leva mais tempo. Agora, se pudermos descobrir que a E/S está demorando menos tempo do que a re-computação do RDD, então, nesse caso, é melhor armazenar o RDD no disco.

portanto, sempre que RDD1 for necessário na próxima vez na transformação subsequente, o Spark fará uma operação de E/S e a levará à memória do Executor.

RDD1.persist(StorageLevel.DISK_ONLY)

– MEMORY_AND_DISK – digamos que eu tenha 3 RDDs (nenhum é armazenado em cache) na memória do Executor e não há memória disponível. Enquanto isso, outro RDD (digamos RDD4) entra. Portanto, o Spark removerá o RDD menos usado recentemente (LRU) da memória do Executor e abrirá espaço para o novo RDD entrar (neste caso RDD4).

Agora, vamos supor que 3 RDDs são armazenados em cache na memória e quando RDD4 chega LRU não vai expulsar qualquer BDR da memória cache do Trabalhador Nó. E pode haver problemas OOM.

mas se usarmos o nível de persistência MEMORY_AND_DISK com RDD4, o RDD4 será armazenado no disco, se não encontrar espaço suficiente na memória cache.

RDD4.persist(StorageLevel.MEMORY_AND_DISK)

além disso, se um grande RDD for armazenado em cache na memória e não houver memória cache suficiente, as partições restantes que não são capazes de caber na memória cache serão derramadas no disco se usarmos MEMORY_AND_DISK.

novamente o desafio aqui é operações de E / S.

Nota: Os dados persistidos no disco são armazenados no local tmp.

formato de memória

serialização – podemos optar por serializar os dados armazenados na memória cache.

MEMORY_ONLY_SER e MEMORY_AND_DISK_SER

persistir o RDD em uma forma serializada (binária) ajuda a reduzir o tamanho do RDD, criando assim espaço para que mais RDD seja persistido na memória cache. Portanto, esses dois formatos de memória são eficientes em termos de espaço.

mas o problema com isso é que eles são menos eficientes em termos de tempo porque precisamos incorrer no custo do tempo envolvido na desserialização dos dados.

portanto, é uma escolha do desenvolvedor se o desempenho é importante ou se o armazenamento é importante. Definitivamente, o impacto do desempenho não seria muito, mas seria um minuto.

replicação de partição

armazena a partição em dois nós.

DISK_ONLY_2
MEMORY_AND_DISK_2
MEMORY_ONLY_2
MEMORY_AND_DISK_SER_2
MEMORY_ONLY_SER_2

Estas opções armazena uma cópia replicada do RDD em algum outro Trabalhador do Nó de cache de memória.

os dados replicados no disco serão usados para recriar a partição, ou seja, isso ajuda a recomputar o RDD se o outro nó do trabalhador cair.

Unpersisting the RDD

– to stop persisting and remove from memory or disk
– To change an RDD’s persistence level
rdd.unpersist ()

então, é assim que podemos trabalhar com nossa memória cache no Apache Spark.

isso é tudo deste blog, espero que você tenha gostado e ajudou você!! Fique conectado para mais blogs futuros. Obrigada!!

Deixe uma resposta

O seu endereço de email não será publicado.