apache-spark - 无法从 spark 中的 sse-kms 加密 s3 对象中检索数据
问题描述
因为我使用的当前 spark 环境是 hadoop2.7 中的 spark 2.4,但是 hadoop2.7 不支持 SSE-KMS。来自 apache: HADOOP-13075,它是在 2.8 中引入的,在 hadoop 3.0 之后完全支持。然后从官方文档中添加
两个配置参数fs.s3a.server-side-encryption-algorithm
& fs.s3a.server-side-encryption.key
" 。
基于以前的文档,我添加了 package org.apache.hadoop:hadoop-aws:3.1.1
& com.amazonaws:aws-java-sdk:1.9.5
inspark-submit
参数,并添加
spark._jsc.hadoopConfiguration().set("fs.s3a.server-side-encryption-algorithm", aws_sse_algorithm)`
spark._jsc.hadoopConfiguration().set("fs.s3a.server-side-encryption.key", aws_sse_key)
to spark config
,aws_sse_algorithm
是SSE-KMS
&sse_key
由我们的管理员提供的。
与此同时,我基本上将所有我可以添加到配置中的参数。但是,我得到了这个异常:
Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4.
当我在 spark 中检索 s3 对象时:
df = spark.read.json('s3a://XXXXXXX/XXXXX/XXXXXXXX/result.json')
2019-08-09 14:54:09,525 ERROR executor.Executor: Exception in task 0.0 in stage 4.0 (TID 4)
**com.amazonaws.services.s3.model.AmazonS3Exception: Status Code: 400, AWS Service: Amazon S3, AWS Request ID: 7C1C371AE02F476A, AWS Error Code: InvalidArgument,
AWS Error Message: Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4.**, S3 Extended Request ID: hlCH96//G18Bs47fGJwxt+Ccpdf0YNOadt9bUPYei2InkkUeKCslq/4m353RnQEhopBfvjVIcx0=
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:798)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:421)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:232)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3528)
at com.amazonaws.services.s3.AmazonS3Client.getObject(AmazonS3Client.java:1111)
.......
我的完整代码:
import datetime, time
from pyspark.sql import SparkSession
from pyspark.sql import functions as func
from pyspark.sql.functions import udf
from pyspark.sql.types import StringType, IntegerType, DoubleType, ArrayType, StructType, StructField, MapType
import boto3
import json
import pytz
import configparser
import argparse
from dateutil.parser import parse
import os
os.environ['PYSPARK_SUBMIT_ARGS'] = "--packages=org.apache.hadoop:hadoop-aws:3.1.1,org.apache.hadoop:hadoop-common:3.1.1,org.apache.hadoop:hadoop-auth:3.1.1," \ ... "com.amazonaws:aws-java-sdk:1.9.5 " \ ... "pyspark-shell"
spark = SparkSession.builder.appName("test").getOrCreate() aws_sse_algorithm = 'SSE-KMS'
aws_sse_key = 'arn:aws:kms:ap-southeast-1:XXXXXXX:key/XXXXXX'
aws_access_id = 'XXXXX'
aws_access_key = 'XXXXX'
aws_region = 'ap-southeast-1'
spark._jsc.hadoopConfiguration().set("fs.s3a.access.key", aws_access_id) spark._jsc.hadoopConfiguration().set("fs.s3a.secret.key", aws_access_key) spark._jsc.hadoopConfiguration().set("fs.s3a.fast.upload", "true") spark._jsc.hadoopConfiguration().set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem") spark._jsc.hadoopConfiguration().set("com.amazonaws.services.s3.enableV4", "true") spark._jsc.hadoopConfiguration().set("fs.s3a.aws.credentials.provider","org.apache.hadoop.fs.s3a.BasicAWSCredentialsProvider") spark._jsc.hadoopConfiguration().set("fs.s3a.endpoint", "s3."+aws_region+".amazonaws.com")
spark._jsc.hadoopConfiguration().set("fs.s3a.sse.enabled", "true") spark._jsc.hadoopConfiguration().set("fs.s3a.enableServerSideEncryption", "true")
spark._jsc.hadoopConfiguration().set("fs.s3a.server-side-encryption-algorithm", aws_sse_algorithm) spark._jsc.hadoopConfiguration().set("fs.s3a.server-side-encryption.key", aws_sse_key) spark._jsc.hadoopConfiguration().set("fs.s3a.sse.kms.keyId", aws_sse_key)
df = spark.read.json('s3a://XXXXXXX/XXXXX/XXXXXXXX/result.json')
我不确定它是否与本地 spark_classpath 中的 hadoop jars 仍然低于 2.7.3 版本有关。但是我将 3.1.1 jar 添加到 spark 的 --packages 部分。
解决方案
如果您必须为 v4 签名设置 jvm 选项才能工作,那么您仍在使用 hadoop-2.7 s3a 实现。
- 所有 hadoop-* JAR 必须是完全相同的版本,否则您将看到堆栈跟踪
- aws-sdk 版本必须与构建和测试 hadoop-aws 的版本完全相同,否则您将看到不同的堆栈跟踪。
遗憾的是,在你拥有一组一致的 JAR 之前,你注定要失败。您最终只会浪费时间移动堆栈跟踪。首先正确获取这些依赖项。
这意味着:升级到 Hadoop 2.8+ 工件。完全
推荐阅读
- sql - How to divide string by comma into new columns?
- excel - 尝试将表格的多个部分复制并粘贴到新的 word 文档中,不断在第一个单元格中粘贴新表格
- android - 毕加索中的get()不能应用于(android.content.context)
- xcode - React Native:“:CFBundleIdentifier”,不存在
- javascript - 鼠标悬停时停止 jquery 函数淡入淡出
- excel - Visio Web 部件数据连接格式问题格式值需要 2 亿美元与 200000000 美元
- php - 有没有一种方法可以更改新用户在 Wordpress 中通过电子邮件收到的密码?
- r - 如何使用具有多列的 dplyr 在行组之间进行划分?
- javascript - 如何通过 forEach 循环将 Map() 项目渲染到 React jsx 中?
- reactjs - 使用 React + Electron 创建新窗口