ELK 시리즈 4, Elasticsearch 성능 최적화

 


앞말


최근 1년 동안 Elasticsearch를 사용하여 억 개의 로그 검색 플랫폼인'ELK', 억 개의 분포식 추적 시스템을 완성했다.이러한 시스템을 설계하는 과정에서 밑바닥은 모두 Elasticsearch를 이용하여 데이터의 저장을 하고 데이터의 양은 모두 억 등급을 초과하며 심지어 100억 등급에 달한다.
그래서 틈틈이 시간을 내서 구체적으로 어떻게 Elasticsearch의 성능 최적화를 하는지 정리하고 Elasticsearch에 관심이 있는 학생들에게 도움이 되었으면 합니다.

배경


Elasticsearch는 Lucene 기반 검색 서버입니다.이것은 RESTful 웹 인터페이스를 기반으로 하는 분포식 다중 사용자 능력의 전문 검색 엔진을 제공한다.Elasticsearch는 Java로 개발되었고 Apache 허가 조항의 오픈 소스로 발표되어 현재 유행하는 기업급 검색엔진입니다.디자인은 클라우드 컴퓨팅에 사용되어 실시간 검색에 도달할 수 있고 안정적이고 신뢰할 수 있으며 빠르며 설치와 사용이 편리하다.
상자를 열면 바로 사용할 수 있는 제품으로서 생산 환경이 출시된 후에 우리는 사실 반드시 그 성능과 안정성을 확보할 수 있는 것은 아니다.어떻게 실제 상황에 따라 서비스의 성능을 향상시킬 것인가는 사실 많은 기교가 있다.
다음은 세 가지 측면에서 최적화된 서비스의 성능을 설명합니다.
  • 인덱스 효율 최적화
  • 검색 효율 최적화
  • JVM 구성 최적화
  • 인덱스 효율 최적화


    색인 최적화는 주로 Elasticsearch 삽입 차원에서 최적화된다. 만약에 병목이 여기에 있지 않고 데이터 부분, 예를 들어 DB나 Hadoop에서 발생한다면 최적화 방향은 바뀌어야 한다.이 동시에 Elasticsearch 자체의 인덱스 속도는 사실 매우 빠르다. 구체적인 데이터는 정부의benchmark 데이터를 참고할 수 있다.

    대량 제출


    대량의 데이터가 제출되었을 때, 대량 제출을 건의합니다.
    예를 들어 ELK를 하는 과정에서 Logstash indexer가 데이터를 Elasticsearch에 제출하면batchsize는 최적화 기능점으로 삼을 수 있다.그러나size 크기를 최적화하려면 문서 크기와 서버 성능에 따라 결정해야 한다.
    Logstash에서 제출한 문서의 크기가 20MB를 초과하면 Logstash는 하나의 대량 요청을 여러 개의 대량 요청으로 나누어 요청합니다.
    제출 과정에서 Es Rejected Execution Exception 이상이 발생하면 집단의 인덱스 성능이 한계에 도달했다는 것을 의미합니다.이런 상황은 서버 집단의 자원을 향상시키거나 업무 규칙에 따라 데이터 수집 속도를 줄인다. 예를 들어 Warn, Error 등급 이상의 로그만 수집한다.

    하드웨어 최적화


    하드웨어 설비를 최적화하는 것은 줄곧 가장 빠르고 효과적인 수단이다.
  • 경제적인 압력을 견딜 수 있는 범위 내에서 가능한 한 고체 하드디스크 SSD를 사용한다.SSD는 랜덤으로 쓰든 순서대로 쓰든 기계 하드디스크에 비해 크게 향상되었다.
  • B2D는 RAID0을 사용합니다.Elasticsearch는 자체 차원에서 복사본을 통해 백업 기능을 제공하기 때문에 디스크의 백업 기능을 이용할 필요가 없고 디스크 백업 기능을 사용하면 쓰기 속도에 큰 영향을 미친다.

  • Refresh 간격 증가


    색인 성능을 높이기 위해 Elasticsearch는 데이터를 쓸 때 쓰기 지연 정책을 사용합니다. 즉, 데이터를 메모리에 먼저 쓰고 기본 1초 (index.refresh_interval) 를 초과하면 쓰기 작업을 합니다. 메모리에 있는segment 데이터를 운영체제에 리셋해야 데이터를 검색할 수 있습니다. 그래서 이것이 바로 Elasticsearch가 실시간 검색 기능을 제공하는 이유입니다.실시간 검색 기능이 아니라
    물론 우리 내부 시스템처럼 데이터 지연에 대한 요구가 높지 않으면refresh 시간 간격을 연장함으로써segment 합병 압력을 효과적으로 줄이고 인덱스 속도를 제공할 수 있다.전체 체인 추적을 하는 과정에서 우리는 index를 할 것이다.refresh_interval을 30s로 설정하여refresh 횟수를 감소합니다.
    또한 전체 인덱스를 진행할 때refresh 횟수를 임시로 닫을 수 있습니다. 즉, index입니다.refresh_interval은 -1로 설정하고 데이터 가져오기가 성공한 후에 정상적인 모드로 엽니다. 예를 들어 30s입니다.

    복제본 수 감소


    Elasticsearch의 기본 복사본 수량은 3개입니다. 이것은 집단의 가용성을 높이고 검색의 병렬 수를 증가시키지만 색인 쓰기 효율에도 영향을 줍니다.
    색인 과정 중, 업데이트된 문서를 사본 노드에 보내야 하며, 사본 노드가 발효된 후에 되돌아오는 것이 끝난다.Elasticsearch를 사용하여 업무 검색을 할 때 복사본 수를 3개로 설정하는 것을 권장하지만, 내부 ELK 로그 시스템, 분포식 추적 시스템과 같이 복사본 수를 1개로 설정할 수 있습니다.

    검색 효율 최적화


    경로


    우리가 문서를 조회할 때, Elasticsearch는 어떤 문서가 어느 부분에 저장되어야 하는지 어떻게 알 수 있습니까?그것은 사실 아래의 이 공식을 통해 계산해 낸 것이다
    shard = hash(routing) % number_of_primary_shards
    routing 기본값은 문서의 id이며, 사용자 id와 같은 사용자 정의 값을 사용할 수도 있습니다.

    routing 쿼리 없음


    조회할 때 조회할 데이터가 구체적으로 어느 부분에 있는지 모르기 때문에 전체 과정은 2단계로 나뉜다
  • 분배: 협조 노드에 도착하면 협조 노드는 조회 요청을 각 분할에 분배한다.
  • 집합: 조율 노드가 각 섹션에 수집된 조회 결과를 조회하고 조회한 결과를 정렬한 후에 사용자에게 결과를 되돌려줍니다.

  • 라우팅 쿼리 포함


    조회할 때routing 정보에 따라 특정한 분배 조회에 직접 위치를 정할 수 있으며 모든 분배를 조회할 필요가 없고 조율 노드를 통해 정렬할 수 있다.
    위에서 사용자 정의한 사용자에게 조회합니다.routing이userid로 설정되면 데이터를 직접 조회할 수 있어 효율이 많이 향상됩니다.

    Filter VS Query


    Ebay는 Elasticsearch를 사용한 경험을 공유했습니다.
    Use filter context instead of query context if possible. 가능한 한 필터 컨텍스트(Filter)를 사용하여 질의 컨텍스트(Query)를 대체합니다.
  • Query: 이 문서와 이 질의 자구의 일치 정도는 어떻습니까?
  • Filter: 이 문서는 질의 자구와 일치합니까?

  • Elasticsearch는 Filter 조회에 대해 "예"또는 "아니오"만 대답할 수 있으며, Query처럼 관련성 점수를 계산할 필요가 없으며, Filter 결과는 캐시할 수 있습니다.

    페이지를 크게 넘기다


    Elasticsearch를 사용하는 과정에서 페이지가 크게 넘어가는 것을 최대한 피해야 한다.
    정상적인 페이지 넘기 조회는 모두From부터 Size 게이지 데이터입니다. 그러면 각 섹션에서 점수 순위가 앞에 있는 From + Size 게이지 데이터를 조회해야 합니다.협동 노드는 각 분배의 전 From + Size 게이지 데이터를 수집합니다.협동 노드는 모두 N*(From + Size) 개의 데이터를 받은 다음에 정렬을 하고 그 중에서 From + Size 개의 데이터를 되돌려줍니다.
    From이나 Size가 크면 정렬에 참여하는 수량이 동시에 많이 늘어나 결국 CPU 자원 소모가 커진다.
    Elasticsearch scroll과 scroll-scan을 사용하여 효율적으로 스크롤하는 방식으로 이런 문제를 해결할 수 있다.구체적인 묘사는 Elasticsearch: 권위 가이드-scroll 조회를 참고할 수 있다

    JVM 설정


    32G 현상


    Elasticsearch 기본 설치 후 설정된 메모리는 1GB입니다.어떤 업무 배치에 대해서도 말하자면, 이 설정은 너무 작다.
    예를 들어 기계에 64G 메모리가 있다면, 우리는 설치가 클수록 좋지 않습니까?
    사실은 아니에요.
    주요 Elasticsearch 베이스에는 Lucene이 사용됩니다.Lucene은 운영체제의 기본 메커니즘을 이용하여 메모리 데이터 구조를 캐시할 수 있도록 설계되었다.Lucene의 세그먼트는 개별 파일에 각각 저장됩니다.세그먼트는 변할 수 없기 때문에 이 파일들도 변하지 않는다. 이것은 캐시에 우호적이며 운영체제도 이 세그먼트 파일을 더욱 빨리 접근하기 위해 캐시할 것이다.
    만약 당신이 모든 메모리를 Elasticsearch의 메모리에 분배한다면, Lucene에게 남은 메모리가 없을 것입니다.이것은 전체 텍스트 검색의 성능에 심각한 영향을 줄 것이다.
    표준적인 건의는 사용 가능한 메모리의 50%를 Elasticsearch의 메모리로 하고 나머지 50%를 보존하는 것이다.물론 낭비되지 않을 것이다. 루틴은 남은 메모리를 기꺼이 이용할 것이다.
    ES 친구들도 32G를 넘지 말라는 말을 들은 적이 있겠지.
    사실 주요 원인은 JVM이 메모리가 32GB보다 적을 때 하나의 메모리 대상 포인터 압축 기술을 사용하기 때문이다.
    Java에서는 모든 객체가 더미에 할당되고 포인터를 통해 참조됩니다.일반 객체 포인터(OOP)는 일반적으로 CPU 길이의 크기인 32비트 또는 64비트를 가리키며 프로세서에 따라 다릅니다.포인터는 이 OOP 값의 바이트 위치를 참조합니다.
    32비트 시스템의 경우 최대 4GB의 메모리 더미 크기를 의미합니다.64비트의 시스템은 더 큰 메모리를 사용할 수 있지만, 64비트의 바늘은 더 큰 낭비를 의미한다. 왜냐하면 바늘 자체가 크기 때문이다.더 큰 포인터는 주 메모리와 각 캐시 (예를 들어 LLC, L1 등) 사이에서 데이터를 이동할 때 더 많은 대역폭을 차지한다.
    그래서 결국 저희가 31G 설정을 하게 됩니다.
    수정 jvm.옵션 파일 설정
    -Xms 31g
    -Xmx 31g

    만약 당신이 128GB의 메모리를 가지고 있다고 가정한다면, 당신은 두 개의 노드를 만들 수 있으며, 각 노드의 메모리 분배는 32GB를 초과하지 않는다.즉, ES에 64GB를 초과하지 않고 나머지 64GB를 초과하는 메모리는 Lucene에
     
     
    로 이동http://blog.51cto.com/13527416/2132270?from=timeline

    좋은 웹페이지 즐겨찾기