[ELK] 개요

Development Stack/ELK / / 2020. 12. 1. 09:53

# ELK 스택이란?

ElasticSearch + Logstash + Beats + Kibana의 조합

일라스틱 서치로 데이터를 적재하고, 데이터를 시각화하는 스택

메인은 엘라스틱 서치이고, 나머지 도구는 서포트하는 도구라고 생각하면 된다.

- 키바나 : 데이터를 시각화하고, E의 모든 기능을 구성 및 관리할 수 있는 확장 가능한 UI 도구

(elastic.com 에서 지원)

적재 & 데이터 시각화


# Elasticsearch 기초

1. 인덱스 구조(엑셀 쉬트에 비교)

document가 합쳐진 것이 Index

document는 rows

field는 cols

type은 sheet

# json 포멧

{ K : V, ... },

{ K : V, ... }, // row 수 만큼

2. 클러스터 구성

- 클러스터 안에는 여러개의 물리서버가 들어갈 수 있음

- 클러스터 내 물리 서버 내에 노트가 들어갈 수 있고, 노드 내에 ElasticSearch가 설치되는 듯

- 노드 사이에는 9300포트로 통신

- 클라이언트와는 9200포트로 통신

3. 샤드

- 인덱스는 샤드라는 단위로 나뉨(샤드는 rows 들을 분산으로 나누는 기술을 의미한다.)

- 인덱스가 샤드라는 단위가 나뉘게 되고, 또 레플리카 샤드로 나뉘어져서, 데이터 손실이 없게 한다.

- 데이터가 적재되면, 인덱스(rows)가 쌓이는데, 만약 1,2,3 총 3개의 인덱스를 저장하고, 서버와 노드가 3개일 때,

각 노드에, 1,2,3이 나누어져서 들어가고, 복제된 레플리카 샤드인 1,2,3도 프라이머리 샤드와는 다른 순서도 들어간다


# 개발 환경 구축

- 폴더경로에 영어먄 들어가도록 할 것

- 폴더경로가 255자 넘으면 안되는 듯

1. Elasticsearch

1-1. \configs\jvm.options : 자바 힙메모리 설정

- 설정 안해도 기본값으로 동작

- 31GB 내에서 서버의 인메모리를 할당해 줄 수 있다.

 Xms represents the initial size of total heap space

 Xmx represents the maximum size of total heap space

 Xms1g

 Xmx1g

1-2. \configs\elasticsearch.yml : 실행 환경 설정

- Cluster, Node 이름을 주석을 풀어서 지정할 수 있다.

- Path

path.data: /path/to/data > 데이터 지정장소 설정 가능

path.logs: /path/to/logs > 로그 저장소 설정 가능

- Network

network.host: 192.168.0.1 > 0.0.0.0 or 노트북 서버 ip or _site_(ip 변경시 사용)

http.port: 9200 > 포트 설정 가능

\bin\elasticsearch.bat : 키바나 서버 실행

- 127.0.0.1:9200 로 접속 가능

{ "name" : "DESKTOP-2S46457", -> Node 이름 "cluster_name" : "elasticsearch", -> 클러스터 이름 "cluster_uuid" : "b7nCwEMRQzKV1ElRUKn_Vw", "version" : { "number" : "7.10.0", "build_flavor" : "default", "build_type" : "zip", "build_hash" : "51e9d6f22758d0374a0f3f5c6e8f3a7997850f96", "build_date" : "2020-11-09T21:30:33.964949Z", "build_snapshot" : false, "lucene_version" : "8.7.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }

2. Kibana

2.1 \configs\kibana.yml : 실행 환경 설정

#server.port: 5601 : 키바나 기본 포트

#server.host: "localhost" > localhost 또는 0.0.0.0(외부 접속 가능) 또는 노트북ip(외부접속가능)

#elasticsearch.hosts: ["http://localhost:9200"] > 연동할 ElasticSearch 접속 정보, 콤마로 여러개의 노드에 접속가능

2.2 \bin\kibana.bat : 키바나 서버 실행

2.3 localhost:5601 접속 후, 죄측 햄버거 메뉴 접속 후, dev tools 접속

2.4 PUT, GET, POST 와 같은 REST API와 ElasticSearch와 통신하여 작용

- 데이터 적재할 때도 사용

- Elastic Search Field별 자료형 매핑 설정 시에도 REST API로 사용


# Kibana 코드

## 조회 결과 속성 정보

- took : 얼마나 ms가 걸렸나

- time_out : 타임아웃이 있었나

- shards : 몇개의 샤드에 저장되었는지 정보

- hits.total.value : 총 몇개의 search 값이 뜨는지 정보

1. Field 별 자료형, 타입 매핑 설정법(mappings 속성)

2. 클러스터, 노드 샤드 설정법(settings 속성)

PUT sample_index  // 인덱스명은 소문자만 가능

{

  "settings" : {

    "index" : {

      "number of shards" : "2",  // 인덱스가 넘어오면 몇개의 샤드로 나뉘어져 저장될 것인지 지정

      "number of replicas" : "1" // 인덱스가 넘어오면 몇개의 레플리카를 둘것인가?

    }

  },

  "mappings" : {

    "properties": {

      "FILED1" : {

        "type" : "date"

      },

      "FILED2" : {

        "type" : "keyword"

      }

    }

  }

}


GET sample_index/_mapping : 해당 인덱스의 매핑 정보를 조회하라.

GET <인덱스명>/_mapping 


PUT sample_index/_doc/1 : 데이터를 넣어라

{

   "FILED1": "2020-11-12"

}

PUT <인덱스명>/<타입명, 보통 _doc으로 고정>/<id명, 미지정시 자동 생성> : 데이터를 넣어라

{

   "FILED1": "2020-11-12"

}


GET sample_index/_search : 해당 인덱스의 모든 내용을 조회하라.

GET <인덱스명>/_search


GET index_keyword_text/_search

{

  "query": {

    "match": {

      "FILED2": "일라스틱"

    }

  }

}


Tip. 자동완성 시, 대문자 부분은 지우고 바꾸어줘야하고, 

// 결과값.hits.source에서 원본값 확인 가능

## 자료형

- 정수형 : long, integer

- 실수형 : float

- 문자열 키워드형 : keyword > 빈칸까지 정확하게 일치할 경우에만 검색가능, 추후 집계 기능 사용 가능

- 문자열 : text > 해당 타입으로 저장할 경우, 텍스트 전문 검색 (토큰화해서 각각 row로 저장) 가능, 집계(그룹핑) 기능 사용 불가

- 날짜 : date : yyyy-MM-ddTHH:mm:ssZ (ISO 8601 표준, epoch_millis 표준 설정 가능)

- 위치 : geo_point

================================

PUT 신문기사

{

  "mappings": {

    "properties": {

      "title" : {

        "type" : "text"

      },

      "content" :  {

        "type" : "text"

      }

    }

  }

}


PUT 신문기사/_doc/1

{

  "title": "기사제목",

  "content": "기사 내용"

}


GET 신문기사/_search

{

  "query": {

    "match": {

      "content": "내용"

    }

  }

}

===============================


## 멀티 필드 : 필드 안에 자식 필드 만들기

PUT index_multifields

{

  "mappings": {

    "properties": {

      "부서명": {

        "type": "text",

        "fields": { // 해당 속성을 정의할 경우, 부서명.키워드필드 접근 가능

          "키워드필드":{

            "type" : "keyword"

          }

        }

      },

      "사원명": {

        "type": "keyword"

      },

      "연봉": {

        "type": "long"

      }

    }

  }

}


===============================

GET index_multifields/_search

{

  "size": 0,

  "aggs": {

    "부서": {

      "terms": {

        "field": "부서명.키워드필드",

        "size": 10

      },

      "aggs": {

        "연봉합계": {

          "sum": {

            "field": "연봉"

          }

        }

      }

    }

  }

}

===============================

## 날짜 

PUT index_date 

{

  "mappings":{

    "properties": {

      "date" :{

        "type":"date",

        "format":"iso8601" // or yyyy-MM-dd

      }

    }

  }

}


## 날짜 iso8601 포멧이 아니더라도, 여러개의 포멧 인지하기


PUT index_date 

{

  "mappings":{

    "properties": {

      "date" :{

        "type":"date",

        "format":"iso8601||yyyy/MM/dd||epoch_millis" //ISO표준, epochMillis 형식으로 들어와도 파싱 가능

        // <format>속성 지정

}

    }

  }

}

===============================

## 위치 정보

PUT index_geo_point1

{

  "mappings": {

    "properties": {

      "location":{

        "type": "geo_point"

  // ['lat': 경도값, 'lon': 위도값] 형식으로 넣어주어야하는 번거로움 존재

      }

    }

  }

}

## location.lon location.lat [위도, 경도] 식으로 넣어줘야 함

PUT index_geo_point1_temp/_doc/1

{

  "latitude" : 20.12321,

  "longitude" : 128.31233

}


# reindex 재색인 기술 : 기존에 있는 인덱스를 복사(다른 인덱스에)

POST _reindex

// _reindex 예약어를 통해, source의 index를 dest의 index로 이동

{

  "source": {

    "index": "index_geo_point1_temp"

  },

  "dest": {

    "index": "index_geo_point1"

  }, // 여기까지 이미 index_geo_point1_temp에서 이동

  "script": { // 스크립트

    "source": "ctx._source.location = ['lat':ctx._source.latitude, 'lon':ctx._source.longitude]"

  }

}


# Logstash 로 CSV파일을 쉽게 적재하자

1. Kibana 상에서, Index 정의하기

PUT upload_sample1

{

  "mappings": {

    "properties": {

      "rank":{

        "type": "long"

      },

      "open_date":{

        "type": "date",

        "format": "iso8601||yyyy/MM/dd"

      },

      "lat":{

        "type": "double"

      },

      "lon": {

        "type": "double"

      },

      "name": {

        "type": "keyword"

      },

      "content": {

        "type": "text"

      }

    }

  }

}


2. <사용자정의이름>.conf 파일 만들고, logstash\bin 폴더 내에 붙여넣기

input {

file{

path => ["c:/sample/*.csv"]

// 적재할 csv 파일 경로

start_position => "beginning"

// 어느 위치부터 읽을 것인가?

sincedb_path => "NUL" 

// 만약에 기존 읽었던 csv 파일이었다면, 어디까지 읽었는지를 저장해둔 파일 경로 

}

}


filter {

csv{

separator=>","

// csv 구분자

columns=>["rank","open_date","lat","lon","name","content"]

// csv 컬럼 필드명

skip_header=>true

// header skip

}

mutate{

remove_field=>["message","path","host","@version"]

// logstash가 자동으로 생성하는 field, 적재와 동시에 제거

}

}


output{

stdout{

 codec=>rubydebug

}

elasticsearch{

hosts=>["http://localhost:9200"]

// 적재할 elasticSearch url

index=>"upload_sample1"

// 해당 csv 파일의 mapping을 정의한 index명

}

}


3. cmd 관리자 권한 실행 후, 명령어를 통해 ElasticSearch에 입력

c:\ELK\logstash-7.10.0\bin>logstash -f upload.conf

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기