Os RDDs no Spark são carregados lentamente. Todos os RDDs são calculados do zero apenas quando um operador de ação é encontrado e, quando o mesmo RDD é usado várias vezes, ele precisa ser recalculado a cada vez, o que aumentará seriamente o consumo. Para evitar recalcular o mesmo RDD, o RDD pode ser persistido.
Uma das funções importantes no Spark é que os dados em um determinado RDD podem ser salvos na memória ou disco. Toda vez que uma operação do operador é necessária neste RDD, os dados persistentes deste RDD podem ser recuperados diretamente da memória ou disco. precisando calcular do zero para conseguir esse RDD.
(2) Operação de Persistência de Demonstração de Caso
1. Diagrama de dependência do RDD
Leia o arquivo, execute uma série de operações, existem vários RDDs, conforme mostrado na figura a seguir.
2. Não use operações persistentes
Na figura acima, duas operações de operador são executadas em RDD3 para gerar RDD4 e RDD5, respectivamente. Se o RDD3 não for salvo de forma persistente, toda vez que você operar no RDD3, será necessário iniciar o cálculo de textFile(), converter os dados do arquivo em RDD1 e depois convertê-lo em RDD2 e, finalmente, obter RDD3.
Visualize o arquivo a ser manipulado
Iniciar Spark Shell
Siga o diagrama para obter RDD4 e RDD5
Calcule RDD4, ele será executado de RDD1 a RDD2 a RDD3 a RDD4 e verifique o resultado
Calcule RDD5 e também faça uma viagem de RDD1 para RDD2 para RDD3 para RDD4 para visualizar os resultados
3. Use operações persistentes
Você pode usar o método persist() ou cache() no RDD para marcar o RDD a ser persistido (o método cache() na verdade chama o método persist() na parte inferior). Os dados serão computados na primeira ação e armazenados em cache na memória do nó. O cache do Spark é tolerante a falhas: se qualquer partição de um RDD armazenado em cache for perdida, o Spark recalculará automaticamente e armazenará em cache o processo de transformação original do RDD.
Ao calcular para RDD3, marque persistência
Calcular o RDD4 é iniciar o cálculo com base nos dados armazenados em cache no RDD3, sem executá-lo do início ao fim
Calcular o RDD5 é iniciar o cálculo com base nos dados armazenados em cache no RDD3, sem executá-lo do início ao fim
Em segundo lugar, o nível de armazenamento
(1) Parâmetros do método de persistência
Use o método persist() do RDD para obter persistência e passe um StorageLevelobjeto para o método persist() para especificar o nível de armazenamento. Cada RDD persistente pode ser armazenado usando um nível de armazenamento diferente, o nível de armazenamento padrão é StorageLevel.MEMORY_ONLY.
(2) Tabela de nível de armazenamento Spark RDD
Existem sete níveis de armazenamento para Spark RDDs
Na operação Shuffle do Spark (como reduceByKey()), alguns dados intermediários são salvos automaticamente mesmo que o usuário não use o método persist(). Isso é feito para evitar recalcular a entrada inteira se ela falhar durante o embaralhamento de nós. Se você quiser usar um RDD várias vezes, é altamente recomendável chamar persist()métodos nesse RDD.
(3) Como escolher o nível de armazenamento - compensação entre uso de memória e eficiência da CPU
Se o RDD for armazenado na memória sem estouro, o nível de armazenamento padrão (MEMORY_ONLY) é o preferido, o que maximiza o desempenho da CPU e permite que as operações no RDD sejam executadas na velocidade mais rápida.
Se o RDD transbordar quando armazenado na memória, use MEMORY_ONLY_SER e escolha uma biblioteca de serialização rápida para serializar o objeto para economizar espaço e ainda ser razoavelmente rápido para acessar.
A menos que calcular um RDD seja muito caro, ou que o RDD filtre muitos dados, não grave dados derramados no disco, porque recalcular partições pode ser tão rápido quanto lê-los do disco.
Se desejar uma recuperação rápida em caso de falha do servidor, você pode usar o nível de armazenamento de várias cópias MEMORY_ONLY_2 ou MEMORY_AND_DISK_2. Esse nível de armazenamento permite que as tarefas continuem em execução em RDDs após a perda de dados sem ter que esperar que as partições perdidas sejam recalculadas. Outros níveis de armazenamento exigem o recalculo de partições perdidas após a perda de dados.
(4) Visualize o código-fonte dos métodos persist() e cache()
Como pode ser visto no código acima, o método cache() chama o método sem parâmetros do método persist(), e o nível de armazenamento padrão de ambos é MEMORY_ONLY, mas o método cache() não pode alterar o nível de armazenamento, enquanto persist () pode passar parâmetros de níveis de armazenamento personalizados.
(5) Demonstração de Caso Configurando o Nível de Armazenamento
(2) Spark WebUI para visualizar informações de armazenamento RDD
Acesse a WebUI do Spark Shell no navegador para http://master:4040/storage/visualizar as informações de armazenamento RDD e você pode ver que as informações de armazenamento estão vazias
Execute o comando: rdd.collect(), colete dados RDD
Atualize a WebUI e descubra que há uma ParallelCollectionRDDinformação de armazenamento, o nível de armazenamento do RDD é MEMORY, a partição persistente é 8, e ela está completamente armazenada na memória.
Clique ParallelCollectionRDDno hiperlink para visualizar as informações detalhadas de armazenamento do RDD
A operação acima mostra que chamar o método persist() de um RDD apenas marca o RDD como persistente, e o RDD marcado como persistente só será persistido quando uma operação de ação for executada.
Execute os seguintes comandos para criar rdd2 e persistir rdd2 no disco
Atualize a WebUI acima e encontre mais uma MapPartitionsRDDinformação de armazenamento.O nível de armazenamento do RDD é DISK, a partição persistente é 8, e está completamente armazenada no disco.
(3) Exclua o RDD do cache
Execute o seguinte comando, ele será removido rdd(ParallelCollectionRDD)do cache
Atualize a WebUI acima e descubra que resta apenas uma MapPartitionsRDD, que ParallelCollectionRDDfoi removida.
O Spark monitora automaticamente o uso do cache em cada nó e remove os dados de partição antigos do cache da maneira menos usada recentemente. Se você deseja excluir um RDD manualmente, em vez de esperar que o RDD seja excluído automaticamente do cache pelo Spark, você pode usar o unpersist()método RDD.