2016-12-15 17 views
5

Podczas próby zapisu Dataframe do S3 przy pomocy Sparka napotykam S3 SignatureDoesNotMatch.Spark Napisz do S3 V4 SignatureDoesNotMatch Błąd

Objawem/rzeczy próbowałem:

  • Kod nie czasami ale działa czasami;
  • Kod może czytać z S3 bez problemu, i być w stanie napisać do S3 od czasu do czasu, co wyklucza błędne ustawienia konfiguracyjne jak S3A/enableV4/Niewłaściwy klucz/Region Endpoint itp
  • Punkt końcowy S3A został ustawiony zgodnie z dokumentami S3 S3 Endpoint;
  • Upewniłem się, że AWS_SECRETY_KEY nie zawiera żadnych niealfanumerycznych zgodnie z sugestią: here;
  • Upewniono się, że czas serwera jest zsynchronizowany za pomocą NTP;
  • Poniższe testy zostały przetestowane na komputerze EC2 m3.xlarge z spark-2.0.2-bin-hadoop2.7 w trybie lokalnym;
  • Problem zniknął, gdy pliki są zapisywane w lokalnych plikach fs;
  • w tej chwili obejściem było zamontowanie wiaderka z s3fs i napisanie tam; nie jest to jednak idealne, ponieważ s3fs dość często umiera ze stresu, jaki rzucił na niego Spark;

Kod można sprowadzić do:

spark-submit\ 
    --verbose\ 
    --conf spark.hadoop.fs.s3n.impl=org.apache.hadoop.fs.s3native.NativeS3FileSystem \ 
    --conf spark.hadoop.fs.s3.impl=org.apache.hadoop.fs.s3.S3FileSystem \ 
    --conf spark.hadoop.fs.s3a.impl=org.apache.hadoop.fs.s3a.S3AFileSystem\ 
    --packages org.apache.hadoop:hadoop-aws:2.7.3\ 
    --driver-java-options '-Dcom.amazonaws.services.s3.enableV4'\ 
    foobar.py 


# foobar.py 
sc = SparkContext.getOrCreate() 
sc._jsc.hadoopConfiguration().set("fs.s3a.access.key", 'xxx') 
sc._jsc.hadoopConfiguration().set("fs.s3a.secret.key", 'xxx') 
sc._jsc.hadoopConfiguration().set("fs.s3a.endpoint", 's3.dualstack.ap-southeast-2.amazonaws.com') 

hc = SparkSession.builder.enableHiveSupport().getOrCreate() 
dataframe = hc.read.parquet(in_file_path) 

dataframe.write.csv(
    path=out_file_path, 
    mode='overwrite', 
    compression='gzip', 
    sep=',', 
    quote='"', 
    escape='\\', 
    escapeQuotes='true', 
) 

zapłonowa wylewa następujące error.


Set log4j do verbose, wydaje się, dodaje się stało:

  • Każdy będzie wysyłany do staing lokalizację na S3 /_temporary/foorbar.part-xxx;
  • Wywołanie PUT spowoduje przeniesienie partycji do ostatecznej lokalizacji;
  • Po kilku pomyślnie wykonanych połączeniach PUT, wszystkie kolejne wywołania PUT nie powiodły się z powodu 403;
  • Ponieważ reuqety zostały wykonane przez aws-java-sdk, nie wiesz, co zrobić na poziomie aplikacji; - Następujący log pochodził z innego zdarzenia z dokładnie tym samym błędem;

>> PUT XXX/part-r-00025-ae3d5235-932f-4b7d-ae55-b159d1c1343d.gz.parquet HTTP/1.1 
>> Host: XXX.s3-ap-southeast-2.amazonaws.com 
>> x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 
>> X-Amz-Date: 20161104T005749Z 
>> x-amz-metadata-directive: REPLACE 
>> Connection: close 
>> User-Agent: aws-sdk-java/1.10.11 Linux/3.13.0-100-generic OpenJDK_64-Bit_Server_VM/25.91-b14/1.8.0_91 com.amazonaws.services.s3.transfer.TransferManager/1.10.11 
>> x-amz-server-side-encryption-aws-kms-key-id: 5f88a222-715c-4a46-a64c-9323d2d9418c 
>> x-amz-server-side-encryption: aws:kms 
>> x-amz-copy-source: /XXX/_temporary/0/task_201611040057_0001_m_000025/part-r-00025-ae3d5235-932f-4b7d-ae55-b159d1c1343d.gz.parquet 
>> Accept-Ranges: bytes 
>> Authorization: AWS4-HMAC-SHA256 Credential=AKIAJZCSOJPB5VX2B6NA/20161104/ap-southeast-2/s3/aws4_request, SignedHeaders=accept-ranges;connection;content-length;content-type;etag;host;last-modified;user-agent;x-amz-content-sha256;x-amz-copy-source;x-amz-date;x-amz-metadata-directive;x-amz-server-side-encryption;x-amz-server-side-encryption-aws-kms-key-id, Signature=48e5fe2f9e771dc07a9c98c7fd98972a99b53bfad3b653151f2fcba67cff2f8d 
>> ETag: 31436915380783143f00299ca6c09253 
>> Content-Type: application/octet-stream 
>> Content-Length: 0 
DEBUG wire: << "HTTP/1.1 403 Forbidden[\r][\n]" 
DEBUG wire: << "x-amz-request-id: 849F990DDC1F3684[\r][\n]" 
DEBUG wire: << "x-amz-id-2: 6y16TuQeV7CDrXs5s7eHwhrpa1Ymf5zX3IrSuogAqz9N+UN2XdYGL2FCmveqKM2jpGiaek5rUkM=[\r][\n]" 
DEBUG wire: << "Content-Type: application/xml[\r][\n]" 
DEBUG wire: << "Transfer-Encoding: chunked[\r][\n]" 
DEBUG wire: << "Date: Fri, 04 Nov 2016 00:57:48 GMT[\r][\n]" 
DEBUG wire: << "Server: AmazonS3[\r][\n]" 
DEBUG wire: << "Connection: close[\r][\n]" 
DEBUG wire: << "[\r][\n]" 
DEBUG DefaultClientConnection: Receiving response: HTTP/1.1 403 Forbidden 
<< HTTP/1.1 403 Forbidden 
<< x-amz-request-id: 849F990DDC1F3684 
<< x-amz-id-2: 6y16TuQeV7CDrXs5s7eHwhrpa1Ymf5zX3IrSuogAqz9N+UN2XdYGL2FCmveqKM2jpGiaek5rUkM= 
<< Content-Type: application/xml 
<< Transfer-Encoding: chunked 
<< Date: Fri, 04 Nov 2016 00:57:48 GMT 
<< Server: AmazonS3 
<< Connection: close 
DEBUG requestId: x-amzn-RequestId: not available 
+0

'X-Amz bieżąco: 20161104T005749Z' było więcej niż 1 miesiąc temu. Czy ten wpis dziennika jest również taki stary? –

+1

@ Michael-sqlbot Tak, wcześniej napotkaliśmy ten problem, w tym czasie (na początku listopada) unikaliśmy go, obniżając rozmiar partycji pod pewną magiczną liczbę (11 dla tej instancji) i (aws-java-sdk verbose) był od tego czasu. ponieważ główna przyczyna nie została nigdy zidentyfikowana, a teraz problem ponownie pojawił się, wykopywam te dzienniki jako przykład tutaj –

+0

Mogę potwierdzić, że zmniejszenie liczby partycji do niskiego numeru jak 10 przez coś takiego jak 'df.repartition (10) .write.parquet ("s3a: //" + s3_bucket_out + "/", mode = "overwrite", compression = "snappy")) wydaje się unikać tego problemu. – asmaier

Odpowiedz

1
  1. Co masz na myśli "S3A" umrze? Ciekawi mnie to. Jeśli masz ślady stosu, umieść je na serwerze Apache JIRA, projekcie HADOOP, komponencie fs/s3.
  2. s3n nie obsługuje interfejsu API V4. to nie kwestia punktu końcowego, ale nowego mechanika podpisu. Nie zostanie przeprowadzona aktualizacja jego biblioteki Jetts z wyjątkiem powodów bezpieczeństwa, więc przestań próbować z nią pracować.

Jeden problem, że Spark będzie miał z S3, niezależnie od kierowcy, jest to, że jest to w końcu zgodne sklep obiektu, gdzie: zmienia nazwę wziąć O (bajtów), aby zakończyć, a opóźnione spójność między PUT i lista może przerwać zatwierdzenie. Bardziej powodzenia: Spark zakłada, że ​​po napisaniu czegoś do systemu plików, jeśli zrobisz ls katalogu nadrzędnego, znajdziesz to, co właśnie napisałeś. S3 tego nie oferuje, stąd termin "ostatecznie konsystencja". Teraz w HADOOP-13786 staramy się poprawić, a HADOOP-13345 zobaczyć, czy nie możemy użyć Amazon Dynamo do szybszego, spójnego widzenia świata. Ale będziesz musiał zapłacić premię dynodb za tę funkcję.

Wreszcie wszystko, co jest obecnie znane na temat rozwiązywania problemów z s3a, w tym z możliwych przyczyn błędów 403, is online. Mam nadzieję, że to pomoże i, jeśli istnieje inna przyczyna, którą się identyfikuje, łatki są mile widziane

+0

Witam Steve, miałem na myśli [s3fs] (https://github.com/s3fs-fuse/s3fs-fuse) umiera (montuję s3 wiadro i niech iskra napisz do lokalnego fs, aby obejść ten problem; –

+0

s3 uri, którego używamy, to 's3a', jeśli chodzi o ostateczną spójność, z logu faktycznie widzieliśmy, że sdk (lub Spark) jest wystarczająco inteligentny, aby zrobić wiele wywołań HEAD, aby upewnić się, że obiekt został pomyślnie zapisany w lokalizacji przemieszczania (S3 zwraca 200 zamiast 404) przed wydaniem wywołania PUT, aby przenieść go do ostatecznego miejsca docelowego. –

1

Doświadczyłem dokładnie tego samego problemu i znalazłem rozwiązanie z pomocą this article (other resources są wskazujące w tym samym kierunku). Po ustawieniu tych opcji konfiguracyjnych zapisanie do S3 powiodło się:

spark.hadoop.mapreduce.fileoutputcommitter.algorithm.version 2 
spark.speculation false 

Używam Spark 2.1.1 z Hadoop 2.7. Moja ostatnia komenda zapłonie złożyć wyglądał następująco:

spark-submit 
--packages com.amazonaws:aws-java-sdk:1.7.4,org.apache.hadoop:hadoop-aws:2.7.3 
--conf spark.hadoop.fs.s3a.endpoint=s3.eu-central-1.amazonaws.com 
--conf spark.hadoop.fs.s3a.impl=org.apache.hadoop.fs.s3a.S3AFileSystem 
--conf spark.executor.extraJavaOptions=-Dcom.amazonaws.services.s3.enableV4=true 
--conf spark.driver.extraJavaOptions=-Dcom.amazonaws.services.s3.enableV4=true 
--conf spark.hadoop.mapreduce.fileoutputcommitter.algorithm.version=2 
--conf spark.speculation=false 
... 

Dodatkowo zdefiniowałem te zmienne środowiskowe:

AWS_ACCESS_KEY_ID=**** 
AWS_SECRET_ACCESS_KEY=**** 
Powiązane problemy