인덱스 생성

ElasticSearch는 REST를 지원하기 때문에 여러가지 방법을 이용하여 인덱스를 다룰 수 있습니다.
크게 다루는 방법은 3가지입니다

  • CURL
  • kibana
  • 언어의 라이브러르 이용

여기서는 kibana 쿼리를 이용하여 인덱스를 생성해 보도록 하겠습니다

PUT test_index
{
  "mappings": {
   "_doc": {
      "properties": {
        "testId": {
          "type": "long"
        },
        "testName": {
          "type": "keyword"
        }
      }
    }
  },
  "settings": {
    "index": {
      "refresh_interval": "1s",
      "number_of_shards": "1",
      "number_of_replicas": "1"
    }
  }
}

인덱스의 정보를 위와 같이 정의하였습니다. 사용될 문서의 정보와 샤드 레플리카 정보들로 간단히 설정하였습니다.


Document 생성

마찬가지로 인덱스와 같이 여러 방식을 이용할 수 있습니다.
여기서는 kibana 쿼리를 이용하였습니다

PUT test_index/_doc/1
{
  "testId" : 1,
  "testName" : "yunho"
}

참조

https://esbook.kimjmin.net/04-data/4.2-crud

블로그 이미지

사용자 yhmane

댓글을 달아 주세요

엘라스틱서치를 운영하게 되면 운영 인덱스, 백업용 인덱스들을 여러개 만들게 된다.

다만, 예기치 않은 오류가 발생하여 수동으로 alias를 직접 설정해야 할 경우도 생긴다.

되도록이면 예외처리 코드와 케이스 검사를 잘 해두어 직접 다루는 경우가 없도록 하자 

  • 인덱스 ALIAS 설정 예제 (curl)
curl -X POST "http://www.localhost.com:9200/_aliases" -H 'Content-Type: application/json' -d '{
    "actions": [
        {
            "add" : {
                "index" : "koo-product-202103291800",
                "alias" : "koo-product"
            }
        }
    ]
}'

결과 : {"acknowledged":true}%

 

  • kibana 인덱스 ALIAS 설정 예제
POST _aliases
{
  "actions": [
    {
      "add": {
        "index": "my-data-stream",
        "alias": "my-alias"
      }
    }
  ]
}
블로그 이미지

사용자 yhmane

댓글을 달아 주세요

서비스를 운영하다 보면 데이터 필드의 값을 더하거나 평균을 내는 등 검색 쿼리로 반환된 데이터를 집계하는 경우가 많다. 검색 쿼리의 결과 집계는 다음과 같이 기존 검색 쿼리에 집계 구문을 추가하는 방식으로 수행할 수 있다.

{
    "query": { ... 생략 ...},
    "aggs": { ... 생략 ... }
}

엘라스틱서치는 집계 시 문서를 평가한 후 기준에 만족하는 문서들을 하나로 그룹화한다.
그룹화한 집합을 토대로 집계를 수행하고, 집계가 끝나면 버킷 목록에 속한 문서의 집합이 출력 된다.


집계 종류

  • 메트릭 집계
  • 버킷집계
  • 파이프라인 집계
  • 행렬 집계

메트릭 집계

메트릭 집계는 이름에서도 알 수 있듯이 정수 또는 실수와 같이 숫자 연산을 할 수 있는 값들에 대한 집계를 수행한다. 일반적으로 필드 데이터를 사용해 집계가 이뤄지지만 스크립트를 사용해 조금 더 유연하게 집계를 수행할 수도 있다.

요청값 구조

GET /apache-web-log/_search?size=0  ---1)
{
    "aggs": { ---2)
        "<집계 이름>": { ---3)
            "<집계 타입">: { ---4)
                "field": "<필드명>" ---5)
            }
        }
    }
}
  • 1) size : 집계된 문서들의 데이터는 불필요하므로 size 값을 0 으로 지정해 반환받지 않는다.
  • 2) aggs: 집계를 수행한다. aggregation 또는 aggs를 사용
  • 3) 집계 이름 : 집계에 대한 이름이다. 하위 쿼리 또는 여러 쿼리를 함께 사용할 떄 구별하는 용도로 사용한다.
  • 4) 집계 타입 : 합계, 평규느 시계열 등의 집계 타입을 명시한다.
  • 5) field : 집계의 대상이 되는 필드를 명시한다.

응답값 구조

{
    "took": 1, 
    "timed_out": false,
    "_shards": {
        "total": 5,
        "succeccful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 200,
        "max_score": 0,
        "hits": []
    },
    "aggregations": {
        "<집계이름>": {
            "<집계결과>"
        }
    }
}

합산 집계

합산 집계는 단일 숫자 메트릭 집계에 해당한다. 다음과 같이 집계 쿼리를 수행한다.

GET /apache-web-log/_search?size=0
{
    "aggs": {
        "total_bytes": {
            "sum": {
                "field": "bytes"
            }
        }
    }
}

cerebro를 이용한 화면을 보자. 총 얼마만큼의 데이터 (Bytes)가 유입 됐는지 확인할 수 있다.

조금더 확장해서 사용해보자. 이번엔 filter를 추가하여 'geoip.city_name'의 필드값이 'Paris'인 것을 집계해보자

{
    "query": {
      "constant_score": {
          "filter": {
              "match": {"geoip.city_name": "Paris"}
          }
      }  
    },
    "aggs": {
        "total_bytes": {
            "sum": {
                "field": "bytes"
            }
        }
    }
}

cerebro를 이용해 결과 화면을 봐보자. 필터가 적용된 bytes를 확인할 수 있다.


평균 집계

평균 집계는 단일 숫자 메트릭 집계에 해당한다. 마찬가지로 간단한 예제를 수행해보자

{
    "aggs": {
        "avg_bytes": {
            "avg": {
                "field": "bytes"
            }
        }
    }
}

세레브로로 결과를 확인해보자. 평균값을 확인할 수 있다.

합산 집계와 마찬가지로 평균집계에도 필터를 적용하여 보자.

{
    "query": {
      "constant_score": {
          "filter": {
              "match": {"geoip.city_name": "Paris"}
          }
      }  
    },
    "aggs": {
        "avg_bytes": {
            "avg": {
                "field": "bytes"
            }
        }
    }
}


* 최솟값, 최댓값 집계*

최솟값 집계와 최댓값 집계는 모두 단일 숫자 메트릭 집계에 해당한다.

{
    "query": {
      "constant_score": {
          "filter": {
              "match": {"geoip.city_name": "Paris"}
          }
      }  
    },
    "aggs": {
        "min_bytes": {
            "min": {
                "field": "bytes"
            }
        }
    }
}

cerebro를 확인해보자. 집계이름과, 집계 타입, 결과만 확인해보자. (min, max)



개수 집계

개수집계는 단일 숫자 메트릭 집계에 해당한다.

{
    "query": {
      "constant_score": {
          "filter": {
              "match": {"geoip.city_name": "Paris"}
          }
      }  
    },
    "aggs": {
        "bytes_count": {
            "value_count": {
                "field": "bytes"
            }
        }
    }
}

위 쿼리는 파리 지역에서 일어난 사용자 요청 횟수를 집계 하였다. cerebro를 이용해 확인해보자.


통계 집계

통계 집계는 다중 숫자 메트릭 집계에 해당한다. 통계 집계를 이용하면 앞서 살펴본 합, 평균, 최대, 최소, 개수를 한번의 쿼리로 집계할 수 있다.

{
    "query": {
      "constant_score": {
          "filter": {
              "match": {"geoip.city_name": "Paris"}
          }
      }  
    },
    "aggs": {
        "bytes_stats": {
            "stats": {
                "field": "bytes"
            }
        }
    }
}

결과는 다음과 같다.

통계 이외에도, 확장 통계를 이용하여 더 다양한 집계를 할 수 있다. 표준편차와 같은 통계값이 추가 된다. 집계 타입은 (stats-> extend_stats)으로 바꿔주면 된다.


이번 포스팅에서는 집계에 대하여 간략히 알아보았습니다.
메트릭 집계는 정수 또는 실수와 같은 숫자 연산을 할 수 있는 값들에 대한 집계를 수행하는데, 조금 더 응용하면 유용하게 쓰일 수 있습니다.
다음 포스팅에서는 버킷집계, 파이프라인 집계 등에 대하여 알아보도록 하겠습니다.


참조

  • 엘라스틱서치 실무가이드 chap5
블로그 이미지

사용자 yhmane

댓글을 달아 주세요

초기 세팅


 엘라스틱서치는 일반적으로 대용량 데이터를 처리하기 때문에 클러스터를 구성해서 사용합니다. 따라서, 로컬에서도 클러스터를 구성해서 돌려보기로 하였습니다. 테스트 환경은 아래와 같습니다.



OS

- mac


IDE

- IntelliJ 


Build

- Gradle


Dependency

-implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:6.4.3'


엘라스틱서치

- 클러스터 1개

- node 3개 사용 (port 9200, 9201, 9202)

- monitoring tool cerebro (port 9000)

- cluster-name: javacafe(공통)

- node-name: node1, node2, node3 (개별)




다운로드 링크


엘라스틱서치 6.6.0

https://www.elastic.co/kr/downloads/past-releases/elasticsearch-6-6-0

세레브로 

https://github.com/lmenezes/cerebro/releases



클러스터 구성


 파일을 받았으면 압축을 풀고 elasticsearch-6.6.0을 2개 더 복사하여 클러스터를 만들 준비를 하여 줍니다.


 여기서 주의 사항이 있는데, 인덱스를 만들면 data 파일이 생깁니다. 이렇게 된 경우 yml 파일을 수정하여도 기존 데이터들이 이전 yml 파일을 기준으로 생성되었기 때문에 오류가 생깁니다. 이렇게 된 경우 elasticsearch-6.6.0/data를 밀고 복사하여 줍니다.


 이제 vim으로 해당 파일들을 열어 클러스터를 구성하여 줍니다. 경로는 아래와 같습니다. 주의할 점은 클러스터네임은 공통으로 하여주는 것이고, 노드네임은 다르게 지어주는 것입니다. port는 설정을 따로 하지 않았는데, 일반적으로 마스터노드는 9200번 차순의 노드들은 9201, 9202순으로 매핑되어 집니다.


elasticsearch-6.6.0/config/elasticsearch.yml

cluster.name: javacafe-cluster

node.name: javacafe-node1

node.master: true

node.data: true

elasticsearch-6.6.0-0/config/elasticsearch.yml

cluster.name: javacafe-cluster

node.name: javacafe-node2

node.master: false

node.data: true

elasticsearch-6.6.0-1/config/elasticsearch.yml

cluster.name: javacafe-cluster

node.name: javacafe-node3

node.master: false

node.data: true


 클러스터 구성은 끝이 났습니다. 엘라스틱서치를 실행하여 봅시다. elasticsearch-6.6.0/bin에 있는 elasticsearch 파일을 각자 실행시켜 줍니다. 실행방법은 ./elasticsearch 입니다.


 마찬가지로 cerebro (모니터링 툴)도 실행하여 줍니다. 키바나도 있지만 여기선 cerebro를 사용하여 노드들의 상태를 확인할 것 입니다. 실행방법은 ./cerebro 입니다.




실행을 하게 되면 각 노드들이 올라온 것을 볼 수 있습니다.





 마지막으로, localhost:9000번으로 접속해 봅니다. 마스터노드의 9200번으로 접속하면 아래와 같은 화면이 나올것입니다.




커넥트를 하게 되면 클러스터안에 노드 3대가 떠 있는 것을 볼 수 있을것 입니다.



INDEX API


 이제 클러스터까지 구성해 봤으니, Spring Boot로 API를 실행해 보겠습니다. API 구성은 다음과 같습니다.


  • 인덱스 생성
  • 인덱스 닫기
  • 인덱스 오픈
  • 인덱스 삭제


 여기서 의문이 생길 수 있는데, 인덱스-타입이 일반 RDB의 테이블과 같다고 보면 이해가 쉬울 것 입니다. 개념적인 부분은 구글이나 책을 사서 꼭 공부를 해보길 추천합니다.


 코드보다 엘라스틱서치는 rest를 지원하기 때문에 툴을 이용하여 인덱스를 생성하는 것이 편합니다. cerebro에 있는 rest를 이용하여 movie_rest 인덱스를 생성할 수 있습니다.


movie_rest PUT


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
    "settings": {
            "number_of_shards"3,
            "number_of_replicas"2
    },
    "mappings": {
        "_doc": {
            "properties": {
                "movieCd": { "type" : "integer" },
                "movieNm": { "type" : "text" },
                "movieNmEn": { "type" : "text" },
                "prdtYear": { "type" : "integer" },
                "openDt": { "type" : "date" },
                "typeNm": { "type" : "keyword" },
                "prdtStatNm": { "type" : "keyword" },
                "nationAlt": { "type" : "keyword" },
                "genreAlt": { "type" : "keyword" },
                "repNationNm": { "type" : "keyword" },
                "repGenreNm": { "type" : "keyword" }
            }
        }
    }
}
cs



 이제 코드로 작성하여 봅니다. 우선 build.gradle에 dependency를 추가하여 줍니다.

implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:6.4.3'


@Autowired
private RestHighLevelClient client;

// Index명
private final String INDEX_NAME = "movie_rest";

// 타입명
private final String TYPE_NAME = "_doc";

@Before
public void connection_생성() {
client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http")));
}

@After
public void connection_종료() throws IOException {
client.close();
}


먼저, before/ after로 커넥션을 관리하여 주었습니다.

@Test
public void index_테스트1_생성() throws IOException {

// 매핑정보
XContentBuilder indexBuilder = jsonBuilder()
.startObject()
.startObject(TYPE_NAME)
.startObject("properties")
.startObject("movieCd")
.field("type", "keyword")
.field("store", "true")
.field("index_options", "docs")
.endObject()
.startObject("movieNm")
.field("type", "text")
.field("store", "true")
.field("index_options", "docs")
.endObject()
.startObject("movieNmEn")
.field("type", "text")
.field("store", "true")
.field("index_options", "docs")
.endObject()
.endObject()
.endObject()
.endObject();

// 매핑 설정
CreateIndexRequest request = new CreateIndexRequest(INDEX_NAME);
request.mapping(TYPE_NAME, indexBuilder);

// Alias 설정
String ALIAS_NAME = "moive_auto_alias";
request.alias(new Alias(ALIAS_NAME));

boolean acknowledged = client.indices()
.create(request, RequestOptions.DEFAULT)
.isAcknowledged();

assertThat(acknowledged, is(true));
}

 인덱스 생성 API인데 인덱스 > 타입 > 프로퍼티 순으로 작성후 CREATE를 하였습니다. 테스트를 수행하면 정상작동을 하게 되는데 cerebro를 이용하여 클러스트를 확인해 보겠습니다.



 movie_rest 인덱스가 생성된 것을 볼 수 있습니다. 


추가적으로 실선과 점선으로 생긴 블록들이 생긴 것을 볼 수 있는데 '샤드'와 '레플리카' 라는 것입니다. 이부분이 엘라스틱서치의 중요한 개념인데 엘라스틱서치는 방대한 데이터를 클러스터내에서 분산으로 나누어 요청을 처리합니다. 병렬로 데이터를 처리하기 때문에 빠르게 작업을 하는 것이고 어떠한 이유로 한 노드가 죽게 되어도 '샤드'의 복제본을 다른 노드에서 '레플리카'로 가지고 있기 때문에 모든 데이터를 검색할 수 있습니다.


이 부분은 중요 개념이기에 샤드와 레플리카를 모르시는 분들은 꼭 .. 공부할 것을 권장합니다!!



@RunWith(SpringRunner.class)
@SpringBootTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class IndexApiTest {

@Autowired
private RestHighLevelClient client;

// Index명
private final String INDEX_NAME = "movie_rest";

// 타입명
private final String TYPE_NAME = "_doc";

@Before
public void connection_생성() {
client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http")));
}

@After
public void connection_종료() throws IOException {
client.close();
}

@Test
public void index_테스트1_생성() throws IOException {

// 매핑정보
XContentBuilder indexBuilder = jsonBuilder()
.startObject()
.startObject(TYPE_NAME)
.startObject("properties")
.startObject("movieCd")
.field("type", "keyword")
.field("store", "true")
.field("index_options", "docs")
.endObject()
.startObject("movieNm")
.field("type", "text")
.field("store", "true")
.field("index_options", "docs")
.endObject()
.startObject("movieNmEn")
.field("type", "text")
.field("store", "true")
.field("index_options", "docs")
.endObject()
.endObject()
.endObject()
.endObject();

// 매핑 설정
CreateIndexRequest request = new CreateIndexRequest(INDEX_NAME);
request.mapping(TYPE_NAME, indexBuilder);

// Alias 설정
String ALIAS_NAME = "moive_auto_alias";
request.alias(new Alias(ALIAS_NAME));

boolean acknowledged = client.indices()
.create(request, RequestOptions.DEFAULT)
.isAcknowledged();

assertThat(acknowledged, is(true));
}

@Test
public void index_테스트2_닫기() throws IOException{

CloseIndexRequest requestClose = new CloseIndexRequest(INDEX_NAME);

boolean acknowledged = client.indices().close(requestClose, RequestOptions.DEFAULT).isAcknowledged();

assertThat(acknowledged, is(true));
}

@Test
public void index_테스트3_오픈() throws IOException{

OpenIndexRequest requestOpen = new OpenIndexRequest(INDEX_NAME);

boolean acknowledged = client.indices().open(requestOpen, RequestOptions.DEFAULT).isAcknowledged();

assertThat(acknowledged, is(true));
}

@Test
public void index_테스트4_삭제() throws IOException {

DeleteIndexRequest request = new DeleteIndexRequest(INDEX_NAME);

boolean acknowledged = client.indices()
.delete(request, RequestOptions.DEFAULT)
.isAcknowledged();

assertThat(acknowledged, is(true));
}
}


추가적으로 닫기, 오픈, 삭제 API가 있는데 코드를 수행해보고 cerebro를 이용해 클러스터의 상태를 확인해 보길 바랍니다.



DOCUMENT API


 이제 인덱스-타입을 생성하였으니 데이터를 쌓아 보겠습니다. 이부분을 RDB와 비교해보면 '인덱스-타입' = '테이블', '다큐먼트' = '행' 이라고 이해하면 됩니다.


@Test
public void index_테스트1_insert() throws IOException {

IndexRequest request = new IndexRequest(INDEX_NAME,TYPE_NAME, ID);

request.source(jsonBuilder()
.startObject()
.field("movieCd", "20173732")
.field("movieNm", "살아남은 아이")
.field("movieNmEn", "Last Child")
.endObject()
);


IndexResponse response = client.index(request, RequestOptions.DEFAULT);
String id = response.getId();
RestStatus status = response.status();

assertThat(id, is("1"));
assertThat(status, is(RestStatus.CREATED));

}


1번 ID에 다음 데이터를 넣어보고 데이터를 확인해 보겠습니다. REST 통신을 지원하니 cerebro에서 실행해 보겠습니다.



인덱스/타입/아이디 HTTP METHOD

movie_rest/_doc/1 GET



 데이터가 정상적으로 들어왔습니다. version값이 보인다 해당 아이디에 crud에서 생성/수정/삭제 를 수행하면 version이 올라가는데 이 부분은 증분색인과 관련이 있습니다.


@RunWith(SpringRunner.class)
@SpringBootTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class DocumentApiTest {

@Autowired
private RestHighLevelClient client;
// Index명
private final String INDEX_NAME = "movie_rest";
// 타입명
private final String TYPE_NAME = "_doc";
// 문서 키값
private final String ID = "1";


@Before
public void connection_생성() {
client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http")));
}

@After
public void connection_종료() throws IOException {
client.close();
}

@Test
public void index_테스트1_insert() throws IOException {

IndexRequest request = new IndexRequest(INDEX_NAME,TYPE_NAME, ID);

request.source(jsonBuilder()
.startObject()
.field("movieCd", "20173732")
.field("movieNm", "살아남은 아이")
.field("movieNmEn", "Last Child")
.endObject()
);


IndexResponse response = client.index(request, RequestOptions.DEFAULT);
String id = response.getId();
RestStatus status = response.status();

assertThat(id, is("1"));
assertThat(status, is(RestStatus.CREATED));

}

@Test
public void index_테스트2_get() throws IOException {

GetRequest request = new GetRequest( INDEX_NAME, TYPE_NAME,ID);

GetResponse response = client.get(request, RequestOptions.DEFAULT);

Map<String, Object> sourceAsMap = response.getSourceAsMap();
String movieCd = (String) sourceAsMap.get("movieCd");
String movieNm = (String) sourceAsMap.get("movieNm");
String movieNmEn = (String) sourceAsMap.get("movieNmEn");

assertThat(movieCd, is("20173732"));
assertThat(movieNm, is("살아남은 아이"));
assertThat(movieNmEn, is("Last Child"));
}

@Test
public void index_테스트3_update() throws IOException {

XContentBuilder builder = jsonBuilder()
.startObject()
.field("createdAt", new Date())
.field("prdtYear", "2018")
.field("typeNm", "장편")
.endObject();

UpdateRequest request = new UpdateRequest(INDEX_NAME, TYPE_NAME, ID).doc(builder);

UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT);
RestStatus status = updateResponse.status();

assertThat(status, is(RestStatus.OK));
}

@Test
public void index_테스트4_delete() throws IOException {

DeleteRequest request = new DeleteRequest(INDEX_NAME, TYPE_NAME, ID);
DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);

RestStatus status = deleteResponse.status();
assertThat(status, is(RestStatus.OK));
}
}

 INDEX,DOCUMENT이외에도 검색, 집계에 관한 API가 있는데 이 부분은 추후에 또 올려보도록 하겠습니다.



---

 오류나 오타의 댓글을 남겨 주면 수정하도록 하겠습니다.


참조


[책] 엘라스틱서치 실무 가이드

[링크]  https://github.com/javacafe-project/elastic-book/tree/master/src/main/java/io/javacafe/client/rest


링크에 있는 API를 테스트 케이스로 만들어 기재하였습니다.

블로그 이미지

사용자 yhmane

댓글을 달아 주세요

새로운 플랫폼을 만든다면 

이제는 모바일 환경의 발전에 따라

많은 트래픽이 몰리게 되고 관계형 데이터베이스만으로 서비스를 운영 하기는 쉽지 않은 환경이 도래 됐다.

그에 따라 redis나 elastatic search등을 많은 기업에서 도입하여 서비스를 운영하고 있다.


필자도 이미 늦은감이 있지만 ElasticSearch를 접해 보려고 한다.


먼저 설치를 해보자. 


설치 -> 예제 실습 -> 토이 프로젝트 ->  검증 -> 운영환경에 적용 



링크


https://www.elastic.co/guide/en/elasticsearch/reference/current/brew.html


위는 mac os에 대한 설치 가이드이다.


homebrew를 이용해 쉽게 설치 할 수 있다.



To install with Homebrew, you first need to tap the Elastic Homebrew repository:

brew tap elastic/tap


Once you’ve tapped the Elastic Homebrew repo, you can use brew install to install the default distribution of Elasticsearch:

brew install elastic/tap/elasticsearch-full


위 명령어를 터미널에 입력하여 주자.



설치가 완료 되면 다음과 같은 위치에 저장된다고 한다.

이제 Elastic Search를 처음 접해보는 거라 혹시 몰라 캡쳐해 두었다.



설치가 완료 되었다면, 맥 기준으로 terminal에 elasticsearch를 입력 후

정상구동이 되었다면 localhost:9200으로 접속해보자.


정상적으로 설치 되었다면,


위와 같은 설정이 나올 것이다.

물론, 클러스터네임을 수정하였기에 조금 다를 수 있다.




정상적으로 설치가 완료 되었다면 키바나를 설치해보자.

키바나는 엘라스틱에서 제공하는 데이터 시각화 프로그램이다.

잘 읽어 보면 엘라스틱서치에 색인된 데이터를 검색하거나 문서를 추가 또는 삭제하는 등의 기능을 손쉽게 구현할 수 있다고 한다.



링크


https://www.elastic.co/guide/en/kibana/7.3/brew.html


마찬가지로 homebrew를 이용하여 설치할 것이다.


To install with Homebrew, you first need to tap the Elastic Homebrew repository:

brew tap elastic/tap


Once you’ve tapped the Elastic Homebrew repo, you can use brew install to install the default distribution of Kibana:

brew install elastic/tap/kibana-full


위 명령어를 터미널에 입력하여 주자.


마찬가지로, 별 문제없이 설치될 것이다.


kibana가 정상적으로 구동 되었다면


terminal 에서 elasticsearch 실행 후 kibana를 실행해보자


kibana 명령어를 치면 된다.


그러면 아래와 같이 정상적으로 구동되는 것을 볼 수 있다.






블로그 이미지

사용자 yhmane

댓글을 달아 주세요