io.grpc.StatusRuntimeException:在Spark中使用Grpc客户端时ABORTED

时间:2017-09-18 04:01:51

标签: apache-spark spark-dataframe grpc grpc-java

我正在尝试运行spark(2.2)作业,以便使用GRPC(1.1.2)客户端调用从服务器获取一些数据。当我通过spark运行此代码时出现此错误。为小集合运行相同的工作可以正常工作。根据我的研究,我理解ABORTED消息是由于一些并发问题,所以我猜测是因为客户端无法创建超过一定数量的存根,但我不知道如何继续。此外,我知道GRPC服务器可以很好地处理大量请求,而且我远远低于它可以处理的请求数。有任何想法吗?

按要求添加更多信息: 我的客户端CatalogGrpcClient具有处理通道和请求的这些方法:

private List<ManagedChannel> getChannels() {
    return IntStream.range(0, numChannels).mapToObj(x ->
            ManagedChannelBuilder.forAddress(channelHost, channelPort).usePlaintext(true).build()
    ).collect(Collectors.toList());
}

private ManagedChannel getChannel() {
    return channels.get(ThreadLocalRandom.current().nextInt(channels.size()));
}

private ListingRequest populateRequest(ListingRequest.Builder req, String requestId) {
    return req.setClientSendTs(System.currentTimeMillis())
            .setRequestId(StringUtils.defaultIfBlank(req.getRequestId(), requestId))
            .setSchemaVersion(StringUtils.defaultIfBlank(req.getSchemaVersion(), schema))
            .build();
}

private List<ListingResponse> getGrpcListingWithRetry(ListingRequest.Builder request,
                                                      String requestIdStr,
                                                      int retryLimit,
                                                      int sleepBetweenRetry) {
    int retryCount = 0;
    while (retryCount < retryLimit) {
        try {
            return StreamSupport.stream(Spliterators.spliteratorUnknownSize(CatalogServiceGrpc.newBlockingStub(getChannel()).getListings(populateRequest(request, requestIdStr)), Spliterator.ORDERED), false).collect(Collectors.toList());
        } catch (Exception e) {
            System.out.println("Exception " + e.getCause().getMessage());
            retryCount = retryCount + 1;
            try {
                Thread.sleep(sleepBetweenRetry);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    }
    throw new StatusRuntimeException(Status.ABORTED);
}

我在方法提取中使用getCatalogListingData方法,该方法提取用于映射到spark作业中的case类

def extract(itemIds: List[Long], validAspects: Broadcast[Array[String]]): List[ItemDetailModel] = {
    var itemsDetails = List[ItemDetailModel]()
    val client = new CatalogGrpcClient()
    implicit val formats = DefaultFormats
    val listings = client.getCatalogListingData(itemIds.map(x => x.asInstanceOf[java.lang.Long]).asJava).asScala
    ...
    ...
    itemsDetails
}

这是调用extract的spark代码。 itemsMissingDetails是一个带有“item”列的数据框,该列是唯一的item id列表。 zipWithIndex和以下映射是这样的,我将每个请求中的50个项ID传递给GRPC svc。

itemsMissingDetails
  .rdd
  .zipWithIndex
  .map(x => (x._2 / 50, List(x._1.getLong(0))))
  .reduceByKey(_ ++ _)
  .flatMap(items => extract(items._2, validAspects))
  .toDF
  .write
  .format("csv")
  .option("header",true)
  .option("sep", "\t")
  .option("escapeQuotes", false)
  .save(path)

在很长一段时间(约30分钟到1小时)之后,我的客户实际上抛出了ABORTED错误。当我开始这项工作时,它从GRPC svc获得我需要的信息,每个工人都有几千件物品。在此之后,工作挂起(在每个工人上)并且在经过漫长的等待(约30分钟到1小时)之后,它会因上述异常而失败或继续进行。我无法一直得到StatusRuntimeException。

0 个答案:

没有答案