1. java.sql.SQLException: No suitable driver
这个错误是因为,连接Redshift时需要一个driver,而程序执行时找不到能用的driver,所以报错。AWS提供了多个版本连接Redshift的driver,点击查看。
2. java.lang.NoClassDefFoundError: com/amazonaws/services/kinesis/model/Record
经过几次尝试发现,直接使用AWS提供的驱动可以连上Redshift,打印出表结构,但是不能加载数据,一加载数据会报这个奇怪的错误,表结构都可以打印出来,为什么不能加载数据呢?我想不通。几番查询,找到了一个包装库,github地址。
3. java.lang.IllegalArgumentException: AWS Access Key ID and Secret Access Key must be specified as the username or password (respectively) of a s3n URL, or by setting the fs.s3n.awsAccessKeyId or fs.s3n.awsSecretAccessKey properties (respectively).
按照2里面的github库里的文档说明配置好后,可能会报这个错。因为spark-redshift用到了S3,所以要配置key和secret才可以。文档里也提供了几种方式,i、ii和iii,开始我选择的是第三种方式,直接写在了URI里面。
4. java.lang.NoClassDefFoundError: com/eclipsesource/json/Json
紧接着,配置好aws的key和secret,可能会遇到这个错误。这个错误一眼看上去感觉奇怪,为什么会报json的错误呢?在spark-redshift的issue里面找到了遇到同样问题的人,最下面arvindkanda提供了解决方案,启动时提供一个额外的jar包就可以了。
5. java.sql.SQLException: Amazon Invalid operation: S3ServiceException:The S3 bucket addressed by the query is in a different region from this cluster.
这个问题是说,S3和EMR必须在同一个region,不然Spark是读不到Redshift的数据的。我这里用的都是us-west-2,Oregon,俄勒冈。
6. com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Bad Request (Service: Amazon S3; Status Code: 400; Error Code: 400 Bad Request;
这个问题,就比较厉害了,卡了我好几个小时。网上各种方案都在说,因为签名版本的问题,所以访问S3时,必须指定S3的endpoint,查来的都是s3a
的,比如这个。但是因为spark-redshift里用的是s3n
,我就将a替换成了n,但是这个问题还是在。各种方案不断尝试,可能是运气好,莫名的就试对了一种方式:将3里面的方式替换成ii,然后再配置sc.hadoopConfiguration.set("fs.s3a.endpoint", "s3.us-west-2.amazonaws.com")
,就可以了。
最终代码如下,
1 | spark = SparkSession.builder.getOrCreate() |