프로덕션에서의 Elasticsearch — 배포 모범 사례

Elasticsearch는 최신 데이터 분석을 위해 고도로 최적화 된 검색 엔진입니다.

Elasticsearch는 놀라운 실시간 검색 및 분석 엔진입니다. Apache Lucene을 기반으로합니다. 분산되고 RESTful이며 사용하기 쉽고 가용성이 높습니다. Elasticsearch 사용 사례에는 검색 기능 강화, 트랜잭션 모니터링 및 오류 감지, 컨텐츠 검색, 로그 분석, 퍼지 검색, 이벤트 데이터 집계, 데이터 시각화가 포함됩니다. Elasticsearch와 나머지 Elastic Stack은 매우 다재다능한 것으로 입증되었으며 위의 사용 사례에서 볼 수 있듯이 오늘날 Elasticsearch를 제품이 제공하는 제품에 통합하고 추가 통찰력을 추가하는 여러 가지 방법이 있습니다.

Botmetric의 검색 및 분석에이 도구를 많이 사용하고 하루에 약 10 억 개의 문서를 색인화하며 실시간으로 데이터 시각화를 위해 매우 복잡한 집계를 사용합니다.

즉, 애플리케이션 부트 스트래핑과 프로덕션 환경에서 실행 및 유지 관리는 완전히 다릅니다. 이 기사는 실제 경험에서 나온 이러한 많은 요소를 다루며 프로덕션 환경에서 Elasticsearch를 실행하기 위해 고려해야 할 기본 공통 항목입니다.

기억:

Elasticsearch 및 Lucene은 Java로 작성되므로 힙 공간 및 JVM 통계를 찾아야합니다. Elasticsearch에 사용 가능한 힙이 많을수록 쿼리 성능을 높이기 위해 필터 및 기타 캐싱에 더 많은 메모리를 사용할 수 있습니다. 그러나 힙이 너무 많으면 가비지 콜렉션이 오래 중단 될 수 있습니다. JVM이 압축 된 오브젝트 포인터 (압축 된 oop)에 사용하는 컷오프 이상으로 Xmx를 설정하지 마십시오. 정확한 컷오프는 다양하지만 32GB에 가깝습니다.

일반적인 문제는 너무 큰 힙을 구성하는 것입니다. 64GB 머신이 있습니다. Golly는 Elasticsearch에 64GB의 메모리를 모두 제공하려고합니다. 더 좋습니다! 힙은 Elasticsearch에서 확실히 중요합니다. 많은 인 메모리 데이터 구조에서 사용되어 빠른 작동을 제공합니다. 그러나 그렇게 말하면 힙에서 벗어난 또 다른 주요 메모리 사용자 인 OS 파일 캐시가 있습니다.

Lucene은 메모리 내 데이터 구조를 캐싱하기 위해 기본 OS를 활용하도록 설계되었습니다. Lucene 세그먼트는 개별 파일에 저장됩니다. 세그먼트는 변경할 수 없으므로 이러한 파일은 변경되지 않습니다. 이는 캐시에 매우 친숙하며 기본 OS는 핫 세그먼트를 메모리에 상주시켜 행복하게 액세스 할 수 있습니다. 이러한 세그먼트에는 반전 색인 (전체 텍스트 검색)과 문서 값 (집계)이 모두 포함됩니다. Lucene의 성능은 OS와의 이러한 상호 작용에 의존합니다. 그러나 Elasticsearch의 힙에 사용 가능한 모든 메모리를 제공하면 OS 파일 캐시에 남은 공간이 없습니다. 이는 성능에 심각한 영향을 줄 수 있습니다. 표준 권장 사항은 사용 가능한 메모리의 50 %를 Elasticsearch 힙에 제공하고 나머지 50 %는 사용하지 않는 것입니다. 사용되지 않습니다. Lucene은 파일 캐시에 남은 모든 것을 행복하게 사용합니다. Elasticsearch 힙은 다음과 같은 방법으로 구성 할 수 있습니다.

수출 ES_HEAP_SIZE = 10g

또는

ES_JAVA_OPTS = "-Xms10g -Xmx10g"./bin/elasticsearch

CPU :

Elasticsearch는 집계 및 필터링 된 쿼리를 지원합니다. 복잡한 필터링 된 쿼리, 집중적 인 인덱싱, 퍼콜 레이션 및 인덱스에 대한 쿼리를 실행하려면 많은 CPU가 필요하므로 올바른 것을 선택하는 것이 중요합니다. CPU 스펙과 쿼리가 JVM에서 실행될 때 Java와 작동하는 방식을 이해해야합니다.

각 풀은 여러 스레드를 실행하며 구성 할 수 있으며 대기열이 있습니다. Elasticsearch가 코어를 동적으로 할당하므로 매우 구체적인 요구 사항이없는 한이 변경은 권장되지 않습니다.

스레드 풀 유형 :

Elasticsearch에는 3 가지 유형의 스레드 풀이 있습니다.

  1. 캐시 됨 : 캐시 된 스레드 풀은 보류중인 요청이있는 경우 스레드를 생성하는 바인딩되지 않은 스레드 풀입니다. 이 스레드 풀은이 풀에 제출 된 요청이 차단되거나 거부되지 않도록하는 데 사용됩니다. 이 스레드 풀에서 사용되지 않은 스레드는 연결 유지가 만료 된 후 종료됩니다 (기본값은 5 분). 캐시 된 스레드 풀은 일반 스레드 풀용으로 예약되어 있습니다.
  2. 고정 : 고정 스레드 풀에는 고정 스레드 크기가있어 요청을 처리 할 스레드가없는 보류중인 요청에 대해 큐 (선택적으로 바인드 됨)로 요청을 처리합니다. size 매개 변수는 스레드 수를 제어하며 기본값은 코어 수 x 5입니다.
  3. 스케일링 : 스케일링 스레드 풀은 동적 스레드 수를 보유합니다. 이 숫자는 워크로드에 비례하며 1과 size 매개 변수 값 사이에서 다릅니다.

Elasticsearch는 CPU 사용을 다양한 유형의 스레드 풀로 나눕니다.

  • 일반 : 감지 및 스레드 풀 유형과 같은 표준 조작이 캐시됩니다.
  • 인덱스 : 인덱스 / 삭제 작업용. 스레드 풀 유형이 고정되었습니다.
  • 검색 : 카운트 / 검색 작업용. 스레드 풀 유형이 고정되었습니다.
  • get : get 조작 스레드 풀 유형이 고정되었습니다.
  • 대량 : 대량 색인 생성과 같은 대량 작업의 경우. 스레드 풀 유형이 고정되었습니다. 대량 문서의 최상의 구성은 클러스터 구성에 따라 다르며 여러 값을 시도하여 식별 할 수 있습니다.
  • 퍼 콜레이트 : 퍼콜 레이션. 스레드 풀 유형이 고정되었습니다.
  • 새로 고침 : 새로 고침 작업 스레드 풀 유형이 조정 중입니다.

유형별 매개 변수를 설정하여 특정 스레드 풀을 변경할 수 있습니다.

자세한 내용은 https://www.elastic.co/guide/en/elasticsearch/reference/2.2/modules-threadpool.html#types

파편 크기 :

샤드는 Elasticsearch가 클러스터 내에서 데이터를 배포하는 단위입니다. 데이터를 재조정 할 때 Elasticsearch가 샤드를 이동할 수있는 속도 (예 : 장애 발생시 네트워크 및 디스크 성능뿐만 아니라 샤드의 크기와 수에 따라 달라집니다.

Elasticsearch에서 각 쿼리는 샤드 당 단일 스레드로 실행됩니다. 그러나 동일한 샤드에 대한 여러 쿼리 및 집계와 같이 여러 샤드를 병렬로 처리 할 수 ​​있습니다.

이는 캐싱이 포함되지 않을 때 최소 쿼리 대기 시간이 데이터, 쿼리 유형 및 샤드 크기에 따라 달라짐을 의미합니다. 많은 작은 샤드를 쿼리하면 샤드 당 처리 속도가 빨라지지만 더 많은 작업을 대기열에 넣고 순서대로 처리해야하므로 적은 수의 큰 샤드를 쿼리하는 것보다 반드시 더 빠를 필요는 없습니다. 작은 샤드가 많으면 동시 쿼리가 여러 개인 경우 쿼리 처리량이 줄어들 수 있습니다.

각 샤드는 메모리에 보관해야하는 데이터가 있으며 힙 공간을 사용합니다. 여기에는 디스크의 데이터 위치를 정의하기 위해 샤드 수준과 세그먼트 수준에서 정보를 보유하는 데이터 구조가 포함됩니다. 이러한 데이터 구조의 크기는 고정되어 있지 않으며 사용 사례에 따라 다릅니다. 그러나 세그먼트 관련 오버 헤드의 중요한 특징 중 하나는 세그먼트의 크기에 엄격하게 비례하지 않는다는 것입니다. 이는 큰 세그먼트가 작은 세그먼트에 비해 데이터 볼륨 당 오버 헤드가 적다는 것을 의미합니다. 그 차이는 상당 할 수 있습니다. 시작하기 전에 얻을 수있는 문서 수를 알 수 없기 때문에 올바른 샤드 수를 선택하는 것은 복잡합니다. 샤드가 많으면 클러스터에 좋고 끔찍할 수 있습니다. 인덱스 및 샤드 관리가 마스터 노드에 과부하를 가하여 응답하지 않을 수 있으며, 이상하고 불쾌한 동작이 발생할 수 있습니다. 클러스터 크기에 대처하기에 충분한 리소스를 마스터 노드에 할당하십시오.

나쁜 점은 샤드 수를 변경할 수 없으며 인덱스를 만들 때 정의된다는 것입니다. 인덱스가 생성되면 샤드 수를 변경하는 유일한 방법은 인덱스를 삭제하고 다시 생성 한 후 다시 인덱스하는 것입니다.

복제

Elasticsearch는 복제를 지원하고 데이터 노드간에 데이터가 복제되므로 노드 손실로 인해 데이터가 손실되지 않습니다. 기본적으로 복제 인수는 1이지만 제품 요구 사항에 따라 증가 할 수 있습니다. 복제본이 많을수록 데이터의 재해 방지 기능이 향상됩니다. 더 많은 복제본을 갖는 또 다른 이점은 각 노드에 복제본 샤드를 보유하므로 복제본도 쿼리에 사용되므로 쿼리 성능이 향상됩니다.

일관성을 위해 Elasticsearch에서 사용하는 복제 공식은 다음과 같습니다.

(기본 + number_of_replicas) / 2 + 1

할당 최적화

제품 데이터 요구 사항을 기반으로 데이터를 냉온으로 분류 할 수 있습니다. 다른 것보다 더 자주 액세스되는 인덱스에는 더 많은 데이터 노드가 할당 될 수있는 반면, 덜 자주 액세스하는 인덱스는 더 적은 리소스가 할당 될 수 있습니다. 이 전략은 특히 응용 프로그램 로그 (예 : ELK)와 같은 시계열 데이터를 저장하는 데 유용합니다.

이것은 정기적으로 인덱스를 다른 노드로 이동시키는 cronjob을 실행하여 달성 할 수 있습니다.

핫 노드는 데이터 노드 유형으로 클러스터 내에서 모든 인덱싱을 수행합니다. 또한 가장 최근에 조회되는 경향이 있기 때문에 가장 최근의 지수를 보유합니다. 인덱싱은 CPU 및 IO 집약적 인 작업이므로 연결된 서버에 의해 강력하고 백업이 필요합니다. 고 가용성을 위해 최소 3 개의 핫 노드를 실행하는 것이 좋습니다. 그러나 수집하고 쿼리하려는 최근 데이터의 양에 따라 성능 목표를 달성하기 위해이 수를 늘려야 할 수도 있습니다.

웜 노드는 자주 쿼리되지 않는 대량의 읽기 전용 인덱스를 처리하도록 설계된 데이터 노드 유형입니다. 이러한 인덱스는 읽기 전용이므로 웜 노드는 SSD 대신 큰 연결 디스크 (일반적으로 회전 디스크)를 사용하는 경향이 있습니다. 핫 노드와 마찬가지로 고 가용성을 위해 최소 3 개의 웜 노드를 권장합니다. 그리고 이전과 마찬가지로, 대량의 데이터는 성능 요구 사항을 충족시키기 위해 추가 노드가 필요할 수 있습니다. 또한 CPU 및 메모리 구성은 종종 핫 노드의 구성을 미러링해야합니다. 이는 프로덕션 상황에서 경험할 수있는 것과 유사한 쿼리로 테스트하여 결정할 수 있습니다.

핫 및 웜 노드에 대한 자세한 내용은 여기를 참조하십시오.

적응할 수있는 또 다른 전략은 인덱스를 s3에 보관하고 해당 인덱스의 데이터가 필요할 때 복원하는 것입니다. 여기에서 자세한 내용을 읽을 수 있습니다.

노드 토폴로지 :

Elasticsearch 노드는 마스터 노드, 데이터 노드, 클라이언트 노드의 세 가지 범주로 나눌 수 있습니다.

  1. 마스터 노드 : 인덱스 / 샤드를 저장하지 않으므로 데이터 노드가 아닌 경우 마스터 노드는 작을 수 있습니다. 자세한 클러스터 상태를 저장하고 인덱스 및 샤드 메타 데이터 조회에서 데이터 및 기타 노드를 도와줍니다. Elasticsearch는 분할 두뇌 문제를 피하기 위해 여러 마스터 노드를 가져야합니다.
  2. 데이터 노드 : 데이터 노드는 실제 인덱스 데이터를 저장 / 쿼리합니다.
  3. 클라이언트 노드 : 클라이언트 노드는 인덱싱 및 검색을위한 프록시로 사용됩니다. 집계를 많이 사용하는 경우이 방법을 사용하는 것이 좋습니다. 데이터 나 마스터 자격이없는 특수 ElasticSearch 노드입니다. 클라이언트 노드는 클러스터를 인식하므로 스마트로드 밸런서 역할을 할 수 있습니다. 쿼리를 클라이언트 노드로 보내면 각 데이터 노드의 쿼리 결과에 대한 응답을 수집하는 고가의 작업을 수행 할 수 있습니다.

이러한 설정을 각 노드의 elasticsearch.yml 파일에 추가하십시오.

마스터 노드 : node.master : true node.data:false
데이터 노드 : node.master : false node.data:true
클라이언트 노드 : node.master : false node.data:false

문제 해결 팁 :

Elasticsearch 성능은 설치된 시스템에 따라 크게 다릅니다. CPU, 메모리 사용 및 디스크 I / O는 각 Elasticsearch 노드의 기본 운영 체제 메트릭입니다. CPU 사용량이 급증 할 때 JVM (Java Virtual Machine) 메트릭을 살펴 보는 것이 좋습니다. 다음 예에서 스파이크의 원인은 가비지 콜렉션 활동이 높기 때문입니다.

  1. 힙 압력 : 메모리 압력이 높으면 클러스터 성능에 두 가지 방식으로 작동합니다. 메모리 압력이 75 % 이상으로 높아지면 사용 가능한 메모리가 줄어들고 클러스터는 가비지 수집을 통해 메모리를 회수하기 위해 일부 CPU 리소스를 사용해야합니다. 가비지 수집이 설정되어있는 동안에는 이러한 CPU주기를 사용하여 사용자 요청을 처리 할 수 ​​없습니다. 결과적으로, 시스템이 점점 더 많은 자원을 제한함에 따라 사용자 요청에 대한 응답 시간이 증가합니다. 메모리 압력이 계속 상승하고 거의 100 %에 도달하면 훨씬 더 적극적인 가비지 수집이 사용되어 클러스터 응답 시간에 큰 영향을 미칩니다. Index Response Times (인덱스 응답 시간) 메트릭은 메모리 압력이 높으면 성능에 상당한 영향을 미칩니다.
  2. JVM의 힙이 아닌 메모리가 증가하여 페이지 캐시 용 메모리를 제거하고 커널 수준의 OOM이 발생할 수 있습니다.
  3. 분할 뇌 문제를 피하십시오. 스플릿 브레인은 클러스터가 분할되는 시나리오입니다. 예를 들어 6 개의 노드 클러스터가 있습니다. 2 개의 노드가 클러스터에서 연결이 끊어졌지만 여전히 서로를 볼 수 있습니다. 그런 다음이 두 노드는 다른 클러스터를 만듭니다. 그들은 심지어 그들 가운데 새로운 주인을 선출 할 것입니다. 이제 이름이 같은 두 개의 클러스터가 있습니다. 하나는 4 개의 노드이고 다른 하나는 2 개의 노드입니다. 각각에는 마스터 노드도 있습니다. 이를 ES 클러스터의 분할 두뇌 문제라고합니다.이를 피하려면 ES 매개 변수 discovery.zen.minimum_master_nodes를 노드 수 + 1의 절반으로 설정하십시오.
  4. Elasticsearch는 스토리지 장치를 많이 사용하기 때문에 디스크 I / O를 모니터링하면 이러한 기본 요구 사항이 충족됩니다. 디스크 I / O가 감소하는 데는 여러 가지 이유가 있으며 여러 가지 문제를 예측하기위한 핵심 지표로 간주됩니다. 인덱싱 및 쿼리 성능의 효과를 확인하는 것이 좋습니다. 읽기 및 쓰기 작업을 분석하면 시스템이 특정 사용 사례에서 가장 필요한 것을 직접 나타냅니다. 디스크 I / O의 운영 체제 설정은 다른 모든 최적화의 기초이며 디스크 I / O를 조정하면 잠재적 인 문제를 피할 수 있습니다. 디스크 I / O가 여전히 충분하지 않은 경우, 샤드 수 및 크기 최적화, 병합 제한, 느린 디스크 교체, SSD로 이동 또는 더 많은 노드 추가와 같은 대책은 I / O의 원인에 따라 평가되어야합니다. 병목 현상.
  5. 검색에 의존하는 응용 프로그램의 경우 사용자 경험은 검색 요청의 대기 시간과 밀접한 관련이 있습니다. 생성 된 쿼리, 잘못 구성된 Elasticsearch 클러스터, JVM 메모리 및 가비지 수집 문제, 디스크 IO 등과 같이 쿼리 성능에 영향을 줄 수있는 요소가 많이 있습니다. 쿼리 대기 시간은 사용자에게 직접 영향을주는 지표이므로 이에 대한 경고를 표시해야합니다.
  6. Elasticsearch의 대부분의 필터는 기본적으로 캐시됩니다. 즉, 필터링 된 쿼리를 처음 실행하는 동안 Elasticsearch는 필터와 일치하는 문서를 찾고 해당 정보를 사용하여 "비트 세트"라는 구조를 구축합니다. 비트 세트에 저장된 데이터에는 문서 식별자와 지정된 문서가 필터와 일치하는지 여부가 포함됩니다. 동일한 필터를 사용하는 후속 쿼리 실행은 비트 세트에 저장된 정보를 재사용하므로 I / O 작업 및 CPU주기를 절약하여 쿼리 실행을 더 빠르게합니다. 쿼리에서 필터를 사용하는 것이 좋습니다. 자세한 내용은 여기를 참조하십시오.
  7. 새로 고침 시간 및 병합 시간은 인덱싱 성능과 밀접한 관련이 있으며 전체 클러스터 성능에 영향을줍니다. Lucene 인덱스 (샤드)에 대한 파일 작업 수에 따라 새로 고침 시간이 늘어납니다.
  8. 느린 쿼리 로깅을 사용하면 느린 쿼리와 개선을 위해 수행 할 수있는 쿼리를 식별하는 데 도움이되며 특히 와일드 카드 쿼리에 유용합니다.
  9. 최대 파일을 허용하려면 ulimit 크기를 늘리십시오.
  10. OS가 사용하지 않는 애플리케이션 메모리를 교체하기로 결정할 때 ElasticSearch 성능이 저하 될 수 있습니다. OS 수준 설정을 설정하여 스와핑을 비활성화하거나 ElasticSearch 구성 bootstrap.mlockall에서 다음을 설정하십시오. true
  11. 와일드 카드 쿼리에 의한 모든 인덱스 삭제를 비활성화합니다. 누군가가 모든 인덱스 (* 또는 _all)에 대해 DELETE 조작을 발행하지 않도록하려면 action.destructive_requires_name을 true로 설정하십시오.

마무리하기 전에 측정 항목을 보는 데 유용한 URL 목록이 있습니다.

  • / _cluster / health? pretty : 클러스터 상태 표시기입니다.
  • / _status? pretty : 모든 지수에 대한 모든 정보를 제공합니다.
  • / _nodes? pretty : 노드에 대한 모든 정보를 제공합니다.
  • / _cat / master? pretty : 마스터 노드 용.
  • / _stats? pretty : 샤드 할당의 경우 통계를 나타냅니다.
  • / _nodes / stats? pretty : 개별 노드 통계의 경우 노드에 대한 jvm, http, io 통계가 포함됩니다.

Elasticsearch의 지표 집계는 Datadog, TICK과 같은 대부분의 시스템 모니터링 도구에서 지원됩니다. Elasticsearch를 지속적으로 모니터링하려면 이러한 도구를 사용하는 것이 좋으며 깔때기를 만드는 것이 좋습니다.

결론:

Elasticsearch는 분산 된 전체 텍스트 검색 및 분석 엔진으로, 규모에 관계없이 여러 테넌트가 전체 데이터 세트를 통해 전례없는 속도로 검색 할 수 있습니다. 전체 텍스트 검색 기능 외에도 ElasticSearch는 분석 시스템 및 분산 데이터베이스의 두 배가됩니다. ElasticSearch는 시작하기에 좋은 기본값을 가지고 있습니다. 그러나 초기 실험 단계가 끝나면 필요에 따라 설정을 조정하는 데 시간을 소비해야합니다. 클러스터가 필요에 맞게 구성되도록 나중에 공식 문서와 함께 구성을 다시 방문하는 것이 좋습니다.