Showing posts with label indexes. Show all posts
Showing posts with label indexes. Show all posts

Friday, November 4, 2011

Coherence SIG: Advanced usage of indexes

Another my presentation Coherence SIG, this time from London.
Main theme of presentation was internal mechanics of indexes in Coherence. How indexes are stored, how queries are executed, how create custom filters and indexes - all these topics were covered.

Monday, October 31, 2011

Data Grid Pattern - Time series index for managing versioned data

Many critical application are using append only approach for dealing with transactional data. In other words, they never update data records, but instead insert new records with greater timestamp (or sequence number, or any other kind of version, they are using to find latest record). Common challenge for such data model, is how to retrieve an appropriate version of record (e.g. latest version, or version at certain moment in time). A simple query for latest version for key 'A' would translate into query as complex as
select * from versions where series='A' and version = (select max(version) from versions where key='A')
This query is already too complex for data grid (and even RDBMS would not be too happy).
Accidently Ben Stopford has recently published a great article about this problem, outlining a lot of important aspects. I do not want to repeat him here, I suggest you read his article now, then continue with mine, which complements his two approaches this third one using custom index in Coherence.

Using custom index for accessing versioned data

In this  approach, each version is stored as a separate entry in cache.
Entry key is composite key, including logical key (series key) and some additional field to make version key unique (e.g. transaction ID, sequence number etc). Value contains actual business data (payload) and timestamp, we are using in our queries (technically timestamp could be part of composite key).
Series key should be an affinity key also - all versions related to same series should be physically on one Coherence node (or affinity key can be a part of series key, this will also satisfy this requirement).
Normally, if you want to find certain version by series key and timestamp you have to do aggregation of all versions for this series. In two approaches mentioned by Ben Stopford, latest version is separated from all other versions (using separate cache - approach 1, using marker - approach 2). It solves problem of finding latest version, but doesn't help if we need to find version for certain moment at time.

Time series index structure

Normal Coherence indexes cannot help us much, due to complexity of query, but it is possible to create custom index, tailored specifically for this task.
Time series index is similar to traditional inverted index, but instead of storing set of entry references, it is storing a nested index, indexing  only versions belonging to certain series by timestamp. Using this index structure you could find latest version or version for certain moment in time, without any aggregation, just by index lookup.
This index goes beyond standard index Coherence API, so it requires a complementary implementation of custom filter.

PROs and CONs

Below and PROs and CONs of this approach, compared to approaches from Ben's article.

PRO

  • Inserting new version doesn't require modifications of any other versions. In particular, you do not need to use hack, directly accessing to backing map, and you do not create extra replication traffic.
  • Time series index works efficiently for any point in time, not only latest versions.
  • It can be used with any kind of caches (even with continuous queries).

CON

  • Through custom index usage is straightforward, troubleshooting could be very tricky unless you understand index mechanics very well.

Source code

Time series index implementation is available at GridKit project.

Tuesday, August 30, 2011

Lucene in the grid, query performance


Apache Lucene is very powerful open source full text search engine. Though its primary focus is full text search and relevance, search machinery implemented in Lucene could be used far beyond classical full text search. Oracle Coherence 3.6 has introduced an API for custom indexes. These API allows transparently use custom indexing engines inside of data grid (via normal Coherence query API) and let grid itself handle partitioning and keep index up to date.
In this article I would like to compare Lucene with built in Coherence indexes, and explain when you may want to use Lucene even if same functionality is available using built in Coherence indexes.
You can find more information about Cohernce / Lucene integration at project home page.
Both Lucene and Coherence are using inverted index to efficiently execute queries. Unlike relational databases which are tending to use single index for single select clause (you can read more here), both Lucene and Coherence will try to use all possible indexes matching query criteria. Using multiple indexes means extensive use of binary operations over sets of candidate keys. Coherence is manipulating these sets using hash tables, while Lucene is using bitmaps. This is a main factor explaining performance difference between Lucene and Coherence native indexes on certain types of queries.

Test data set

For testing I'm using a set of 100k objects, having number of randomly generated attributes. Attributes have following cardinality: A - 1, B - 10, C - 50, D - 1000, E - 10000, H - 50000. While 100k is not many, it is a reasonable number, cause data are partitioned in Coherence grid so is index itself. Each storage node is indexing just its own content, and 100k of objects per node is reasonable data set size.

Single criterion query

Lucene and Coherence are in same situation here. Single criterion is producing just one set of candidate keys, no need for any set manipulation. Coherence can just take key set from index and return it as is, while Lucene have to reconstruct keys from documents (which involves base64 decoding and takes time). So here Lucene have no advantages in speed, but it doesn't lag behind too much either. Diagram also shows separate bar for sorted index in Coherence, but its performance is roughly same as hash index.

Range query

Coherence's BetweenFilter implementation is using index extremely inefficient. I have implemented my own RangeFilter using standard Coherence indexes. For my data set RangeFilter beats  BetweenFilter by factor of 1000 (on attribute A). Further in this article I always mean RangeFilter when speaking about range queries.
Range query execution conceptually similar in Coherence and Lucene. Both should scan range of term set, find matching terms and union key sets for these terms. So performance is again roughly on par, Lucene is suffering some penalty for reconstructing each matching key from base64.

Multiple criteria query

So far, there were no much reason for performance difference between Coherence native indexes and Lucene. But for indexes using multiple criteria we may expect to see some considerable difference. I have measure few complex queries including several attributes and sometimes range or multi term match (InFilter for Coherence) .

Queries with two criteria

Top 5 queries have 2 criteria, one of which are E attribute having low selectivity. Coherence filter execution time depends on order of criteria (if most selective criteria is put first execution time would be shorter). Lucene is resilient  to order of criteria.

Three criteria query

This query (E1 = x & E2 = y & E3 = z) have only low selectivity criteria, so Lucene beats Coherence of this query almost 5 times.

Four criteria query

Same trend as with 2 criteria query, if most selective criteria is first Coherence and Lucene are on par, otherwise Lucene few times faster.

Query with range criterion

This query is emulating a case when we need to limit result set by range of attribute values (e.g. timestamp range). Query is using 10k long range of attribute A values, so it is hard work for both indexing engines to union 10k sets. Lucene is doing this job 3 times better.

Query with multi term match criterion

This query includes multi term match criterion (InFilter for Coherence). Lucene is consistently faster with factor about 5 times. This query does not have single good selective criterion, so Coherence is lagging behind.

Query with high cardinality attribute

Attribute H has only 2 possible values, so it makes filter processing a lot harder. Coherence performance ranging from poor to very bad depending on order of criteria. Lucene is fast as usual.

Conclusions

Coherence is sensitive for order of criteria in query. It is showing better results if most selective criteria is first in filter. Lucene is resilient to order of criteria in query. Coherence index performance is suffering considerably as we adding new criteria, especially if attribute has high cardinality (e.g. boolean attribute). Lucene should reconstruct entry key for each entry of final result set, so it is slowing down as result set of query is growing. Lucene is handling range queries better than Coherence.
These tests are showing that for many non trivial queries Lucene is showing better performance than Coherence built in indexes. For certain types of queries Coherence may require hand optimization, while Lucene is not. All above are making Lucene very attractive for ad hoc querying of data datasets and ability to execute full text search and wildcard queries compliments nicely for this purpose.
And BTW Lucene index is consuming few times less memory than built in Coherence index (it is more expensive for updates though). But it takes another article to elaborate these aspects.

Wednesday, April 27, 2011

Indexes: RDBMS vs Coherence vs Lucene

Techincal article comparing popular indexing algorithms between RDBMS, data grid (Oracle Coherence) and full text search engine (Lucene).

Most people are familiar with concept of “index” in SQL database. But indexes are widely used far beyond relational databases. There are even dedicated products, like search engines, which are specializing in indexing of data stored elsewhere. This article will give a high level comparison of capabilities and performance aspects of typical indexes in three different types of technologies: SQL database, in-memory-data-grid (Oracle Coherence) and full text search engine (Apache Lucene).

Full text of article is available at GridDynamics blog - http://blog.griddynamics.com/2011/04/indexes-rdbms-vs-coherence-vs-lucene.html

Monday, October 11, 2010

Coherence, magic trick with cache index

A technical article related to Oracle Coherence.

Oracle Coherence has ability to query data in cache not only by key, but by values (or their attributes). Of course queering by secondary attributes is not as efficient as by primary key, but still can be very useful. Oracle Coherence also supports indexes which improve performance of value based queries significantly.
But some times index may not behave exactly as you expect.

Full text of article is available at GridDynamics blog - http://blog.griddynamics.com/2010/10/coherence-magic-trick-with-cache-index.html

Monday, October 26, 2009

Oracle Coherence memory usage, indexes

In previous posts we discussed a memory consumption in Oracle Coherence. We loaded 1M of DomainObj into cached and looked into memory dumps aquired with jmap utility. Now, we will talk about memory overheads caused by another powerful feature of Coherence - indexes.

Full text of article is available at GridDynamics blog - http://blog.griddynamics.com/2009/10/coherence-memory-usage-indexes.html