Monthly Archives: 6월 2015

KTH, T커머스 추천 콘텐츠 제공 기술 특허 획득

 

KTH, T커머스 추천 콘텐츠 제공 기술 특허 획득

시청이력/빈도/횟수에 다른 T커머스 콘텐츠 제공 방법에 관한 기술

시청패턴 분석하여 시청자별 상이한 콘텐츠 제공하여 맞춤 프로모션으로 활용

국내외 4건의 T커머스 기술 특허 출원하여 3건 획득 성과

KTH_DAISY_RFM_20150624

 

KTH(대표 오세영)는 국내 최초로 독자 개발한 T커머스(데이터방송 홈쇼핑)의 추천 콘텐츠 제공 방법에 관한 기술에 대하여 국내 특허를 획득했다고 24일 밝혔다.

이번 특허는 디지털방송 기반에서 최근 시청 이력, 시청 빈도, 시청 횟수를 분석하여 시청자별 상이한 추천 콘텐츠를 제공하는 기술로, 시청자의 고유한 시청 패턴을 정교하게 분석함으로써 데이터홈쇼핑 방송의 양방향성을 이용한 고객별 맞춤 콘텐츠를 제공하는 방법에 관한 것이다.

이러한 기술을 데이터방송 홈쇼핑에 적용하여 우수 고객에게는 우수 고객 맞춤 이벤트를 제공하고, 이탈위험군에 속하는 고객에게는 이탈방지 이벤트를 제공함으로써 구매율을 높일 수 있는 장점이 있다. 이번 기술에는 RFM1) 모델을 적용하여 사용자의 구체적인 시청패턴을 구조화하여 사용자 맞춤 프로모션을 보다 정교하게 발전시켰다.

특히, TV상의 K쇼핑 앱의 시청 이력 로그를 생성하고 분산, 저장하여 고객등급을 분류하고 고객군별 행동패턴을 예측하는 과정에는 KTH의 자체 기술인 대용량 데이터 실시간 분석/추천 솔루션 ‘데이지(DAISY)’를 적용하여 기술적 완성도를 높였다.

KTH는 이번에 획득한 특허를 포함하여 ‘셋톱박스 ID기반의 사용자 인터페이스’, ‘날씨정보를 이용하여 지역마다 인터페이스를 상이하게 구현하는 기술’ 등 T커머스 관련 총 3건의 국내 특허를 취득하였고, ‘셋톱박스 ID기반 T커머스 시청 데이터를 이용한 상품 추천 기술’ 에 대해서도 특허 출원 중에 있다. 또한 중국과 인도네시아 등 해외에도 총 2건의 특허를 출원하여 글로벌 시장에서의 경쟁력 확보에도 나서고 있다.

<KTH가 특허 출원 및 취득한 T커머스 기술>

 

기술 명칭 및 효과

특허 출원 국가 특허 취득
1 셋톱박스 ID기반의 T커머스 사용자 인터페이스 한국 완료
2 날씨정보를 이용하여 지역마다 인터페이스를 상이하게 구현하는 기술 한국, 중국,

인도네시아

한국 완료.

중국,인도네시아 심사 중

3 셋톱박스 ID기반 T커머스 시청 데이터를 이용한 상품 추천 기술 한국, 중국,

인도네시아

심사 중
4 셋톱박스 ID기반 데이터방송 홈쇼핑의추천 콘텐츠 제공방법 한국 완료

KTH는 이러한 특허 기술을 자사의 디지털방송 홈쇼핑인 ‘K쇼핑’에 적용하여 기존 TV홈쇼핑과는 차별화된 서비스를 선보이고 있다.

KTH 오세영 대표는 “기존의 아날로그 홈쇼핑의 경우 TV 화면에 1개의 방송 콘텐츠만 방송되어 해당 방송에 관심도가 적은 시청자는 쉽게 채널에서 이탈하는 문제점이 있었다”면서 “하지만 데이터방송 홈쇼핑은 방송 콘텐츠와 함께 추천 콘텐츠를 출력해줌으로써, 채널에서 이탈하지 않고 다양한 콘텐츠를 경험할 수 있는 장점이 있다”고 말했다.

Spark 적용기

포스팅의 시작

사용자의 사용로그에서 초 구간 단위 통계를 주기적으로 산출하는 시스템을 만들어달라는 요청이 들어왔었습니다.

데이터를 추출하기 위해 일단 정제된 사용자 로그(1시간, 600만건)와 단위시간(초) 정보 테이블을 데카르트 곱으로 연산하여 2차 데이터를 구성한 후, 해당 시간 대 정보만 필터링 하여 최종 데이터를 추출하기로 하고 성능테스트를 시작 하였습니다.

Hive (MR) 실행

위 연산에 대한 수행 시간은  [그림 1-1] 과 같이 통계 산출 가능 시간을 크게 오버 하였습니다.

image2015-4-16 16-10-1

단위 분

[그림 1 – 1]

Hive (Tez) 실행

Tez는 MR를 대체하여 하둡의 질의 처리를 가속하는 소프트웨어입니다.

Tez에서 설명 하는 Execution Performance 는

– MR보다 성능 향상을 얻을 수 있음

– 최적의 리소스 관리 기능

– 실시간으로 구조 변경 계획 수립

– 동적으로 물리적인 흐름을 결정한다.

인데 한마디로 표현 하자면 MR보다 똑똑하게? 처리 할 수 있다고 합니다.

 동일 쿼리에 대해 hive.execution.engine 를 Tez로 변경 하여 실행 한 결과는  [그림 2-1] 와 같이 MR보다는 성능이 좋으나 MR과 같이 통계 산출 가능 시간을 크게 오버 하였습니다.

  image2015-4-16 16-10-9

단위 분

[ 그림 2 – 1 ]

UDTF Hive (Tez, MR) 실행

구조적으로 성능을 개선 할 수 있는 방법이 있을까 고민 하던 중 Hive UDTF를 참고 하게 되었습니다.

UDTF는 table generating functions으로서 single input을 multiple output rows로 변형이 가능 한 Hive function 입니다.

Hive UDTF explode [ 표 1 ]

Normal user-defined functions, such as concat(), take in a single input row and output a single output row. In contrast, table-generating functions transform a single input row to multiple output rows.

Return Type

Name(Signature)

Description

N rows

explode(ARRAY)

Returns one row for each element from the array.

 [ 2 – 1 ]

o 적용 예시

customUDF 를 사용 하여 start_date ~ end_date 사이에 10초 간격 데이터를 array로 뽑은 후 explode를 적용 하였습니다.

(e.g. ) lateral view explode(customUDF(“2015-02-09 14:00:10”, “2015-02-09 14:00:40”, 10))

user info

view_time

User_A

10

User_A

20

User_A

30

User_A

40

[ 2 – 2 ]

o TIP

lateral view explode(customUDF(“2015-02-09 14:00:10”, “2015-02-09 14:00:40”, 10)) 이 구조를 custom UDTF를 사용하여 lateral view customUDTF(“2015-02-09 14:00:10”, “2015-02-09 14:00:40”, 10) 로 줄일 수 있지만 spark 1.2.1 에서 class not found exception이 발생 합니다.

spark issue link

UDTF를 적용 한 결과 기존 쿼리 대비 성능이 약 50% 정도 [ 그림 2 – 2 ] 향상 되었으며 불 필요 한 Filter 연산을 Skip하여 성능이 향상 된 것으로 판단 할 수 있었습니다. 하지만 통계 산출 가능 시간을 역시나 크게 오버 하였습니다.

 image2015-4-16 16-10-38

단위 분

[ 그림 2 – 2 ]

Spark 도입

Hadoop MR job은 Iter. 단계마다 HDFS에 Write를 하게 되지만 Spark는 [ 그림 3-1 ] 처럼 HDFS가 아닌 Memory에 저장해 놓고 사용하니 MR보다 빠르게 데이터를 처리합니다. 자세한 설명은 http://spark.apache.org/ 와 RDD논문 을 참고 하시면 됩니다.

 image2015-4-16 16-10-44

[ 그림 3 -1 ]

Spark로 job을 실행 하는 방법에는 여러 가지가 있지만, 기존 hive query를 재 사용 할 수 있는 방법은 크게 두가지가 있는데 첫 번째 방법으로는 HiveOnSpark 를 설정하여 hive.execution.engine=spark로 실행하는 방법과 두 번째로는 Spark-SQL을 이용하는 방법이 있습니다.

HiveOnSpark 는 아직 release버전이 아니라서 Spark-SQL을 사용 하기로 하고 기존 장비에 동일 한 구성으로 실행 한 결과 [ 그림 3 – 2 ] Tez 대비 3x 빠르게 처리 되었습니다. 하지만  목표 시간에는 도달 하지 못하였습니다.

 image2015-4-16 16-10-50

단위 분

 [ 그림 3 – 2 ]

Spark 성능 개선

spark 사이트 에서 친절하게 튜닝 가이드를 제공 하고 있습니다. 일단 이번에 적용 한 사례만 찾아 본다면

config setting

o Components 참고

 image2015-4-16 16-10-55

[ 그림 4 – 1 ]

Cluster Manager type을 Standalone 으로 실행 하고 conf/spark-env.sh 을 아래와 같이 수정 하였습니다.

SPARK_EXECUTOR_MEMORY=4g

SPARK_WORKER_MEMORY=4g

SPARK_WORKER_INSTANCES=4 (기존 1)

이슈 : worker 1개에 executor n개는 실행이 안 되는 이슈가 있습니다.

이렇게 설정 하면 worker 4개에 executor 4개가 실행 되어 task가 좀 더 빨리 실행이 됩니다. 최적화에 대해서는 spark jobhistory와 spark config설정 들을 좀 더 공부해야 하겠지만 현재는 worker개수가 증가 될 수록 성능은 어느 정도 비례하게 향상 되는 것을 확인 할 수 있습니다. (물론 executor 가 n개가 될 수록 각 job에 대한 network비용과 동시 사용하는 리소스의 양도 늘어나게 됩니다.)

 image2015-4-16 16-11-2

[ 그림 4 – 2 ]

Data Serialization

가이드에서는 “Serialization plays an important role in the performance of any distributed application.”이 중요하다고 기존 default 설정인 java serialization대신에 Kryo serialzation을 사용 하면 대략 10x 성능 향상을 기대 할 수 있다고 합니다.

o config

spark.serializer     org.apache.spark.serializer.KryoSerializer

spark.kryoserializer.buffer.mb     128

Garbage collection tunning

Eden 영역은 block size 128MB 에 HDFS compression 2~3,  task 2~3을 고려하여 128MB * 3 * 3 할당,  young size는 4/3 * Eden으로 설정 하였고, gc방식은 -XX:+UseParallelGC, -XX:+UseParallelOldGC, -XX:+UseConcMarkSweepGC 3 가지 중 가장 좋은 성능을 내는 -XX:+UseConcMarkSweepGC 로 설정 하였으며 배치 작업 시 생존이 긴 객체들이 많아 -XX:SurvivorRatio과 -XX:NewRatio를 적절히 비교하여 OLD로 넘어가는 데이터를 줄였습니다.

최종 설정 정보는 아래와 같으며 VisualVM으로 모니터링 결과 기존(full gc : 평균 5.5s,  minor gc : 평균 500ms)보다 [ 그림 4 -3 ] 과 같이 성능이 향상 되었음을 확인 할 수 있습니다. minor gc 기준이 일반적으로 100ms 이내로 처리 되어야 하지만 배치 작업 특성 상 minor gc보다 full gc 개선 에 초점을 맞추었습니다.

o vm setting

spark.executor.extraJavaOptions

-Xms5g -Xmx5g

-XX:NewRatio=2

-XX:SurvivorRatio=3

-XX:PermSize=128m

-XX:MaxPermSize=128m

-verbose:gc

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-XX:-UseGCOverheadLimit

-XX:+HeapDumpOnOutOfMemoryError

-XX:+UseConcMarkSweepGC

(full gc : 평균 500ms,  minor gc : 평균 300ms)

 image2015-4-16 16-11-11

[ 그림 4 – 3 ]

Cache Size Tuning

spark.storage.memoryFraction 설정이 0.6 이라면 spark.executor.memory의 60%를 RDD cache에 사용하고 40%의 메모리를 작업 실행 중에 생성 된 다른 object를 위해 사용 됩니다. 메모리가 부족 하거나 작업이 느려지면 이 값을 낮추면 됩니다. 현재 값은 아래와 같습니다.

spark.storage.memoryFraction 0.2

Level of Parallelism

groupbykey가 클 때 이 값을 적절히 조절 하여 각 task에 input을 작게 조절 할 수 있습니다.

일반적으로 각 클러스터 에서 cpu당 2~3개의 작업을 권장 한다.

spark.default.parallelism     96     (8 core * 4node * 3)

위와 같이 개선 후 성능은 아래 [ 그림 4 – 4 ] 과 같습니다.

 image2015-4-16 16-11-16

[ 그림 4 – 4 ]

마치며

위 테스트는 개발 장비에서 진행 되었고 장비가 좋은 성능 아니지만 각 플랫폼에 따른 성능 차이를 확실히 알 수 있었던 계기가 되었습니다. spark에 대해 많은 기능 중 극히 일부분 만을 사용 해 보았지만 여전히 매력이 있는 솔루션 임에는 분명 한 것 같습니다.

2015/03/13일날 1.3.0 버전이 release되었으며 bug patch도 활발히 이루어 지고 있으니 앞으로 활용도가 높아질 것 같습니다.

참고

Hive : http://hive.apache.org/

Tez : http://tez.apache.org/

Hive UDTF : https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF

Spark RDD : http://www.cs.berkeley.edu/~matei/papers/2011/tr_spark.pdf

Spark : http://spark.apache.org/

HiveOnSpark : https://cwiki.apache.org/confluence/display/Hive/Hive+on+Spark%3A+Getting+Started