1. 인덱스

인덱스는 키 값으로 행 데이터의 위치를 식별하는데 사용하는 기능입니다.

그러기 위해서는 원본 테이블을 기준으로 잘 정렬된 별도의 테이블, 즉 인덱스 테이블을 생성해야 하고, 이로 인해 데이터 엑세스 성능을 높일 수 있습니다.

인덱스의 존재 유무에 따라 쿼리의 결과는 달라지지 않습니다.


인덱스를 효과적으로 사용하려면 정규화가 되어 있어야 합니다.

정규화가 되어 있지 않은 테이블은 컬럼이 많으며, 이에 따라 조합할 수 있는 인덱스가 많아지게 됩니다.

인덱스가 많으면, 갱신 성능이 나빠지고 디스크 공간도 많아지므로 인덱스를 효과적으로 사용하려면 정규화가 잘 되어 있어야 합니다.



인덱스 특징

인덱스는 다음과 같은 특징이 있습니다.

  • 인덱스 테이블
    • 이진트리 검색( 뒤에서 살펴볼 인덱스 종류 )을 위해서는 미리 데이터가 정렬되어 있어야 합니다.
    • 하지만 데이터가 항상 정렬되어 있기란 어렵기 때문에, 특정 컬럼을 기준으로 이진트리를 생성하는 새로운 테이블을 생성하여 미리 정렬된 상태를 만들어야 합니다.
    • MySQL에서는 테이블을 생성할 때 특정 컬럼을 PK로 설정하면, 그 컬럼에 대한 인덱스 테이블을 자동으로 만듭니다. ( 링크 )
  • 인덱스 테이블은 일반 테이블과 같이 데이터베이스 객체입니다.
  • 인덱스 테이블만으로는 아무런 기능을 할 수 없기 때문에 다른 테이블에 의존적입니다.


검색 성능이 좋다고 항상 좋은 것은 아닙니다. 언제나 trade off가 존재하죠.

인덱스를 사용하면 다음과 같은 단점이 있습니다.

  • 자원
    • 인덱스 테이블이라는 테이블이 생성되므로 메모리를 많이 소비하게 됩니다. 
    • 따라서 PK 같은 컬럼들을 인덱싱 하도록 하고, 많은 컬럼을 인덱스로 않도록 남용하지 않는 것이 좋습니다.
  • SELECT를 제외한 INSERT, UPDATE, DELETE에 대한 성능 저하
    • 어떤 테이블에 데이터를 추가할 경우, 이에 관계된 인덱스 테이블에서는 데이터를 정렬해야 하므로 전체적인 성능이 저하됩니다.





2. 인덱스 종류, B+ 트리를 중심으로...

인덱스에는 여러 종류가 있습니다.

일반적으로 B+트리 인덱스를 사용하는데, 어떤 인덱스를 사용하는지는 벤더 제품에따라 다릅니다.


다음은 인덱스의 종류에 대한 간단한 소개입니다.

  • 해시 인덱스 ( Hash Index ) - 참고
    • 해시 테이블을 이용한 인덱스로, 해시값을 사용합니다.
    • 해시 값을 사용하기 때문에 매우 빠르지만, 등가비교검색( 값이 같은지 다른지 )만 가능합니다.
    • 기본키는 등가비교만 해도 충분한 경우가 많으므로, 해시 인덱스를 고려해볼 수 있습니다.
  • 풀 텍스트 인덱스 ( Full Text Index ) - 참고
    • "ㅇㅇ"단어를 포함한 행을 검색하고 싶을 때 사용합니다.
    • B+트리는 LIKE 검색으로 중간일치, 후방일치 검색을 할 수 없지만, 전문검색 인덱스 방법으로는 가능합니다.
    • 형태 분석법, N 그램을 통해 단어를 구분합니다.
  • R 트리 인덱스 ( 공간 인덱스 ) - 참고
    • 최소 경계 사각형( MBR, Minimum Bounding Rectangle )이라는 개념을 사용해 인덱스를 구성합니다.
      • MBR이란 어떤 도형을 둘러싼 최소의 직사각형을 의미합니다.
    • 2차원의 데이터를 인덱싱하고 검색하려는 목적으로 사용되며, GPS( 위도, 경도 ) 같은 공간 검색에 활용됩니다.
  • 그 밖에...
    • 함수 인덱스
    • 비트맵 인덱스



B+ 트리
많은 인덱스 알고리즘 중에 자세히 알아볼 인덱스는 B+트리 입니다.

RDB에서 인덱스는 일반적으로 B+트리 자료구조를 이용하여 검색을 수행하며,
B+ 트리는 다음과 같이 구성됩니다.
  • 실제 데이터가 저장된 리프노드( Leaf nodes )
  • 리프노드까지의 경로 역할을 하는 논리프노드( Non-leaf nodes )
  • 경로의 출발점이 되는 루트 노드( Root node )
B+트리는 리프노드에 이르기까지에 대한 자식 노드에 포인터가 저장되어 있습니다.
즉, B+트리의 검색은 루트노드에서 어떤 리프 노드에 이르는 한 개의 경로만 검색하면 되므로, 매우 효율적이다.

위와 같은 구조로 인해, B+ 트리 인덱스는 등가 비교는 물론 범위 검색에도 사용될 수 있습니다.
  • 등가 비교
    • WHERE key = 123
  • 범위 검색
    • WHERE key BETWEEN 100 AND 200
    • LIKE 검색의 와일드카드는 전방 일치여야 인덱스 효과를 얻을 수 있습니다.
      • WHERE key LIKE 'foo%'
      • Leaf node에서 문자열이 사전 순서대로 정렬돼 있기 때문에 전방 일치가 아닌 LIKE 검색은 물리적으로 불가능합니다.

B+ 트리에 대해 더 자세히 알고 싶다면 아래의 링크를 추천합니다.
  • https://www.javatpoint.com/b-plus-tree
  • https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html





3. 인덱스를 설계 한다는 것

인덱스가 늘어날수록 테이블을 갱신할 때 오버헤드가 커지고, 디스크 공간이 늘어나므로 최적의 인덱스를 찾는 것이 중요합니다.


인덱스를 설계 한다는 것은 어떤 컬럼을 조합해서 인덱스를 작성할 것인지,

즉 어떻게 컬럼을 조합해야 조회, 갱신의 모든 성능을 높일 수 있는지에 대한 논의입니다.


인덱스 설계는 응용프로그램에서 실행하는 쿼리에 대해 최적의 인덱스를 찾아내야 하는 것이므로, 최적의 인덱스 조합을 찾는 것은 오래 걸리는 어려운 작업이라고 할 수 있습니다.


단지, 다음과 같은 경우의 인덱스 설계는 피하는 것이 좋습니다.

  • 모든 컬럼이 인덱스
  • 인덱스에 포함된 컬럼이 한 개 밖에 없는 경우
  • 0또는 1같은 값 밖에 없는 플래그 컬럼이 인덱스인 경우




이상으로 인덱스에 대해 알아보았습니다.

B+ 트리를 이해하면, 인덱스가 왜 빠른지에 대해 알 수 있습니다.

이번 기회를 통해 말로만 듣던 B+트리에 대해 알아보는 계기가 되었네요.



책을 읽어서 개발 공부를 하는 것도 좋지만, 토이 프로젝트를 통해 공부하는 것이 나에겐 많은 도움이 되었다.

학생 때 친구들하고 프로젝트를 하면서 어떤 기능을 추가할까, 이건 왜 안될까 등등 하루종일 그 프로젝트에 대한 고민들로 가득찼었다.

그 때가 재밌어서 그런지, 좋은 아이디어가 있으면 또 뭔가를 만들고 싶었다.


간간히 아이디어 대한 고민을 했었는데, 갑자기 떠오른 아이디어가 있었다.

평소에 조금 불편했었던 것에서 생각이 시작이 됐는데, 이걸 토이 프로젝트로 하면 재밌을 것 같다는 생각이 들었다.

이것저것 기능들을 생각해보고, 사용하고 싶은 기술 스택을 나열하고 있는데... 벌써 재밌다.


그런데 아쉽게도 당장 해야할 공부들이 많다.

대략 1년 정도는 책보면서 공부해야 할 것들이 있어서, 토이 프로젝트는 그 뒤에 하려고 한다.

완성도 있는 프로젝트를 하기 위한 밑거름이라 생각하고 열심히 공부해야지...

2020년 안에는 결과물을 볼 수 있기를 기대해본다!


'끄적끄적 > 일기' 카테고리의 다른 글

토이 프로젝트  (1) 2019.05.12
2018년 회고  (4) 2019.03.01
  1. Favicon of https://n-log.tistory.com 꿈꾸는 엔 2019.06.06 21:42 신고

    프로젝트 하자아아



이 책은 관계형 모델과 SQL이 어떻게 다른지, 관계형 모델 설계, 어떻게하면 RDB를 잘 다룰 것인가에 대해 다루고 있다.

이에 대한 방식으로 관계형 모델을 깊게 파고든다.

원래는 기초 SQL이 아닌 잘못된 쿼리 사례, 주의사항 등 튜닝과 관련된 책을 읽고 싶었는데... 내가 생각한 것과 좀 다른 내용이었다.


이 책은 관계형 모델에 대해 정말 깊게 파고드는데, 학부때 들었던 DB 이론 수업이 떠올랐다.

먼저 관계형 모델에 대해 다루면서 관계형 모델과 SQL이 다르다는 것을 알게 되었다.

또 학부때 이해가 안됐던 정규형에 대해 제대로 공부를 해본 계기가 되었다.

정규화는 연습이 필요하기에 당장 정규화를 하라고 하면 할 수 있을지는 모르겠지만, 정규화에 대한 대화는 나눌 수 있을것 같다.


책의 중반부를 넘어가면 본격적으로 SQL과 관련된 얘기가 나오는데, 모두 초반에 다뤘던 관계형 모델을 기반으로 설명을 한다.

왜 SQL을 그렇게 짜면 안되는지, 관계형 모델을 기반으로 설명해준다.

책을 읽다보면 왜 그렇게 앞에서 관계형 모델을 깊이있게 다뤘는지 이해가 된다.


사실 중간에 책을 덮으려 했다.

나는 어떻게 쿼리를 잘 작성할수 있는지에 대한 내용을 원했기 때문이다.

그리고 아직 업무적으로 설계할 일도 없고, 관계형 모델이란게 조금 뜬구름 잡는 얘기 때문인 것도 있다.

그래도 책이 두껍지 않아서 일단 읽었는데, 많은 도움이 된것 같다.


이 책을 읽으면서 가장 기억에 남는건

1. 관계형 모델의 개념과 SQL과 다른점

2. 정규화

3. NULL에 대하여

4. 



관계형 모델에 대해 알고 싶다면 한 번 읽어보는 것도 괜찮을 것 같다.



이번 글에서는 한 번의 API 요청으로 대량으로 document를 추가하고 조회하는 방법에 대해 알아보겠습니다.



1. MultiSearch API ( 링크 )

예를 들어 ES 서버에서 이메일 주소를 검색하는 상황을 가정해보겠습니다.

이메일 주소를 검색하기 위한 query DSL을 ES 서버에서 작성하고, Client에서는 해당 서버의 API를 호출하기만 하면 데이터를 받을 수 있습니다.

그런데 검색해야 할 이메일 주소가 100개라면 총 100번의 API를 호출해야 합니다.

이는 네트워크 비용이 발생하기 때문에 오류가 발생할 수 있으며, 성능 상의 이슈가 있을 수 있습니다.

따라서 한 번의 호출로 100개의 데이터를 조회하는 방법이 필요한데, ES에서는 이를 MultiSearch API로 제공합니다.


1) json 파일 작성

MultiSearch API를 사용하는 방법은 간단합니다.

json 파일을 생성해서 다음과 같은 포맷으로 쿼리를 작성하면 됩니다.

# vi query.json

{"index" : "test"} {"query" : {"match_all" : {}}, "from" : 0, "size" : 10} {} {"query" : { "term" : { "address" : "street" }}}

연속된 2개의 json이 header와 body로 나뉘어 하나의 쌍을 이루며, 결론적으로 위의 예제는 총 2개의 검색을 수행됩니다.

header에는 index와 search_type, preference, routing 같은 정보들을 작성하며,

body에는 query, aggregations, from, size 같은 요청 쿼리를 작성합니다.


json을 개행으로 구분하기 때문에, body의 모양을 예쁘게 하겠다고 개행을 해버리면 MultiSearch API를 호출할 수 없습니다.

즉, 다음과 같이 작성하면 안됩니다.

# vi query.json

{"index" : "test"}

{ "query" : { "match_all" : {} }, "from" : 0, "size" : 10 }

만약 쿼리가 길어서 별도의 파일로 보관하여 유지보수를 용이하게 하고 싶다면 template을 사용할 수 있습니다.

자세한 사용법은 여기를 참고해주세요!




2) MutlSearch API 호출

여러 키워드를 검색하기 위한 json 파일을 준비했다면, 다음과 같이 curl 요청으로 API를 호출할 수 있습니다.

# curl -X GET 'localhost:9200/인덱스/_msearch?pretty' -H 'Content-Type: application/x-ndjson' --data-binary @query.json


인덱스 명시

특정 index에 대해서 MultiSearch API를 호출하려면 URI에 인덱스를 명시해주고, 모든 index에 대해 검색하려면 'localhost:9200/_msearch'만 작성하면 됩니다.

그런데 모든 index에 대해 검색하면 성능이 좋지 않으므로 json 파일 각 header에서 인덱스를 명시하는 것이 좋습니다.


_msearch

MultiSerach API를 호출하기 위해서는 _search가 아닌 _msearch입니다.


Content-Type

공식 문서에서는 application/x-ndjson으로 명시할 것을 권장합니다.


--data-binary

MultiSearch에서 json 파일로 검색하기 위해서는 -d가 옵션이 아닌 --data-binary 옵션으로 full name을 작성해줘야 에러가 발생안합니다.




3) response

MultiSearch API 호출 결과 응답은 다음과 같은 양식을 따릅니다.

{ "responses" : [ { 단일 검색 결과 }, {

단일 검색 결과

},

... ] }

  • responses
    • MutlSearch로 총 100개의 검색을 수행했다면, responses 하위에는 100개의 json이 있습니다.
    • 각 json은 _search API로 단일 호출했을 때의 결과가 그대로 있다고 보시면 됩니다.

그런데 검색하는 키워드가 많을 수록 데이터의 양은 엄청 커질 것이라는 것을 예측할 수 있습니다.

따라서 query를 작성할 때 특정 필드만 보여주는 방법 등으로 결과 document를 가공할 필요가 있습니다.



대량으로 document를 조회하는 방법은 이와 같이 MultiSearch API를 사용하면 됩니다.

다음은 대량으로 document를 추가하는 방법인 Bulk API에 대해 알아보겠습니다.





2. Bulk API ( 링크 )

Bulk API로 document를 대량으로 추가하는 방법도 MultiSearch API와 유사합니다.

json 파일을 만들어서 header와 body를 작성한 후, API를 호출하면 됩니다.


1) json 파일 작성

지금까지 Bulk API로 document를 추가하는 방법에 대해서만 언급했지만, 사실은 Bulk API를 통해 document를 update, delete도 할 수 있습니다.

# vi query.json

{ "index" : {} } { "name" : "test_auto_generate_id" } { "index" : { "_id" : "1" } } { "name" : "name_create1" } { "create" : {"_id" : "2" } } { "name" : "name_create2" } { "update" : {"_id" : "2" } } { "doc" : { "name" : "name_update" } } { "delete" : { "_id" : "2" } }

  • { "index" : {} } / { "name" : "test_auto_generate_id" }
    • URL에 index와 type을 명시한 경우 header에 "index" : {} 만 명시해도 해당 index, type에 document가 추가됩니다.
    • header에 _id를 명시하지 않아도 자동으로 _id 값이 생성됩니다.
  • { "index" : { "_id" : "1" } } / { "name" : "name_create1" }
    • _id 값을 부여해서 document를 추가하는 방법입니다.
  • { "create" : {"_id" : "2" } } / { "name" : "name_create2" }
    • header에 "index"가 아닌 "create"를 명시하여 document를 추가하는 방법입니다.
  • { "update" : {"_id" : "2" } } / { "doc" : { "name" : "name_update" } }
    • Bulk API로 document를 update 할 수도 있습니다.
    • update를 하려면 body에 "doc" 필드를 명시해줘야 합니다.
  • { "delete" : { "_id" : "2" } }
    • Bulk API로 document를 delete 할 수도 있습니다.
    • delete를 할 때 body는 작성할 필요가 없습니다.



2) Bulk API 호출

다음은 Bulk API를 호출하는 curl 요청입니다.

# curl -X POST 'localhost:9200/victolee/test/_bulk?pretty' -H 'Content-Type: application/x-ndjson' --data-binary @query.json

위 예제에서는 URI에 특정 index와 type을 명시해줬으며,

Content-Type도 MultiSearch API와 같이 application/x-ndjson으로 작성했고, --data-binary 옵션으로 json 파일을 넘겨줍니다.


Bulk API를 호출할 때 여러 작업 중 하나가 실패하더라도 Bulk API는 실패하지 않습니다.

즉, 어떤 이유로 어느 한 작업이 실패하더라도 나머지 작업은 계속 처리됩니다.

response에서 각 작업의 상태를 전송 순서와 동일하게 표시하므로 어떤 작업이 실패했는지 여부를 알 수 있습니다.





이상으로 대량으로 document를 추가/수정/삭제하는 Bulk API 그리고 대량으로 document를 조회하는 MultiSearch API에 대해 알아보았습니다.



이번 글에서는 URI 또는 Query DSL을 통해 조회된 document들에 대해서 결과를 가공하는 방법에 대해 알아보겠습니다.

이 글은 공식문서를 참고했으며, 검색 결과 response에 대한 각 필드의 설명은 여기를 참고해주세요.


실습을 위한 테스트 데이터 셋팅은 여기을 참고하시길 바랍니다.

아래의 예제들을 실행하기 위해서는 query.json 파일을 만들어서 각 예제마다 수정을 하고, 명령어는 모두 다음과 같이 실행하면 됩니다.

# curl -XGET 'localhost:9200/bank/account/_search?pretty' -H 'Content-Type: application/json' -d @query.json



1. from / size ( 참고 )

from과 size 필드는 pagination 개념과 관련있습니다.

예를 들어, 게시판 페이징을 할 때 쪽수는 from이 되고, size는 한 번에 나타날 게시글의 수가 됩니다.

즉, SQL로 따지면 from은 offset, size는 limit이 되겠죠.


아래는 3개의 document만 반환하도록 조회하는 예제입니다.

{ "from" : 0,

"size" : 3, "query":{ "match_all":{} } }

from과 size 쿼리는 index setting인 index.max_result_window에 설정된 값을 초과할 수 없습니다.

해당 설정은 기본 값이 10,000이며, 즉, 최대 10,000개의 document를 호출할 수 있고 그 이상 호출을 하려면 scroll API를 사용해야 합니다.




2. sort ( 참고 )

sort 쿼리로 특정 필드마다 하나 이상의 정렬을 추가 할 수 있습니다.

sort 쿼리를 사용하지 않을 경우, 기본 정렬은 _score 내림차순(desc)이며, 다른 항목으로 정렬할 경우 오름차순(asc)으로 기본 설정됩니다.


아래는 age 필드에 대해 내림차순으로 정렬한 후, balance 필드에 대해 내림차순으로 정렬하고 _socre를 내림차순으로 정렬하는 예제입니다.

{
   "sort" : [
        { "age" : "desc" },
        { "balance" : "desc" },
        "_score"
    ],
   "query":{
      "match_all":{}
   }
}




3. source filtering ( 참고 )

_source 필드를 통해 검색된 데이터에서 특정 필드들만 반환하도록 할 수 있습니다.

SQL에서 SELECT 쿼리를 날릴 때 특정 컬럼들을 명시하는 것과 유사합니다.


아래는 검색된 document들에 대해 모든 필드들을 응답받지 않는 예제입니다.

{
   "_source": false,
   "query":{
      "match_all":{}
   }
}

검색된 document의 총 개수만 알고 싶을 경우, _source를 노출시키지 않음으로써 성능을 높일 수 있습니다.


아래는 검색된 document들에 대해 firstname, lastname 필드만 응답받는 예제입니다.

{ "_source": ["firstname","lastname"], "query":{ "match_all":{} } }

그 밖에 *를 사용하여 필드명을 명시할 수 있고, includes/excludes를 사용하여 필드를 포함 제외할 수 있습니다.




4. aggregations ( 참고 )

aggregations는 집계를 의미하며 aggs 필드를 통해 document 개수를 통계낼 수 있습니다.

SQL에서 GROUP BY와 유사합니다.

ES는 검색 엔진인 만큼 다양한 통계 방식을 제공하는데요, 이 글에서 모두 다를 수 없으므로 공식 문서를 참고하시길 바랍니다.


아래는 address에 street 문자열이 포함된 document들의 balance 필드 값들을 평균내는 예제입니다.

{ "query": { "term": { "address" : "street" } }, "aggs" : { "avg_balance_test" : { "avg" : { "field" : "balance" } } } }

  • avg_balance_test
    • response 데이터에 명시될 통계 결과 필드명을 의미하며, 원하는대로 작성하면 됩니다.
  • avg
    • 집계 타입을 의미하며, sum, cardinality 등 여러가지가 있습니다.
  • field
    • 어떤 필드에 대해 통계를 낼 것인지 명시하며, 위 예제에서는 balance 필드에 대한 집계를 했습니다.




이상으로 검색 결과를 가공하는 방법에 대해 알아보았습니다.

aggregations는 통계를 낼 때 매우 유용하다고 생각하지만, 저는 아직 많이 사용해보지 않아서 자세히 못다뤘네요..



이번 글에서는 쿼리를 통해 검색을 하는 Query DSL( Domain Specific Language )에 대해 알아보겠습니다.

실습을 위한 테스트 데이터 셋팅과 Search API 개념과 관련하여 이전 글을 먼저 읽으시길 권장합니다.




1. Query DSL

이제 본격적으로 json 포맷으로 query를 만들어서 검색을 해보는 Query DSL에 대해 알아보겠습니다.

검색할 때 대부분 Query DSL을 사용하므로 이 방법을 익혀두는 것이 좋습니다.


Query DSL에 대해 알아보기에 앞서 Query Context와 Filter Context에 대한 개념이 필요합니다. ( 참고 )

앞으로 소개 할 query 절은 Query Context 또는 Filter Context에서 사용되는지 여부에 따라 다르게 동작합니다.

  • Query Context
    • Query Context에서 사용되는 query 절은 " 해당 document가 query 절과 얼마나 잘 일치하는가? "라는 질문에 응답하는데, document가 얼마나 잘 일치하는지를 _score( 관련성 점수, relevance score )로 표현합니다.
  • Filter Context
    • Filter Context에서 사용되는 query 절은 " 해당 docuemnt가 query 절과 일치합니까? "라는 질문에 응답하는데, 그 대답은 true 또는 false이며 점수는 계산하지 않습니다.


아래의 예제는 다음의 종족이 모두 충족되는 document를 반한하는 예제입니다.

1) title 필드에 search가 있고

2) content 필드에 elasticsearch가 있고

3) status 필드의 값이 정확히 published이고

4) publish_date 필드의 값이 정확히 2015-01-01 이후인 경우

{ "query": { "bool": { "must": [ { "match": { "title": "Search" }}, { "match": { "content": "Elasticsearch" }} ], "filter": [ { "term": { "status": "published" }}, { "range": { "publish_date": { "gte": "2015-01-01" }}} ] } } }

여기서 query 파라미터는 Query Context를 명시한 것이며, bool과 그 아래 2개의 match 절은 Query Context가 됩니다.

filter 파라미터는 Filter Context를 명시한 것이며, term과 range 절은 Filter Context가 됩니다.


  • bool 쿼리 아래에 있는 filter 또는 must_not 파라미터
  • constant_score 쿼리
  • filter aggregation

등과 같이 자주 사용되는 필터는 성능을 높이기 위해 ES가 캐싱합니다.

따라서 두 환경의 차이를 다음과 같이 정리할 수 있습니다.

참고: https://m.blog.naver.com/tmondev/220292262363




2. Query DSL 예제

이제 예제를 통해 Query DSL에는 어떤 것들이 있는지 살펴보도록 하겠습니다.

ElasticSearch의 모든 API를 소개하는 것은 무리가 있으며, 아래와 같이 몇 가지의 사용법을 익힌다면 문서를 보면서 자유자재로 사용할 수 있지 않을까 싶습니다.


아래의 예제들을 실행하기 위해서는 query.json 파일을 만들어서 각 예제마다 수정을 하고, 명령어는 모두 다음과 같이 실행하면 됩니다.

# curl -XGET 'localhost:9200/bank/account/_search?pretty' -H 'Content-Type: application/json' -d @query.json


1) match_all / match_none 참고 )

match_all 쿼리는 지정된 index의 모든 document를 검색하는 방법입니다.

즉, 특별한 검색어 없이 모든 document를 가져오고 싶을 때 사용합니다.

SQL로 치면 WHERE 절이 없는 SELECT문과 같겠네요.


이와 유사하게 match_none이 있는데, 모든 document를 가져오고 싶지 않을 때 사용합니다. 

# vi query.json

{ "query":{ "match_all":{} } }



Full text Queries

2) match ( 참고 )

match 쿼리는 기본 필드 검색 쿼리로써, 텍스트/숫자/날짜를 허용합니다.

아래는 address에 mill이라는 용어가 있는 모든 document를 조회하는 예제입니다.

{

"query":{ "match":{ "address":"mill" } } }



Filter Context

3) bool 참고 )

bool 쿼리는 bool( true / false ) 로직을 사용하는 쿼리이며, 그 종류는 다음과 같습니다.

  • must : bool must 절에 지정된 모든 쿼리가 일치하는 document를 조회
  • should : bool should 절에 지정된 모든 쿼리 중 하나라도 일치하는 document를 조회
  • must_not : bool must_not 절에 지정된 모든 쿼리가 모두 일치하지 않는 document를 조회
  • filter : must와 같이 filter 절에 지정된 모든 쿼리가 일치하는 document를 조회하지만, Filter context에서 실행되기 때문에 score를 무시합니다. 

bool 쿼리 내에 위의 각 절들을 조합해서 사용할 수도 있고,

또한 bool 절 내에 bool 쿼리를 작성할 수도 있습니다.


아래는 나이가 40세이지만, ID 지역에 살고 있지 않은 document를 조회하는 예제입니다.

{

"query": { "bool": { "must": [ { "match": { "age": "40" } } ], "must_not": [ { "match": { "state": "ID" } } ] } } }




4) filter ( 참고 )

filter 쿼리는 document가 검색 쿼리와 일치하는지 나타내는 _score 값을 계산하지 않도록 쿼리 실행을 최적화합니다.

자세한 내용은 위에서 Filter Context에서 다뤘으니 예제도 생략하겠습니다.




5) range ( 참고 )

range 쿼리는 범위를 지정하여 범위에 해당하는 값을 갖는 document를 조회합니다.

앞에서 살펴본 바와 같이 Filter Context이며, 정수, 날짜를 비교할 수 있습니다.


range 쿼리에서 범위를 지정하는 파라미터는 다음과 같습니다.

  • gte : 크거나 같다.
  • gt : 크다.
  • lte : 작거나 같다.
  • lt : 작다.
  • boost : 쿼리의 boost 값을 셋팅합니다. ( 기본 값 1.0 )
    • boost란 검색에 가중치를 부여하는 것으로, 여기를 참고하시길 바랍니다.


아래는 잔액이 20000~30000인 범위에 속하는 document를 조회하는 예제입니다.

{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}



Term Level Queries

6) term ( 참고 )

term 쿼리는 역색인에 명시된 토큰 중 정확한 키워드가 포함된 document를 조회합니다.


term 쿼리를 사용할 때 document가 조회되지 않는 이슈가 있을 수 있습니다.

string 필드는 text 타입( 이메일 본문과 같은 전문(full text) ) 또는 keyword 타입( 전화번호, 우편번호 등.. )을 갖습니다.

text 타입은 ES 분석기를 통해 역색인이 되는 반면, keyword 타입은 역색인이 되지 않는 특징이 있는데요.

예를 들어, "Quick Foxes" 라는 문자열이 있을 때 text 타입은 [quick, foxes]으로 역색인이 됩니다.


이런 상황에서 term 쿼리로 "quick" 문자열을 검색했다면 해당 document를 찾을 수 있지만,

"quick foxes"라는 전문을 검색했을 경우에는 document를 찾을 수 없습니다.


따라서 term 쿼리는 정확한 키워드를 찾기 때문에 전문 검색( full text search )에는 어울리지 않습니다.

전문 검색을 하고자 할 경우에는 match 쿼리를 사용하는 것이 좋다고 합니다.

또는 "Quick Foxes"라는 문자열의 타입을 keyword 타입이 되도록 mapping을 하는 방법도 있습니다.


term 쿼리 사용방법은 다음과 같습니다.

{ "query": { "term" : { "lastname" : "bond" } } }

term 쿼리는 역색인에 명시된 문자열을 찾으므로 Bond 문자열에 대해선 찾을 수 없습니다.

ES에서 분석기를 거쳐 역색인이 될 때 lowercase 처리하기 때문이죠.




7) terms ( 참고 )

terms 쿼리는 배열에 나열된 키워드 중 하나와 일치하는 document를 조회합니다.


아래는 address 필드에서 street, place, avenue 키워드가 하나라도 존재하는 document를 조회하는 예제입니다.

{
  "query": {
    "terms": {
      "address": ["street", "place", "avenue"]
    }
  }
}

최소 몇 개의 검색어가 포함되기를 원한다면 여기를 참고하면 좋을 것 같습니다.




8) regexp ( 참고 )

regexp 쿼리는 정규 표현식 term 쿼리를 사용할 수 있습니다.

regexp 쿼리는 Term Level 쿼리인데, 이는 정확한 검색을 한다는 의미입니다.


아래는 address 필드에서 끝 문자열이 street인 document를 조회하는 예제입니다.

{
    "query": {
        "regexp":{
            "address": ".*street"
        }
    }
}

정규식 .* 을 분석해보면 다음과 같습니다.

  • . : 모든 문자열
  • * : 0개 이상의 자리수

즉, " ( 0개 이상의 자리수를 갖는 모든 문자열 ) + street " 인 문자열을 찾는 쿼리가 됩니다.

그 밖에 ES 정규식 문법에 대해서는 여기를 참고해주세요





이상으로 Query DSL의 몇 가지 쿼리들에 대해 알아보았습니다.

다음 글에서는 이렇게 조회한 쿼리들에 대한 검색 결과를 가공하는 방법에 대해 알아보겠습니다.


[ 참고 문서 ]

http://www.jopenbusiness.com/mediawiki/ElasticSearch_-_REST_API

https://bakyeono.net/post/2016-08-20-elasticsearch-querydsl-basic.html


ES는 검색 엔진인 만큼 다양한 검색 API를 제공하며, 이를 잘 알아야 ES를 효과적으로 사용할 수 있을 것이라 생각합니다.

이번 글에서는 Search API에 대해 알아보겠습니다.

다음 글 Query DSL을 다루기 위한 사전지식/준비작업 느낌입니다.




1. 검색하기 전 테스트 테이터 셋팅

검색을 하려면 대량의 데이터가 필요합니다.

ES 공식 문서에 이를 제공해주는데요( 링크 ), 이를 복붙해서 json 파일을 만들고 아래의 명령어를 실행해서 bulk API를 호출합니다.

bulk API는 여기에서 다룰 것이며, 지금은 대량으로 document를 추가하기 위한 API라고 생각하시면 됩니다.

# vi test_data.json 위 링크에서 데이터를 복붙하여 저장

// bulk API 호출

# curl -XPOST 'localhost:9200/bank/account/_bulk?pretty&refresh' -H "Content-Type: application/json" --data-binary "@test_data.json"


// bank index가 추가되었는지 확인

# curl -XGET 'localhost:9200/_cat/indices?v'

위와 같이 1000개의 데이터가 추가되었으면 성공입니다.





2. search API

search API는 이전 글에서 모든 document를 검색할 때 사용했었습니다.

# curl -XGET 'localhost:9200/_all/_search?pretty'

_serach는 검색 작업을 하겠다는 액션을 의미합니다. ( serach API )

그리고 어떻게 검색을 할 것인지에 대한 조건( 쿼리 )들을 명시를 해줘야 원하는 정보들을 얻을 수 있을겁니다.


조건 전달 방법은 2가지가 있습니다.

  • URL에 파라미터를 넘기는 방법 ( URI Search )
  • json 파일에 쿼리를 작성하여 POST 방식으로 넘기는 방법 ( Query DSL )

이 중에서 후자의 방법을 더 많이 사용합니다.

그 이유는 URL이 깔끔해지고, 더 상세한 표현이 가능할 뿐더러 재사용이 가능하기 때문이죠.


URL을 호출하는 방법은 짧게만 언급하고 다음 글에서 Query DSL에 대해 자세히 알아보도록 하겠습니다.





3. URI Search

URI Search 방식은 모든 검색 옵션을 노출하지 않지만, 빠른 curl 테스트에 유용한 방법입니다.


아래의 API 호출은 위의 테스트 데이터에서 age가 39살인 document만 조회하는 예제입니다.

# curl -XGET 'localhost:9200/bank/account/_search?q=age:39&pretty'


파라미터로 q=age:39를 전달 했더니, 1000개의 document 중 60개만 조회되는 것을 확인할 수 있습니다.

참고로 파라미터 q는 쿼리 스트링으로 Query String Query( 참고 )로 변환됩니다.

그 밖에,

  • 정렬 옵션 sort
  • offset과 유사한 from - 기본 값 0
  • 몇 개를 반환할 것인지에 대한 size - 기본 값 10개

등 다양한 파라미터를 전달 할 수 있는데요, 더 많은 파라미터 정보는 링크를 참고해주세요.

이처럼 검색 결과를 가공하는 부분은 다음 글에서 다루도록 하겠습니다.





4. Response 분석

Search API를 요청하니 응답을 json으로 주고 있습니다.


response의 각 의미는 다음과 같습니다.

  • took : 검색하는데 걸린 시간 (단위: ms)
  • timed_out : 검색시 시간 초과 여부
  • _shards : 검색한 shard 수 및 검색에 성공 또는 실패한 shard의 수
  • hits : 검색 결과
    • total : 검색 조건과 일치하는 문서의 총 개수
    • max_score : 검색 조건과 결과 일치 수준의 최댓값
    • hits : 검색 결과에 해당하는 실제 데이터들 ( 기본 값으로 10개가 설정되며, size를 통해 조절 가능 )
      • _score : 해당 document가 지정된 검색 쿼리와 얼마나 일치하는지를 상대적으로 나타내는 숫자 값이며, 높을수록 관련성이 높음
    • sort : 결과 정렬 방식을 말하며, 기본 정렬 순서는 _score 내림차순(desc)이고, 다른 항목일 경우 오름차순(asc)으로 기본 설정 됨 ( _score 기준일 경우 노출되지 않음 )




이상으로 Search API에 대해 알아보았습니다.

다음 글에서는 Query DSL에 대해 알아보겠습니다.



1. Index, Type, Document

이전 글에서 Cluster에 대해 알아보았습니다.

Clusternode들의 집합이고 노드는 shard로 구성되며, 데이터는 shard로 분산되어 저장합니다.


Index는 1개 이상의 primary shard에 매핑되고, 0개 이상의 replica shard를 가질 수있는 논리적 이름 공간을 말하며, RDBMS의 database와 같은 개념입니다.

Type은 RDBMS에서 database안에 존재하는 table 개념이고,

Document는 RDBMS에서 row와 같은 개념입니다. 즉, 실제로 검색 할 데이터를 의미합니다.


Rest API를 통해 index에 document를 추가할 수 있는데, 이를 "문서를 색인화 한다"고 합니다.

문서를 색인화 하기 위해서는 index가 어떤 type인지, 그리고 _id를 지정해줘야 합니다.

여기서 _id는 RDBMS에서 table의 pk와 같습니다.


다음은 customer index에서 external type으로 1번 id에 document를 추가하는 API입니다.


이제부터 Index, Type, Document에 대한 CURD API를 알아보겠습니다.





1. 클러스터에 존재하는 모든 index 조회

# curl -XGET 'localhost:9200/_cat/indices?v'

처음엔 아무런 데이터가 없습니다.





2. index 추가

다음으로 customer라는 index를 추가해보고 다시 모든 index를 조회 해보겠습니다.

# curl -XPUT 'localhost:9200/customer?pretty'
# curl -XGET 'localhost:9200/_cat/indices?v'


"acknowledged: true"이면, 작업이 성공되었다는 뜻입니다.

조회 결과 customer index가 생성된 것을 확인할 수 있습니다.

그리고 API를 호출할 때 ?pretty를 URL에 추가해줬는데요, 이는 결과( response )를 예쁘게 보여주기 위함입니다.

yellow status인 이유는 이전 글( 링크 )에서 언급을 했었습니다.





3. document 추가

다음으로 index에 document를 추가해보겠습니다.

문서를 색인화 하려면 어떤 type인지, 몇 번 _id에 색인화할 것인지 명시해줘야 합니다.


아래의 API 호출은 customer2 index에서 info type의 1번 _id에 색인화하는 작업입니다.

-d 옵션은 --data-binary의 축약이며, 추가할 데이터를 명시합니다.

# curl -XPOST 'localhost:9200/customer2/info/1?pretty' -H 'Content-Type: application/json' -d '{ "name": "victolee" }'


여기서 customer2 index와 info type는 생성을 한 적이 없는데, index와 type을 자동으로 생성하면서 색인화가 되었다는 점에 주목할 필요가 있습니다.



또한 document를 추가할 때 _id 값을 명시하지 않으면, 임의의 문자열을 _id로 할당합니다.

# curl -XPOST 'localhost:9200/customer2/info?pretty' -H 'Content-Type: application/json' -d '{
"name": "victolee2"
}'



그런데 추가하려는 필드가 name 뿐만 아니라 여러가지가 있다면 명령어에 데이터를 모두 입력하기가 귀찮고, 반복적으로 사용할 수도 없습니다.

그래서 데이터를 json 형식의 파일로 만들어서 API를 호출하는 방법을 사용할 수 있습니다.

-d 옵션에 json을 작성하는 것이 아닌 @파일경로 를 작성하여 명령어를 실행하면 됩니다.

# vi data.json

{ "name": "victory", "address": "경기도", "phone": "010-123-1234", "reg_date": "2019-03-31" }


# curl -XPOST 'localhost:9200/customer2/info/2?pretty' -H 'Content-Type: application/json' -d @data.json





4. document 조회

다음으로 지금까지 추가한 document들을 조회해보겠습니다.

ES는 검색 엔진으로서 다양한 검색 방법을 제공하는데요.

다음 글에서 검색에 대해 자세히 알아보도록 하고, 지금은 간단한 API만 소개하도록 하겠습니다.


먼저 customer2 index의 모든 document를 조회하는 방법입니다.

# curl -XGET 'localhost:9200/customer2/_search?pretty'


URL에 있는 _search는 query DSL를 위해 사용하는 API이며, 원래는 뒤에 query를 명시해줘야 하지만 다음 글에서 자세히 다루도록 하겠습니다.



다음은 모든 index( _all )에서 모든 document를 검색해보겠습니다.

customer index에 데이터가 없으므로 데이터를 추가하고 검색을 해보도록 하겠습니다.

# curl -XPOST 'localhost:9200/customer/info?pretty' -H 'Content-Type: application/json' -d '{ "name": "victolee" }' # curl -XGET 'localhost:9200/_all/_search?pretty'

customer, customer2 두 index 모두에서 document를 검색한 것을 확인할 수 있습니다.



다음은 _id를 이용해서 document를 검색하는 방법입니다.

# curl -XGET 'localhost:9200/customer2/info/1?pretty'

맨 처음 추가했던 document가 조회되네요.

응답 결과의 _source 프로퍼티에는 실제 데이터가 있습니다.



다음은 document의 응답 결과를 줄일 수 있는 방법입니다. ( 참고 링크 )

SQL에서 SELECT 문에 특정 컬럼들을 명시하는 방법과 같은 개념입니다. ( SELECT 컬럼1, 컬럼2 FROM 테이블 )

예를 들어, 실제 데이터인 _source만 보고 싶을 때 query String에 filter_path=_source를 추가합니다.

# curl -XGET 'localhost:9200/customer2/info/2?pretty&filter_path=_source'

# curl -XGET 'localhost:9200/customer2/info/2?pretty&filter_path=_source.name'




5. document 수정

수정 작업은 추가 작업이랑 유사합니다.

customer2 index에서 _id가 1인 document를 수정해보도록 하겠습니다.

# curl -XPUT 'localhost:9200/customer2/info/1?pretty' -H 'Content-Type: application/json' -d '{
"name": "victolee_update"
}'

document가 수정 됐고, _version 정보가 바뀐 것을 확인할 수 있습니다.





6. index, document 삭제

특정 id의 document를 삭제하는 방법입니다.

# curl -XDELETE 'localhost:9200/customer2/info/1?pretty'



다음은 index를 삭제하는 방법입니다.

# curl -XDELETE 'localhost:9200/customer2?v'





이상으로 index, document를 중심으로 데이터를 조작하는 CRUD 작업을 해보았습니다.

다음은 조금 더 응용된 방식으로 document를 검색하는 API에 대해 알아보겠습니다.



서론

제가 처음 Elasticsearch( ES )를 공부할 때 어려웠던 것은 용어에 대한 낯섦, 방대한 API와 ES 아키텍쳐였습니다.

용어가 낯선 것이야 익숙해질텐데, 방대한 API 속에서 뭐부터 알아야 할지, 검색으로 아키텍쳐에 대한 설명은 찾을 수 있지만 튜닝을 어떻게 해야 할지 감이 안왔었죠.


그런데 사실 데이터베이스 CRUD를 처음 배울 때 Mysql 아키텍쳐가 어떻고, indexing, sharding, master-slave 등 이런 모든 것들을 이해할 필요가 없습니다. 나중에 알아두면 좋지만요.

처음엔 그저 SELECT, INSERT, UPDATE, DELETE 쿼리를 따라해서 익숙해지면 기본은 할 수 있습니다.

그러다가 join이나 subquery 등의 응용 개념들이 쌓이는거죠.


이런 관점에 맞춰 ES에서 데이터를 다루는 방법에 대해 알아보려고 합니다.

기본을 통해 용어들과 API 사용방법에 익숙해지면 그 후는 검색으로 레퍼런스를 찾아보면 되니까요.


예제들은 공식 문서를 참고했고, API를 다루기에 앞서 아래의 글들을 꼭 참고하시길 바랍니다.

용어와 기본 아키텍쳐를 모르면 이해가 어려울 수 있습니다.





1. ES API 호출 방법

ES는 Rest API로 호출을 한다는 것이 특징입니다.

그래서 API를 호출할 때 리눅스에서 curl 요청을 해도 되고, Postman 같은 툴로 HTTP 요청을 해도 ES API를 사용할 수 있습니다.


저는 앞으로 curl 요청을 통해 API를 조회할 것입니다.

현재 curl이 뭔지 몰라도 하다보면 자연스럽게 알게 되는데요, 그래도 궁금하시다면 여기를 참고하면 좋을 것 같네요.





2. Cluster health 체크 - 클러스터 정보

Cluster란 ES에서 가장 큰 시스템 단위를 말하며, node들의 집합입니다.

클러스터는 아키텍쳐를 구축하는게 중요한 부분이라 생각되어 클러스터 구성에 대한 그림을 그릴 수 있을 정도로 간단하게만 짚고 넘어가겠습니다.


ES를 설치하고 나면 Cluster와 node는 1개씩 존재하는데, 그 정보들은 아래의 명령어를 통해 확인할 수 있습니다.

# curl -XGET https://localhost:9200/_cluster/health?pretty=true





3. Cluster status

ES를 설치하고 클러스터 상태를 보니, yellow 상태입니다.

yellow 상태는 모든 데이터의 읽기/쓰기가 가능한 상태이지만 일부 replica shard가 아직 배정되지 않은 상태를 말합니다.

즉, 정상 작동중이지만 replica shard가 없기 때문에 검색 성능에 영향이 있을 수 있습니다.


status에 대한 자세한 설명은 여기를 참고하시면 좋을 것 같습니다.



현재 설치된 ES에서 클러스터의 상태가 yellow인 이유를 알아보도록 하겠습니다.

먼저 아래의 명령어로 index와 shard의 정보들을 조회합니다. ( cat API - indicesshards )

# curl -XGET localhost:9200/_cat/indices?v

# curl -XGET localhost:9200/_cat/shards?v


보시면 victolee index에 primary 당 replica가 1개 존재하는데, replica가 전부 unassigned입니다.

replica는 primary와 같은 노드상에 있을 수 없습니다.

즉, 현재는 하나의 노드가 실행 중이므로 replica를 배정할 수 없게 됩니다.

나중에 다른 노드가 클러스터에 포함되면 replica를 배정할 수 있고, 배정되면 green status로 바뀝니다.


지금은 replica를 갖지 않도록 클러스터 setting을 수정해서 green 상태로 바꿔보도록 하겠습니다.

# curl -XPUT 'localhost:9200/_settings?pretty' -d '{"index":{"number_of_replicas": 0}}' -H 'Content-Type: application/json'


그리고나서 다시 클러스터 상태를 확인해보면,

# curl -XGET https://localhost:9200/_cluster/health?pretty=true

다음과 같이 상태가 green으로 바뀌는 것을 확인할 수 있습니다.



그런데 항상 이렇게 처리하는 것은 좋지 않습니다.

지금 같은 경우는 노드가 master node 1개 밖에 없습니다.

하지만 data node가 추가 되어 클러스터를 구성해야 한다면, replica shard가 노드마다 할당되는 것이 고가용성에 있어서 좋습니다.

이런 상황에서 지금과 같이 replica를 0으로 셋팅한다면 안정성이 떨어지는 아키텍쳐가 되겠죠.





4. Cluster 구성 이해하기

고작 클러스터의 status만 바꾸는 작업이었는데, node와 shard의 개념들이 나오고 있습니다.

  • 클러스터는 여러 노드의 집합으로 구성되며, 설치시 master node만 존재
  • primary shard는 데이터를 저장할 때 나눠진 파티션을 말하며, 설치시 5개가 존재
  • replica shard는 고가용성을 위해 존재하는 primary shard의 복제본을 말하며, 설치시 1개가 존재
  • primary와 replica는 같은 노드에 존재할 수 없음

이를 바탕으로 아래의 아키텍쳐를 이해할 수 있습니다.





이상으로 클러스터에 대해 알아보았습니다.

실험적으로 여러 노드를 생성해서 클러스터를 구성하여 상태를 green으로 바꾸고 싶었지만, 아쉽게도 실패했습니다.

조사한 바로는 노드를 셋팅할 수 있는 elasticsearch.yml 파일은 서버당 하나씩 존재해야 한다는데, 한 서버에서 여러 노드를 구성하기 위한 여러 시도를 해봤는데 잘 안되더라구요.

다행히도 AWS를 이용해서 클러스터를 구성해보는 좋은 글이 있으니 클러스터를 구성해보고 싶다면 참고해주세요. ( 링크 )


다음 글에서는 index 관련 CRUD 작업을 해보도록 하겠습니다.




CentOS7에서 yum으로 Elasticsearch(ES)를 설치하는 방법에 대해 알아보겠습니다.


1. JVM 설치

ES는 JVM위에서 구동되기 때문에 JDK를 설치해야 합니다.

쉽게 설치하기 위해 openjdk로 설치할 것이며, 1.8 이상의 버전을 설치해야 합니다.

JDK 버전에 따른 호환성은 링크를 참고하시길 바랍니다.

# yum install -y java-1.8.0-openjdk-devel.x86_64

# java -verison






2. Elasticsearch 설치

ES를 설치하는 방법으로 컴파일 설치, Docker 설치 등이 있지만 그 중에서 yum으로 설치하는 방법에 대해 말씀드리겠습니다. ( 참고링크 )


yum으로 설치하기에 앞서 먼저 repo 파일을 생성해야 합니다.

repo를 등록하지 않으면 yum으로 설치할 수 없습니다.

/etc/yum.repos.d/elasticsearch.repo 경로에 아래의 내용을 작성합니다.

# vi /etc/yum.repos.d/elasticsearch.repo
[elasticsearch-6.x]
name=Elasticsearch repository for 6.x packages
baseurl=https://artifacts.elastic.co/packages/6.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md


다음으로 yum으로 설치하면 현재 6.6.2버전이 설치됩니다.

# yum install -y elasticsearch

특정 버전으로 설치하고 싶을 경우, 버전만 입력해주면 됩니다.

예를 들어, 6.1.0 버전을 설치하고 싶다면 아래와 같이 명령을 실행합니다.

# yum install -y elasticsearch-6.1.0


yum으로 설치했을 때, 각 디렉터리의 설명은 다음과 같습니다.

  • /usr/share/elasticsearch : 홈디렉토리
    • bin : 실행 파일 디렉토리
    • plugins : 플러그인
  • /etc/elasticsearch : 설정 파일 디렉토리
    • elasticsearch.yml : 주 설정 파일
    • jvm.options : java 설정 파일

    • log4j2.properties : 로그 설정 파일

  • /var/lib/elasticsearch : 데이터 저장 디렉토리

  • /var/log/elasticsearch : 로그 저장 디렉토리





3. 서비스 등록
다음으로 서버 전원이 켜지면 ES가 실행될 수 있도록 서비스를 등록합니다.
ES service 파일은 yum 설치시에 생성됩니다.

# systemctl enable elasticsearch

# systemctl start elasticsearch





4. 확인
ES가 잘 설치 및 실행이 되는지 확인하기 위해 curl요청을 해봅니다.
# curl -X GET 'localhost:9200'

그러면 다음과 같이 ES 버전을 확인할 수 있습니다.






이상으로 CentOS7에서 yum으로 ES를 설치하는 방법에 대해 알아보았습니다.
다음 글부터는 ES를 사용하는 방법에 대해 알아보도록 하겠습니다.


  1. ehye826 2019.05.27 10:45

    좋은 정보 감사합니다 :)

+ Recent posts