Real-time full-text search with Luwak and Samza

70
Real-time full-text search with Luwak and Samza by Alan Woodward and Martin Kleppmann 번역: 이명현 [email protected]

Transcript of Real-time full-text search with Luwak and Samza

Page 1: Real-time full-text search with Luwak and Samza

Real-time full-text search with Luwak and Samza

by Alan Woodward and Martin Kleppmann번역: 이명현 [email protected]

Page 2: Real-time full-text search with Luwak and Samza

이 자료는...

• Martin Kleppmann 이 confluent.io 블로그로 올린 글을 번역한 자료입니다.

• 때문에 글의 진행과 내용이 원문의 그것과 같습니다.

• 번역 과정에서 다소 주관적인 해석이 들어가기도 했습니다.

• 원문을 읽어보시기를 추천드립니다.

Page 3: Real-time full-text search with Luwak and Samza

검색의 변화

Page 4: Real-time full-text search with Luwak and Samza

검색의 변화

• 전통적인 데이터

• 큰 규모의 코퍼스(corpus)

• 사용자의 필요에 따라서 그때 그때 필요한 내용을 코퍼스에서 검색한다

• 때때로 코퍼스 문서 내용에 변화가 있긴 하지만, 크게 변하지 않는다

• 빠르게 변화하는 데이터

• 문서가 들어오는대로 검색을 할 수 있으면 유용하다

• 뉴스 모니터링, 트위터 검색과 같은 경우에 적용 가능

Page 5: Real-time full-text search with Luwak and Samza

여기서 소개하고자 하는 것은

• Luwak과 Samza를 연동해서 효율적이고 확장가능한 stream 검색엔진을 만드는 것

• Luwak

• Lucene-based library

• 단일 문서에 여러 쿼리를 수행할 수 있다

• Samza (+Kafka)

• Kafka 기반의 stream 처리 프레임워크

• 실시간 스트림 처리를 분산된 컴퓨터들에서 할 수 있도록 한다

Page 6: Real-time full-text search with Luwak and Samza

Full-text search on stream

Page 7: Real-time full-text search with Luwak and Samza

Full-text search on stream

• Solr나 Elasticsearch 와 같은 일반적인 검색엔진과 다른 문제들을 다뤄야 한다

• 데이터가 급속히 변화하는 경우에 그 중요성이 더 커진다

Page 8: Real-time full-text search with Luwak and Samza

여기서 말하는 Stream은 무엇인가?

• 데이터의 모음

• 데이터의 ‘추가’만 가능하다

• 데이터들이 일정한 순서를 가지고 있다

• 예

• log file

• exception stack trace

Page 9: Real-time full-text search with Luwak and Samza

• Producer

• Stream에 쓰기 작업을 하는 프로세스

• Consumer

• Stream으로 부터 읽는 프로세스

• can read entire file sequentially

• can use tail -f to watch new records

Page 10: Real-time full-text search with Luwak and Samza

그렇다면 Stream을 어떻게 full-text 검색을 할까?

• 전통적인 방법

• 모든 것을 큰 색인에 올린다

• Elasticsearch 나 Solr 등을 사용해서

• ELK (Elasticsearch, Logstash and Kibana) is a trendy way

Page 11: Real-time full-text search with Luwak and Samza

• 새로운 데이터가 추가된다

• 검색을 할 수 있도록 색인에 추가한다

• 색인 구성의 예: index of different time periods

• 어제

• 지난 1시간

• 지난 1분

• Near-real-time search 을 구성할 수 있다

• 위에 구성한 모든 색인에 검색을 한다

Page 12: Real-time full-text search with Luwak and Samza

그렇다면 Stream 검색을 하는 곳은 어디가 있을까?

• Twitter

• 검색을 하면 지난 얼마간의 트윗들을 검색한다

• 어느 정도 시간이 지나면 새로운 트윗들이 결과에 추가된다

• 트위터는 검색 쿼리를 기억하고 새로운 트윗들 중에서 검색을 계속 수행한다.

• called firehose of tweets

Page 13: Real-time full-text search with Luwak and Samza

• Google Alerts

• 사용자가 쿼리를 등록한다

• 검색에 매칭되는 페이지가 새로 등장하면 시스템이 알림을 보내준다

• Google Alerts 는 수집되는 문서들의 stream에서 등록된 쿼리와 매칭되는 문서를 검색하는 것

Page 14: Real-time full-text search with Luwak and Samza

검색은 두가지로 나눠볼 수 있다

• After-the-fact search

• 과거의 문서들을 검색한다

• 모든 문서들을 큰 색인에 담는다

• Streaming search

• 쿼리를 문서보다 먼저 등록한다

• Stream에 나타나는 문서들을 등록된 쿼리들에 매칭한다

Page 15: Real-time full-text search with Luwak and Samza

• 이 둘을 결합하는게 좋은 결과를 가져오기도 한다

• Twitter

• 7day search + stream search

• 비슷한 제품: Elasticsearch Percolator

Page 16: Real-time full-text search with Luwak and Samza
Page 17: Real-time full-text search with Luwak and Samza

Implementing Stream Search

Page 18: Real-time full-text search with Luwak and Samza

Stream search, 단순한 접근 방법

• 극단적으로는 한 문서당 색인을 생성하고 등록된 모든 쿼리를 날려볼 수 있다.

• 하지만 위 방법은 효율적이지 못하다.

• 쿼리가 많아지면: 느려진다

• 쿼리가 복잡할수록: 느려진다

• 예: Media monitoring service

• “which” magazine 의 복잡한 쿼리 사례

Page 19: Real-time full-text search with Luwak and Samza

옵티마이징을 해야한다

• The fastest query is a query that you never execute

• 절대 실행되지 않을 쿼리를 찾아낼 수 있다면 그 쿼리들을 건너뜀으로써 많은 시간을 아낄수있다

Page 20: Real-time full-text search with Luwak and Samza

Luwak: A java library for stored queries

Page 21: Real-time full-text search with Luwak and Samza

Luwak

• “A library that we (Flax) wrote in order to do efficient streaming search. Luwak is open source and builds upon Apache Lucene"

• 쿼리를 먼저 등록하고 새로운 문서들을 매칭한다

• 문서를 먼저 색인하는 것이 아니다

• 매칭해야하는 쿼리의 수를 줄이기 위해 몇 가지 옵티마이징을 한다

Page 22: Real-time full-text search with Luwak and Samza

Index of Queries

Page 23: Real-time full-text search with Luwak and Samza

• Conjunction 쿼리

• Q1: “WHEELS” NEAR “BUS”

• Q2: “WHEELS” NEAR “CAR”

• 모든 단어들이 문서에 등장해야한다

• Q1 쿼리와 매칭되는 문서는 “wheels” 와 “bus” 가 등장하는 문서

• 만일 문서에 “bus”/“wheels” 중 하나가 없다면 Q1하고 매칭이 안된다

• 쿼리에서 단어를 하나 골라서 어떤 문서와 전체 쿼리가 매칭되는지를 확인할 수 있다

Page 24: Real-time full-text search with Luwak and Samza

• Disjunction 쿼리

• Q3: “WHEELS” OR “BUMPERS”

• 단어 중 하나만 문서에서 등장 해도 쿼리가 문서와 매치가 된다

• 반대로 어떤 쿼리가 문서와 매칭되지 않는지를 확인하려면 모든 단어를 문서와 매칭해봐야 한다

Page 25: Real-time full-text search with Luwak and Samza

• Query 글에서 추출한 단어들을 가지고 색인을 만든다.

• Q1: “bus”

• Q2: “car”

• Q3: “bumpers” and “wheels”

• 이 색인은 term들을 실제의 query 와 매핑하는 역할을 한다.

Page 26: Real-time full-text search with Luwak and Samza

Document as a Query

Page 27: Real-time full-text search with Luwak and Samza

• 어떤 문서와 매칭되는 모든 쿼리들을 찾기위해 문서를 쿼리로 던져야 한다

• 문서의 모든 단어들로 disjunction(OR) query 를 만든다

• 문서의 단어 중에서 하나라도 나타나는 모든 쿼리를 찾는다

• 하나의 문서로부터 inverted index를 만들면 자동으로 이 term 들이 생성된다

Page 28: Real-time full-text search with Luwak and Samza

문서와 매칭되는 쿼리들을 찾는 과정

1. 쿼리의 색인을 만든다

2. 문서의 disjunction query 를 퀴리의 색인에 검색해서 어떤 쿼리들이 매칭될 가능성이 있는지 찾는다

3. 이 쿼리들을 가지고 실제로 문서에 검색을 해서 매칭이 되는지 확인한다

Page 29: Real-time full-text search with Luwak and Samza
Page 30: Real-time full-text search with Luwak and Samza

• 문서: “The wheels on the bus go round and round”

• disjunction query:“and” OR “bus” OR “go” OR “on” OR “round” OR “the” OR “wheels”

• 쿼리 색인 term

• Q1: “bus”

• Q2: “car”

• Q3: “wheels”, “bumpbers”

• Q1와 Q3는 전체 쿼리를 검색을 해서 문서와 매칭되는지 확인한다

• Q2는 검색을 할 필요가 없으므로 건너뛴다

Page 31: Real-time full-text search with Luwak and Samza

• 이 작업이 복잡해 보일수있지만 전체 99%의 쿼리들을 수행하지 않아도 되게 한다

• 가장 빠른 쿼리는 수행하지 않는 쿼리다

Page 32: Real-time full-text search with Luwak and Samza

More Optimizations

Page 33: Real-time full-text search with Luwak and Samza

Term Frequency Analysis

• Conjunction query 의 단어를 선택할때 기준을 term frequency 로 잡을 수 있다.

• “car” AND “bumpers”

• Query 색인과 문서를 매칭할때 한 단어라도 나타나지 않으면 그 문서와 매칭되지 않는 다는 것을 안다

• “bumpers” 라는 단어가 나타나는 빈도가 적으므로 선택한다

Page 34: Real-time full-text search with Luwak and Samza

More Optimization

• 지금까지 세운 규칙

• Conjunction(AND)인 경우 그 중 하나의 단어만 추출

• Disjunction(OR) 인 경우 모든 단어를 추출

Page 35: Real-time full-text search with Luwak and Samza

• 규칙에 의해 예제 트리에서 3가지의 다른 조합을 추출할 수 있다

Page 36: Real-time full-text search with Luwak and Samza

• 조합에 따라서 매치가 될수도 있고 안될수도 있다

• 문서의 내용이 “term1 term2 term3” 라면 세번째 경우에 매치가 안된다.

• 세번째: term4 term5

Page 37: Real-time full-text search with Luwak and Samza

• 조금 더 정확하게 query pre-selection을 만들 수 없을까?

• 위 조합을 다시 조합하면 된다. 각각의 경우의 수를 다른 필드에 색인하고, 문서를 각 필드에 검색한 결과를 AND 한다.

• _a:(term1 OR term2 OR term3) AND

• _b:(term1 OR term2 OR term3) AND

• _c:(term1 OR term2 OR term3)

• 여전히 실제로 문서가 매칭되는지는 검색을 통해야 알 수 있지만, 많이 줄일 수 있다.

Page 38: Real-time full-text search with Luwak and Samza

Luwak stream search 정리

• Luwak은 위 optimizations들을 다 구현했다

• Luwak은 library 이다

• Single machine 에서 돌리는 건 한계가 있다.

• 어떤 시점 부터는 쿼리양이 늘어나서 위에서 설명한 optimization들로도 감당이 되지 않는다.

• 그렇다면 어떻게 확장할 것인가?

Page 39: Real-time full-text search with Luwak and Samza

Scaling Stream Searching

Page 40: Real-time full-text search with Luwak and Samza

어떻게 확장 할 것인가?

• Scaling search across a cluster of machines

• 분산프레임워크를 새로 구축하는 것은 어렵다

• Apache Kafka 와 Apache Samza를 사용하기로 했다

Page 41: Real-time full-text search with Luwak and Samza

Kafka

Page 42: Real-time full-text search with Luwak and Samza

• “Kafka is a kind of message broker or message queue”

• 하나의 프로세스(producer)에서 생성한 메세지를 다른 프로세스(consumer)로 전달한다

• Scalable

• Fault-tolerant

Page 43: Real-time full-text search with Luwak and Samza

• 매우 큰 append-only file이라고 생각할 수 있다.

• Producer는 이 파일 맨 마지막에 메세지를 쓸 수 있다

• Consumer는 tail -f 와 같다

• 각 consumer는 순차적으로 메세지를 읽는다

• 각 consumer 별로 파일의 position을 가지고 있다

• Kafka 는 누가 어디까지 읽었는지 추적하지 않아도 된다.

• Consumer는 자기 위치만 기록해두면 된다.

Page 44: Real-time full-text search with Luwak and Samza

Kafka Stream

Page 45: Real-time full-text search with Luwak and Samza

Kafka: for scaling

• Kafka의 stream은 partition 되어있다

• hash 방식의 partitioning 이다

• Kafka는 replication을 지원한다

• Leader/follower 모델을 사용한다. Leader가 broker 역할

• 새로운 메세지는 모두 leader에게 가고 follower들에게 복제된다

• Leader였던 노드가 죽으면 follower 중 하나가 leader가 된다

Page 46: Real-time full-text search with Luwak and Samza
Page 47: Real-time full-text search with Luwak and Samza

Kafka: Messages

• Kafka의 모든 메세지는 key, value 형태로 되어있다.

• Key는 메세지를 구분짓는 값이다

• Partition할때 사용한다

• Compaction을 할때 사용한다 (다음장에)

• Value는 임의의 길이의 문자열

Page 48: Real-time full-text search with Luwak and Samza

Kafka: Compaction

• Compaction 은 append-only 정책의 예외

• 스트림에 동일한 key를 가진 스트림이 여럿 있다면 가장 최신의 메세지만 남기고 나머지를 삭제한다

• 즉, 나중에 들어온 메세지들이 그 전 메세지들을 overwrite 한다

• 이것은 바로 일어나지 않고 특정 시간에 이루어진다. GC처럼.

Page 49: Real-time full-text search with Luwak and Samza
Page 50: Real-time full-text search with Luwak and Samza

• Compaction을 사용하지 않으면 메세지 개수가 늘면서 stream크기가 증가

• Compaction을 사용하면 유일한 key 개수에 비례해서 stream이 커진다. 즉, DB와 비슷하다.

• DB에 모든 key value 를 저장할 수 잇다면 Kafka에도 그렇게 할 수 있다

Page 51: Real-time full-text search with Luwak and Samza

Kafka 와 Luwak의 관계는?

• Luwak은 메모리에 모든 쿼리를 로딩한다

• Luwak은 누군가 query를 새로 등록하거나, 수정하거나, 삭제했을 때 알림을 받을 수 있어야 한다

• Query ID을 key 로 사용하고 query string을 value 로 사용한다.

• Stream compaction 으로 stream이 너무 커지는 것을 방지

• Luwak을 처음 실행할때 stream을 처음부터 끝까지 읽는다

• bootsrap stream이라고 부른다.

Page 52: Real-time full-text search with Luwak and Samza

Samza

Page 53: Real-time full-text search with Luwak and Samza

Samza

• “A framework for writing stream processing jobs on top of Kafka”

Page 54: Real-time full-text search with Luwak and Samza

Samza: Jobs

• 특정 stream을 consume 하도록 지정

• StreamTask Interface를 상속해서 구현

• process() 함수에서 stream message를 처리한다

• Output stream에 메세지를 출력하도록 할 수도 있다

Page 55: Real-time full-text search with Luwak and Samza
Page 56: Real-time full-text search with Luwak and Samza

Samza: Scaling

• Samza의 StreamTask를 Kafka의 partition 별로 생성

• 각 stream의 partition들의 message들을 순차적으로 처리한다

• Output은 자신의 stream 중 어떠한 partition으로도 보낼 수 있다

Page 57: Real-time full-text search with Luwak and Samza

• Partition별로 작업을 처리하는 특성을 이용해서 두 개 이상의 stream 작업을 join 할 수 있다

• 두 개의 stream

• 각 stream의 partition1 들을 join 처리하는 StreamTask

• 각 stream의 partition2 들을 처리하는 StreamTask

• 단, input stream 들이 같은 수의 partition을 가지고 있어야 한다.

Page 58: Real-time full-text search with Luwak and Samza
Page 59: Real-time full-text search with Luwak and Samza

• 이러한 특성때문에 stream join을 scale 할 수 있다

• 각 stream이 user ID로 partition

• 각 stream 에서 user ID가 동일한 message들을 하나의StreamTask에서 처리한다

Page 60: Real-time full-text search with Luwak and Samza

이 둘을 이용해서 어떻게 full-text search on stream을 할 수 있는 것일까?

Page 61: Real-time full-text search with Luwak and Samza

Luwak & Samza

Page 62: Real-time full-text search with Luwak and Samza

• Query Stream

• Bootstrap stream with compaction

• 사용자 쿼리를 추가/수정/삭제 할 수 있다

• 쿼리를 Luwak의 in-memory 에 반영한다

• Document Stream

• 쿼리와 매칭될 문서들

• Samza job이 문서를 읽어서 query색인에 매칭한다

• 결과를 output stream에 쓴다

Page 63: Real-time full-text search with Luwak and Samza

• Does it scale?

• Samza 의 partition 모델은 다음과 같다.

• Stream A는 query stream

• Stream B는 document stream

• 각자 자신과 관련된 query-document 끼리 partition을 구성할 수 있으면 예제와 같은 모델을 사용할 수 있다.

Page 64: Real-time full-text search with Luwak and Samza
Page 65: Real-time full-text search with Luwak and Samza

• 하지만, 실제로는 다음과 같은 모델이 필요하다

• 모든 query 들과 모든 document들을 매칭할 방법이 필요하다

• SimpleTask8는 쿼리 파티션 4와 문서 파티션 2를 처리

• 쿼리와 문서 모두 여러개의 task에서 처리되는 것이다

• 그러면 마지막에 모든 matches를 합치면 된다.

Page 66: Real-time full-text search with Luwak and Samza
Page 67: Real-time full-text search with Luwak and Samza

• 안타깝게도 지금 Samza는 이러한 기능을 지원하지 않는다

• SAMZA-353 이슈에서 다뤄지는 중

• Samza와 Luwa 연동의 POC (Proof of Concept)를 Github에서 찾을 수 있다.

Page 68: Real-time full-text search with Luwak and Samza

마무리 Luwak + Kafka + Samza

Page 69: Real-time full-text search with Luwak and Samza

Luwak & Samza를 이용한 stream 검색의 시사점

• Luwak

• 쿼리를 색인하고 문서와 매칭하는 과정의 옵티마이징에서 배울 점이 있다

• Kafka

• Streaming framework 에 대한 이해

• Samza

• Streaming framework 을 어떻게 처리해야할지에 대해 시사

Page 70: Real-time full-text search with Luwak and Samza

출처

• Blog post: Real-time full-text search with Luwak and Samza

• http://www.confluent.io/blog/real-time-full-text-search-with-luwak-and-samza/

• Samza-Luwak Proof of Concept

• https://github.com/romseygeek/samza-luwak#high-level-architecture

• Luwak GitHub

• https://github.com/flaxsearch/luwak

• Apache Kafka

• http://kafka.apache.org

• Apache Samza

• http://samza.apache.org

• Blog post: Elasticsearch Percolator & Luwak: a performance comparison of streamed search implementations

• http://www.flax.co.uk/blog/2015/07/27/a-performance-comparison-of-streamed-search-implementations/