티스토리 뷰

IT지식

ELK Stack

chief 2022. 5. 26. 18:10
반응형

🚀  들어가며...

  • ELK Stack은 무엇이며, 각각의 특징들과 실제 사용했던 코드 예제들을 알아보겠습니다.

 

📑 내용

ELK Stack이 검색엔진으로 인기가 많은 이유 => (역인덱스&분석기)

(여기서 말하는 역인덱스란 흔히 책장 맨 뒤쪽에 단어단위로 나눠져서 어떤 페이지에 나와있는지 적혀있는 것을 말합니다.)

 

엘라스틱서치에 인덱싱이 이루어지는 경우 분석기 라는 것을 통하여 용어(Term)가 분해되어 역인덱스 사전이 구축됩니다.

이것을 통하여 관계형 데이터베이스, NoSQL에서는 볼 수 없었던 엄청나게 빠른 속도의 전문 검색을 지원하게 됩니다.

SQL의 Like 구문이 전문검색이라고 이야기를 하지만 완벽한 전문 검색은 지원하지 않습니다.
하지만 엘라스틱서치  분석기를 통한 역인덱싱 으로 이것을 완벽하게 지원합니다.

그렇다면 분석기에는 어떤 것이 있는지 확인을 해보고 넘어가 봅시다.

여기서 이야기하는 전문(Fulltext) 검색이란 긴 장문의 문자열 속에서 일부를 검색해도 나오는 것을 이야기 합니다.

분석기

엘라스틱서치는 전문 검색을 위하여 3가지로 구성되어있는 분석기 모듈이 존재합니다.

예시

여기서 주의를 해야할 점은, 토큰과 용어의 차이가 존재한다는 것입니다.

토큰은 분석기에서 토크나이저를 통해 필터링 된 문자열이 잘리는데, 이때 잘린 단위를 토큰이라고 지칭하며
토큰 필터를 거쳐서 최종적으로 정제가 되어 인덱스에 저장되는 토큰들을 용어라고 부릅니다.

이렇게 문자를 잘라서 인덱스하는 것을 역인덱스(역색인)이라고 부릅니다.

즉, 토큰은 잠시동안 유지되는 상태라는 것이고 실질적으로 검색에 사용되는 것은 용어라고 부르면 됩니다.

각각의 특징은 아래와 같고, 중요한 점은 반드시 한개의 토크나이저가 포함되어야 합니다.

  • 캐릭터 필터
    • 입력받은 문자열을 변경하거나, 불필요한 문자를 제거합니다.
    • HTML의 태그같은 것을 처리하거나, 특정 단어를 다른 단어로 변경할 수 있습니다.
  • 토크나이저
    • 문자열을 토큰으로 분리합니다.
    • 기본값의 경우에는 공백을 기준으로 토큰화가 이루어집니다.
  • 토큰 필터
    • 분리된 토큰의 필터 작업을 합니다.
    • 소문자, 대문자로 변경하거나 형태소 분석같은 작업이 이루어집니다.

이와같이 3개의 모듈을 통해서 역인덱싱이 적용되는데, 분석기 자체의 옵션을 지정하는 방법과

각각 모듈에 옵션을 지정하는 방법, 원하는 옵션이 없을 경우 직접 지정하는 커스텀 분석기가 존재합니다.

자주 사용되는 분석기

분석기 이름 설명
standard 옵션을 적용하지 않을 경우 엘라스틱서치가 기본적으로 사용하는 분석기 입니다.
영어를 기준으로 스탠다드 토크나이저와 소문자 변경 필터, 스톱 필터가 포함되어 있습니다.
simple 문자만 토큰화를 합니다. 공백, 숫자, 하이픈(-) 따옴표(')같은 문자는 토큰화하지 않습니다.
stop simple 분석기와 비슷하지만 스톱 필터가 포함되어 있습니다.

 

존재하는 캐릭터 필터

필터 이름 설명
html_strip HTML 태그를 제거하여 일반 텍스트로 만듭니다.
mapping 지정한 단어를 다른 단어로 변경합니다. 특수문자를 포함한 검색에서 보통 사용합니다.
pattern_replace 정규식을 사용하여 더욱 더 복잡한 패턴을 변경할 수 있도록 만듭니다.

 

대표적인 토크나이저

토크나이저 이름 설명
standard 스탠다드 분석기가 사용하는 토크나이저 입니다. 쉼표, 점, 특수문자 같은 것을 제거하여
토큰화를 시키며 특징은 문자열 중간에 있는 것은 지우지 않습니다.
Leetter 알파벳을 제외한 모든 것을 제거한 후 토큰화를 시킵니다.
whitespace 공백을 기준으로 구분하여 토큰화를 합니다.
ngram 원문으로부터 N개의 연속된 글자 단위를 모두 토큰화시킵니다.
예시로 2gram으로 양념치킨을 토큰화 시킬 경우 [양념,념치,치킨] 이런식으로 분리가 됩니다.
이것으로 전문검색이 가능하긴 하지만 ngram의 수보다 적은 글자일 경우 검색이 불가능하고,
문장이 길 경우에는 모든 조합을 추출하여 저장공간을 많이 차지하는 문제가 존재합니다.
uax_url_email 스탠다드 분석기와 비슷하지만, URL과 이메일을 토큰화를 시켜줍니다.

 

자주 사용하는 토큰 필터

토큰 필터 이름 설명
lowercase 모든 문자를 소문자로 변환한 후 term으로 만듭니다.
uppercase 모든 문자를 대문자로 변환한 후 term으로 만듭니다.
stop 모든 불용어를 제거합니다. 불용어란 한국어에는 존재하지 않는 영어의 'a' 'the' 같은 것들 입니다.
stemmer 문자의 형태를 분석해 어간으로 변환시킵니다. 기본적으로 영어를 지원합니다.

 

이렇게 다양한 것이 존재하지만, 기본적으로 영어를 베이스로 제작이 되었기때문에
한글 형태소 분석기 를 활용하고 싶은 경우에는 직접 구현 을 해야합니다.

하지만 이것도 어느정도 제작되어서 이것을 활용하여 추가적으로 제작을 하고 있습니다.

 

이제 좀 더 상세하게 알아봅시다.

ELK Stack이란, ELK 솔루션에서 Beats 추가된 형태로, 각각의 하는 역활은 다음과 같습니다.

Elasticsearch

  • ElasticSearch는 Apache Lucene 기반의 OpenSource noSQLDB / 검색엔진 입니다.
  • 엘라스틱서치의 특징
    • 아파치 루씬 기반 : 아파치 루씬은 자바 언어로 개발된 검색 라이브러리 입니다.  루씬의 기능을 대부분 지원하며, 마찬가지로 자바 언어로 개발됐습니다.
    • 실시간 분석 : 데이터는 색인작업이 완료됨과 동시에 바로 검색할 수 있습니다.
    • 분산 시스템 : 여러개의 노드로 구성되는 분산 시스템이다. 노드는 데이터를 색인하고 검색 기능을 수행하는 엘라스틱서치의 단위 프로세스 입니다.
      • 기존 노드에 새노드를 실행해 연결하는 것으로 쉽게 시스템을 확장할 수 있습니다.
      • 데이터는 각 노드에 분선 저장되고 복사본을 유지해 노드 데이터의 유실을 방지합니다.
    • 멀티 테넌시 : 구조 이야기 후에...여러개로 분리된 인덱스들 에 그룹으로 저장 → 다른 인덱스의 데이터들을 갖고 올 수 있습니다.
    • 전문검색 : Full Text Search 지원
    • JSON 문서 기반 :  저장되는 데이터는 JSON형식으로
    • RestFul API 지원 
  • 엘라스틱 서치의 구조(RDBMS와 비교)
ElasticSearch RDBMS 비고
인덱스 데이터베이스 6.X 버전용→7.X 버전에서는 테이블로 인식하면 됩니다.
타입 테이블 6.X 버전용 → 7.X 버전에서 삭제.
도큐멘트 열(Row)  
필드 행(Column)  
매핑 스키마(Schema)  

 

  • 엘라스틱 6.x 버전까지는 type이 존재해서 위와 같지만 7.X버전 부터는 type이란 항목이 사라졌습니다. 따라서 인덱스를 테이블로 인식하면 됩니다.
  • 7.X버전 이전에는 회사 내에서 타입 별로 실제 해당 데이터 타입을 각각 저장했지만, 이후에는 index별로 관리되기 때문에 타입 오류 발생한 적이 있습니다. (xmlconf에서)
  • 7.X버전에도 type은 존재하지만...default가 _doc이고, 아무 의미 없습니다.

 

Logstash

- 오픈소스 서버측 데이터 처리 파이프라인으로, 다양한 소스에서 동시에 데이터를 수집하고 변환하여 stash 보관소로 보냅니다.

- 수집할 로그를 선정해서, 지정된 대상 서버(ElasticSearch)에 인덱싱하여 전송하는 역할을 담당하는 소프트웨어 입니다.

회사내에서 logstash 예제를 알아보겠습니다.

input {
  kafka { #Kafka에서 읽어오기
    bootstrap_servers => "kfaka ip :9092"
    topics => [""]
    group_id => ""
    codec => json
 
    # Kafka 토픽의 파티션 개수와 동일하게 설정
    consumer_threads => 2
 
    # Kafka metadata 포함하기
    decorate_events => basic
  }
}
 
filter {
  json {
    # 유효하지 않은 JSON에 대한 필터 건너뛰기 허용
    skip_on_invalid_json => true
 
    # data를 JSON Parsing하여 Root로 위치 변경
    source => "data"
 
    # 실제 'data' 값은 삭제
    remove_field => ["data", "category"]
  }
 
  date {
    match => [ "time", "MMM dd, yyyy @ HH:mm:ss.SSS", "ISO8601" ]
    target => "@timestamp"
  }
}
 
output {
  elasticsearch {
#elastic에 적재
    hosts => ["elastic_ip:80"]
    index => "%{main}_%{sub}_%{type}_%{+yyyy}"
 
    # Deprecated. 다음 버전 Logstash 에서 사라질 기능.
    document_type => "%{type}"
  }
#그밖에 용도 file log기록도 가능하고....api호출도 가능. api 호출 예제
  http {
        # History Log 남기는 용도.
    url => "http://ip/history_log_%{+yyyy-MM}/_doc"
    content_type => "application/json"
    http_method => "post"
    format => "json"
    mapping => {
        "@timestamp" => "%{@timestamp}"
        "step_order" => 5
        "step_title" => "SAVE FROM LOGSTASH"
        "is_success" => "T"
        "remote_ip" => "%{remote_ip}"
        "serial_number" => "%{serial_number}"
        "time" => "%{time}"
    }
  }
}

 

현재 Wehago내 사용 예

  • apigateway의 시스템로그 (logfile에서 읽어서 elastic에 적재)
  • docc_etl에서 data 적재 용도
  • sao_exception은 아직 사용 전

 

Kibanna

- 데이터를 시각적으로 탐색하고 실시간으로 분석 할 수 있습니다.

- 시각화를 담당하는 HTML + Javascript 엔진이라고 보면 됩니다.

 

실제로 제가 사용했던 코드 예제입니다.

def renewal_car_data(request, data):
    error_msg = ''
    with get_service_connection(request) as cursor:
        cursor.execute(q_select_car_renewal_check(), data)
        yn_renewal = name_to_json(cursor)
        if yn_renewal:
            try:
                cursor.execute(q_insert_renewal_gisu(), data)
            except:
                try:
                    try:
                        error_msg = '\n'.join(traceback.format_exception(*(sys.exc_info())))
                    except:
                        error_msg = '알 수 없는 오류 발생'
                    dic = {
                        "cno": data["cno"],
                        "ctaxnum": data.get("cno_taxnum", ""),
                        "menu": 'sabc0109',
                        "gubun": "renewal table",
                        "result": "exception",
                        "detail": error_msg
                    }
                    eshelp = EsSearchHelper(index='sao_data_check', type='cmstatus', mode="log")
                    eshelp.post(data=dic)
                    if error_msg.find('중복') >= 0:
                        pass
                    else:
                        return Response(data={"resultCode": 500})
                except:
                    error_msg = "오류 전송중 오류 발생"

        else:
            cursor.execute(q_insert_default_environ_renewal(), data)

    return Response(data=error_msg)

 

q_insert_renewal_gisu()가 혹시나 터졌을 경우에 kibanna에 적재해주기 위해 제가 실제로 사용했던 소스 예제입니다.

 

Beats

기존의 ELK에서의 큰 문제점 중 하나는 Logstash였습니다.
데이터 수집의 역할을 맡고 있는 Logstash는, 원하는 형태로의 데이터 입출력 변환 기능까지 맡고 있었기 때문에 그 오버헤드가 컸습니다.

많은 사용자들의 요구사항을 받아들인 Elastic 회사는, 오로지 데이터의 수집만을 담당하는 경량화된 모듈 Beats를 도입 했습니다.

 

정리하자면, 서버에 에이전트로 설치하여 다양한 유형의 데이터를 ElasticSearch 또는 Logstash에 전송하는 오픈 소스 데이터 발송자 입니다.

 

🙋🏻‍♂️ 후기

저는 부족한 글솜씨로, 실제 코드를 예로들어 설명하였지만, ELK는 개발자로써 거의 필수로 알아야 하는 항목이므로, 공식문서와 개념정리가 잘 된 다른 블로그도 참고하셔서 꼭 한번 로그를 적재하여 키바나로 확인해보시기 바랍니다.

ELK가 생각보다 역사가 길고, 많은 변화를 시도하기 때문에 가끔 한번씩 공식홈페이지를 들어가보시는것을 추천드립니다!

(오랜만에 홈페이지에 들어가보니 Cloud 기반의 Elasticsearch를 도입하였던데 이 부분은 저도 공부중이어서 따로 포스팅하지 못한점 양해부탁드립니다..!)

 

 

🔗  참고한 글

https://www.elastic.co/kr/what-is/elk-stack

 

ELK Stack: Elasticsearch의 개발자들이 제공합니다

ELK Stack이란 무엇인가요? ELK Stack은 널리 알려진 세 개의 오픈 소스 프로젝트인 E=Elasticsearch(Lucene 기반), L=Logstash, K=Kibana의 머리글자를 합친 것입니다. Beats가 추가되어 이제 ELK Stack을 Elastic Stack이

www.elastic.co

 

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함