개인적인 테스트를 진행한 결과를 정리한 개인의 생각이므로, 제가 잘못알고 있는 것이면 댓글 달아주세요.

index segments _max count = 1 ?

인덱스를 고정하기 전에 먼저 force_merge를 실행하는 것이 좋습니다. 그러면 샤드별로 디스크에 하나의 세그먼트만 있게 됩니다. 또한, 압축률이 훨씬 향상되고, 고정 인덱스에 대해 집계 또는 정렬된 검색 요청을 실행할 때 필요한 데이터 구조가 간소화됩니다. 여러 세그먼트가 있는 고정 인덱스에 대한 검색을 실행하면 최대 수백 배의 성능 오버헤드가 발생할 수 있습니다.

POST /sampledata/_forcemerge?max_num_segments=1

https://www.elastic.co/kr/blog/creating-frozen-indices-with-the-elasticsearch-freeze-index-api

실습

기존 인덱스의 segments 의 수를 보자

아래를 보면 하나의 샤드당 segments 카운트는 8개로 나뉘어져있다.

이것을 하나의 세그먼트로 force merge를 해보자

$car_wash/_forcemerge?max_num_segments=1

해보기전

$curl -X GET "localhost:9200/car_wash/_segments?verbose=true&pretty" > car_wash_segments_default

Max_segments 크기 변경

$curl -X POST "localhost:9200/car_wash/_forcemerge/?max_num_segments=1&pretty"

{
  "_shards" : {
    "total" : 10,
    "successful" : 5,
    "failed" : 0
  }
}

변경 후 force merge

$curl -X GET "localhost:9200/car_wash/_segments?verbose=true&pretty" > car_wash_segments_forcemerge

car_wash_segments_default 와 car_was_segments_forcemenrge 두개의 파일을 비교 해보자

car_wash_segments_default는 한 샤드당 9개의 세그먼트로 각 세그먼트당 "memory_in_bytes" 의 값을 더해보았다.

값을 다 더해보면 61158 의 값이 나왔고,

"_shards" : {
    3     "total" : 10,
    4     "successful" : 5,
    5     "failed" : 0
    6   },
    7   "indices" : {
    8     "car_wash" : {
    9       "shards" : {
   10         "0" : [
   11           {
   12             "routing" : {
   13               "state" : "STARTED",
   14               "primary" : true,
   15               "node" : "uCyuJNg-TVu3E7g7nzRAZw"
   16             },
   17             "num_committed_segments" : 9,
   18             "num_search_segments" : 9,
   19             "segments" : {
   20               "_0" : {
   21                 "generation" : 0,
   22                 "num_docs" : 25,
   23                 "deleted_docs" : 0,
   24                 "size_in_bytes" : 23400,
   25                 "memory_in_bytes" : 6033,
   26                 "committed" : true,
   27                 "search" : true,
   28                 "version" : "7.5.0",
   29                 "compound" : true,
   30                 "ram_tree" : [
   31                   {
   32                     "description" : "postings [PerFieldPostings(segment=_0 formats=1)]",
   33                     "size_in_bytes" : 4794,
   34                     "children" : [
   35                       {
   36                         "description" : "format 'Lucene50_0' [BlockTreeTermsReader(fields=21,delegate=Lucene50Po      stingsReader(positions=true,payloads=false))]",
   37                         "size_in_bytes" : 4594,
   ....

car_was_segments_forcemenrge 의 segments의 갯수는 하나이고,

memory_in_bytes 의 값은 12268로 메모리가 줄어든 것을 확인할 수 있었다.

7   "indices" : {
   8     "car_wash" : {
   9       "shards" : {
  10         "0" : [
  11           {
  12             "routing" : {
  13               "state" : "STARTED",
  14               "primary" : true,
  15               "node" : "uCyuJNg-TVu3E7g7nzRAZw"
  16             },
  17             "num_committed_segments" : 1,
  18             "num_search_segments" : 1,
  19             "segments" : {
  20               "_9" : {
  21                 "generation" : 9,
  22                 "num_docs" : 2774,
  23                 "deleted_docs" : 0,
  24                 "size_in_bytes" : 1128655,
  25                 "memory_in_bytes" : 12268,
  26                 "committed" : true,
  27                 "search" : true,
  28                 "version" : "7.5.0",
  29                 "compound" : false,
  30                 "ram_tree" : [
  31                   {
  32                     "description" : "postings [PerFieldPostings(segment=_9 formats=1)]",
  33                     "size_in_bytes" : 11073,
  34                     "children" : [
  35                       {
  36                         "description" : "format 'Lucene50_0' [BlockTreeTermsReader(fields=21,delegate=Lucene50Pos     tingsReader(positions=true,payloads=false))]",
  37                         "size_in_bytes" : 10873,

일반적인 샤드의 segments의 크기는 61158

forcemerge 한 세그먼트의 메모리 byte 크기12268

Force merge 의 세그먼트의 메모리가 확 줄어든것을 볼수 있다.

세그먼트의 verbose로 살펴본 결과 segments.compound 의 값이 변경된것을 알수 있다. 무엇을 의미 하는것일까 ?

compound
    (Boolean) If true, Lucene merged all files from the segment into a single file to save file descriptors.

왜 그런것일까 ??

https://discuss.elastic.co/t/what-is-in-segments-memory/61651

indices.segments.terms_memory_in_bytes ??

역인덱싱 으로 되어있어서, segments로 나뉘어있어서, 하나로 합쳐지니까 메모리가 줄여지는거 아닐까??

아래의 내용들은 답을 이해 하기 위해 찾다가 참고가 된 문서인데 확실하지는 않지만, segments 에서 Terms 이 동일한것이 많아서 줄어들거나,

참고

Lucene Merge 설명

https://juanggrande.wordpress.com/2011/02/07/merge-policy-internals/

Maybe in your case some segments shares same terms or something else that duplicates in memory but belongs to different segments. After segment reduction same terms merged and so you have a little gain in memory. But it just my guess.

https://discuss.elastic.co/t/segments-memory-in-bytes-goes-down-after-reduction-of-segments-restart/41258/7

In my case, after merging segments into 1 segment using force merge 46, segments.terms_memory was decreased by 30%. (note that this percentage depends on your index characteristics)

I hope segment merging help you prevent adding more nodes (or resources, or money).

https://discuss.elastic.co/t/reducing-heap-usage-dedicated-to-indices-segments-terms-memory-in-bytes/68899

생각과 추측이 맞는지 테스트 해보기segments의 크기를 1로 테스트 해보기

조건 : 같은 데이터를 사용해서 segments가 여러개일때와 segments를 하나로 합쳤을때의 결과를 비교해봤다.

아래는 테스트 내용이다.

##인덱스 생성
PUT segments_test
##세그먼트 확인
GET segments_test/_segments



##데이터 삽입 X 3번 
POST segments_test/_doc
{
  "name":"cup",
  "text" : "the bowllike part of a goblet or the like."
}

3번의 데이터를 삽입한 결과 1번 샤드에 두개의 도큐먼트가 삽입된것을 알수 있다. 같은 도큐먼트 이지만, 메모리는 각 세그먼트 마다 가지고 있다.

{
  "_shards" : {
    "total" : 10,
    "successful" : 5,
    "failed" : 0
  },
  "indices" : {
    "segments_test" : {
      "shards" : {
        "0" : [
          {
            "routing" : {
              "state" : "STARTED",
              "primary" : true,
              "node" : "uCyuJNg-TVu3E7g7nzRAZw"
            },
            "num_committed_segments" : 0,
            "num_search_segments" : 0,
            "segments" : { }
          }
        ],
        "1" : [
          {
            "routing" : {
              "state" : "STARTED",
              "primary" : true,
              "node" : "uCyuJNg-TVu3E7g7nzRAZw"
            },
            "num_committed_segments" : 0,
            "num_search_segments" : 2,
            "segments" : {
              "_0" : {
                "generation" : 0,
                "num_docs" : 1,
                "deleted_docs" : 0,
                "size_in_bytes" : 4092,
                "memory_in_bytes" : 1698,
                "committed" : false,
                "search" : true,
                "version" : "7.5.0",
                "compound" : true,
                "attributes" : {
                  "Lucene50StoredFieldsFormat.mode" : "BEST_SPEED"
                }
              },
              "_1" : {
                "generation" : 1,
                "num_docs" : 1,
                "deleted_docs" : 0,
                "size_in_bytes" : 4092,
                "memory_in_bytes" : 1698,
                "committed" : false,
                "search" : true,
                "version" : "7.5.0",
                "compound" : true,
                "attributes" : {
                  "Lucene50StoredFieldsFormat.mode" : "BEST_SPEED"
                }
              }
            }
          }
        ],
        "2" : [
          {
            "routing" : {
              "state" : "STARTED",
              "primary" : true,
              "node" : "uCyuJNg-TVu3E7g7nzRAZw"
            },
            "num_committed_segments" : 0,
            "num_search_segments" : 1,
            "segments" : {
              "_0" : {
                "generation" : 0,
                "num_docs" : 1,
                "deleted_docs" : 0,
                "size_in_bytes" : 4092,
                "memory_in_bytes" : 1698,
                "committed" : false,
                "search" : true,
                "version" : "7.5.0",
                "compound" : true,
                "attributes" : {
                  "Lucene50StoredFieldsFormat.mode" : "BEST_SPEED"
                }
              }
            }
          }
        ],
        "3" : [
          {
            "routing" : {
              "state" : "STARTED",
              "primary" : true,
              "node" : "uCyuJNg-TVu3E7g7nzRAZw"
            },
            "num_committed_segments" : 0,
            "num_search_segments" : 0,
            "segments" : { }
          }
        ],
        "4" : [
          {
            "routing" : {
              "state" : "STARTED",
              "primary" : true,
              "node" : "uCyuJNg-TVu3E7g7nzRAZw"
            },
            "num_committed_segments" : 0,
            "num_search_segments" : 0,
            "segments" : { }
          }
        ]
      }
    }
  }
}

여기서 segments 의 크기를 병합 후에 확인 한다면?

POST segments_test/_forcemerge/?max_num_segments=1

GET segments_test/_segments

아래의 결과대로 1번의 샤드의 사용되는 메모리는 1698 바이트 의 두배가 되어야한다고 생각했지만, 메모리의 사용량은 1698 바이트 그대로 인것을 보면 segments의 term이 중복되는 경우에는 메모리의 양이 줄어든 것을 알수 있다.

{
  "_shards" : {
    "total" : 10,
    "successful" : 5,
    "failed" : 0
  },
  "indices" : {
    "segments_test" : {
      "shards" : {
        "0" : [
          {
            "routing" : {
              "state" : "STARTED",
              "primary" : true,
              "node" : "uCyuJNg-TVu3E7g7nzRAZw"
            },
            "num_committed_segments" : 0,
            "num_search_segments" : 0,
            "segments" : { }
          }
        ],
        "1" : [
          {
            "routing" : {
              "state" : "STARTED",
              "primary" : true,
              "node" : "uCyuJNg-TVu3E7g7nzRAZw"
            },
            "num_committed_segments" : 1,
            "num_search_segments" : 1,
            "segments" : {
              "_2" : {
                "generation" : 2,
                "num_docs" : 2,
                "deleted_docs" : 0,
                "size_in_bytes" : 4165,
                "memory_in_bytes" : 1698,
                "committed" : true,
                "search" : true,
                "version" : "7.5.0",
                "compound" : false,
                "attributes" : {
                  "Lucene50StoredFieldsFormat.mode" : "BEST_SPEED"
                }
              }
            }
          }
        ],
        "2" : [
          {
            "routing" : {
              "state" : "STARTED",
              "primary" : true,
              "node" : "uCyuJNg-TVu3E7g7nzRAZw"
            },
            "num_committed_segments" : 1,
            "num_search_segments" : 1,
            "segments" : {
              "_0" : {
                "generation" : 0,
                "num_docs" : 1,
                "deleted_docs" : 0,
                "size_in_bytes" : 4092,
                "memory_in_bytes" : 1698,
                "committed" : true,
                "search" : true,
                "version" : "7.5.0",
                "compound" : true,
                "attributes" : {
                  "Lucene50StoredFieldsFormat.mode" : "BEST_SPEED"
                }
              }
            }
          }
        ],
        "3" : [
          {
            "routing" : {
              "state" : "STARTED",
              "primary" : true,
              "node" : "uCyuJNg-TVu3E7g7nzRAZw"
            },
            "num_committed_segments" : 0,
            "num_search_segments" : 0,
            "segments" : { }
          }
        ],
        "4" : [
          {
            "routing" : {
              "state" : "STARTED",
              "primary" : true,
              "node" : "uCyuJNg-TVu3E7g7nzRAZw"
            },
            "num_committed_segments" : 0,
            "num_search_segments" : 0,
            "segments" : { }
          }
        ]
      }
    }
  }
}

+ Recent posts