There are a few hotspots in Elasticsearch that people just can’t seem to avoid tweaking. We understand: knobs just beg to be turned. But of all the knobs to turn, these you should really leave alone. They are often abused and will contribute to terrible stability or terrible performance. Or both.
Elasticsearch에서 바꾸지 않아야 하는 설정 몇 가지가 있다. 우리는 조정되어야 하는 설정은 알고 있다. 하지만, 변경하려는 설정 중, 몇 가지는 정말로 그대로 둬야 한다. 그것들을 오용하면, 형편 없는 안정성이나 형편없는 성능 또는 둘 모두의 원인이 될 것이다.
Garbage Collectoredit
As briefly introduced in garbage collection의 개요, the JVM uses a garbage collector to free unused memory. This tip is really an extension of the last tip, but deserves its own section for emphasis:
garbage collection의 개요에서 간단히 소개한대로, JVM은 사용하지 않는 메모리를 정리하기 위하여, garbage collector를 사용한다. 이 팁은 마지막 팁의 확장이자만, 강조하기 위해 다시 한번 이야기한다.
Do not change the default garbage collector!
기본 garbage collector를 변경하지 말자!
The default GC for Elasticsearch is Concurrent-Mark and Sweep (CMS). This GC runs concurrently with the execution of the application so that it can minimize pauses. It does, however, have two stop-the-world phases. It also has trouble collecting large heaps.
Elasticsearch의 기본 GC는 CMS(Concurrent-Mark and Sweep)이다. 이 GC는 일시 정지를 최소화하기 위하여, 응용프로그램의 실행과 동시에 실행된다. 그러나, 그것은 두 개의 stop the world 단계를 가지고 있다. 또한, 큰 heap을 수집하는 문제점을 가지고 있다.
Despite these downsides, it is currently the best GC for low-latency server software like Elasticsearch. The official recommendation is to use CMS.
이러한 단점에도 불구하고, 현재로써는 Elasticsearch처럼 낮은 대기 시간이 필요한 서버 S/W에 가장 적합한 GC이다. 공식적인 권장 사항은 CMS를 사용하는 것이다.
There is a newer GC called the Garbage First GC (G1GC). This newer GC is designed to minimize pausing even more than CMS, and operate on large heaps. It works by dividing the heap into regions and predicting which regions contain the most reclaimable space. By collecting those regions first (garbage first), it can minimize pauses and operate on very large heaps.
G1GC(Garbage First GC)라 불리는 새로운 GC가 있다. 이 새로운 GC는 CMS보다 더 일시 정지를 최소화하고, 더 큰 heap에서 동작하도록 설계되었다. heap을 여러 부분으로 나누고, 어느 부분이 정리할 수 있는 공간인지를 예측하여 동작한다. 이 부분을 먼저 수집(먼저 garbage)하여, 일시 정지를 최소화하고, 매우 큰 heap을 다룰 수 있다.
Sounds great! Unfortunately, G1GC is still new, and fresh bugs are found routinely. These bugs are usually of the segfault variety, and will cause hard crashes. The Lucene test suite is brutal on GC algorithms, and it seems that G1GC hasn’t had the kinks worked out yet.
멋지다. 불행히도, G1GC는 여전히 새로운 버그가 일상적으로 발견되고 있다. 이들 버그는 일반적으로 다양한 세그먼테이션 폴트(segfault)이고, 심각한 crash의 원인이 된다. Lucene의 테스트는 GC 알고리즘에 냉혹하다. 그래서, G1GC의 결함은 아직 해결되지 않은 것으로 보고 있다.
We would like to recommend G1GC someday, but for now, it is simply not stable enough to meet the demands of Elasticsearch and Lucene.
언젠가는 G1GC를 추천하겠지만, 지금까지는 Elasticsearch와 Lucene의 요구 사항을 충족시킬만큼 충분히 안정되지 않았다.
Threadpoolsedit
Everyone loves to tweak threadpools. For whatever reason, it seems people cannot resist increasing thread counts. Indexing a lot? More threads! Searching a lot? More threads! Node idling 95% of the time? More threads!
모든 이가 threadpool을 조정하려 한다. 어떤 이유로도, 사람들이 thread의 수를 증가시키려는 것에 반대할 수 없을 것 같다. 많은 색인? 더 많은 thread! 많은 검색? 더 많은 thread! node의 95%가 유휴 시간? 더 많은 thread!
The default threadpool settings in Elasticsearch are very sensible. For all threadpools (except search
) the threadcount is set to the number of CPU cores. If you have eight cores, you can be running only eight threads simultaneously. It makes sense to assign only eight threads to any particular threadpool.
Elasticsearch의 기본 threadpool 설정은 매우 합리적이다. 모든 threadpool(search
를 제외하고)에 대해, threadcount는 CPU의 core 수로 설정되어 있다. 8개의 core를 가지고 있다면, 동시에 8개의 thread만 동작될 수 있다. 그것은 특정 threadpool에 8개의 thread만 할당하라는 의미이다.
Search gets a larger threadpool, and is configured to int((# of cores * 3) / 2) + 1
.
검색은 더 큰 threadpool를 가지는데, int((# of cores * 3) / 2) + 1
로 설정되어 있다.
You might argue that some threads can block (such as on a disk I/O operation), which is why you need more threads. This is not a problem in Elasticsearch: much of the disk I/O is handled by threads managed by Lucene, not Elasticsearch.
일부 thread(디스크 I/O 연산 같은)가 block될 수 있어서, 더 많은 thread가 필요하다고 주장할 수도 있다. 이것은 Elasticsearch의 문제가 아니다. 대부분의 디스크 I/O는 Elasticsearch가 아닌 Lucene에 의해 관리되는 thread로 처리된다.
Furthermore, threadpools cooperate by passing work between each other. You don’t need to worry about a networking thread blocking because it is waiting on a disk write. The networking thread will have long since handed off that work unit to another threadpool and gotten back to networking.
또한, threadpool은 서로 작업을 전달하며 협력한다. 네트워킹 thread blocking은 디스크 쓰기 작업을 기다리고 있기 때문에, 그것에 대해 걱정할 필요가 없다. 네트워킹 thread는 다른 threadpool로 작업 단위를 건네거나 네트워킹으로 돌려 주기 때문에 오래 걸릴 것이다.
Finally, the compute capacity of your process is finite. Having more threads just forces the processor to switch thread contexts. A processor can run only one thread at a time, so when it needs to switch to a different thread, it stores the current state (registers, and so forth) and loads another thread. If you are lucky, the switch will happen on the same core. If you are unlucky, the switch may migrate to a different core and require transport on an inter-core communication bus.
마지막으로, 프로세스의 연산 능력은 유한하다. 더 많은 thread는 processor에게 thread contexts 교체를 강제할 뿐이다. 하나의 processor는 한 번에 하나의 thread만 실행할 수 있다. 따라서, 다른 thread로 전환해야 할 경우, 현재 상태를 저장(register 등)하고, 다른 thread를 로드한다. 운이 좋다면, 그 전환은 동일한 core에서 발생할 것이다. 운이 좋지 않으면, 그 전환은 다른 core로 이동하고, core간 통신 bus로 전송해야 한다.
This context switching eats up cycles simply by doing administrative housekeeping; estimates can peg it as high as 30μs on modern CPUs. So unless the thread will be blocked for longer than 30μs, it is highly likely that that time would have been better spent just processing and finishing early.
이러한 contexts 전환은 단순한 관리적인 housekeeping에 CPU cycle을 소모(요즘 CPU에서 30μs 정도 되는 것으로 추정)하는 것이다. 따라서, thread가 30μs 보다 더 오래 block 되지 않는다면, 그 시간에 작업을 처리하고 더 빨리 끝내는 것에 소비하는 것이 더 나을 것이다.
People routinely set threadpools to silly values. On eight core machines, we have run across configs with 60, 100, or even 1000 threads. These settings will simply thrash the CPU more than getting real work done.
사람들은 일상적으로 바보 같은 값으로 threadpool을 설정한다. 8 core machine에서, 60, 100 심지어 1,000개의 thread로 설정한 것을 본적이 있다. 이런 설정은 실제 작업을 끝내기 보다는 CPU를 허우적거리게 할 것이다.
So. Next time you want to tweak a threadpool, please don’t. And if you absolutely cannot resist, please keep your core count in mind and perhaps set the count to double. More than that is just a waste.
그러니, 다음에 threadpool을 조정한다면, 제발 그러니 말자. 그래도 해야 한다 면, core 수를 기억하고, 두 배 정도로 설정하자. 그 이상은 낭비일 뿐이다.
'2.X > 7. Administration Monitoring Deployment' 카테고리의 다른 글
7-2-4. Configuration Management (0) | 2017.09.23 |
---|---|
7-2-5. Important Configuration Changes (0) | 2017.09.23 |
7-2-7. Heap: Sizing and Swapping (0) | 2017.09.23 |
7-2-8. File Descriptors and MMap (0) | 2017.09.23 |
7-2-9. Revisit This List Before Production (0) | 2017.09.23 |