You can monitor filter cache from three different levels - index, node and
cluster. The output is similar for all three outputs, you'll see a size in
bytes and an eviction count.
Regarding your question about bitset combination speed and caching
intermediate booleans...it depends (heh). The question is less about the
speed of combining say 50 individual bitsets compared to 1 combined bitset.
The single bitset will obviously be faster, but the speed difference is
pretty negligible compared to other operations.
What you should be thinking about is the effect of a "cache miss". Let's
operate under the assumption that filter cache size is limited, and
evictions will occur in some fashion (otherwise we'd just keep everything
in memory and be happy).
If you have a boolean combination of 50 filters that is cached, you only
need to keep that single filter "hot" in the cache. If your usage pattern
keeps it cached, you will have very little churn. But if it happens that
there is a lull and the combo-filter falls out of cache, the next time it
is executed you'll need to re-evaluate all 50 "interior" filters to derive
the final bitset. Those interior filters could potentially touch a large
number of documents (and the associated disk access). A cache miss could
be relatively expensive (still fast, but relative to simple bitset lookups)
When filters are specified independently, there is a greater chance that
individual filters may be missing from the cache. Each execution of the
set of filters may require a few of the "interior" filters to be evaluated,
but since the filters are cached separately there is a good chance the
majority of them remain cached. So the computational cost
is amortized over time instead of being lumpy. There is also a better
chance that filters stay cached since they are reused in other parts of
your query, which keeps them "live" even if the total combination rarely
re-occurs.
It also gets complicated because filter caching is technically per-segment.
It is possible for the very same filter to be cached in one segment but
evicted on another segment. The LRU cache tries to evict old (unused)
filters, but weights towards smaller segments since they are cheaper to
recalculate. This also means that data indexing has an affect on filter
caching, since a constant ingestion of new documents equals segment merges,
which clears the caches for those newly created segment.
Some other assorted thoughts:
-
Remember that boolean caching will cache the result of the bool, not
the filter's themselves. E.g. if you have a bool of 10 Terms, the final
bitset is the set of documents that matches the filters, not the 10 Term
filters themselves. Probably obvious, but wanted to make it clear
-
Eviction metrics are...meh at best. Like I mentioned above, evictions
are per-segment, and weighted towards small segments. You can see high
eviction rates without it actually equalling much churn (e.g. lots of newly
created, small segments are evicting when they merge, but 95% of your data
is remaining safely cached). You can even see a lot of churn but still get
good performance, since big segments tend to keep their caches around and
they account for most of your data.
-
I'd tune by setting a cache size, timing query latency across a wide
variety of queries and sorta watching eviction metrics. Bump the filter
cache size and repeat, see if latency gets better. Similar idea for caching
-
In general, I only reach for caching boolean combinations when I know
it will get hit very often.
This turned into a really long message! Let me know if you have any
questions
-Zach
On Monday, January 27, 2014 5:03:47 PM UTC-5, Tikitu de Jager wrote:
Hi folks,
I'm optimising our queries based on the advice in Zachary Tong's
presentation:
https://speakerdeck.com/polyfractal/elasticsearch-query-optimization
So far just switching all our query elements to filters has given a 6x
speedup on a monster query (65Kchars of compact json), which is very
encouraging
All our queries are auto-generated from our own query syntax, though, so
if we switch to filters it's gonna have to be pretty much across the board
(all terminals in the query AST, or all boolean nodes, or some similarly
blunt instrument). Which makes me worry about cache churn.
Actually I have two questions:
-
Can I monitor the filter cache size and eviction rate somehow? (REST
for preference, but jmx would be fine too.) I only seem to see
documentation for the field data cache.
-
Any advice for caching/not caching the intermediate boolean nodes in a
complex query? In our case many of these intermediate nodes will recur
in other queries, so my default feeling is to cache them, but that has to
be balanced against the extra cache usage (and risk of churn). So I guess
the question is, just how fast is the bitset bool filter (we frequently
have ANDs and ORs with 10 to 20 children) compared to caching the node?
Should I even be considering caching these, or is the bitset combination
fast enough to make it a no-brainer?
Cheers,
Tikitu
--
You received this message because you are subscribed to the Google Groups "elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elasticsearch+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elasticsearch/623481ed-bf05-47be-9d33-a0402e4bcfdb%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.