In Elasticsearch 6.0, we released a new feature called index sorting. Read up more on this on the linked blog, but in short, what this does is to take the documents at index time and sort them by a key or set of keys in an order of your choosing. This has a few advantages that we’ve talked about:
Elasticsearch 6.0 에서 index sorting이라는 새로운 기능이 출시되었다. link된 게시물에서 이에 대해 자세히 읽어 보자. 간단히 말하자면, index시에 document를 가져와 선택한 key나 key의 집합으로 정렬하는 것이다. 여기에는 다음과 같은 몇 가지 장점이 있다.
- If you ask Elasticsearch to return a set of results sorted by the same key you’ve sorted the index on, Elasticsearch doesn’t need to do the sorting of results at query time. They’re already pre-sorted!
Elasticsearch에서 index를 정렬한 것과 동일한 key로 정렬된 결과를 반환하도록 요청하면, Elasticsearch는 query시에 결과를 정렬하지 않아도 된다. 이미 미리 정렬되어 있다. - If you don’t need the total hit count and you’re sorting by the sort key, Elasticsearch can actually short circuit the query once it’s found enough hits to meet your request. This can result in unbounded query performance improvements.
전체 수가 필요하지 않고 정렬 key로 정렬하려면, Elasticsearch는 request에 부합하는 hit를 발견하면, 실제로 query를 중단시킬 수 있다. 이로 인해 무한한 query 성능 향상을 기대할 수 있다. - If you have queries that use ANDs across different fields, index sorting on those fields can end up grouping them in such a way that Elasticsearch can skip large blocks of documents that don’t match, which can also make search faster.
서로 다른 query간에 AND를 사용하는 query가 있을 경우, 해당 field에 대한 index sorting은 Elasticsearch가 일치하지 않는 document의 큰 block을 건너뛸 수 있도록 하는 방식으로 그룹화 하여, search 속도를 더 높일 수 있다.
In short, index sorting can make search faster in some cases: especially cases where you have a few common ways people are searching and sorting your documents. What isn’t often talked about is that index sorting can also reduce the amount of disk your indices are using. I’ll talk about why and how here.
즉, index sorting을 사용하면, 특정 경우에 search 속도를 더 빠르게 할 수 잇다. 사람들이 document를 search하고 정렬하는 몇 가지 공통적인 방법이 있는 경우 특히 그렇다. 자주 언급되지 않는 사항은, index sorting을 사용하면, index가 사용하고 있는 disk의 양을 줄일 수도 있다는 점이다. 그 이유와 방법에 대해 이야기 하겠다.
Caution: Index Sorting Isn’t for Everyone
Before I talk about what happens, I do want to mention once again that index sorting isn’t for everyone. It causes the sort action to happen at index time. Sorting is an expensive operation, so if indexing speed is a primary concern, exercise caution before turning it on. It can slow write performance by as much as 40-50%. So if indexing throughput is a primary concern, as it often is in high-volume logging, metrics, and security analytics use cases, index sorting probably isn’t for you. It can be useful if you have a lower index rate, if query speed is the most important thing to your use case, or if you have a regular reindex process anyway that acts during off-peak-indexing times.
이야기하기 전에, index sorting이 모두에게 적절하지는 않다라는 사실을 다시 한번 이야기한다. 정렬 동작이 index시에 발생하기 때문이다. 정렬은 비용이 많이 발생하는 연산이므로, index 속도가 중요하다면, 바꾸기 전에 주의하자. 쓰기 성능이 40-50% 정도 낮아질 수 있다. 따라서, 대용량 logging, 분석, 보안 분석 사례처럼, index 처리량이 중요하다면, index sorting은 아마도 여러분에게 적당하지 않다. index 속도가 낮거나 query 속도가 가장 중요하거나, 사용량이 적은 시간에 작동하는 정기적인 reindex process의 경우, 이것이 유용할 수 있다.
Examining Potential Sort Orders: An Example
Suppose I run an Elasticsearch instance that’s used for product search. Imagine that I have a set of documents that, at index time, look something like the following (I’ll flatten into a matrix just for ease of viewing):
제품 search를 위해 사용되는 Elasticsearch instance를 실행한다고 가정해 보자. index시에 다음처럼 보이는 document 집합을 가지고 있다고 가정해 보자. 보기 쉽게 표로 만들었다.
Product ID | Product Category | Product Color | Price |
206f467b-8cfe | Shoes | Red | $97.00 |
4f89fbec-acc3 | Jackets | Black | $120.50 |
47771396-dfe3 | Jackets | Grey | $170.10 |
c6c8fbdf-651b | Hats | Yellow | $15.00 |
dc18c426-0eb3 | Shoes | Red | $107.20 |
ee304259-df57 | Jackets | Black | $88.00 |
9332c0ac-e55e | Shoes | Black | $49.00 |
30e96765-52a1 | Hats | Blue | $11.00 |
811cc8ca-d6bb | Jackets | Blue | $92.99 |
And now suppose we wanted to enable index sorting. What would we sort by? We have some options: product category, product color, and/or price may be interesting. If user searches are almost always just sorted by price and we don’t have filters for category or color, sorting by price may make the most sense for a sort key. However, it’s probably likely that users are at least selecting a category before finding the cheapest item, and they also may have preference for a color. Let’s sort by category ascending, color ascending, and then price ascending.
그리고, 이제 index sorting을 활성화한다고 가정해 보자. 무엇으로 정렬할까? product category, product color, 그리고 price가 괜찮을 것 같다. 사용자 search가 거의 항상 price로 정렬되고, category나 color로 filter하지 않는다고 하면, price에 의한 정렬이 정렬 key에 가장 적절할 것이다. 그러나, 사용자는 가장 저렴한 제품을 검색하기 전에 최소한 하나의 category를 선택하거나 선호하는 color를 가질 수 있다. category 오름차순, color 오름차순, price 오름차순으로 정렬하자.
"sort.field" : ["product_category", "product_color", "price"], "sort.order" : ["asc", "asc", "asc"]
The sorted index looks something like this:
정렬된 index는 다음과 같다.
Product ID | Product Category | Product Color | Price |
30e96765-52a1 | Hats | Blue | $11.00 |
c6c8fbdf-651b | Hats | Yellow | $15.00 |
ee304259-df57 | Jackets | Black | $88.00 |
4f89fbec-acc3 | Jackets | Black | $120.50 |
811cc8ca-d6bb | Jackets | Blue | $92.99 |
47771396-dfe3 | Jackets | Grey | $170.10 |
9332c0ac-e55e | Shoes | Black | $49.00 |
206f467b-8cfe | Shoes | Red | $97.00 |
dc18c426-0eb3 | Shoes | Red | $107.20 |
A few interesting things now happen, which I’ll explain by example:
이제 몇 가지 흥미로운 점이 나타난다. 예제로 설명하겠다.
- If I ask Elasticsearch for the top 2 cheapest shoes sorted by price and I don’t ask it for a total hit count of all shoes, it needs to find the block of shoes, which it can do efficiently by skipping past all of the other categories. And once it’s found just 2 results, it can stop processing the rest of the index and return. Note that in order for this to work, you must include every element of the sort order in the index, even if you have filters that match.
price로 정렬한 상위 2개의 가장 싼 shoes를 Elasticsearch에 요청하고, 일치하는 모든 shoes의 수를 요청하지 않는다면, 다른 모든 category를 생략하여 효율적으로 할 수 있도록, shoes의 block을 찾아야 한다. 그리고, 2개의 결과를 찾자마자 index의 나머지 부분을 처리하는 것을 중단하고 return할 수 있다. 이를 위해서는 일치하는 filter가 있더라도, index에 정렬 순서의 모든 요소를 포함해야 한다. - If I ask Elasticsearch for
product_category:Jackets AND product_color:Black
, Elasticsearch can skip past all the hats and all the shoes, and within Jackets, it can find the “Black” ones and once it’s done looking at those, it can skip past all of the other colors efficiently.product_category:Jackets AND product_color:Black
를 Elasticsearch에 요청한다면, Elasticsearch는 모든 hats과 shoes를 생략할 수 있고, Jackets내에서, “Black”을 찾을 수 있고, 일단 해당하는 것을 다 찾으면, 다른 모든 colors를 효율적으로 생략할 수 있다. - Elasticsearch uses compression significantly behind the scenes. The compression works when there are repeated values and it does so most efficiently when the repeated values are near each other in the index. By having all of the “jackets” or “colors” next to one another, those can be efficiently compressed on disk. That means less disk space, but it also means the operating system will be able to fit more into the filesystem cache, which will make things even faster.
Elasticsearch는 압축을 많이 사용한다. 압축은 반복되는 값이 있을 경우 동작하며, index에서 반복되는 값이 서로 가까이 있을 경우 가장 효울적으로 동작한다. 모든 “jackets” 이나 “colors” 를 서로 옆에 두면, disk에서 효율적으로 압축될 수 있다. 즉, disk 공간이 적게 소모되는 것을 의미하지만, 또한, OS가 filesystem cache에 더 잘 적응할 수 있다는 것을 의미하며, 이는 더 빠른 속도를 가져온다.
In general, it’s best practice to use sort orders of increasing cardinality so that we can get the benefit of as many repeated values in a row as possible.
일반적으로, row에서 가능한 한 많은 반복된 값의 이점을 얻을 수 있도록, cardinality가 증가하는 정렬 순서를 사용하는 것이 가장 좋다.
How Much Disk Space Will I Save?
So how much disk space will you save by turning on index sorting? As with many things in life, the answer is “it depends.” One of the big things it depends on is the cardinality of the field you sort by. However, the disk savings can be substantial. Last weekend, I decided to move some IoT/home automation data I’ve been using for a personal project off an old machine and onto a new one. There are faster ways to do this data migration like snapshot/restore, but I had the time to do a reindex and was interested to see how much savings index sorting may provide. I first did the remote reindex into an unsorted index:
그렇다면, idnex sorting을 사용하면 disk 공간을 얼마나 절약할 수 있을까? 만사가 그렇지만, 답은 "경우에 따라 다르다" 이다. 가장 큰 요소는 정렬하려는 field의 cardinality이다. 그러나 disk 절약 효과는 상당할 수 있다. 지난 주말, 개인 프로젝트에서 사용하던 IoT/home automation data를 새로운 machine으로 옮기기로 했다. snapshot/restore 처럼 data migration을 하는 더 빠른 방법이 있지만, reindex할 시간이 있었고 index sorting을 통해 얼마나 많은 절감 효과가 있는지 알고 싶었다. 먼저, 정렬되지 않은 index에 원격으로 reindex했다.
status index pri docs.count docs.deleted pri.store.size open devices-2017 1 33310674 0 4.2gb
It’s a little over 30 devices and each sends its status back about once every 30 seconds, so the total index rate is about 1 document per second. I’m never anywhere close to being throttled on the indexing side, and I’d have to massively increase the index rate or number of devices for that to change. It seems like a reasonable candidate for index sorting. The data consists of hardware IDs, hardware names, times, and various sensor readings like the temperature or whether the device is on or off at the time or what some other sensor level is. I sorted the index by device ID and then by time, my thinking being that it’s likely that for a given device, there’s a reasonably high chance that there will be similar or the same values around the same time, which may lead to better compression. For example, if a switch is turned into an “on” state at 7:00:00, there’s a pretty high chance that it will be “on” at 7:00:30, 7:01:00, and at least several minutes after, and that should compress nicely. The sorted index stats show…
30개가 약간 넘는 장치가 있고, 각각은 매 30초마다 상태를 전송한다. 따라서, 총 index 속도는 초당 약 1개의 document이다. 이를 변경하기 위해서는, index쪽에서는 조절할 수 있는 곳이 거의 없었고, index 속도나 장치의 수를 크게 늘려야 한다. index sorting의 적절한 후보인 것 같다. data는 HW ID, name, 시간, 온도나 해당 시점에 장치의 on/off 또는 기타 sensor 수준으로 구성된다. 특정 장치에서, 동일한 시간대에는 비슷하거나 동일한 값이 있을 가능성이 상당히 높기 때문에, 압축이 더 잘될 수 있다고 생각해, index를 장치 ID, 그 다음에 시간으로 정렬했다. 예를 들자면, 7:00:00에 switch가 "on" 상태가 되면, 7:00:30, 7:01:00, 그리고 적어도 몇 분 후까지는 "on" 일 가능성이 상당히 높다. 그리고, 그것은 잘 압축될 것이다. 정렬된 index 상태는 다음과 같다.
status index pri docs.count docs.deleted pri.store.size open devices-2017 1 3310674 0 2.5gb
About a 40% disk savings!
약 40%의 disk 절약이다.
Caution Again
At this point, I feel compelled to caution everyone again, because almost everyone would appreciate using 40% less disk for the same data. I’ll sum it up into two quick statements:
이 시점에서 다시 한번 모두에게 경고해야 한다고 생각한다. 왜냐하면, 거의 모든 이들이 동일한 data에 40% disk 절약을 높이 평가할 것이기 때문이다. 2가지로 요약하겠다.
- Your mileage will vary. I used index sorting on another dataset and found a 20% savings. Be thoughtful about what fields you sort on.
이득은 다양할 것이다. 다른 data 집합에 index sorting을 사용했더니, 20%를 절약했다. 정렬하려는 field에 대해 신중하게 생각하자. - Your index rate will be slowed. If the speed of indexing is really important to you, e.g. you’re running in a high volume logging or metrics use case, you’re likely sensitive to the number of documents you can get indexed in a short amount of time and it may not be a good choice to turn on index sorting as a result.
index 속도가 느리게 될 것이다. index 속도가 중요(예: 대용량 logging, metric 사용 사례)하다면, 짧은 시간에 index할 수 있는 document의 수에 민감할 수 있어, 결과적으로 index sorting을 사용하는 것은 좋은 선택이 아닐 수 있다.
If you’re much more sensitive to disk space than index speed or your index volumes are low enough that you’re not limited by index speed, it may be interesting to see if index sorting is worth it for you.
index 속도보다 disk 공간에 훨씬 더 민감하거나, index 양이 index 속도에 의해 제한되지 않을 만큼 충분히 적다면, index sorting이 쓸만한지 알아보는 것이 좋다.
원문 : Space Savings: A Lesser Known Benefit of Index Sorting in Elasticsearch