sparkプログラム最適化の1つ:persistメソッドの使用


シーン
sparkプログラムコードを記述する際、ビッグデータ演算に関わる場合、1回の計算で数十分から1時間以上かかる可能性があり、さらに極端な場合、1つの大きなオブジェクトが複数回使用され、複数回計算が繰り返されることになります.このようなやり方は資源を消費し、私たちの時間を浪費します.では、このような状況に対して、私たちは何か避ける方法がありますか?はい、明らかにあります.それは、この複数回計算されたオブジェクトをキャッシュし、最初にキャッシュした後、次回は使用せずに呼び出すことができ、計算を繰り返す時間を節約することです.もちろん、これは状況によって異なり、計算時間や計算資源の消費が大きい場合には、この状況が合っています.自分のデータ量が小さく、計算が簡単であれば、必要ありません.キャッシュに保存する時間は、計算を繰り返す時間よりも長いからです.今日は、関数persistの方法について説明します.
適用シーン
  • sparkバージョン:1.6以上(バージョン1.6またはバージョン2以上にかかわらず、この関数定義は一致しているが、内部実装に差があるだけ)
  • spark Data Frameによる演算
  • 1オブジェクトは、
  • を複数回計算する.
    関数の説明spark1.6persistメソッドコードを見てみましょう.
    /**
       * Persist this [[DataFrame]] with the default storage level (`MEMORY_AND_DISK`).
       * @group basic
       * @since 1.3.0
       */
      def persist(): this.type = {
        sqlContext.cacheManager.cacheQuery(this)
        this
      }
    
      /**
       * Persist this [[DataFrame]] with the default storage level (`MEMORY_AND_DISK`).
       * @group basic
       * @since 1.3.0
       */
      def cache(): this.type = persist()
    
      /**
       * Persist this [[DataFrame]] with the given storage level.
       * @param newLevel One of: `MEMORY_ONLY`, `MEMORY_AND_DISK`, `MEMORY_ONLY_SER`,
       *                 `MEMORY_AND_DISK_SER`, `DISK_ONLY`, `MEMORY_ONLY_2`,
       *                 `MEMORY_AND_DISK_2`, etc.
       * @group basic
       * @since 1.3.0
       */
      def persist(newLevel: StorageLevel): this.type = {
        sqlContext.cacheManager.cacheQuery(this, None, newLevel)
        this
      }
    

    上のコードから、
  • cacheを呼び出す方法は、実際には、パラメータのないpersistを呼び出すことである.
  • persist()は、実はpersist(StorageLevel.MEMORY_AND_DISK)に相当します.

  • その中で重要なのはStorageLevelオブジェクトです.このオブジェクトは主にキャッシュのレベルを指定します.では、StorageLevelの内部メンバーを見てみましょう.
    class StorageLevel private(
        private var _useDisk: Boolean, //      
        private var _useMemory: Boolean,//      
        private var _useOffHeap: Boolean,//        
        private var _deserialized: Boolean,//      
        private var _replication: Int = 1//    ,   1)
      extends Externalizable 
    

    キャッシュ・ポリシーはいくつありますか?次の表を見てみましょう.
    レベル
    スペースの使用
    CPU時間
    メモリにあるかどうか
    ディスク上にあるかどうか
    コメント
    MEMORY_ONLY
    高い
    低い
    はい
    いいえ
    MEMORY_ONLY_2
    高い
    低い
    はい
    いいえ
    データを2部保存
    MEMORY_ONLY_SER
    低い
    高い
    はい
    いいえ
    データのシーケンシング
    MEMORY_ONLY_SER_2
    低い
    高い
    はい
    いいえ
    データシーケンス化、データ格納2部
    MEMORY_AND_DISK
    高い
    中程度
    ぶぶん
    ぶぶん
    メモリにデータが入らない場合は、ディスクにオーバーフローします.
    MEMORY_AND_DISK_2
    高い
    中程度
    ぶぶん
    ぶぶん
    データを2部保存
    MEMORY_AND_DISK_SER
    低い
    高い
    ぶぶん
    ぶぶん
    MEMORY_AND_DISK_SER_2
    低い
    高い
    ぶぶん
    ぶぶん
    データを2部保存
    DISK_ONLY
    低い
    高い
    いいえ
    はい
    DISK_ONLY_2
    低い
    高い
    いいえ
    はい
    データを2部保存
    NONE
    OFF_HEAP
    まとめ
  • 一般的には、persist(StorageLevel.MEMORY_AND_DISK)関数の代わりにcache()を使用することを推奨し、メモリ不足による出張を避ける.
  • メモリが十分な場合は、レベルMEMORY_ONLYを直接使用できます.直接メモリ操作なので、速度が速いです.
  • スペースが不足している場合は、使用レベルMEMORY_ONLY_SERを考慮することができ、スペースを節約することができますが、シーケンス化操作が1ステップ増えただけです.
  • 第3ステップがまだだめであれば、使用レベルMEMORY_AND_DISKを考慮して、一部のデータをディスクに格納します.
  • 本当に仕方がない限り、DISK_ONLYの使用は推奨されません.ディスクを再読み込みすると、パフォーマンスが急激に低下し、再計算よりも遅くなる可能性があります.
  • レベルの後に_2が続くのは、データバックアップを表すものです.ジョブの高可用性を追求する行でなければ、使用は推奨されません.
  • OFF_HEAPは、 JVM のためです.OFF_の使用HEAPの利点は、メモリが限られている場合、頻繁なGCや不要なメモリ消費を減らすことができ、プログラム性能を向上させることである
  • .