Spark SQL의 데이터 스키핑

데이터 스키핑은 각 데이터 오브젝트와 연관되는 요약 메타데이터를 기반으로 상관없는 데이터 오브젝트 또는 파일을 건너뜀으로써 SQL 조회의 성능을 현저히 향상시킬 수있습니다.

데이터 스키핑은 Apache Spark에서 데이터 스키핑 인덱스를 작성, 관리, 배치하기 위한 오픈 소스 Xskipper 라이브러리를 사용합니다. Xskipper-확장 가능한 데이터 건너뛰기 프레임워크를 참조하십시오.

Xskipper 작업 방법에 대한 자세한 정보는 다음을 참조하십시오.

Xskipper에서 오픈 소스 기능 외에도, 다음 기능도 사용할 수 있습니다.

지리공간 데이터 건너뛰기

또한 Spatio-Temporal 라이브러리에서 지리 공간 함수 를 사용하여 지리 공간 데이터 세트를 쿼리할 때 데이터 건너뛰기를 사용할 수 있습니다.

  • 경도 및 위도 열이 있는 데이터 세트에서 데이터 스키핑의 해택을 얻기 위해 위도 및 경도 열에서 최소/최대 인덱스를 수집할 수 있습니다.
  • 내장 Xskipper 플러그인을 사용하여 Geometry 컬럼 (UDT 컬럼) 이 있는 데이터 세트에서 데이터 건너뛰기를 사용할 수 있습니다.

다음 섹션에서는 지리공간 플러그인에 대한 작업을 수행하는 방법을 보여줍니다.

지리공간 플러그인 설정

플러그인을 사용하려면 등록 모듈을 사용하여 관련 구현을 로드하십시오.

  • Scala의 경우:

    import com.ibm.xskipper.stmetaindex.filter.STMetaDataFilterFactory
    import com.ibm.xskipper.stmetaindex.index.STIndexFactory
    import com.ibm.xskipper.stmetaindex.translation.parquet.{STParquetMetaDataTranslator, STParquetMetadatastoreClauseTranslator}
    import io.xskipper._
    
    Registration.addIndexFactory(STIndexFactory)
    Registration.addMetadataFilterFactory(STMetaDataFilterFactory)
    Registration.addClauseTranslator(STParquetMetadatastoreClauseTranslator)
    Registration.addMetaDataTranslator(STParquetMetaDataTranslator)
    
  • Python의 경우:

    from xskipper import Xskipper
    from xskipper import Registration
    
    Registration.addMetadataFilterFactory(spark, 'com.ibm.xskipper.stmetaindex.filter.STMetaDataFilterFactory')
    Registration.addIndexFactory(spark, 'com.ibm.xskipper.stmetaindex.index.STIndexFactory')
    Registration.addMetaDataTranslator(spark, 'com.ibm.xskipper.stmetaindex.translation.parquet.STParquetMetaDataTranslator')
    Registration.addClauseTranslator(spark, 'com.ibm.xskipper.stmetaindex.translation.parquet.STParquetMetadatastoreClauseTranslator')
    

인덱스 빌드

인덱스를 빌드하기 위해 addCustomIndex API를 사용할 수 있습니다.

  • Scala의 경우:

    import com.ibm.xskipper.stmetaindex.implicits._
    
    // index the dataset
    val xskipper = new Xskipper(spark, dataset_path)
    
    xskipper
      .indexBuilder()
      // using the implicit method defined in the plugin implicits
      .addSTBoundingBoxLocationIndex("location")
      // equivalent
      //.addCustomIndex(STBoundingBoxLocationIndex("location"))
      .build(reader).show(false)
    
  • Python의 경우:

    xskipper = Xskipper(spark, dataset_path)
    
    # adding the index using the custom index API
    xskipper.indexBuilder() \
            .addCustomIndex("com.ibm.xskipper.stmetaindex.index.STBoundingBoxLocationIndex", ['location'], dict()) \
            .build(reader) \
            .show(10, False)
    

지원되는 기능

지원되는 지리공간 함수의 목록에는 다음이 포함됩니다.

  • ST_Distance
  • ST_Intersects
  • ST_Contains
  • ST_Equals
  • ST_Crosses
  • ST_Touches
  • ST_Within
  • ST_Overlaps
  • ST_EnvelopesIntersect
  • ST_IntersectsInterior

인덱스 암호화

Parquet 메타데이터 저장소를 사용하는 경우 선택적으로 PME(Parquet Modular Encryption)를 사용하여 메타데이터를 암호화할 수 있습니다. 메타데이터 자체를 Parquet 데이터 세트로 저장하면 됩니다. 그러면 PME를 사용하여 암호화할 수 있습니다. 이 기능은 모든 입력 형식(예: PME를 사용하여 메타데이터를 암호화할 수 있는, CSV 형식으로 저장된 데이터 세트)에 적용됩니다.

다음 섹션에서는 별도로 언급하지 않는 한, 바닥글, 열 등을 참조할 때 인덱싱된 데이터 세트의 오브젝트가 아니라 메타데이터 오브젝트와 관련됩니다.

인덱스 암호화는 다음과 같은 방식에서 모듈식으로 세부화되어 있습니다.

  • 각 인덱스는 암호화(인덱스당 키 세분화 사용)되거나 평문으로 남아 있을 수 있음
  • 바닥글 + 오브젝트 이름 열:
    • 자체적으로 Parquet 파일인 메타데이터 오브젝트의 바닥글 열은 특히 다음을 포함합니다.
      • 수집된 모든 인덱스에 대한 유형, 매개변수, 열 이름을 표시하는 메타데이터 오브젝트의 스키마. 예를 들어, BloomFilter이(가) 0.1의 긍정 오류 확률로 city 열에 정의되어 있음을 알 수 있습니다.
      • 원래 데이터 세트에 대한 전체 경로 또는 Hive 메타저장소 테이블의 경우 테이블 이름
    • 오브젝트 이름 열은 인덱싱된 모든 오브젝트 이름을 저장합니다.
  • 바닥글 + 메타데이터 열은 다음과 같을 수 있습니다.
    • 둘 다 동일한 키를 사용하여 암호화됩니다. 이는 기본값입니다. 이 경우 메타데이터를 구성하는 Parquet 오브젝트의 평문 바닥글 구성은 암호화된 바닥글 모드로 암호화되며 오브젝트 이름 열은 선택한 키를 사용하여 암호화됩니다.

    • 둘 다 일반 텍스트입니다. 이 경우 메타데이터를 구성하는 Parquet 오브젝트는 평문 바닥글 모드이고, 오브젝트 이름 열은 암호화되지 않습니다.

      하나 이상의 인덱스가 암호화됨으로 표시되는 경우 평문 바닥글 모드의 사용 여부에 상관없이 바닥글 키를 구성해야 합니다. 평문 바닥글이 설정된 경우 변조 방지를 위해서만 바닥글 키가 사용됩니다. 이 경우 오브젝트 이름 열에는 변조 방지 기능이 적용되지 않습니다.

      바닥글 키가 구성된 경우 하나 이상의 인덱스를 암호화해야 합니다.

인덱스 암호화를 사용하기 전에 PME에서 문서를 확인하고 개념을 잘 알고 있는지 확인해야 합니다.

인덱스 암호화를 사용하는 경우, 임의의 Xskipper API에서 key이(가) 구성될 때마다 항상 NEVER the key itself 레이블이 있습니다.

인덱스 암호화를 사용하려면 다음을 수행하십시오.

  1. 모든 단계를 수행하여 PME를 사용하도록 하십시오. PME 를 참조하십시오.

  2. 키 관리 구성을 포함하여 모든 정기적 PME 구성을 수행하십시오.

  3. 데이터 세트에 대한 암호화된 메타데이터를 작성하십시오.

    1. 메타데이터 작성 시 일반 플로우를 따르십시오.
    2. 푸터 키를 구성하십시오. 일반 텍스트 푸터 +오브젝트 이름 열을 설정하려면 io.xskipper.parquet.encryption.plaintext.footer을(를) true(으)로 설정하십시오(아래 샘플 참조).
    3. IndexBuilder에서 암호화할 각 인덱스에 대해 해당 인덱스에 사용할 키의 레이블을 추가하십시오.

    조회 시간 동안 메타데이터를 사용하거나 기존 메타데이터를 새로 고치려는 경우, 키가 액세스 가능한지 확인하는 데 필요한 정기적 PME 설정 이외에 다른 설정은 필요하지 않습니다(문자 그대로 암호화된 데이터 세트를 읽는 데 필요한 동일한 구성).

샘플

다음 샘플은 k1 키를 푸터 + 오브젝트 이름 키로 사용하고 k2 키를 temp에 대한 MinMax을(를) 암호화하기 위한 키로 사용하여 메타데이터를 작성하는 한편 일반 텍스트로 남아 있는 city에 대한 ValueList을(를) 작성하는 내용을 보여줍니다.

  • Scala의 경우:

    // index the dataset
    val xskipper = new Xskipper(spark, dataset_path)
    // Configuring the JVM wide parameters
    val jvmComf = Map(
      "io.xskipper.parquet.mdlocation" -> md_base_location,
      "io.xskipper.parquet.mdlocation.type" -> "EXPLICIT_BASE_PATH_LOCATION")
    Xskipper.setConf(jvmConf)
    // set the footer key
    val conf = Map(
      "io.xskipper.parquet.encryption.footer.key" -> "k1")
    xskipper.setConf(conf)
    xskipper
      .indexBuilder()
      // Add an encrypted MinMax index for temp
      .addMinMaxIndex("temp", "k2")
      // Add a plaintext ValueList index for city
      .addValueListIndex("city")
      .build(reader).show(false)
    
  • Python의 경우

    xskipper = Xskipper(spark, dataset_path)
    # Add JVM Wide configuration
    jvmConf = dict([
    ("io.xskipper.parquet.mdlocation", md_base_location),
    ("io.xskipper.parquet.mdlocation.type", "EXPLICIT_BASE_PATH_LOCATION")])
    Xskipper.setConf(spark, jvmConf)
    # configure footer key
    conf = dict([("io.xskipper.parquet.encryption.footer.key", "k1")])
    xskipper.setConf(conf)
    # adding the indexes
    xskipper.indexBuilder() \
            .addMinMaxIndex("temp", "k1") \
            .addValueListIndex("city") \
            .build(reader) \
            .show(10, False)
    

위에 언급한 대로 바닥글 + 오브젝트 이름을 평문 모드로 두려면 구성 매개변수를 추가해야 합니다.

  • Scala의 경우:

    // index the dataset
    val xskipper = new Xskipper(spark, dataset_path)
    // Configuring the JVM wide parameters
    val jvmComf = Map(
      "io.xskipper.parquet.mdlocation" -> md_base_location,
      "io.xskipper.parquet.mdlocation.type" -> "EXPLICIT_BASE_PATH_LOCATION")
    Xskipper.setConf(jvmConf)
    // set the footer key
    val conf = Map(
      "io.xskipper.parquet.encryption.footer.key" -> "k1",
      "io.xskipper.parquet.encryption.plaintext.footer" -> "true")
    xskipper.setConf(conf)
    xskipper
      .indexBuilder()
      // Add an encrypted MinMax index for temp
      .addMinMaxIndex("temp", "k2")
      // Add a plaintext ValueList index for city
      .addValueListIndex("city")
      .build(reader).show(false)
    
  • Python의 경우

    xskipper = Xskipper(spark, dataset_path)
    # Add JVM Wide configuration
    jvmConf = dict([
    ("io.xskipper.parquet.mdlocation", md_base_location),
    ("io.xskipper.parquet.mdlocation.type", "EXPLICIT_BASE_PATH_LOCATION")])
    Xskipper.setConf(spark, jvmConf)
    # configure footer key
    conf = dict([("io.xskipper.parquet.encryption.footer.key", "k1"),
    ("io.xskipper.parquet.encryption.plaintext.footer", "true")])
    xskipper.setConf(conf)
    # adding the indexes
    xskipper.indexBuilder() \
            .addMinMaxIndex("temp", "k1") \
            .addValueListIndex("city") \
            .build(reader) \
            .show(10, False)
    

이전 메타데이터에 대한 지원

Xskipper는 MetaIndexManager에서 작성한 이전 메타데이터를 원활하게 지원합니다. 다음 새로 고치기 오퍼레이션에 의해 Xskipper 메타데이터에 대한 업데이트가 자동으로 수행되므로 이전 메타데이터를 스키핑에 사용할 수 있습니다.

인덱스를 나열하거나 describeIndex 조작을 실행할 때 인덱스 앞에 DEPRECATED_SUPPORTED이(가) 표시되면 메타데이터 버전은 더 이상 사용되지 않지만 여전히 지원되며 건너뛰기가 작동됩니다. 다음 새로 고치기 오퍼레이션은 메타데이터를 자동으로 업데이트합니다.