博客地址: http://blog.csdn.net/yueqian_zhu/


    spark缓存清理机制:

    MetadataCleaner对象中有一个定时器,用于清理下列的元数据信息:

      
       
       
      
      
       
        
         
          MAP_OUTPUT_TRACKER:Maptask的输出元信息
         
        
       
      
       
        
         
          SPARK_CONTEXT:
         
         
          persistentRdds中的rdd
         
        
       
      
       
        
         
          HTTP_BROADCAST
         
         , http广播的元数据
        
       
      

      
       
        
         BLOCK_MANAGER:
        
        blockmanager中存储的数据
       
      
     
      
       
        
         
          SHUFFLE_BLOCK_MANAGER:
         
         shuffle的输出数据
        
       
      
       
        
         
          BROADCAST_VARS:
          
           Torrent方式广播broadcast的元数据
          
         
        
       
      

      
       
        contextcleaner清理真实数据:
       
      
     
      
       
        
         ContextCleaner为RDD、shuffle、broadcast、
        
        
         
          accumulator、
         
        
        
         Checkpoint
        
        
         维持了一个弱引用,当相关对象不可达时,就会将对象插入
        
        
         referenceQueue中。有一个单独的线程来处理这个队列中的对象。
        
       
      
     
      
       
        
         RDD:最终从各节点的blockmanager的
        
        
         memoryStore、
        
        
         diskStore中删除RDD数据
        
       
      
     
      
       
        shuffle:删除driver中的mapstatuses关于该shuffleId的信息;删除所有节点中关于该shuffleId的所有分区的数据文件和索引文件
       
      
     
      
       
       
      
      
       
        
         broadcast:
        
       
       
        
         最终从各节点的blockmanager的memoryStore、diskStore中删除
        
        
         broadcast
         
          
           数据
          
       
        
         
         
        
        
         
          
           Checkpoint:清理checkpointDir目录下关于该rddId的文件
          
          
           举个RDD的例子,说明一下这样做有什么好处?
          
           默认情况下,RDD是不缓存的,即计算完之后,下一次用需要重新计算。如果要避免重新计算的开销,就要将RDD缓存起来,这个道理谁都明白。但是,缓存的RDD什么时候去释放呢?这就用到了上面提到的弱引用。当我们调用
           
            
             
              persist缓存一个RDD时,会调用
             
            
             
              registerRDDForCleanup
             
            
             
              (this),这就是将本身的RDD注册到一个弱引用中。当这个RDD变为不可达时,会自动将该RDD对象插入到
             
            
             
              
               referenceQueue中,等到下次GC时就会走
              
             
              
               doCleanupRDD分支。RDD可能保存在内存或者磁盘中,
              
             
              
               这样就能保证,不可达的RDD在GC到来时可以释放blockmanager中的RDD真实数据。
              
           
            
             
              再考虑一下,什么时候RDD不可达了呢?为了让出内存供其他地方使用,除了手动unpersist之外,需要有机制定时清理缓存的RDD数据,这就是MetadataCleaner的
             
            
             
              
               SPARK_CONTEXT干的事情。它就是定期的清理
              
             
            
             
              
              
              
               persistentRdds中过期的数据,其实与unpersist产生的作用是一样的。一旦清理了,那这个缓存的RDD就没有强引用了。