|Getting Started with Pivotal GemFire / Pivotal GemFire Tutorial|
Use the tutorial application to explore additional GemFire features.
In the tutorial, the PostID and Profile classes implemented java.io.Serializable. Java serialization works, but a few things about it are inefficient. Serialization uses reflection to find the fields to serialize. Serializing an object writes the entire classname and field names to the output stream. GemFire provides two serialization mechanisms that you can use to improve the performance and flexibility of serialization in your application. In addition, using GemFire serialization makes it easier to share data between Java, C++, and C# clients. For more information, see Data Serialization.
In the tutorial, we only used a single locator, which is a single point of failure for the application. In a production scenario you should use at least two locators. The locators property accepts a comma-separated list of locators.
Suppose you want to show all people who have someone listed as a friend. GemFire supports querying region contents using Object Query Language (OQL). See Querying and the Javadocs for the com.gemstone.gemfire.cache.query package for more information. To find all people who have listed Ethan as a friend:
select p.key from /people.entrySet p, p.value.friends f where f='Ethan'
In the tutorial, the client registered interest in updates to the people region by using a regular expression. You can also register for updates with an OQL query. For example, you can register interest in all of the posts from a particular user. For more information, see Continuous Querying.
By default, posts are assigned to different peers based on the hash code of the key. That means no organization exists that determines which posts go to which servers. If you need to do work with all of the posts from a particular user, such as running a spelling check on them, you would have to access posts on many different peers. To make this type of operation efficient, it makes sense to group those posts by user name, so that the spellcheck could be performed in a single member. GemFire lets you do this with a PartitionResolver. The partition resolver lets you return a value that indicates the logical group that a key belongs to. In this sample application, the PartitionResolver could just return the author field of the PostID. That would tell GemFire to put all posts by the same author in the same member.
Once the posts are grouped together logically, you execute your spelling check on the member that actually stores the posts. GemFire lets you ship functions to a subset of the peers based on what keys those functions intend to work with. The function is then executed in parallel on the subset of peers that host those keys. To execute the spelling check function:
SpellingCheck spellcheck = new SpellingCheck(); //implements Function Set<String> authors = new HashSet<String>(); authors.add("Ethan"); FunctionService.onRegion(people).withFilter(authors).execute(spellcheck);
For more information on function execution, see Function Execution.
If you have multiple data centers in remote locations, the synchronous replication between GemFire peers may cause too much latency if those peers are in different locations. GemFire supports gateway sender and gateway receiver configurations, which allow two or more remote sites to send updates asynchronously across a WAN. With a parallel gateway sender configuration, many updates are sent at once to improve throughput between sites. For more information on multi-site configurations, see Multi-site (WAN) Configuration.
As you have seen, a CacheListener callback is invoked after an entry is changed. A CacheWriter callback is invoked before the entry is updated. You can block the update, or send the update to another system in a cache writer. You can add a CacheLoader callback to a region to fetch or generate a value if it was not present in the cache when a get was invoked. For more information on these callbacks, see Events and Event Handling.
GemFire provides full support for the eviction and expiration features you might expect from a cache. You can limit the size of a region to a certain number of entries or a certain size in bytes. You can configure regions to expire entries after a certain amount of time, or simply evict entries when your heap is getting full.
Rather than lose the values completely, you can configure the region to overflow values onto disk.