全部產品
Search
文件中心

AnalyticDB:Apache Spark全密態計算引擎高效能版使用樣本

更新時間:Jan 15, 2026

AnalyticDB for MySQLApache Spark全密態計算引擎高效能版,在Apache Spark全密態引擎基礎版能力的基礎上,支援Parquet模組化加密功能,且相容社區版Spark、Hadoop、Hive等計算引擎,在保證資料轉送與預存程序安全的同時,提升了資料處理效率。本文介紹如何通過Apache Spark全密態計算引擎高效能版加密資料,並基於密文表執行SQL計算。

前提條件

資料準備

待加密的資料檔案格式必須為Parquet,您可以直接下載Spark全密態樣本資料,完成後續操作。

操作步驟

AnalyticDB for MySQL支援通過控制台和加密工具兩種方式加密明文資料。若您的資料存放區在本地,可以通過加密工具加密資料;若儲存在雲資料庫中,可以通過控制台加密資料。兩種加密方式用法的區別如下:

  • 通過控制台加密資料:上傳明文資料至OSS,再加密。

  • 通過加密工具加密資料:在本地加密資料,上傳密文至OSS。

通過控制台加密資料並建立密文表

  1. 資料準備章節中的明文資料上傳至OSS儲存空間。本文樣本為oss://testBucketName/adb/Spark/customer。具體操作,請參見簡單上傳

  2. 登入雲原生資料倉儲AnalyticDB MySQL控制台,在左上方選擇叢集所在地區。在左側導覽列,單擊集群清單,然後單擊目的地組群ID。

  3. 在左側導覽列,單擊作業開發 > SQL開發

  4. SQLConsole視窗,選擇Spark引擎和Job型資源群組。

  5. 執行以下語句,建立密文表。

    1. 開啟密態計算,設定使用者的主要金鑰,並建立資料庫。

      -- 開啟native計算
      SET spark.adb.native.enabled=true;
      -- 配置資源
      SET spark.driver.resourceSpec=medium;
      SET spark.executor.instances=2;
      SET spark.executor.resourceSpec=medium;
      SET spark.app.name=Spark SQL Encryption Test;
      -- 開啟密文讀寫支援並設定主要金鑰列表,KMS Client 以及 CryptoFactory(開啟後引擎可同時支援明文和密文)
      SET spark.hadoop.parquet.encryption.key.list=kf:MDEyMzQ1Njc4OTAxMjM0****,kc1:bvCDwqcOJGSdZSEMLjfk****,kc2:kflI/sq+uf50Qhl1MmtG****;
      SET spark.hadoop.parquet.encryption.kms.client.class=io.glutenproject.encryption.InMemoryKMS;
      SET spark.hadoop.parquet.crypto.factory.class=org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory;
      --建立資料庫
      CREATE database IF NOT EXISTS adb_external_db;

      參數說明:

      參數

      說明

      spark.hadoop.parquet.encryption.key.list

      使用者主要金鑰列表。一個主要金鑰對應一個密鑰ID,多個主要金鑰之間用半形逗號(,)分隔,每個主要金鑰ID與主要金鑰之間用半形冒號(:)分隔。格式為:<主要金鑰ID1>:<Base64編碼的主要金鑰1>,<主要金鑰ID2>:<Base 64 編碼的主要金鑰2>。詳情請參見密鑰介紹

      本文樣本為kf:MDEyMzQ1Njc4OTAxMjdy****,kc1:bvCDwqcOJGSdZSEMLjfk****,kc2:kflI/sq+uf50Qhl1MmtG****

      警告

      您可以使用通用工具(例如:OpenSSL)隨機產生使用者主要金鑰。使用者主要金鑰是訪問加密資料的根憑據,一旦丟失密鑰,將無法再訪問已有的資料,請妥善保管使用者主要金鑰。

      spark.hadoop.parquet.encryption.kms.client.class

      KMS用戶端類名。固定填寫為io.glutenproject.encryption.InMemoryKMS

      spark.hadoop.parquet.crypto.factory.class

      CryptoFactory類名。固定填寫為org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory

    2. 建立外表customer,用於儲存明文資料。LOCATION為明文資料所在的OSS路徑。本文樣本為oss://testBucketName/adb/Spark/customer

      SET spark.adb.native.enabled=true;
      SET spark.hadoop.parquet.encryption.key.list=kf:MDEyMzQ1Njc4OTAxMjM0****,kc1:bvCDwqcOJGSdZSEMLjfk****,kc2:kflI/sq+uf50Qhl1MmtG****;
      SET spark.hadoop.parquet.encryption.kms.client.class=io.glutenproject.encryption.InMemoryKMS;
      SET spark.hadoop.parquet.crypto.factory.class=org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory;
      CREATE TABLE IF NOT EXISTS adb_external_db.customer 
       (
          c_custkey long,
          c_name       string,
          c_address    string,
          c_nationkey long,
          c_phone      string,
          c_acctbal    decimal(12, 2),
          c_mktsegment string,
          c_comment    string
      )
      USING parquet 
      LOCATION 'oss://testBucketName/adb/Spark/customer';
      說明
      • adb_external_db資料庫中已有明文表,可跳過該步驟。

      • 若資料存放區在其他雲資料庫中,需建立對應的外表。建立外表的文法請參見CREATE EXTERNAL TABLE

    3. 建立外表enc_customer,用於儲存密文資料。本文樣本將enc_customer外表的資料指定儲存在oss://testBucketName/adb/Spark/enc_customer

      SET spark.adb.native.enabled=true;
      SET spark.hadoop.parquet.encryption.key.list=kf:MDEyMzQ1Njc4OTAxMjM0****,kc1:bvCDwqcOJGSdZSEMLjfk****,kc2:kflI/sq+uf50Qhl1MmtG****;
      SET spark.hadoop.parquet.encryption.kms.client.class=io.glutenproject.encryption.InMemoryKMS;
      SET spark.hadoop.parquet.crypto.factory.class=org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory;
      CREATE TABLE IF NOT EXISTS adb_external_db.enc_customer
      USING Parquet
      OPTIONS (
       'parquet.encryption.column.keys'='kc1:c_name;kc2:c_phone',
       'parquet.encryption.footer.key'='kf'
      )
      LOCATION 'oss://testBucketName/adb/Spark/enc_customer'
      AS
      SELECT *
      FROM adb_external_db.customer;

      參數說明:

      參數

      是否必填

      說明

      parquet.encryption.column.keys

      使用密鑰ID所對應的主要金鑰加密列。一個主要金鑰可加密多個列,主要金鑰ID和列名之間用半形冒號(:)分隔,加密列之間用半形逗號(,)分隔,不同主要金鑰之間用半形分號(;)分隔。

      parquet.encryption.footer.key

      Footer密鑰,用來加密Parquet檔案的中繼資料等資訊。

      說明

      Footer是位於Parquet檔案尾部的資料結構,一般用來隱藏檔的中繼資料資訊,例如:版本號碼、分組元資訊、列的元資訊以及密鑰元資訊等。

      重要

      parquet.encryption.column.keysparquet.encryption.footer.key參數必須同時設定,否則檔案不會被加密。

    4. (可選)刪除外表customer

      DROP TABLE IF EXISTS adb_external_db.customer;
      重要

      DROP TABLE語句會刪除customer外表,對應OSS中的中繼資料請手動刪除,避免明文資料泄露。

  6. 建立外表enc_customer_output,將enc_customer表的SQL計算結果寫入enc_customer_output外表。enc_customer_output外表的資料指定儲存在oss://testBucketName/adb/Spark/enc_customer_output

    SET spark.adb.native.enabled=true;
    SET spark.hadoop.parquet.encryption.key.list=kf:MDEyMzQ1Njc4OTAxMjM0****,kc1:bvCDwqcOJGSdZSEMLjfk****,kc2:kflI/sq+uf50Qhl1MmtG****;
    SET spark.hadoop.parquet.encryption.kms.client.class=io.glutenproject.encryption.InMemoryKMS;
    SET spark.hadoop.parquet.crypto.factory.class=org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory;
    CREATE TABLE IF NOT EXISTS adb_external_db.enc_customer_output
    USING Parquet
    OPTIONS (
     'parquet.encryption.column.keys'='kc1:c_name;kc2:c_phone',
     'parquet.encryption.footer.key'='kf'
    )
    LOCATION 'oss://testBucketName/adb/Spark/enc_customer_output'
    AS
    SELECT *
    FROM adb_external_db.enc_customer
    WHERE 
    c_custkey < 15;
  7. 解密計算結果。

    1. 建立外表customer_output,將enc_customer_output表的資料解密後寫入customer_output外表。customer_output外表的資料指定儲存在oss://testBucketName/adb/Spark/customer_output

      SET spark.adb.native.enabled=true;
      SET spark.hadoop.parquet.encryption.key.list=kf:MDEyMzQ1Njc4OTAxMjM0****,kc1:bvCDwqcOJGSdZSEMLjfk****,kc2:kflI/sq+uf50Qhl1MmtG****;
      SET spark.hadoop.parquet.encryption.kms.client.class=io.glutenproject.encryption.InMemoryKMS;
      SET spark.hadoop.parquet.crypto.factory.class=org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory;
      CREATE TABLE IF NOT EXISTS adb_external_db.customer_output
      USING Parquet
      LOCATION 'oss://testBucketName/adb/Spark/customer_output'
      AS
      SELECT *
      FROM adb_external_db.enc_customer_output;
    2. 查詢customer_output表資料。

      SELECT * FROM adb_external_db.customer_output;

通過加密工具加密資料並建立密文表

  1. 通過加密工具將儲存在本地的明文資料加密成密文資料集,加密工具的更多資訊,請參見Spark加密工具

    import org.apache.spark.sql.SparkSession
    import org.apache.spark.sql.functions._
    import org.apache.spark.SparkConf
    
    // 初始化SparkSession,並輸入加解密相關的參數。
    val conf = new SparkConf()
    .set("spark.hadoop.parquet.encryption.kms.client.class", "org.apache.parquet.crypto.keytools.mocks.InMemoryKMS")
    .set("spark.hadoop.parquet.encryption.key.list", "kf:MDEyMzQ1Njc4OTAxMjM0****,kc1:bvCDwqcOJGSdZSEMLjfk****,kc2:kflI/sq+uf50Qhl1MmtG****")
    .set("spark.hadoop.parquet.crypto.factory.class", "org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory")
    
    val spark = SparkSession.builder().appName("SquareDataFrame").config(conf).getOrCreate()
    
    // 讀取明文customer。
    val df = spark.read.parquet("customer")
    // 對明文customer加密,其中name列使用kc1加密,footer使用kf加密,加密後的密文檔案為enc_customer。
    df.write
    .option("parquet.encryption.column.keys" , "kc1:c_name")
    .option("parquet.encryption.footer.key" , "kf")
    // 密文資料集所在的本地路徑。
    .parquet("enc_customer")

    參數說明:

    參數

    是否必填

    說明

    spark.hadoop.parquet.encryption.kms.client.class

    KMS用戶端類名。

    • 本地加密時需填寫為org.apache.parquet.crypto.keytools.mocks.InMemoryKMS

    • 控制台建立密文表時需填寫為io.glutenproject.encryption.InMemoryKMS

    spark.hadoop.parquet.encryption.key.list

    使用者主要金鑰列表。一個主要金鑰對應一個密鑰ID,多個主要金鑰之間用半形逗號(,)分隔,每個主要金鑰ID與主要金鑰之間用半形冒號(:)分隔。格式為:<主要金鑰ID1>:<Base64編碼的主要金鑰1>,<主要金鑰ID2>:<Base 64 編碼的主要金鑰2>。詳情請參見密鑰介紹

    本文樣本為kf:MDEyMzQ1Njc4OTAxMjdy****,kc1:bvCDwqcOJGSdZSEMLjfk****,kc2:kflI/sq+uf50Qhl1MmtG****

    警告

    您可以使用通用工具(例如:OpenSSL)隨機產生使用者主要金鑰。使用者主要金鑰是訪問加密資料的根憑據,一旦丟失密鑰,將無法再訪問已有的資料,請妥善保管使用者主要金鑰。

    spark.hadoop.parquet.crypto.factory.class

    CryptoFactory類名。固定填寫為org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory

    parquet.encryption.column.keys

    使用密鑰ID所對應的主要金鑰加密列。一個主要金鑰可加密多個列,主要金鑰ID和列名之間用半形冒號(:)分隔,加密列之間用半形逗號(,)分隔,不同主要金鑰之間用半形分號(;)分隔。

    parquet.encryption.footer.key

    Footer密鑰,用來加密Parquet檔案的中繼資料等資訊。

    說明

    Footer是位於Parquet檔案尾部的資料結構,一般用來隱藏檔的中繼資料資訊,例如:版本號碼、分組元資訊、列的元資訊以及密鑰元資訊等。

  2. 將密文資料集enc_customer.parquet上傳至OSS。本文樣本為oss://testBucketName/adb/Spark/enc_customer.parquet。具體操作,請參見簡單上傳

  3. 建立密文表。

    1. 登入雲原生資料倉儲AnalyticDB MySQL控制台,在左上方選擇叢集所在地區。在左側導覽列,單擊集群清單,然後單擊目的地組群ID。

    2. 在左側導覽列,單擊作業開發 > SQL開發

    3. SQLConsole視窗,選擇Spark引擎和Job型資源群組。

    4. 執行以下語句,建立密文表。

      1. 開啟native計算,並建立資料庫。

        -- 開啟native計算
        SET spark.adb.native.enabled=true;
        -- 配置資源
        SET spark.driver.resourceSpec=medium;
        SET spark.executor.instances=2;
        SET spark.executor.resourceSpec=medium;
        -- 開啟密文讀寫支援並設定主要金鑰列表,KMS Client 以及 CryptoFactory(開啟後引擎可同時支援明文和密文)
        SET spark.hadoop.parquet.encryption.key.list=kf:MDEyMzQ1Njc4OTAxMjM0****,kc1:bvCDwqcOJGSdZSEMLjfk****,kc2:kflI/sq+uf50Qhl1MmtG****;
        SET spark.hadoop.parquet.encryption.kms.client.class=io.glutenproject.encryption.InMemoryKMS;
        SET spark.hadoop.parquet.crypto.factory.class=org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory;
        -- 建立資料庫
        CREATE DATABASE IF NOT EXISTS adb_external_db;
      2. 建立外表enc_customerLOCATION為密文資料集enc_customer所在的OSS路徑。本文樣本為oss://testBucketName/adb/Spark/enc_customer.parquet

        SET spark.adb.native.enabled=true;
        SET spark.hadoop.parquet.encryption.key.list=kf:MDEyMzQ1Njc4OTAxMjM0****,kc1:bvCDwqcOJGSdZSEMLjfk****,kc2:kflI/sq+uf50Qhl1MmtG****;
        SET spark.hadoop.parquet.encryption.kms.client.class=io.glutenproject.encryption.InMemoryKMS;
        SET spark.hadoop.parquet.crypto.factory.class=org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory;
        CREATE TABLE IF NOT EXISTS adb_external_db.enc_customer 
        USING parquet
        LOCATION  'oss://testBucketName/adb/Spark/enc_customer';
  4. 建立外表enc_customer_output,將enc_customer表的SQL計算結果寫入enc_customer_output外表。enc_customer_output外表的資料指定儲存在oss://testBucketName/adb/Spark/enc_customer_output

    SET spark.adb.native.enabled=true;
    SET spark.hadoop.parquet.encryption.key.list=kf:MDEyMzQ1Njc4OTAxMjM0****,kc1:bvCDwqcOJGSdZSEMLjfk****,kc2:kflI/sq+uf50Qhl1MmtG****;
    SET spark.hadoop.parquet.encryption.kms.client.class=io.glutenproject.encryption.InMemoryKMS;
    SET spark.hadoop.parquet.crypto.factory.class=org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory;
    CREATE TABLE IF NOT EXISTS adb_external_db.enc_customer_output
    USING Parquet
    OPTIONS (
     'parquet.encryption.column.keys'='kc1:c_name;kc2:c_phone',
     'parquet.encryption.footer.key'='kf'
    )
    LOCATION 'oss://testBucketName/adb/Spark/enc_customer_output'
    AS
    SELECT *
    FROM adb_external_db.enc_customer
    WHERE 
    c_custkey < 15;
  5. 下載密文結果並解密。

    1. 從OSS路徑oss://testBucketName/adb/Spark/enc_customer_output下載密文計算結果到本地。具體操作,請參見下載檔案

    2. 解密計算結果密文資料集,並將解密後的檔案儲存在customer_output中。

      // 解密密文資料集
      val conf = new SparkConf()
      .set("spark.hadoop.parquet.encryption.kms.client.class", "org.apache.parquet.crypto.keytools.mocks.InMemoryKMS")
      .set("spark.hadoop.parquet.encryption.key.list", "kf:MDEyMzQ1Njc4OTAxMjM0****,kc1:bvCDwqcOJGSdZSEMLjfk****,kc2:kflI/sq+uf50Qhl1MmtG****")
      .set("spark.hadoop.parquet.crypto.factory.class", "org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory")
      val spark = SparkSession.builder().appName("SquareDataFrame").config(conf).getOrCreate()
      val df2 = spark.read.parquet("enc_customer_output")
      // 將解密後的檔案下載至本地
      df2.write
      .parquet("customer_output")