Hi Ivan,
On Thursday, November 22, 2012 8:13:34 PM UTC+1, Ivan Brusic wrote:
Did not know about the ES_DIRECT_SIZE setting. It should be documented
(perhaps I will contribute once I fully comprehend all the bells and
whistles). Can direct memory cause out of memory exceptions if it is
outside of the heap or will to OS not allow it?
it's a recently introduced flag and a setting which is not really required,
it maps to -XX:MaxDirectMemorySize for the JVM. I guess the ES JVM can
settle for less memory for NIO by manipulating this parameter.
The memory outside of the heap of the JVM is also garbage collected, so, an
OOM because of lack of memory for NIO is possible. But with the default
settings, the JVM takes really good care of it.
The question was more one of what objects are stored by the heap? The
total cache sizes (field + filter) are only several gigabytes each. How
much more overhead is needed by Elasticsearch? Making up some numbers (not
in front of my app right now): if the field cache is around 8GBs and the
filter cache around 4GBs, would having a 32GB heap on a 64GB node make
sense? Will Elasticsearch effectively use the other 20GB (32-12) of heap?
Might be more effective to have a smaller heap and give the rest to the
direct memory.
I recommend tools like bigdesk for visualizing the heap allocation over
time. There is no easy answer, simply because there are a lot of possible
workloads. Just to name a few. If you are writing more data into the index
than reading, you can calculate the maximum batch size of the data in the
bulk API for the heap and tune the slowest part of the system (it's the I/O
disk subsystem). If you have a high load of simple queries and small
result sets, you could be interested in moving all the Lucene index files
into RAM so response times are fast, probably by using mmap/mlockall. If
you have an analytical workload - long running queries, each of theme
generating huge result sets, with lots of filters and facets - you should
take care of large heaps first and get the heap filled most of the time.
All these workloads can also be mixed, there is a "sweet spot" between heap
reservation and other memory, but it's hard to predict, and not
surprisingly, it may change over time while your application runs.
ES can run with large heaps, very large heaps of even >8GB, although the
current standard JVM versions will have a tough time to handle
it. Generally, ES does not clutter the heap with lots of small objects, so
GC times will stay in an acceptable range. If you configure a 32GB heap,
you can run the warmer API or some excessive facet constructions to get the
heap filled at startup time. Not surprisingly this will take some seconds
or even up to minutes. And be aware not to destroy such large caches
randomly by index writes, because they have to be build again in such
cases, which is getting the more expensive the larger the cache is.
Isn't the default NIO on 64bit Linux?
Yes, in org.elasticsearch.index.store.IndexStoreModule, there is a
heuristic: default is niofs, except for Windows 64bit and Solaris 64bit
with mmap() support, then it's mmapfs; and other Windows (32bit) is
simplefs.
I would rather use mmapfs for Linux 64bit also, but in the current 0.20, it
is not the default.
Currently the app is more CPU constrained than memory which leads me to
believe I am not utilizing memory as efficiently as possible. The field
cache hits its upper limit rather quickly despite there being no explicit
field cache limit.
Maybe it helps to play with the cache expiration policy, or the cache entry
type: Elasticsearch Platform — Find real-time answers at scale | Elastic
"resident" is the default and tends to get full utilization and OOM early,
so "soft" and "weak" are an option to help the garbage collector when
memory gets tight. They correspond to the Java SoftReference and
WeakReference classes.
Best regards,
Jörg
--