elasticsearch

elasticsearch

    Java Lowlevel client bulk api에서 filter_path 사용하기

    https://wedul.site/690 Bulk Index 진행 시 search api 느려지는 현상 해결 방법 리서치 현재 회사에서 하고있는 프로젝트에 경우 Elasticsearch를 사용해서 데이터를 제공하고 있다. 서비스 특성상 초당 받는 데이터 업데이트 요청이 많고 real time engine이 아닌 elasticsearch에 거의 리얼타 wedul.site 이전글에서 작성하였듯이 계속해서 쓰기 작업 시 발생할 수 있는 순단을 줄이기 위해서 여러가지 방법을 찾고 있다. 그중 쓰기 작업이 많이 발생할 때 불필요한 response를 줄이기 위해서 filter_path를 적용해보고자 한다. Filter Path rest api 작업 시 필요한 응답값만 받을 수 있는 기능이다. 하지만 Java Hig..

    Bulk Index 진행 시 search api 느려지는 현상 해결 방법 리서치

    현재 회사에서 하고있는 프로젝트에 경우 Elasticsearch를 사용해서 데이터를 제공하고 있다. 서비스 특성상 초당 받는 데이터 업데이트 요청이 많고 real time engine이 아닌 elasticsearch에 거의 리얼타임 수준의 데이터 변경을 보여줘야한다. 그러다보니 들어오는 요청을 별도의 buffer를 많이 주어 업데이트 할 수 없기 때문에 들어오는 요청을 document id 기준으로 묶어서 bulk 업데이트 될 수있도록 기능을 개발했었다. 회사 블로그에 관련된 내용을 썼었는데 참고 https://techblog.woowahan.com/2718/ 검색을 위한 데이터 다루기 | 우아한형제들 기술블로그 {{item.name}} 안녕하세요. 우아한형제들 검색개발팀 정철입니다. 배달의민족 검색시스..

    Nested field에 대한 대체 필드 flattened type

    일반적으로 하나의 공통 Document내에 서로 다른 속성을 가지고 있어서 별도의 Document인 것 처럼 저장하고 query하기 위해서 우리는 nested obejct 타입을 많이 사용한다. 사용했었던 예로는 가게 - 메뉴, 상품 - 아이템 정도이다. 하지만 nested 필드의 개수만큼 내부적으로 별도의 도큐먼트로 분리되어 저장이 되고 쿼리 시 상위 도큐먼트와 합쳐져서 보여줘야하는 등에 여러 이유로 nested 필드는 많이 느리다. Elasticsearch nested type설명에도 flattened type을 고려해보라고 써있는거 보면 얼마나 좋지 못한지 사용해보지 않아도 가늠해 볼 수 있다. (실사용에서도 퍼포먼스를 극대화 해도 쉽지 않았다.) 그래서 성능이슈를 해결해보고자 찾던 중 7.3 버전..

    Lucene의 segment가 immutable한 이유

    Elasticsearch의 Document의 수정, 삭제 동작이 발생되었을 때 실제 Document를 구성하고 있는 각 shard 내부 Segment는 바로 지워지지 않는다. 대신 해당 세그먼트가 지워졌다고 mark만 하고 수정되었을 경우에는 새로운 세그먼트를 할당한다. 이렇게 동작하는 이유는 Lucene레벨에서 비용을 아끼기 위해서 사용된다고 알고는 있었는데 정확하게 왜 segment가 immutable한지 알지 못해서 정리해 봤다. 1. 동시성 이슈 우선 개인적으로 생각했을 때는 immutable한 데이터의 경우 수정에 의한 고민을 할 필요가 없기 때문에 multi thread 환경에서 특별한 race condition을 고려할 필요가 없어서 이점이 있다고 생각했다. 우연한 기회에 해당 부분에 대해 ..

    Elasticsearch의 Translog 설명

    Lucene을 공부하면서 실제 세그먼트를 조작 하고 인덱싱을 반영 하는 부분을 보면서 Lucene에 commit에 대해서 공부했었다. wedul.site/678 Lucene의 commit과 flush의 차이 Lucene에서 데이터 색인을 위해서 사용하는 IndexWriter의 flush와 commit 두 가지 command의 차이를 정리해보자. 두 개의 operation 이름만 보게되면 동일한 동작을 수행할 것 같지만 실질적으로 다른 동작을 wedul.site 그럼 실제로 Elasticsearch에서 이 Lucene commit에 영향을 받는 부분이 어디인지 알아보게 되면서 translog에 대해 공부해봤다. 우선 translog는 양 자체가 워낙 방대하기 때문에 성능을 위해서는 이 부분에 대한 튜닝이 ..

    Lucene 기본, 색인, 성능 최적화 정리

    용어 정리 재현율 검색 시스템에서 관련된 문서를 얼마나 빼먹지 않고 찾아두는지 정확도 검색 시스템에서 사용자가 입력한 검색어와 관련없는 문서를 얼마나 정확하세 제거 하는지 fuzzy 레빈슈타인 편집거리를 통해서 입력한 텀과 유사한 텀을 가진 문서를 찾아줌 비교되는 두 단어의 추가, 수정, 삭제에 대한 비용 처리를 하며 비용이 높을수로 서로 다른 term 검색 모델 순수 boolean 모델 지정된 질의에 문서가 해당하는지 아니면 해당하지 않는지를 판단하며 별도의 계산 부분이 없다. 벡터 공간 모델 질의와 문서 모두 고차원(차원은 term을 의미)의 벡터로 표현. 벡터간의 거리를 계산하면 문서와 질의 사이의 연관도나 유사도를 산출 할 수 있다. 확률모델 확률적인 방법을 통해 개별 문서가 질의와 일치하는 확률..

    elasticsearch metric 수집 방법

    Elasticsearch metric 정보 수집관련해서 요근래 질문을 받았었다. 처음에는 java application이라면 기본적으로 생각하는 JMX metric을 고려했었으나 그때 당시에 이 community를 보고 직접 aggregation해서 influxdb에 수집하는 방법을 선택했던게 생각난다. (실제로 내 입장에서는 jmx로 metric 정보를 보는게 너무 불편했다.) 또 aggregation할 때 spring actuator micrometer를 사용하려 했으나 이곳에서 모으는 데이터를 정제해서 보고자 하는 데이터 형태로 influxdb에 넣는건 좋지 못한 방법이었다. 그래서 결국 pooling방식으로 얻고자 하는 클러스터에 직접 stats관련된 http api를 요청해서 잘 조립해서 inf..

    Too many dynamic script compilations 에러

    elasticsearch를 사용하여 개발을 하다보면 스크립트를 사용하는 경우가 굉장히 많이 발생한다. 나는 아무생각없이 스크립트를 만들어서 사용했는데 어느날 운영에 반영을 하는데 본적이 없던 에러를 발견했다. java.lang.AssertionError: Expecting code not to raise a throwable but caught

    RestHighLevelClient를 사용하여 search after 기능 구현하기

    https://wedul.site/541에서 search after 기능을 사용해서 검색을 하는 이유를 알아봤었다. 그럼 spring boot에서 RestHighLevelClient를 이용해서 search after를 구현을 해보자. 1. Mapping 우선 index가 필요한데 간단하게 상품명과 지역 가격정보들을 가지고 있는 wedul_product 인덱스를 만들어 사용한다. { "settings": { "index": { "analysis": { "tokenizer": { "nori_user_dict": { "type": "nori_tokenizer", "decompound_mode": "mixed", "user_dictionary": "analysis/userdict_ko.txt" } }, "ana..

    nginx 서버에 filebeat를 이용하여 ELK에 로그 기록하기

    git clone https://github.com/deviantony/docker-elk nginx를 설치하고 docker 기반으로 ELK (elasticsearch, logstash, kibana)를 설치하고 nginx 로그를 filebeat를 설치하여 acces.log, error.log, syslog등을 전송해보자. 설치 ELK를 도커에 설치하는 스크립트를 아래 github에 잘 정리되어 제공해주고 있다. https://github.com/deviantony/docker-elk ELK는 이걸로 설치하면 되는데 docker-compose로 nginx와 filebeat까지 함께 설치하기 위해서 아래 저장소에서 제공하는 nginx-filebeat 스크립트를 혼합해서 사용해보자. https://githu..

    Elasticsearch node 종류와 기본 설정 옵션

    Elasticsearch의 노드 Elasticsearch의 인스턴스를 시작하는 동시에 노드도 같이 시작된다. 노드들을 연결해놓은 것을 클러스터라고 한다. 만약 하나의 엘라스틱 서치 노드만을 실행시킨 경우도 하나의 노드를 가진 클러스터라고 한다. 클러스터안에서 모든 노드는 HTTP와 Transport 트래픽을 기본적으로 다룬다. Transport 레이어는 오로지 노드들과 Java TransportClient와의 통신에만 사용된다. Http 레이어는 오직 외부 Rest Cliente들과 통신할 때 사용된다. 모든 노드는 클러스터 안에서 서로 다른 노드들에 대하여 알고 있고 client에 요청을 적적한 노드로 향하게 조절해준다. 기본적으로 노드는 master-eligible, data, ingest, mach..

    Elasticsearch version conflict 에러

    배치를 이용해서 Elasticsearch에 데이터를 삽입하던 중 version conflict라는 오류가 자주 발생했다. 처음에는 Elasticsearch 버전이 동일한데 왜? 오류가 나는지 몰랐다. 그래서 검색해보니 인덱스안에 document에는 각자 관리하는 version이 존재한다. 이 version은 document가 수정될 때 하나씩 올라가게 되는데 version이 10인 상태에 document에 여러 서버 모듈에서 해당 document에 업데이트를 하려고 하니 문제가 발생하였다. 그 이유는 version 10인 상태에서 작업에 들어간 두 모듈은 한 모듈이 먼저 11로 업데이트를 시키고 다음 모듈이 작업을 진행하려고 할 때 자기가 알고 있던 마지막 version인 10이 아니라 11로 바껴있는것..

    Elasticsearch reindex시 alias를 사용하여 무중단으로 진행하기 & big index 리인덱싱 시 비동기 처리 방법

    Elasticsearch reindex를 진행할 때, 단순하게 새로운 인덱스를 만들고 reindex api를 진행하고 기존 인덱스를 지우고 새로 만들어서 다시 reindex를 해줬다. (이전글: https://wedul.site/611?category=680504) 하지만 그것은 해당 인덱스의 document의 수가 적어서 금방 진행이 되었었고 만약 document수가 10만가지만 넘어도 생각보다 오래걸려서 서비스의 흐름이 끊어지게 된다는걸 인지하지 못했다. 같은 회사 동료분께서 해당 부분에 대해서 말씀해주셨고, 그 분이 가이드 해주신대로 진행해서 reindex를 무중단하게 진행하는 방법을 찾아봤다. Alias를 이용하여 reindex하기 기존 index wedul의 매핑구조이다. PUT wedul { ..

    Elasticsearch nori 형태소 분석기에서 readingform filter를 이용해서 한자 내용을 한글로 변환하기

    Elasticsearch filter에서 한자로 검색했을 때 일치하는 한글 결과로 tokenizing하게 해주는 filter가 있다. 해당 filter는 nori-readingform이다. 적용 방법은 기존에 synonmys나 speech필터 적용과 동일하다. 인덱스 생성 위에서 부터 사용했던 인덱스에 nori_readingform 필터를 추가해서 생성만 해주면 된다. PUT wedul_anaylyzer { "settings": { "index" : { "analysis" : { "tokenizer": { "nori_user_dict": { "type": "nori_tokenizer", "decompound_mode": "none", "user_dictionary": "dic/nori_userdict_k..

    Elasticsearch 특정 형태소 종류를 제외하여 검색하는 필터 nori_part_of_speech 적용

    Elasticsearch를 사용하여 analyze를 사용하다가 조사, 형용사 등등을 제외하고 형태소 토크나이즈가 되어야 했다. 그래서 정식 문서를 찾아보더니 nori_part_of_speech라는 필터가 있었다. 우선 저번 시간에 만들었던 wedul_analyzer 인덱스를 이용해서 토크나이즈를 해보자. { "tokens": [ { "token": "바보", "start_offset": 0, "end_offset": 2, "type": "word", "position": 0 }, { "token": "위들", "start_offset": 3, "end_offset": 5, "type": "word", "position": 1 }, { "token": "이", "start_offset": 5, "end_o..

    Elasticsearch에서 Dictionary 변경 시 analyzer와 인덱싱된 Document 갱신 방법

    Elasticsearch에서 Dictionary를 사용하여 analyzer를 만들고 그를 사용해서 index에 Document를 인덱싱할 수 있다. 근데 Dictionary가 변경되면 analyzer를 변경하고 indexing된 document를 갱신하려면 어떻게 해야하는지 정리해보자. Background 지식 Analyzer는 character filter, tokenizer, token filter 순서대로 적용한다. 기본적으로 anaylyzer는 indexing time과 search time에 적용된다. index time 분석 대상은 source data(원본 데이터)이고 search time 분석 대상은 query string이다. 그러므로 사전을 변경하는 것은 indexing, serchin..

    [번역] Elasticsearch 퍼포먼스 튜닝 방법 - ebay

    Elasticsearch에 대해 검색하다가 ebay에 퍼포먼스 튜닝방법에 대해 좋은 글이 있어서 간단하게 정리해봤다. 새롭게 알게된 사실이 많아서 좋았다. 정리 잘된 기술 블로그를 보는것은 책을 읽는거보다 훨씬 유익한 경우가 많은 것 같다. Elasticsearch 엘라스틱 서치는 아파치 루씬을 기반으로한 검색과 분석 엔진으로 데이터를 실시간에 가깝게 보여주고 분석해 준다. 실시간성으로 분석과 검색을 위해서 많이 사용되는 엘라스틱 서치의 퍼포먼스는 무엇보다 중요한데 이를 위한 퍼포먼스 튜닝방법을 정리해보자. 높은 엘라스틱서치의 퍼포먼스를 위해서는 많은 처리량, 낮은 검색 지연시간등이 요구된다. 고효율성 Elasticsearch를 위한 솔루션 - 효율 적인 인덱스 디자인 인덱스를 설계하다보면 하나의 인덱스..

    Elasticsearch template를 일별 index 구성하기

    Elasticsearch를 이용해서 로그기록을 많이한다. 일별 로그성 인덱스를 자동으로 만들기 위해 template를 사용해서 구성하는 법을 정리해보자. 우선 매일 새롭게 생성될 index에 대한 template를 생성해보자. template 생성 PUT _template/wedul_log_* { "index_patterns": [ "wedul_log_*" ], "mappings": { "_doc": { "dynamic": false, "properties": { "id": { "type": "integer" } } } } } 생성한 템플릿이 잘 만들어졌는지 확인해보자. 확인 GET template/wedul_log* 그럼 이제 wedul_log라는 대표 인덱스를 생성해주고 template에 맞는 일자별..

    Elasticsearch에서 reindex를 이용해서 매핑정보 변경하기

    Elasticsearch에서 index를 구성하다보면 매핑정보를 추가하거나 수정하고 싶을때가 있다. 내가 아는 내에서는 한번 생성된 index의 매핑정보를 변경하는건 어렵다. 그래서 reindex를 통해 index의 매핑정보를 변경해줘야한다. 우선 wedul_mapping이라는 인덱스가 있다고 해보자. 매핑 정보는 다음과 같다. PUT wedul_mapping { "mappings": { "_doc": { "dynamic": "false", "properties": { "id": { "type": "integer" }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword" } } } } } } } 이때 name에서 keyword필드를 ..

    Elasticsearch에서 synonyms.txt로 동의어 필터 만들어서 사용하기

    elasticsearch에서 검색기능을 넣다가 2080이라는 키워드를 검색 했을때와 이공팔공이라는 검색어를 입력했을 때 두개 모두 동일한 데이터를 출력하도록 지정하고 싶었다. 그래서 synonyms 필터를 만들기로 했다. 우선 synonyms 필터를 만들어서 사용하기 위해서는 동의어에 대한 정리가 되어있는 사전을 만들어야 한다. 사전 생성 방법은 다음과 같고 아래 링크를 참조해서 간단하게 사전을 만들었다. https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-synonym-tokenfilter.html 파일명은 synonyms.txt이고 내용은 다음과 같다. synonyms.txt 노레바,noreva,노래바 airpods,에어팟..

    elasticsearch 7.0 docker 설치 후 변경사항 확인

    엘라스틱서치 7.0이 출시했다. 엘라스틱서치 7.0에는 kibana UI변경과 multi mapping type 제거 등의 이슈가 있다. 우선 달라진점을 확인하기 위해 docker에 설치해보자. 설치 elasticsearch docker run --name elastic7.0 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.0.0 kibana docker run -d --rm --link elastic7.0:elastic-url -e "ELASTICSEARCH_HOSTS=http://elastic-url:9200" -p 5601:5601 --name kibana7...

    Spring Boot에서 6.4 Elasticsearch 연결 및 간단 CRUD

    Elasticsearch를 Spring Boot에서 작업을 하는 간단한 정리를 해보자. 1. Library 추가Elasticsearch를 사용하기 위해서는 spring-data-elasticsearch 라이브러리가 추가되어야 한다. gradle에 추가해보자.1234567dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' compileOnly "o..

    docker logstash 설치 및 log 파일 elasticsearch에 기록

    ELK에서 logstash를 제외하고는 모두 경험해봤다.이제 logstash를 사용해서 log파일을 elasticsearch에 기록해보자. 설치elasticseach도 kibana도 pc에 직접 설치하고 싶지 않아서 docker에 설치해서 사용했다. logstash도 docker에 설치해서 사용해보자. 물론 logstash를 사용하기전에 elasticseach와 kibana가 설치되어 있어야한다. 설치법은 저번 게시물에 올려놨다. logstash를 이름을 지정해서 background에서 동작하도록 실행시킨다.1docker run --name logstash -d docker.elastic.co/logstash/logstash:6.4.0cs 설정파일logstash를 설치하면 내부에 다음과 같은 설정파일이 ..

    Elasticsearch에서 refresh 정리

    Elasticsearch에서 document를 업데이트하고 바로 해당 정보를 조회하려고 했다.하지만 조회가 되지 않았다. 분명이 업데이트가 종료된 것을 확인 했는데 왜 그런지 의문이 들었다. 그래서 찾아봤는데 document가 업데이트가 되고나서 인덱스에서 실제로 조회가 될 수있는 상태가 되기위해서는 일정시간이 필요한 것 같다.자세히는 모르지만 다시 인덱싱을 걸기 때문에 그러는건 아닌가 생각된다. 그래서 이런경우에 업데이트가 종료 되었다고 알리는 시간을 검색이 가능하게 변경된 시간까지 포함해서 알려주도록 하는 옵션이 존재한다. 그렇게 되면 업데이트가 되고 검색이 가능한줄 알고 프로그램을 작성하다가 버그가 발생하는 비율을 줄일 수 있다. 일반적인 bulkInsert나 update, create같은 명령에는..

    Elasticsearch에서 search_after 기능 사용하여 조회하기

    elasticsearch에서 search_after를 이용하여 데이터를 조회하는 방법을 정리해보자.우선 사용할 인덱스를 생성하자. 12345678910111213141516171819202122PUT wedul{ "mappings": { "cjung": { "properties": { "id": { "type": "keyword" }, "name": { "type": "text", "analyzer": "nori", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } }}Colored by Color Scriptercs 생성된 인덱스에 데이터 몇개만 삽입하여보자.123456789101112131415POST wedul/cju..

    Elasticsearch에서 Full text queries와 Term level queries 정리

    Elasticsearch를 사용하다보면 term과 match 관련된 쿼리에 대해 헷갈리는 경우가 많다. Document에 있는 내용을 가져와서 정리해보자. Full text queriesThe high-level full text queries are usually used for running full text queries on full text fields like the body of an email. They understand how the field being queried is analyzed and will apply each field’sanalyzer (or search_analyzer) to the query string before executing. match queryThe s..

    Elasticsearch query string 조회시 parse exception 에러 처리

    elasticsearch에서 query_string로 데이터 조회시에 쿼리문으로 ) 특수문자가 포함하여 조회했다. 하지만 다음과 같이 문제가 발생했다. 1234567891011{ "error": { "root_cause": [ { "type": "parse_exception", "reason": "parse_exception: Encountered \" \")\" \") \"\" at line 1, column 11.\nWas expecting one of:\n \n ...\n ...\n ...\n \"+\" ...\n \"-\" ...\n ...\n \"(\" ...\n \"*\" ...\n \"^\" ...\n ...\n ...\n ...\n ...\n ...\n ...\n \"[\" ...\n \"..

    Elasticsearch에서 Paging시 max_result_window 초과시 조회가 안되는 이슈

    엘라스틱 서치에서 데이터를 paging 하여 조회할때 from과 size를 사용한다. from은 시작 지점을 이야기하고 size는 그 시작 지점으로 부터 몇 개의 데이터를 보여주어야 하는 건지 설정할 때 사용 되는 값이다. 그래서 계산 방법은 다음과 같다.from : (page - 1) * size size : size 그럼 만약 3개씩 보여주는 페이지에서 2번째 페이지를 보여주기 위해서는 from은 3, size는 3으로 설정하면 된다.123456789GET wedul/_search{ "from": 3, "size": 3, "query": { "match_all": {} }} cs 그럼 만약 wedul 페이지를 접근하다가 다음과 같이 Document의 숫자가 10000을 넘어가게 되면 어떻게 될까? 쿼..

    Elasticsearch 6.4 기본 한글 형태소 분석기 노리 (nori) 설명 및 사전 추가하기

    엘라스틱 서치를 쓰면서 기존에 형태소 분석기를 아리랑, 은전한닢, open korea등을 사용했었다. 근데 이번에 6.4버전이 출시 되면서 Elasticsearch에서 기본으로 제공하는 한글 형태소 분석기가 나왔다. 이름은 nori(노리)이다. 노리는 놀이라는 뜻에서 가져왔으며 mecab-ko-dic 사전을 이용하지만 사전을 압축하므로 기존 형태소 분석기와 비교하여 메모리를 적게 쓰고 훨씬 빠르다. 그럼 Docker에 엘라스틱서치 6.4와 Kibana 6.4를 설치하고 Nori 플러그인을 설치해서 한글 형태소분석기를 사용해보자. Docker에 Elasticsearch와 Kibana 설치12docker run -d -p 9200:9200 -p 9300:9300 --name elastic -e "discov..

    엘라스틱 서치 (elasticsearch) fielddata

    엘라스틱 서치에서 aggregations를 사용하여 text 필드를 그룹화 하려고 했다. 하지만 이런 오류와 함께 사용이 되질 않았다.12Fielddata is disabled on text fields by default. Set fielddata=true on [your_field_name] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory.cs 그래서 엘라스틱 서치 문서를 살펴보던 중 text 필드에 fielddata에 대해 알게 되었다. 대 부분의 필드 들은 기본적으로 자신의 필드가 검색가능하도록 인덱스 처리가 된다. 그러기 위해서..