2017-11-13 3 views
0

uaparser 라이브러리에서 scala (uap-scala)를 사용하여 사용자 에이전트에서 장치를 파싱하는 스칼라로 작성된 spark (EMR에서 실행)의 UDF가 있습니다. 작은 세트로 작업 할 때는 잘 작동하지만 (5000 행) 큰 세트 (2M)에서 실행하면 매우 느리게 작동합니다. 나는 나열 Dataframe를 수집하고 드라이버에 대한 반복했는데, 그 날은 UDF 드라이버에서 실행되고 노동자Spark의 UDF는 매우 느리게 작동합니다.

  1. 가 어떻게이를 설정할 수 있습니다하지 않는 것이 무엇인지를 생각하게도 매우 느렸다? 다른 이론을 가진 사람 있습니까?
  2. 그렇다면 왜 이런 일이 발생할 수 있습니까?

이것은 UDF 코드 :

def calcDevice(userAgent: String): String = { 

val userAgentVal = Option(userAgent).getOrElse("") 
Parser.get.parse(userAgentVal).device.family 
} 

val calcDeviceValUDF: UserDefinedFunction = udf(calcDevice _) 

사용 :

.withColumn("agentDevice", udfDefinitions.calcDeviceValUDF($"userAgent")) 

감사 Nir 씨

+0

다른 값으로 'userAgent'값을 공유 할 수 있습니까? –

+0

예, 사용자 에이전트가 반복되지만 목록이 너무 작지 않습니다. –

+0

구문 분석이 비쌀 수 있습니다. 캐시가 사용 된 경우 어떻게 될까요? –

답변

0

질문에서 누락 Parser.get.parse을 감안할 때, 단지 udf을 판단 할 수 있습니다 부품.

성능을 위해 당신은 Option을 제거 할 수 있습니다

def calcDevice(userAgent: String): String = { 
    val userAgentVal = if(userAgent == null) "" else userAgent 
    Parser.get.parse(userAgentVal).device.family 
} 
1

문제가 UDF itelf 내에서 빌더를 인스턴스화로했다. 해결책은 udf 외부에서 객체를 만들고 행 수준에서 사용하는 것입니다.

val userAgentAnalyzerUAParser = Parser.get 

def calcDevice(userAgent: String): String = { 

val userAgentVal = Option(userAgent).getOrElse("") 
userAgentAnalyzerUAParser.parse(userAgentVal).device.family 
} 

val calcDeviceValUDF: UserDefinedFunction = udf(calcDevice _)