Elasticsearch 조정편 05 - Elasticsearch 검색 차원 최적화

6288 단어

1. 가능한 한 적은 필드


elasticsearch의 검색엔진은 밑바닥의 filesystemcache에 심각하게 의존합니다. 만약에 filesystemcache에 더 많은 메모리를 주고 메모리가 모든 indxsegment 파일 인덱스 데이터 파일을 수용할 수 있도록 한다면 검색할 때 기본적으로 메모리를 사용하므로 성능이 매우 높을 것입니다.
예를 들어 당신의 es 노드에는 세 대의 기계가 있는데 한 대의 기계는 64G이고 총 메모리는 64*3입니다.모든 기계가esjvmheap에 32G를 주면 남은 것은 filesystemcache에 남겨진 것은 기계마다 32g이고 총 집단에서 filesystemcache에 주는 것은 32*3=96gb 메모리이다.만약 이 때 전체 디스크에 데이터 파일을 인덱스한다면, 세 대의 기계에서 모두 1T의 디스크 용량을 차지하고, es 데이터량은 1t이다.filesystemcache의 메모리는 100g에 불과하고 10분의 1의 데이터는 메모리를 넣을 수 있으며 다른 것은 디스크에 있습니다. 그리고 검색 작업을 실행합니다. 대부분의 작업은 디스크를 가져가기 때문에 성능이 틀림없습니다.결국, 당신은es의 성능을 좋게 해야 합니다. 가장 좋은 상황은 당신의 기계의 메모리입니다. 적어도 당신의 총 데이터량의 절반을 수용할 수 있습니다.예를 들어 당신은 모두es에 1T의 데이터를 저장해야 합니다. 그러면 당신의 여러 기계가 filesystemcache에 남겨 놓은 메모리를 합치면 적어도 512G, 적어도 절반의 상황에서 검색은 메모리를 가져가야 합니다. 성능은 보통 몇 십 밀리초까지 가능합니다.
만약에 가장 좋은 상황에서 우리 자신의 생산 환경 실천 경험은 es로 소량의 데이터를 저장하는 것이 가장 좋다. 바로 당신이 검색할 색인이다. 메모리가 filesystemcache에 남겨진 것은 100G이다. 그러면 당신은 100gb 이내로 제어한다. 당신의 데이터는 거의 전부 메모리로 검색하는 것과 같다. 성능이 매우 높고 보통 10ms 이내일 수 있다.그래서 es에 반드시 검색해야 할 데이터를 저장합니다. 예를 들어 현재 데이터가 하나 있고 100개의 필드가 있습니다. 사실 검색하는 필드는 10개밖에 없습니다. 10개의 필드의 데이터를 es에 저장하고 90개의 필드의 데이터를 남기면 mysql,hadoop,hbase 등을 넣을 수 있습니다.이렇게 하면es 데이터량이 매우 적고 10개 필드의 데이터는 모두 메모리를 넣어서 검색하고 일부 id를 검색할 수 있으며 id를 통해 mysql, hbase에서 내역을 조회할 수 있다.

2. 문서 모형 디자인


문서 모형 디자인은 매우 중요하다. 검색할 때만 각종 복잡한 난잡한 조작을 실행하려고 하지 마라.
es가 지원할 수 있는 조작이 그렇게 많으니 es로 조작하기 어려운 일을 고려하지 마세요.만약 정말 그런 조작이 있다면, 가능한 한 문서 모형을 설계할 때, 쓸 때 완성해야 한다.
또한 너무 복잡한 조작, 예를 들어join,nested,parent-child 검색은 최대한 피해야 하며 성능이 매우 떨어진다.
검색/조회를 할 때 업무의 강도와 관련된 매우 복잡한 조작을 수행해야 한다.
  • 데이터를 쓸 때 모델을 설계하고 몇 개의 필드를 추가하여 처리된 데이터를 추가된 필드에 기록한다
  • 자신은 자바 프로그램으로 봉인한다.es가 할 수 있는 것은es로 하고 검색한 데이터는 자바 프로그램에서 한다. 예를 들어 우리는 자바 프로그램으로 봉인된 매우 복잡한 조작을 바탕으로 한다

  • 3. 사전 인덱스 데이터


    예를 들어 전자상거래 플랫폼에는rangeaggregation 작업이 많지만 그 범위를 확정할 수 있는 것이 많으면 색인할 때 관련 필드를 추가한다.
    예를 들어 가격 구간에 따라 분류 통계를 내야 하는데 이 가격 구간은 기본적으로 고정되어 있다. 예를 들어 0~100100~200200~500...그러면 우리가 색인을 할 때 가격에 맞추어 이 상품이 도대체 어느 가격 구간에 속하는지 명확하게 확정하고 해당하는 라벨을 달아서 다시 모으고 조회할 때 직접 이 필드를 통해 신속하게 포지셔닝을 하고 검색 성능을 향상시킬 수 있다.

    4. 날짜 조회


    여기에 날짜 조회에 대해 단독으로 제기한 것은 날짜 조회가 규범에 맞지 않을 때 성능이 급격히 떨어지기 때문이다.
    가능한 한 now와 같은 내장 함수를 사용하여 날짜 조회를 실행하지 마십시오. 기본 now는 밀리초급이기 때문에 결과를 캐시할 수 없습니다. 가능한 한 한 단계 범위를 사용하십시오.
    예를 들어now/m는 분급이다. 그러면 1분 안에 이 검색을 실행하면 검색 캐시를 사용할 수 있다.

    5. 동적 유형 매핑 비활성화


    기본 동적string 형식 맵은string 형식의field를text 형식과keyword 형식으로 동시에 맵니다. 이것은 디스크 공간을 낭비할 수 있습니다. 두 가지 모두 필요하지 않기 때문입니다.
    일반적으로 idfield라는 필드는 키워드만 비추고, bodyfield는textfield만 필요할 수 있습니다.
    content, content: text, content를 비추십시오.내장 필드:keyword
    문자열 형식의field가 text와 keyword로 자동으로 비치지 않도록 mappings 맵을 수동으로 설정할 수 있습니다.
    PUT index
    {
     "mappings": {
       "type": {
         "dynamic_templates": [
           {
             "strings": {
               "match_mapping_type": "string",
               "mapping": {
                  "type":"keyword"
               }
             }
           }
         ]
        }
      }
    }

    6. 국부 예열


    만약에 우리가es를 다시 시작하거나 새로운 집단을 재건한다면 filesystemcache는 빈 껍질로 변할 것입니다. 끊임없는 조회가 있어야만 filesystemcache를 다시 뜨겁게 할 수 있습니다.
    우리는 먼저 수동으로 일부 데이터에 대해 조회를 진행할 수 있다.예를 들어 사용자가 클릭한 후에야 실행할 수 있고 디스크에서 filesystemcache에 불러올 수 있습니다. 첫 번째 실행은 1s, 이후 매번 몇 십 밀리초입니다.
    너는 그 조회를 실행하는 프로그램을 만들 수 있다. 예열하면 데이터는 filesystemcahce에 불러온다. 프로그램이 실행될 때는 1s이고 나중에 사용자가 정말로 볼 때는 겨우 몇 십 밀리초이다.

    7, 적당히 증가 던전


    일반적인 던전량은 검색의 토출량을 증가시키지만 색인 성능을 떨어뜨리기 때문에 실제 장면에서 서로 다른 업무 장면에 따라 합리적인 던전 수량을 설정한다. 일반적으로 우리가 설정한 던전 수량은 항상 2이다.
    만약 업데이트가 빈번하지 않고 조회량이 비교적 많을 때 복사본 수량을 적당히 늘릴 수 있다. 예를 들어 증가하는 3, 4, 5 등이다.
    업데이트가 빈번하고 조회하는 qps가 높지 않으면 복사본 수량을 1로 설정할 수 있습니다.

    8, 더 나은 하드웨어 장치 사용


    기계 디스크를 대체하기 위해 성능이 더 좋은 SSD 디스크를 사용할 수 있습니다. 특히 무작위 읽기 성능은 제조업체가 제공한 데이터에 따라 기계 디스크보다 100배 빠릅니다.

    9. 데이터 희소 방지


    루틴의 내부 핵 구조는 조밀한 데이터와 결합하면 성능이 더욱 좋아진다.
    예를 들어 100개의 문서가 있는데 모든 문서는 20개의field가 있고 20개의field는 값이 있는데 이것이 바로 조밀한 데이터이다.
    그러나 만약에 100개의 문서가 있다면, 모든 문서의field는 다르다. 어떤 문서는field가 2개이고, 어떤 문서는field가 50개이다. 이것이 바로 희소한 데이터이다.
    그 이유는 루틴이 내부에서docid를 통해 유일하게document를 표시하기 때문이다. 이docid는integer 유형으로 범위는 0에서 인덱스에 포함된document 수량 사이이다.
    이러한docid는 루틴 내부의api 간에 통신하는 데 사용된다. 예를 들어term에 대해matchquery를 사용하여 검색하면docids 집합이 생기고 이러한docids는 대응하는norm값을 가져와 각각doc의 관련도 점수를 계산하는 데 사용된다.
    반면docid에서norm를 찾는 과정은 모든document의field를 통해 바이트를 보존하는 알고리즘이다. 이 과정을norm찾기라고 하는데 norm는 모든document의field가 보존하는 바이트이다.
    모든docid에 대응하는norm값은es의 내장 인덱스를 읽을 수 있습니다.doc_id의 인덱스에서 바이트를 가져옵니다.이 과정은 성능이 매우 높고 루틴이 모든 문서의norm값을 신속하게 포지셔닝하는 데 도움을 줄 수 있지만 동시에 이렇게 하면document 자체는 이 바이트의 norm값을 저장할 필요가 없다.
    실제 운행 과정에서 이것은 색인에 100개의document가 있다면, 각각field에 대해norm값을 저장하기 위해서는 100바이트가 필요하다는 것을 의미한다. 100개의document에 10개의document가 특정field를 함유하고 있더라도, 그 필드는 100개의 바이트로 norm값을 저장해야 한다.이것은 저장에 더욱 큰 비용을 발생시키고 저장 공간이 낭비되는 문제를 일으킬 뿐만 아니라 읽기와 쓰기 성능에도 영향을 줄 것이다.

    다음은 희소한 데이터를 피할 수 있는 몇 가지 방법이 있다.


    (1) 연관성이 없는 데이터를 같은 인덱스에 쓰는 것을 피한다
    우리는 구조가 완전히 다른 데이터를 같은 색인에 쓰는 것을 피해야 한다. 구조가 완전히 다른 데이터이기 때문에field는 완전히 다르기 때문에 index 데이터가 매우 드물기 때문이다.
    가장 좋은 것은 이런 데이터를 서로 다른 인덱스에 기록하는 것이다. 만약에 이런 인덱스 데이터의 양이 비교적 적으면primaryshard, 예를 들어 1개를 고려하여 자원 낭비를 피할 수 있다.
    (2)document의 구조를 규범화/표준화
    설령 우리가 정말로 서로 다른 유형의document를 같은 색인에 쓰려고 한다 하더라도, 희소성을 피할 수 있는 방법은 바로 서로 다른 유형의document를 표준화하는 것이다.
    예를 들어 만약에 모든 문서에 타임 스탬프가 있다면,timestamp라고,creation_date, 그러면 서로 다른document의 이field를 같은 필드로 바꾸고documment의 구조를 최대한 같게 할 수 있습니다.
    또 하나, 예를 들어 어떤 문서에는 goods_라는 필드가 있다type, 하지만 어떤 문서는 이 필드가 없습니다. 이 필드가 없는 문서에 goods_type은 기본값, 예를 들어default를 줍니다.
    (3) 여러 types로 서로 다른 구조의document를 저장하는 것을 피한다
    많은 사람들이 하나의 index에 다양한 유형의 데이터를 저장하는 것을 좋아할 것이다.
    그러나 사실은 그렇지 않다. 이렇게 하지 않는 것이 가장 좋다. 만약에 당신이 하나의 index에 여러 개의 type이 있다면, 이런 type의 데이터 구조는 그다지 같지 않다. 그러면 이런 type들은 실제로 밑바닥이 모두 이 인덱스에 쓰여 있는 것인지, 아니면 희소성을 초래할 것인지.
    만약 여러 type의 구조가 같지 않다면, 다른 색인에 넣는 것이 가장 좋고, 색인에 쓰지 않는 것이 가장 좋다.
    (4) 드문드문한field에 norms와doc_ 비활성화values
    만약 위의 절차를 모두 할 수 없다면, 그 드문드문한field에 대해서만 norms와doc_를 금지할 수 있습니다values 필드는 이 두 필드의 저장 메커니즘이 유사하기 때문에 각각field마다 전량의 저장이 있기 때문에 저장에 대한 낭비가 매우 크다.
    필드가 관련도 점수를 고려할 필요가 없다면norms를 사용하지 않을 수 있고, 필드를 정렬하거나 집합할 필요가 없다면doc_values 필드...

    좋은 웹페이지 즐겨찾기