HTTP500操作APPEND失败了吗?

时间:2017-04-19 07:02:53

标签: azure azure-data-lake

package org.apache.spark.examples.kafkaToflink;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer010;
import org.apache.flink.streaming.util.serialization.SimpleStringSchema;

import com.microsoft.azure.datalake.store.ADLException;
import com.microsoft.azure.datalake.store.ADLFileOutputStream;
import com.microsoft.azure.datalake.store.ADLStoreClient;
import com.microsoft.azure.datalake.store.IfExists;
import com.microsoft.azure.datalake.store.oauth2.AccessTokenProvider;
import com.microsoft.azure.datalake.store.oauth2.ClientCredsTokenProvider;

import scala.util.parsing.combinator.testing.Str;

public class App {

    public static void main(String[] args) throws Exception {
        final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        Properties properties = new Properties();
        properties.setProperty("bootstrap.servers", "192.168.1.72:9092");
        properties.setProperty("group.id", "test");
        DataStream<String> stream = env.addSource(
                new FlinkKafkaConsumer010<String>("tenant", new SimpleStringSchema(), properties), "Kafka_Source");

        stream.addSink(new ADLSink()).name("Custom_Sink").setParallelism(128);
        env.execute("App");
    }
}

class ADLSink<String> extends RichSinkFunction<String> {

    private java.lang.String clientId = "***********";
    private java.lang.String authTokenEndpoint = "***************";
    private java.lang.String clientKey = "*****************";
    private java.lang.String accountFQDN = "****************";
    private java.lang.String filename = "/Bitfinex/ETHBTC/ORDERBOOK/ORDERBOOK.json";

    @Override
    public void invoke(String value) {

        AccessTokenProvider provider = new ClientCredsTokenProvider(authTokenEndpoint, clientId, clientKey);
        ADLStoreClient client = ADLStoreClient.createClient(accountFQDN, provider);
        try {
            client.setPermission(filename, "744");
            ADLFileOutputStream stream = client.getAppendStream(filename);

            System.out.println(value);
            stream.write(value.toString().getBytes());

            stream.close();

        } catch (ADLException e) {

            System.out.println(e.requestId);
        } catch (Exception e) {

            System.out.println(e.getMessage());
            System.out.println(e.getCause());
        }

    }

}

我一直在尝试使用while循环附加Azure数据湖存储中的文件。但有时它会给出这个,操作APPEND失败,HTTP500,启动错误或有时10分钟后。我正在使用java

1 个答案:

答案 0 :(得分:1)

Anubhav,Azure Data Lake流是单写入器流 - 即,您不能从多个线程写入相同的流,除非您在这些线程之间进行某种形式的同步。这是因为每次写入指定它写入的偏移量,并且对于多个线程,偏移量不一致。

您似乎是从多个线程编写的(.setParallelism(128)调用代码)

在您的情况下,您有两种选择:

  1. 在每个帖子中写入不同的文件。我不知道你的用例,但是我们发现很多情况下自然使用不同的线程 - 写入不同的文件。
  2. 如果让所有线程写入同一个文件很重要,那么您需要稍微重构一下,以便所有实例都引用相同的ADLFileOutputStream,并且您需要确保同步write()close()的来电。
  3. 现在,还有一个问题 - 你得到的错误应该是HTPP 4xx错误(表明租约冲突,因为ADLFileOutputStream获得租约),而不是HTTP 500,它说有服务器端问题。要解决这个问题,我需要知道您的帐户名称和访问时间。这个信息在StackOverflow上分享是不安全的,所以请为此打开一张支持票并参考这个SO问题,这样问题最终就会发送给我。