Elasticsearch Developer Course Review

in elasticsearch •  7 years ago 

Day 1

shard는 하나의 Lucene instance이며, ElasticSearch의 각 node들에 분산되어 처리되는 작업 단위이다.
cluster들은 nodes로 구성되며, 각 nodes에는 index의 (primary/replica) shard들이 있다. shard들은 다시 여러개의 segments들로 구성되며, segments들은 immutable속성을 갖는다.
하나의 Index는 최소 1개의 primary shard와 0개 이상의 replica로 구성 된다.
replica는 read 용도로도 사용 된다.
replica distribution mechanism에는 해당 node의 disk size가 주요하며, network card(ip)와 같은 정보는 고려 대상이 아니다.
따라서, 현재와 같이 multi-instance on single machine으로 구성 할때, 운이 나쁜 경우 replica와 primary shard가 동일한 machine node1/2에 분산 되어 있다면, 데이터가 유실 될 우려가 있다.
새로운 document가 indexing 될때 transaction log에도 저장되며, buffer에도 함께 저장 된다.
새로운 document가 indexing 될때 primary shard에서 먼저 indexing 된 다음, replica shard들에 parallel하게 indexing 된다.
새로운 document가 buffer에 insert 될때, analyze까지는 처리가 다 된 다음에 들어간다. 하지만 아직 flush가 된 상태가 아님으로 Inverted index에서는 찾을 수 없음으로, search 결과에서는 찾을 수 없다.(default로 1초의 refresh 시간이 필요하다)
하지만 GET API는 transaction log에서 정보를 조회 함으로 바로 결과를 출력 할 수 있다.(refresh가 필요 없다.)
Refresh는 transaction log를 segment에 저장하고, 이를 disk에 write하는 작업을 수행 한다.(Lucene의 commit operation을 포함하고 이음)
Refresh는 모든 shard들에 대해 parallel하게 수행된다.
optimize를 수행하기 전까지 여러 segments에 동일한 inverted index key에 대한 색인 결과가 흩어저 있을 수 있다.
optimize를 수행하기 전/후의 검색 성능에 영향을 미치는 이유
_template API를 이용해 index를 생성 할때 공통으로 적용 할 mapping 정보를 pre-define 할 수 있다.
index를 생성 할 시점의 _template configuration을 따르며, 그 이후에 _template을 수정해도, 기존 생성된 indices에는 영향을 미치지 않는다.
Analayze 작업은 3가지 step으로 이루어 지며 그 순서는 변경 할 수 없다.
Character filter is Pre-processing before tokenization(remove HTML tags)
Tokenizer is convert string to terms
Token filter changes the term(lower case), remove term(stopwords) and add term(synonym)
token filter는 여러개 정의 할 수 있지만, 이전에 정의한 순서가 다음 filter에 영향을 주게 됨으로 명시한 순서가 매우 중요하다.
explain param을 추가하면 분석 되는 정보에 대한 바이트 size와 같은 부가 정보를 알 수 있다.
한 field에는 한 analyzer만 mapping 가능하며, 여러 analayzer를 사용하고 싶은 경우, multi-field option을 고려 해 볼 수 있다.
synonym filter에서 파생된 token은 그 기준이 되는 token과 동일한 position 값을 얻게 된다.
Alias는 Read only, Write only, multiple indices 크게 3가지 용도로 나누어 서로 구분된 이름으로 사용하는 것이 좋다.
Alias는 transaction을 지원한다. add/remove
Delete는 가급적 사용하지 않고 remove를 쓰는 쪽이 좋다.(잘못해서 index를 삭제해버리는 문제를 방지하기 위해)
_ttl property와 _timestamp property는 2.x 부터는 deprecated되거나 삭제 될 예정
_timestamp property는 가급적 사용하지 않고 명시적으로 date field를 만들어 사용하는 것으로 가이드 함.
search API에 preference parameter를 추가하여 search query를 어떤 shard에서 수행 시킬지 가이드 할 수 있다.
논리적으로 서비스/백업 둘로 나누어 검색 할 수 있게 가능 할듯 (service = primary_first, etc = replica 사용)
검색 성능 향상에 기여 할 수 있을듯(preference=local)
pre-define 되지 않는 정보들을 담고 있는 document의 persist operation으로 인해 dynamic하게 신규 인덱스 추가, 신규 mapping이 추가 될 수 있는데, 이를 명시적으로 막을 수 있다.
현재는 index 생성은 막아 두었지만 dynamic property add는 막아 두지 않는 상태
property add는 risk가 있음으로 적어도 false(new field ignore) 상태로 하는것이 좋지 않을까?(strict=error return)
Lucene bit packing mechanism으로 인해 numeric type의 data에 대해서는 80% 저장 공간을 절약 할 수 있다(int,long 고민 관련)
The _all field is enabled by default, it has all of the field value and indexed.
it’s impossible to configure to disable after put mapping.
the update operation is consist of three steps, get an old document and make a new document and delete the old document.
If you call bulk update actions by single thread. you don’t need to consider version conflict
bulk action을 수신한 node는 decorator node가 되어서 query 내용을 parsing 하고 parsing 된 action들을 shard level로 나누어 해당 document들이 위치한 각 shard들에 해당 action을 delivery하고, 그 결과를 다시 merge 해서 client로 응답하는 역할을 하게 된다.
2.3 버젼 부터는 update by query api를 사용 할 수 있다.
search API는 query type에 따라 two contexts를 가지고 있다
Query context
score를 return 한다. 이 계산을 위해 상대적으로 filter context보다는 느리다.
Filter context
score가 없다.
결과가 yes or no로 나뉨으로 cache 가 잘 된다.
rescoring featue가 있는데, main query에서 범위를 줄인 다음, 그 결과에 대해서 score를 생성해 낼 수 있음으로 성능 향상에 효과가 있다.
after gathering results by the main query, you can make a score by window_size on each shard level.
https://www.elastic.co/guide/en/elasticsearch/reference/1.3/search-request-rescore.html
the ordering of specified your query is important on 1.x ElasticSearch version but it’s not important since 2.x version
query profiler feature is added since 2.x
you don’t kill your running query.
You can use ingest node to pre-process documents before the actual indexing takes place. it calls ingest node.
DAY 2

field data or doc value
default mechanism이 field data 방식에서 –> 보다 안정적으로 동작 할 수 있는 doc value 방식으로 변경 됨 (since 2.x)
스크린샷 2016-08-05 오후 2.53.42.png
이전에 많은 data를 search result로 조회 했을때, 발생한 circuit-break exception의 원인에 대해 상기 내용이 연관이 있음
https://www.elastic.co/guide/en/elasticsearch/reference/1.4/index-modules-fielddata.html#circuit-breaker
Doc value에 대한 값은 indexing time에 미리 만들어 짐.
Search Request는 a page context(window size) 만큼 만 처리 됨
990-1000 범위를 search 하고자 하는 경우 각 shard에서 1000개씩 가져와서 최종 결과를 만들어 내는 형태 임.
Search Request는 두 가지 mechanism으로 동작 할 수 있다.
https://www.elastic.co/blog/understanding-query-then-fetch-vs-dfs-query-then-fetch
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-search-type.html
두 방법 모두 기본 동작은 다음과 같다.
모든 shard 조각에 query를 수행하고 정렬된 결과를 만들어 냄
최초 요청을 전달받은 coordinator node가 각 샤드에서 수행된 query 결과에 대한 부가 정보를 (연관된) 각 shard에 한번 더 질의 한 다음 re-sort 해서 merge 함.
Dfs(Document Frequency Statics), Query Then Fetch는 다음과 같은 사전 동작을 한가지 더 처리 하는것이 차이가 남. (Tf-Idf라고 하는 Lucene의 score 계산에 대한 항목의 값을 보다 더 정확히 준비 할 수 있음).
추가로 제일 먼저, 각 shard에 query를 수행해서 document Frequency 정보를 조회 함. 이 값을 바탕으로 각 shard에서 보다 더 정확한 score를 만들어 낼 수 있음.
Single search result에 대한 제한이 기본으로 10,000으로 지정되었다. (since 2.1)
scroll_id 는 명시적으로 지울 수 있다. 사용이 완료된 scroll에 대해서는 곧 바로 clear 해주는 것도 자원 관리면에서는 바람직 하다.
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html#_clear_scroll_api
scroll_id에 대한 expired_time은, 다시 scroll 요청을 할때마다 갱신 된다.
결과는 shard 내부의 segments에 정의된 id에 순서로 정렬되서 온다.
filter cache는 각 segements에 현재 질의된 filter의 결과가 몇 건 포함 되었는지를 bitset에 marking해 두고 이를 활용해 다음번에 동일한 filter 조건이 오면, 더 빠르게 처리 할 수 있도록 하고 있다.
https://www.elastic.co/blog/all-about-elasticsearch-filter-bitsets
completion suggest는 FST data structure로 disk에 만들어 indexing 해 둔 결과에 대해서 몇 가지 방식으로 질의해서 그 결과를 가져오는 형태이다.
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html
ordering은 결과를 수신한 client측에서 수행 해야 한다.
Terms Aggregation의 doc_count 값은 집계한 문서들에 출현한 단어의 빈도수가 아닌, 해당 단어가 포함된 문서 수이다. 즉 하나의 document에 2회 “java”라는 term이 있어도 doc_count는 1로 표기된다.
Terms Aggregation은 각 shard들에서 shard_size 만큼 peek해서 그 결과를 ranking으로 만들어 top n건을 return 한 결과들의 합이다. 따라서 한 shard에서 shard_size가 충분하지 않다면 100% 정확하지 않은 ranking이 return 될 수 있다.
show_term_doc_count_error : true로 전달하여, Terms aggregation의 정확도를 doc_count_error_upper_bound field 결과 값으로 알 수 있다.
각 집계 결과 별로 doc_count_error_upper_bound 값이 0이라면 100% 정확한 값으로 봐도 무방하다.
https://www.elastic.co/guide/en/elasticsearch/reference/1.4/search-aggregations-bucket-terms-aggregation.html#_calculating_document_count_error
결과 값으로 rank를 조회 할 것이 아니라면, cardinality, terms aggregation 대신에 filter aggregation을 사용하는 것이 좋다.
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filter-aggregation.html
Graph api를 이용해, 시각화 된 연관 관계 정보를 찾을 수 있다.
https://www.elastic.co/kr/products/graph
combinatorial_explosions(aggregation 중첩 수행 시 발생되는 메모리 이슈 회피)
예를 들어, Terms aggregation은 하나의 term 하나하나가 bucket이 되고 이에 따른 추가적인 aggregation 작업을 수행 할 수 있다.
기본적으로 Depth first collect mode임으로 하나의 term에 대한 추가적인 aggregation을 끝까지 다 수행 할때까지 연속적으로 자원을 소모한다. 하지만 이로인해 사용가능한 메모리 한계에 도달하면 에러가 발생하며 동작을 멈추게 된다
이를 해결하기 위해 breadth_first를 collection_mode로 설정해서 회피 할 수 있다.
이는 각 단계별로 execution을 여러번 수행하고 중간 중간 불필요한 결과를 정리해 나가는 형태로 처리 된다.
즉 하나의 loop에서 모든 aggregation execution을 수행하는 것이 Depth_first이다.
https://www.elastic.co/guide/en/elasticsearch/guide/current/_preventing_combinatorial_explosions.html#_depth_first_versus_breadth_first
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#_collect_mode
Inner Object (자료 p.396)에 있는 lucene과 original 세계의 결과 값은 다르다.
스크린샷 2016-08-05 오후 4.32.17

Inner object는 물리적으로 볼때 동일한 block, document의 저장공간에 hidden 영역으로 함께 관리된다.
단점은 Inner object를 업데이트 할때도 root object까지 함께 재색인 되어야 한다.
Parent/Child
서로 soft link를 가지며, Parent가 없는 Child document들이 생길 수 있다. 그리고 그 반대의 경우도 성립 된다.
서로 다른 mapping 정보를 가질 수 있다.
동일한 shard이지만 서로 다른 segments에 위치 해 있다.
child가 index될때 parent id가 반드시 필요하다.
장점은 어떤 자식 문서를 가진 부모를 조회 할 수 있다. 그리고 그 반대의 경우도 성립 한다.
부모는와 자식은 one to many 관계이다. 따라서 부모를 정렬할때는 score or none이며, 자식의 정렬 기준은 보다 다양하다.
parent_child는 동

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Congratulations @hongsgo! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

You published 4 posts in one day

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

Upvote this notification to help all Steemit users. Learn why here!

Congratulations @hongsgo! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 1 year!

Click here to view your Board

Do not miss the last post from @steemitboard:

Carnival Challenge - Collect badge and win 5 STEEM
Vote for @Steemitboard as a witness and get one more award and increased upvotes!

Congratulations @hongsgo! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Do not miss the last post from @steemitboard:

Use your witness votes and get the Community Badge
Vote for @Steemitboard as a witness to get one more award and increased upvotes!