elasticsearch가 버전업하면서. 변경되고, 좋아진점을 잘 정리해둔 글이다.


http://kimjmin.net/2019/04/2019-04-elastic-stack-7-release/

 

Elastic Stack 7.0 출시 밎 지금까지의 변경들 - Jongmin's blog

Elasticsearch, Kibana, Logstash, Beats 제품들을 개발하는 Elastic 사 에서는 이 4 제품들을 통틀어 Elastic Stack 이라고 부릅니다. 예전에 Beats가 생기기 전에는 ELK(Elsaticsearch, Logstash, Kibana) 스택으로 더 잘 알려져 있었는데 이 스토리는 https://www.elastic.co/kr/elk-stack 페이지에서 좀 더 자세히 보실 수 있습니다. Elastic Stack은

kimjmin.net


나는 <<es 7.2버전>>을 사용중이므로, 6점대에 비해서 뭐가 좋아졌는지를 살펴보았다.
* adaptive replica selection이 적용되었음 : 코디네이터 노드에서 search request를 받아 해당 샤드에게 전달할때 샤드를 선택하는 방식으로, 기존 RR방식에서 똑똑해짐.
* cross cluster search의 성능이 향상되었음
* refresh interval 설정이 디폴트 30초로 설정되어 색인성능을 높였음
* minimum master node설정 자동화 : split brain 발생 가능 없어짐.
* default primary shard  수를 5에서 1로 변경.
* open jdk가 기본 번들로 포함되어 java 따로 설치 안해도 됨.

 

es에서 노드들을 어떻게 발견할까?
discovery.seed_hosts에 array값으로 initial nodes list를 주기는 하지만
그 이후에 노드가 추가, 삭제되는 경우는 어떻게될까?

# Discovery :  discovery.seed_hosts
discovery는 cluster formation module이 클러스터를 형성하는 다른 노드들을 찾는 과정을 의미한다.
(cluster formation module이 있고 역할에 따라 나뉘는데 그 중에 하나가 discovery임.)
이 과정은 es노드를 시작할때 또는 노드에서 마스터 노드가 실패했다고 판단될때 실행되는데,
마스터 노드가 발견되거나 새로 선출될때까지 계속해서 실행된다.

이 과정은 seed hosts 리스트에 의해 시작되고,
프로세스는 두 단계로 동작하는데
* 첫째 각 노드는 연결된 노드를 식별하고, 마스터 자격이 있는지 확인하여 seed 주소를 검사함
* 둘째 성공하면 원격 노드와 알려진 master-eligible 노드 목록을 모두 공유하고 원격 노드는 피어와 차례로 응답.
그런 다음 노드는 방금 발견한 새 노드들을 검사하고, 피어를 요청하는 등의 작업을 수행.
노드가 마스터 자격이 없는 경우 선택된 마스터 노드를 감지할때까지 이 감지 프로세스가 계속됨.

결론은 새로운 노드를 추가할때에 master-eligible nodes를 포함하는 클러스터의 모든 리스트를 
discover.seed_hosts에 기입해주고, 띄우면 master-eligible nodes에서 discovery하는 듯.
원래 있던 노드의 discovery.seed_hosts까지 수정해서 재시작해줄필요 없음.

# cluster.initial_master_nodes
최초 bootstrap당시의 master-eligible-nodes 목록임.
새 노드를 기존 클러스터에 추가할때는 master-eligible nodes를 포함하여 모두 discovery.seed_hosts에만 넣어주면되고,
initial_master_nodes 셋팅 해 줄 필요없음.
대신, inital_master_nodes에 설정된 master-eligible-nodes들 중에서 과반수 이상이 살아있어야 클러스터가 정상적으로 실행됨.

* discovery에 대하여.
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery-hosts-providers.html

 

Discovery | Elasticsearch Reference [7.6] | Elastic

Discovery is the process by which the cluster formation module finds other nodes with which to form a cluster. This process runs when you start an Elasticsearch node or when a node believes the master node failed and continues until the master node is foun

www.elastic.co

* cluster.initial_master_nodes에 대하여. discovery에 사용되는 여러 셋팅값들.
https://www.elastic.co/guide/en/elasticsearch/reference/current/discovery-settings.html#unicast.hosts

 

Important discovery and cluster formation settings | Elasticsearch Reference [7.6] | Elastic

Important discovery and cluster formation settingsedit There are two important discovery and cluster formation settings that should be configured before going to production so that nodes in the cluster can discover each other and elect a master node. disco

www.elastic.co

 

https://www.elastic.co/blog/a-practical-introduction-to-logstash

 

A Practical Introduction to Logstash

Elasticsearch에 대한 액세스 로그를 구문 분석하고 수집하기 위한 구성을 개발할 때 어떻게 Logstash를 사용할 수 있는지 보여주는 Logstash에 대한 소개.

www.elastic.co

((위의 공식 홈페이지 글을 보고 정리한 글입니다.))


logstash를 통해 es로 데이터를 수집하고 싶은데, es-logstash에 대해 간단히 살펴보자.
filebeat는 logstash module을 제공해서 filebeat로 log파일을 logstash로 쏘고, logstash에서 정제하여 es에 수집도 가능!

나는 logstash-es 부분만 일단 확인해본다.

# logstash 간단한 개요
logstash는 플러그인 기반의 데이터 수집 및 처리 엔진.
광범위한 플러그인이 구비됨 -> 다양한 아키텍처에서 손쉽게 데이터 수집,처리,전달이 가능하다.
프로세싱은 하나 이상의 파이프라인으로 구성된다.
각 파이프라인에서 하나 이상의 입력 플러그인이 내부 큐에 배치된 데이터를 수신하거나 수집한다.
  * 이 큐는 기본적으로 작아서 메모리에 보관되지만, 안정성과 복원력을 향상시키도록 디스크에서 더 크고 영구적으로 구성 가능. 

프로세싱 스레드는 마이크로 배치에 있는 큐로 부터 데이터를 읽고, 순서대로 설정된 filter plugin을 처리해준다.
logstash는 많은 수의 plugin을 제공하여 데이터를 파싱하고, 처리하고, 강화할수있게 해준다.

데이터가 처리되면 프로세싱 스레드는 데이터를 output plugin에 넣어준다. formatting하고 데이터를 계속 보내주는 역할을 하는 것이다. 가령  es 로 데이터를 보내는 것 처럼.


logstash pipeline은 한개 이상의 config파일로 생성된다.

1. 파이프라인 지정.

1)  single pipeline using a single configuration file.
     *  logstatsh를 시작하는 가장 쉬운 방법
     * -f 파라미터로  conf파일을 명시하여 실행시키는 방법.

2) single pipeline using multiple configuration files
     * 특정 directory의 모든 파일을 사용하여 설정될수도 있음.
     * logstash.yml에 기술하거나 -f 옵션으로 실행시킬수있음.
     * directory로 주어지면 그 directory의 모든 파일들을 사전식 순서로 연결한 다음 단일 구성 파일로 분석이됨.
     * 따로 conditinals를 사용해서 flow를 컨트롤하지 않는다면,
       모든 input으로부터의 데이터가 모든 filter로 처리되고, 모든 output으로 보내지게 됨.

3) using multiple pipelines
    * multiple pipelines를 사용하려면 pipeliens.yml 파일을 수정해야함.
    * multiple pipelines은 서로 다른 로직의 flow를 분리해서 복잡성을 낮추고, 많은 양의 conditionals를 사용하지 않게 함.
       * 그만큼 유지보수도 쉬워짐
    * 병렬 실행 될 것이기에 퍼포먼스도 향상됨. 효율적임.

2. 첫번째 구성 만들어보기
    * input, output은 필수, filter는 optional

input {
 file {
   path => ["/home/logstash/testdata.log"]
   sincedb_path => "/dev/null"
   start_position => "beginning"
  }
}
filter {
}
output {
  stdout {
    codec => rubydebug
  }
}

input file path를 주고, 
start_position : 시작점. one of ["beginning", "end"]
sincedb : input plugin은 현재 위치를 기록하기 위해 를 사용한다.
   * 다시말해 각각의 input file에 데이터를 계속 트레킹하기 위해 sincedb를 사용하는 것.

sincedb_path
Value type is string
There is no default value for this setting.
Path of the sincedb database file (keeps track of the current position of monitored log files) that will be written to disk. The default will write sincedb files to <path.data>/plugins/inputs/file NOTE: it must be a file path and not a directory path


   * 아래 path가서 보면 sincedb가 생성되어있음.
     그래서 es로 한번 넣었던 파일 다시 넣으니까..안되는구나

sudo cd /usr/share/logstash/data/plugins/inputs/file 
ls -al

 

stdout output plugin은 콘솔에 데이터를 쓰고, rubydebug codec은 구조를 보여줌으로써 config 개발 중에 debugging을 단순화해줌.

3. logstash 시작하기.

 logstash -r -f “/home/logstash/test.conf”

-r 옵션은 구성이 변경되었음을 식별할때마다 자동으로 구성을 다시 로드함.

{
 "message" => "Hello Logstash!",
 "@version" => "1",
 "path" => "/home/logstash/testdata.log",
 "@timestamp" => 2018-04-24T12:40:09.105Z,
 "host" => "localhost"
}

logstash에 들어간 모습. 데이터 포함하여 몇몇 메타데이터도 넣어줌.


## hot thread api
* cpu사용일이 높을때 hot threads api를 통해 특정 프로세스가 블락되어 문제를 일으키고 있는지 확인 할 수 있음.
* _nodes/hot_threads
* response 내용
   * 첫줄 : 노드의 신원 정보(스레드 정보가 어느 cpu에 속하는지에 관한 기초적 정보)
   * 둘째줄 : 'search'스레드에 xx%사용중이라고 나옴. search, merge, index와같은 행동이 기술됨.
   * 마지막줄 : es가 같은 스택트레이스를 가지고 이는 스레드가 최근 몇밀리초내에 뜬 10개 스냅샷 중 10개에 있다는 것을 의미.
   * 블락된 스레드 확인 : 블락 사용율, waiting상태에 있는 스레드들에 대한 대기 사용율.


## thread pool
* cpu와 memory의 효율적 사용을 위해 각 노드는 스레드풀을 관리하고있음.
* 요청종류에 따라 bulk/index/search thread pool이 있음.
threadpool.bulk.type:fixed
threadpool.bulk.size
threadpool.bulk.queue_size: 스레드수를 제어 (기본으로 cpu core * 5)


## 메모리
* heap크기, 필드와 필터 캐시.
* 집계와 필터에 메모리 사용.
* 필드데이터를 메모리에 올림으로써 필드데이터 접근 효율을 높임.
* 쿼리에 해당하는 문서만 올리는게 아니라 색인에 있는 모든 문서에 대한 값들을 로딩해서 쿼리가 엄청 빨라지는 것임.
* jvm ram의 50프로정도는 남겨
   * 루씬이 빈번하게 사용하는 파일 시스템 캐시를 위한 메모리 부족을 막기위해.
* 운영체제에 메모리가 부족하면 메모리페이지를 디스크로 내리는 스와핑이 발생할 수 있음. 급격한 성능저하로 이어지기때문에 스와핑은 끄도록.


## 필터와 필드 캐시
* 필터 캐시 : 필터와 쿼리 작업의 결과를 메모리내에 저장, 필터가 적용된 최초 쿼리 결과를 필터 캐시에 저장, 색인 수준으로는 사용 권장하지 않고. 노드수준의 사용을 권장 (LRU)
* 필트데이터 캐시 제한은 없음. 필드 데이터 서킷 프레이커 값에 도달까지 커질 수 있음.
* 케시 제거되는 것도 주의가 필요함. 비용이 큰 작업이고, 필드데이터가 너무 작게 설정되어있는건 아닌지 확인해볼필요가 있음.


## 운영체제 캐시
* 루씬 세그먼트는 불변 파일이고, os의 파일시스템 캐시를 적극 활용함.
  * 불변 파일이라느 것은 루씬에 의해 한번만 쓰이고, 여러번 읽힌다는 것을 의미.
* 루씬의 불변파일은 캐시 친화적. 기반이 되는 os에서 핫한 세그먼트에 빠른 접근이 가능하게 메모리에 상주시키도록 설계됨
node.tag정보를 가지고 라우팅하여 특정색인을 성능좋은 장비로 위치시킬수있음.


## 플러그인
* 사이트 플러그인, 코드 플러그인이 있음.
* 사이트 플러그인은 추가적인 기능제공은 아니고, 단순히 es가 서비스하는 웹페이지를 제공하는 것. ex) head plugin
* 코드 플러그인은 es가 실행하는 jvm코드를 포함하는 플러그인으로. jar파일. 
   * es가 인터페이스 제공을 위해 서비스 할 수 있는 기본 html, 이미지 그리고 자바스크립트 파일 포함 가능함.
   * ex) marvel plugin

Chaining

작업을 chain의 형태로 진행한다고 해서 chaining 이라고 한다
chaining으로 package를 생성하고 관리하니 코드도 한결 보기 좋아졌다.

Transform

MyTransform

두개의 테이블을 Merge하는 Transform

Udf와 함께 Parameter를 받는 Transform

사용하는 방법

  • DataFrametransform을 이용하면 다음과 같이 사용이 가능하다.
  • withColumn의 성격이 비슷한 녀석끼리 모아주니까 확실히 편하다 (UDF, transform이 한 object에 있다고 생각해보면 잡)
  • 이 방법 외에도 chain을 먼저 설정하고 chain에 함수들을 추가해서 한번에 실행도 가능하다. chained-transformations 여기를 참고!

참고

보통 vi/vim 에서 소스코드를 편집하게 되는데, 이때 indentation이 내가 원하는 포맷에 맞지 않을때가 있다.예를 들어서 들여쓰기가 2가 아닌 4가 될수도 있고, multiple line으로 작성하는 방식도 통일되어 있지 않다면 협업능력이 떨어져 보인다... 나만 보는게 아니니까! 나만 보기에는 편할수 있어도 일반적인 코드스타일을 맞추는게 중요하다고 최근에 생각... 이전에는 빨리 신속하게 기능을 구현하는게 중요하다고 생각했지만 이제는 협업도 중요하게 생각하면서! (잡소리 이상)

Scala Style Guide Indentation

vim-scala

  • vim-scala 에서 plugin vim plugin 다운로드
:SortScalaImports

scala-style

project/plugins.sbt
addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0")

config를 생성하면 현재 폴더에 scalastyle-config.xml이 생성

$ sbt scalastyleGenerateConfig

scalastyle을 통해서 현재 코드들의 sytle 체크를 하고 target/scalastyle-result.xml을 확인하면 된다.

$ sbt scalastyle # src/main
$ sbt test:scalastyle # src/test

scalastyle 의 룰이 약 60개정도 정해져있다. 이룰을 어기면 warn을 주는데, 각각 코드는 내가 수동으로 고쳐야한다.? 일단 그렇게 하고 있음

참고

DataFrameSuiteBase

  • DataFrameSuiteBase를 이용해서 주어진 두개의 DataFrame이 일치하는지 확인이 가능하다.
  • 간단하게 사용방법은 두개의 결과 df1, df2를 생성하고 assertDataFrameEquals를 사용하면 된다.
  • 사용하면서 까다로웠던것은 DataFrameSchema도 확인을 한다. 심지어 Nullable을 체크...
  • 만약 조인했던 결과에 null이 들어있고, 기대하는 값에 null이 없었다면 두개의 Schema는 다르고 결과적으로 Fail이 난다.
  • expectedDf에 만약 Null의 값을 포함시키기 위해서는 다음 Null값이 포함되는 DataFrame 생성하기 포스트 를 확인
  • 참고로 아이템의 순서도 동일해야 한다! 아이템 정렬하는 방법은 아래 DataFrame 정렬하기 포스트를 확인

참고

+ Recent posts