<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0MNQHw4eyp7ImA9WhBbGU4.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412</id><updated>2013-05-18T20:51:31.233-07:00</updated><category term="SQL" /><category term="cloud" /><category term="cache" /><category term="compute grid" /><category term="data grid" /><category term="grid" /><title>GridGain - In-Memory Big Data</title><subtitle type="html">GridGain by Dmitriy Setrakyan</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://gridgain.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>118</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/gridify" /><feedburner:info uri="gridify" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>gridify</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry gd:etag="W/&quot;D0YERHgyfyp7ImA9WhNXGUw.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-129764770189151436</id><published>2012-12-07T12:26:00.002-08:00</published><updated>2012-12-07T13:18:25.697-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-07T13:18:25.697-08:00</app:edited><title>Java Serialization - Good, Fast, and Faster</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-mPfJToWysdk/UMJNP5_ut3I/AAAAAAAAAGE/Cm2nCOAxdcM/s1600/serialization.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="190" src="http://1.bp.blogspot.com/-mPfJToWysdk/UMJNP5_ut3I/AAAAAAAAAGE/Cm2nCOAxdcM/s200/serialization.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
Probably anyone who has ever worked with serialization of objects, be that in Java or any other language, knows that it should be avoided whenever possible. Just like the first rule of distribution is "&lt;i&gt;Do not distribute!&lt;/i&gt;", the first rule of serialization should be "&lt;i&gt;Do not serialize!&lt;/i&gt;". However, in many cases, especially in distributed environments, serialization cannot be avoided and therefore must be significantly optimized to achieve any kind of reasonable throughput.&lt;br /&gt;
&lt;br /&gt;
At &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt;, given the distributed nature of our product, we have always been working on optimizing of our serialization routines, but starting with version 4.3.0 we have achieved the fastest results so far. Our &lt;a href="http://www.gridgain.com/javadoc40DG/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshaller.html"&gt;GridOptimizedMarshaller&lt;/a&gt; in our tests achieved up to 20x performance optimization on standard Java serialization with &lt;i&gt;java.io.Serializable&lt;/i&gt;. If you switch to &lt;i&gt;java.io.Externalizable&lt;/i&gt;, then GridGain marshaller is up to 10x faster. We have even compared our marshaller to &lt;a href="http://code.google.com/p/kryo/"&gt;Kryo&lt;/a&gt; serialization, and turns out that our marshaller is up to 5x faster than Kryo. On top of that, the footprint of GridGain serialized objects is significantly smaller than Java.&lt;br /&gt;
&lt;br /&gt;
The coolest thing here is that &lt;b&gt;we do not require any custom interfaces or API s - GridGain optimized serialization works directly with standard Java POJOs&lt;/b&gt;, regardless if they implement &lt;i&gt;java.io.Serializable&lt;/i&gt; interface or not. If your POJOs implement &lt;i&gt;java.io.Externalizable&lt;/i&gt;, then our&amp;nbsp;marshaling&amp;nbsp;works even faster.&lt;br /&gt;
&lt;br /&gt;
How do we do it? The main culprit of Java serialization is &lt;i&gt;java.io.ObjectOutputStream&lt;/i&gt; which is extremely expensive to initialize and performs poorly. The first thing we did is replaced it with our own implementation, based on direct memory copying by invoking native C and Java so-called "unsafe" routines. &amp;nbsp;We also serialize fields in predefined order by doing lots of object&amp;nbsp;introspection which allows us to pass only values and not their type names or other metadata.&lt;br /&gt;
&lt;br /&gt;
Here are the results from the test on my MacBookPro 2.7 GHz Intel i7:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;i&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&amp;gt;&amp;gt;&amp;gt; Java serialization via Externalizable (average): 22,551 ms&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&amp;gt;&amp;gt;&amp;gt; Kryo serialization (average): 17,300 ms&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&lt;span style="color: blue; font-family: Verdana, sans-serif;"&gt;&amp;gt;&amp;gt;&amp;gt; GridGain serialization (average): 2,937 ms&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;
&lt;/blockquote&gt;
Here is the test itself. This test is included with our product, so feel free to &lt;a href="http://www.gridgain.com/"&gt;download&lt;/a&gt; it and try for yourself.&amp;nbsp;&lt;/div&gt;
&lt;pre class="brush: java"&gt;public class SerializationBenchmark {
    /** Number of runs. */
    private static final int RUN_CNT = 3;

    /** Number of iterations. */
    private static final int ITER_CNT = 200000;

    public static void main(String[] args) throws Exception {
        // Create sample object.
        SampleObject obj = createObject();

        // Run Java serialization test.
        javaSerialization(obj);

        // Run Kryo serialization test.
        kryoSerialization(obj);

        // Run GridGain serialization test.
        gridGainSerialization(obj);
    }

    private static long javaSerialization(SampleObject obj) throws Exception {
        long avgDur = 0;

        for (int i = 0; i &amp;lt; RUN_CNT; i++) {
            SampleObject newObj = null;

            long start = System.currentTimeMillis();

            for (int j = 0; j &amp;lt; ITER_CNT; j++) {
                ByteArrayOutputStream out = new ByteArrayOutputStream();

                ObjectOutputStream objOut = null;

                try {
                    objOut = new ObjectOutputStream(out);

                    objOut.writeObject(obj);
                }
                finally {
                    U.close(objOut, null);
                }

                ObjectInputStream objIn = null;

                try {
                    objIn = new ObjectInputStream(
                        new ByteArrayInputStream(out.toByteArray()));

                    newObj = (SampleObject)objIn.readObject();
                }
                finally {
                    U.close(objIn, null);
                }
            }

            long dur = System.currentTimeMillis() - start;

            avgDur += dur;
        }

        avgDur /= RUN_CNT;

        System.out.format("\n&amp;gt;&amp;gt;&amp;gt; Java serialization via Externalizable (average): %,d ms\n\n", avgDur);

        return avgDur;
    }

    private static long kryoSerialization(SampleObject obj) throws Exception {
        Kryo marsh = new Kryo();

        long avgDur = 0;

        for (int i = 0; i &amp;lt; RUN_CNT; i++) {
            SampleObject newObj = null;

            long start = System.currentTimeMillis();

            for (int j = 0; j &amp;lt; ITER_CNT; j++) {
                ByteArrayOutputStream out = new ByteArrayOutputStream();

                Output kryoOut = null;

                try {
                    kryoOut = new Output(out);

                    marsh.writeObject(kryoOut, obj);
                }
                finally {
                    U.close(kryoOut, null);
                }

                Input kryoIn = null;

                try {
                    kryoIn = new Input(new ByteArrayInputStream(out.toByteArray()));

                    newObj = marsh.readObject(kryoIn, SampleObject.class);
                }
                finally {
                    U.close(kryoIn, null);
                }
            }

            long dur = System.currentTimeMillis() - start;

            avgDur += dur;
        }

        avgDur /= RUN_CNT;

        System.out.format("\n&amp;gt;&amp;gt;&amp;gt; Kryo serialization (average): %,d ms\n\n", avgDur);

        return avgDur;
    }

    private static long gridGainSerialization(SampleObject obj) throws Exception {
        GridMarshaller marsh = new GridOptimizedMarshaller(false, 
            Arrays.asList(SampleObject.class.getName()), null);

        long avgDur = 0;

        for (int i = 0; i &amp;lt; RUN_CNT; i++) {
            SampleObject newObj = null;

            long start = System.currentTimeMillis();

            for (int j = 0; j &amp;lt; ITER_CNT; j++)
                newObj = marsh.unmarshal(marsh.marshal(obj), null);

            long dur = System.currentTimeMillis() - start;

            avgDur += dur;
        }

        avgDur /= RUN_CNT;

        System.out.format("\n&amp;gt;&amp;gt;&amp;gt; GridGain serialization (average): %,d ms\n\n", avgDur);

        return avgDur;
    }

    private static SampleObject createObject() {
        long[] longArr = new long[3000];

        for (int i = 0; i &amp;lt; longArr.length; i++)
            longArr[i] = i;

        double[] dblArr = new double[3000];

        for (int i = 0; i &amp;lt; dblArr.length; i++)
            dblArr[i] = 0.1 * i;

        return new SampleObject(123, 123.456f, (short)321, longArr, dblArr);
    }

    private static class SampleObject 
        implements Externalizable, KryoSerializable {
        private int intVal;
        private float floatVal;
        private Short shortVal;
        private long[] longArr;
        private double[] dblArr;
        private SampleObject selfRef;

        public SampleObject() {}

        SampleObject(int intVal, float floatVal, Short shortVal, 
            long[] longArr, double[] dblArr) {
            this.intVal = intVal;
            this.floatVal = floatVal;
            this.shortVal = shortVal;
            this.longArr = longArr;
            this.dblArr = dblArr;

            selfRef = this;
        }

        // Required by Java Externalizable.
        @Override public void writeExternal(ObjectOutput out) 
            throws IOException {
            out.writeInt(intVal);
            out.writeFloat(floatVal);
            out.writeShort(shortVal);
            out.writeObject(longArr);
            out.writeObject(dblArr);
            out.writeObject(selfRef);
        }

        // Required by Java Externalizable.
        @Override public void readExternal(ObjectInput in) 
         throws IOException, ClassNotFoundException {
            intVal = in.readInt();
            floatVal = in.readFloat();
            shortVal = in.readShort();
            longArr = (long[])in.readObject();
            dblArr = (double[])in.readObject();
            selfRef = (SampleObject)in.readObject();
        }

        // Required by Kryo serialization.
        @Override public void write(Kryo kryo, Output out) {
            kryo.writeObject(out, intVal);
            kryo.writeObject(out, floatVal);
            kryo.writeObject(out, shortVal);
            kryo.writeObject(out, longArr);
            kryo.writeObject(out, dblArr);
            kryo.writeObject(out, selfRef);
        }

        // Required by Kryo serialization.
        @Override public void read(Kryo kryo, Input in) {
            intVal = kryo.readObject(in, Integer.class);
            floatVal = kryo.readObject(in, Float.class);
            shortVal = kryo.readObject(in, Short.class);
            longArr = kryo.readObject(in, long[].class);
            dblArr = kryo.readObject(in, double[].class);
            selfRef = kryo.readObject(in, SampleObject.class);
        }
    }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/129764770189151436/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=129764770189151436" title="18 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/129764770189151436?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/129764770189151436?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/GNszvSw0JPw/java-serialization-good-fast-and-faster.html" title="Java Serialization - Good, Fast, and Faster" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-mPfJToWysdk/UMJNP5_ut3I/AAAAAAAAAGE/Cm2nCOAxdcM/s72-c/serialization.png" height="72" width="72" /><thr:total>18</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/12/java-serialization-good-fast-and-faster.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08ARn8-fCp7ImA9WhNQFEk.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-1131864697446339597</id><published>2012-11-20T12:03:00.000-08:00</published><updated>2012-11-20T12:04:07.154-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-11-20T12:04:07.154-08:00</app:edited><title>GridGain and Hadoop: Differences and Synergies</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;Overview&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div class="p1"&gt;
GridGain is Java-based middleware for in-memory processing of big data in a distributed environment. It is based on high performance in-memory data platform that integrates fast In-Memory MapReduce implementation with In-Memory Data Grid technology delivering easy to use and easy to scale software. Using GridGain you can process terabytes of data, on 1000s of nodes in under a second.&amp;nbsp;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt; typically resides between business, analytics, transactional or BI applications and long term data storage such as RDBMS, ERP or Hadoop HDFS, and provides in-memory data platform for high performance, low latency data storage and processing.&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
Both, GridGain and Hadoop, are designed for parallel processing of distributed data. However, both products serve very different goals and in most cases are very complementary to each other. Hadoop is mostly geared towards batch-oriented offline processing of historical and analytics payloads where latencies and transactions don't really matter, while GridGain is meant for real-time in-memory processing of both transactional and non-transactional live data with very low latencies. To better understand where each product really fits, let us compare some main concepts of each product.&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;GridGain In-Memory Compute Grid vs Hadoop MapReduce&lt;/span&gt;&lt;/h4&gt;
&lt;div class="p2"&gt;
&lt;i&gt;&lt;span style="color: blue;"&gt;MapReduce&lt;/span&gt;&lt;/i&gt; is a programming model developed by Google for processing large data sets of data stored on disks. Hadoop MapReduce is an implementation of such model. The model is based on the fact that data in a single file can be distributed across multiple nodes and hence the processing of those files has to be co-located on the same nodes to avoid moving data around. The processing is based on scanning files record by record in parallel on multiple nodes and then reducing the results in parallel on multiple nodes as well. Because of that, standard disk-based MapReduce is good for problem sets which require analyzing every single record in a file and does not fit for cases when direct access to a certain data record is required. Furthermore, due to offline batch orientation of Hadoop it is not suited for low-latency applications.&amp;nbsp;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="color: blue;"&gt;GridGain &lt;i&gt;In-Memory Compute Grid&lt;/i&gt;&lt;/span&gt; (IMCG) on the other hand is geared towards in-memory computations and very low latencies. GridGain IMCG has its own implementation of MapReduce which is designed specifically for real-time in-memory processing use cases and is very different from Hadoop one. Its main goal is to split a task into multiple sub-tasks, load balance those sub-tasks among available cluster nodes, execute them in parallel, then aggregate the results from those sub-tasks and return them to user.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.gridgain.com/images/in_memory_compute_grid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="247" src="http://www.gridgain.com/images/in_memory_compute_grid.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;/div&gt;
&lt;div class="p1"&gt;
Splitting tasks into multiple sub-tasks and assigning them to nodes is the &lt;i&gt;mapping&lt;/i&gt;&amp;nbsp;step and aggregating of results is &lt;i&gt;reducing&lt;/i&gt;&amp;nbsp;step. However, there is no concept of mandatory data built in into this design and it can work in the absence of any data at all which makes it a good fit for both, stateless and state-full computations, like traditional HPC. In cases when data is present, GridGain IMCG will also automatically colocate computations with the nodes where the data is to avoid redundant data movement.&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
It is also worth mentioning, that unlike Hadoop, GridGain IMCG is very well suited for processing of computations which are very short-lived in nature, e.g. below 100 milliseconds and may not require any mapping or reducing.&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
Here is a simple Java coding example of GridGain IMCG which counts number of letters in a phrase by splitting it into multiple words, assigning each word to a sub-task for parallel remote execution in the map step, and then adding all lengths receives from remote jobs in reduce step.&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;
&lt;pre class="brush: java" style="text-align: left;"&gt;    int letterCount = g.reduce(
        BALANCE,
        // Mapper
        new GridClosure&amp;lt;String, Integer&amp;gt;() {
            @Override public Integer apply(String s) {
                return s.length();
            }
        },
        Arrays.asList("GridGain Letter Count".split(" ")),
        // Reducer
        F.sumIntReducer()
    ));
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;GridGain In-Memory Data Grid vs Hadoop Distributed File System&lt;/span&gt;&lt;/h4&gt;
&lt;div class="p1"&gt;
Hadoop Distributed File System (HDFS) is designed for storing large amounts of data in files on disk. Just like any file system, the data is mostly stored in textual or binary formats. To find a single record inside an HDFS file requires a file scan. Also, being distributed in nature, to update a single record within a file in HDFS requires copying of a whole file (file in HDFS can only be appended). This makes HDFS well-suited for cases when data is appended at the end of a file, but not well suited for cases when data needs to be located and/or updated in the middle of a file. With indexing technologies, like HBase or Impala, data access becomes somewhat easier because keys can be indexed, but not being able to index into values (*secondary indexes*) only allow for primitive query execution.&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;i&gt;&lt;span style="color: blue;"&gt;GridGain In-Memory Data Grid&lt;/span&gt;&lt;/i&gt; (IMDG) on the other hand is an in-memory key-value data store. The roots of IMDGs came from distributed caching, however GridGain IMDG also adds transactions, data partitioning, and SQL querying to cached data. The main difference with HDFS (or Hadoop ecosystem overall) is the ability to transact and update any data directly in real time. This makes GridGain IMDG well suited for working on operational data sets, the data sets that are currently being updated and queried, while HDFS is suited for working on historical data which is constant and will never change.&amp;nbsp;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
Unlike a file system, GridGain IMDG works with user domain model by directly caching user application objects. Objects are accessed and updated by key which allows IMDG to work with volatile data which requires direct key-based access.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.gridgain.com/images/in_memory_data_grid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="216" src="http://www.gridgain.com/images/in_memory_data_grid.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
GridGain IMDG allows for indexing into keys and values (i.e. primary and secondary indices) and supports native SQL for data querying &amp;amp; processing. One of unique features of GridGain IMDG is support for distributed joins which allow to execute complex SQL queries on the data in-memory without limitations.&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;GridGain and Hadoop Working Together&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
To summarize:&lt;/div&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;i&gt;Hadoop essentially is a Big Data warehouse which is good for batch processing of historic data that never changes, while GridGain, on the other hand, is an In-Memory Data Platform which works with your current operational data set in transactional fashion with very low latencies. Focusing on very different use cases make GridGain and Hadoop very complementary with each other.&lt;/i&gt;&lt;/blockquote&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.gridgain.com/images/bigdata_paper.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="262" src="http://www.gridgain.com/images/bigdata_paper.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4 style="text-align: left;"&gt;
Up-Stream Integration&lt;/h4&gt;
&lt;div class="p1"&gt;
The diagram above shows integration between GridGain and Hadoop. Here we have GridGain In-Memory Compute Grid and Data Grid working directly in real-time with user application by partitioning and caching data within data grid, and executing in-memory computations and SQL queries on it. Every so often, when data becomes historic, it is snapshotted into HDFS where it can be analyzed using Hadoop MapReduce and analytical tools from Hadoop eco-system.&amp;nbsp;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
Down-Stream Integration&lt;/h4&gt;
&lt;div class="p1"&gt;
Another possible way to integrate would be for cases when data is already stored in HDFS but needs to be loaded into IMDG for faster in-memory processing. For cases like that GridGain provides fast loading mechanisms from HDFS into GridGain IMDG where it can be further analyzed using GridGain in-memory Map Reduce and indexed SQL queries.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;Conclusion&lt;/span&gt;&lt;/h4&gt;
&lt;div class="p1"&gt;
Integration between an in-memory data platform like GridGain and disk based data platform like Hadoop allows businesses to get valuable insights into the whole data set at once, including volatile operational data set cached in memory, as well as historic data set stored in Hadoop. This essentially eliminates any gaps in processing time caused by &lt;i&gt;Extract-Transfer-Load&lt;/i&gt; (ETL) process of copying data from operational system of records, like standard databases, into historic data warehouses like Hadoop. Now data can be analyzed and processed at any point of its lifecycle, from the moment when it gets into the system up until it gets put away into a warehouse.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/1131864697446339597/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=1131864697446339597" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/1131864697446339597?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/1131864697446339597?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/e6SlVereDMY/gridgain-and-hadoop-differences-and.html" title="GridGain and Hadoop: Differences and Synergies" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/11/gridgain-and-hadoop-differences-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUICR38zeip7ImA9WhNRF0o.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-1456625012009525105</id><published>2012-11-12T18:26:00.000-08:00</published><updated>2012-11-12T18:26:06.182-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-11-12T18:26:06.182-08:00</app:edited><title>GridGain 4.3.1 Released</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;br /&gt;
&lt;div style="background-color: white; border: 0px; color: #666666; font-family: ubuntu-1, ubuntu-2, Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; padding: 0px; vertical-align: baseline;"&gt;
&lt;a href="http://www.gridgain.com/download/" style="background-color: transparent; border: 0px; color: black; margin: 0px; outline: none; padding: 0px; vertical-align: baseline;"&gt;GridGain 4.3.1&lt;/a&gt;&amp;nbsp;service release includes several important bug fixes and host of new optimizations. It is 100% backward compatible and it is highly recommended update for anyone running production systems on 4.x code line.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;Details&lt;/span&gt;&lt;/h4&gt;
&lt;table style="background-color: white; border-collapse: collapse; border-spacing: 0px; border: 1px solid rgb(229, 229, 229); color: #666666; font-family: ubuntu-1, ubuntu-2, Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; margin: 0px -1px 25px 0px; padding: 0px; text-align: left; vertical-align: baseline; width: 549px;"&gt;&lt;tbody style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;
&lt;tr style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;td style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border-top-color: rgb(229, 229, 229); border-top-style: solid; border-width: 1px 0px 0px; margin: 0px; padding: 15px; vertical-align: baseline;"&gt;Date&lt;/td&gt;&lt;td style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border-top-color: rgb(229, 229, 229); border-top-style: solid; border-width: 1px 0px 0px; margin: 0px; padding: 15px; vertical-align: baseline;"&gt;&lt;strong style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;November 10&lt;sup style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border: 0px; bottom: 1ex; font-size: 10px; height: 0px; line-height: 1; margin: 0px; padding: 0px; position: relative; vertical-align: baseline;"&gt;th&lt;/sup&gt;, 2012&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;td style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border-top-color: rgb(229, 229, 229); border-top-style: solid; border-width: 1px 0px 0px; margin: 0px; padding: 15px; vertical-align: baseline;"&gt;Version&lt;/td&gt;&lt;td style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border-top-color: rgb(229, 229, 229); border-top-style: solid; border-width: 1px 0px 0px; margin: 0px; padding: 15px; vertical-align: baseline;"&gt;&lt;strong style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;4.3.1e&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;td style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border-top-color: rgb(229, 229, 229); border-top-style: solid; border-width: 1px 0px 0px; margin: 0px; padding: 15px; vertical-align: baseline;"&gt;Build&lt;/td&gt;&lt;td style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border-top-color: rgb(229, 229, 229); border-top-style: solid; border-width: 1px 0px 0px; margin: 0px; padding: 15px; vertical-align: baseline;"&gt;&lt;strong style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;10112012&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;New Features and Enhancements&lt;/span&gt;&lt;/h4&gt;
&lt;ul style="background-color: white; border: 0px; color: #666666; font-family: ubuntu-1, ubuntu-2, Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; list-style-image: initial; list-style-position: initial; margin: 0px 0px 15px 16px; padding: 0px; text-align: left; vertical-align: baseline;"&gt;&lt;ul&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Added remove operation to data loader&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Significantly improved performance of partition to node mapping&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Added&amp;nbsp;&lt;code style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;GridSerializationBenchmark&lt;/code&gt;&amp;nbsp;for comparing performance of Java, Kryo, and GridGain serialization&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Added property-based configuration to remote clients&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Optimized concurrency for asynchronous methods in C++ client&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Removed support for Groovy++ DSL Grover&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;Core Bug Fixes&lt;/span&gt;&lt;/h4&gt;
&lt;ul style="background-color: white; border: 0px; color: #666666; font-family: ubuntu-1, ubuntu-2, Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; list-style-image: initial; list-style-position: initial; margin: 0px 0px 15px 16px; padding: 0px; text-align: left; vertical-align: baseline;"&gt;&lt;ul&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Unmarshalling of&amp;nbsp;&lt;code style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;SimpleDateFormat&lt;/code&gt;&amp;nbsp;fails with NPE&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Possible NPE in Indexing Manager when using distributed data structures&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Swap partition iterator skips entries if off-heap iterator is empty&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;`GridDataLoader` does not allow to cache primitive arrays&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Excessive memory consumption in indexing SPI&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Add check on startup that&amp;nbsp;&lt;code style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;GridOptimizedMarshaller&lt;/code&gt;&amp;nbsp;is supported by running JDK version&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;If ordered message is timed out, other messages for the same topic may not be processed&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;code style="background-color: transparent; background-position: initial initial; background-repeat: initial initial; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;ScalarPiCalculationExample&lt;/code&gt;&amp;nbsp;does not provide correct estimate for PI&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;Client Connectivity Bug Fixes&lt;/span&gt;&lt;/h4&gt;
&lt;ul style="background-color: white; border: 0px; color: #666666; font-family: ubuntu-1, ubuntu-2, Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; list-style-image: initial; list-style-position: initial; margin: 0px 0px 15px 16px; padding: 0px; text-align: left; vertical-align: baseline;"&gt;&lt;ul&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Client router with explicit default configuration leads to NPE.&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Repair REST client support to make session token and client ID optional&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Ping does not work properly in C++ client&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;Visor Management Bug Fixes&lt;/span&gt;&lt;/h4&gt;
&lt;ul style="background-color: white; border: 0px; color: #666666; font-family: ubuntu-1, ubuntu-2, Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; list-style-image: initial; list-style-position: initial; margin: 0px 0px 15px 16px; padding: 0px; text-align: left; vertical-align: baseline;"&gt;&lt;ul&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Clear and Compact operations in Visor do not account for node selection&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Move Visor management tasks into a separate thread pool&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Preload dialog in Visor does not show correct number of keys&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;GC dialog in Visor waits indefinitely for dead nodes&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Increase tooltip dismiss time in Visor&lt;/li&gt;
&lt;li style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;Visor log search does not show nodes table correctly on Windows&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;span style="color: #666666; font-family: ubuntu-1, ubuntu-2, Georgia, Times New Roman, serif;"&gt;&lt;span style="font-size: 14px; line-height: 22px;"&gt;&lt;a href="http://www.gridgain.com/download/"&gt;Download it now&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/1456625012009525105/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=1456625012009525105" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/1456625012009525105?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/1456625012009525105?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/If3vuhjK8_4/gridgain-431-released.html" title="GridGain 4.3.1 Released" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/11/gridgain-431-released.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IFSHs4fip7ImA9WhNREEs.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-3276637018240757808</id><published>2012-11-01T21:46:00.000-07:00</published><updated>2012-11-04T13:45:19.536-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-11-04T13:45:19.536-08:00</app:edited><title>In-Memory Data Grids... Explained</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;br /&gt;
In-memory processing has been a pretty hot topic lately.&amp;nbsp;Many companies that historically would not have considered using in-memory technology because it was cost prohibitive are now changing their core systems’ architectures to take advantage of the low-latency transaction processing that in-memory technology offers. &amp;nbsp;This is a consequence of the fact that the price of RAM is dropping significantly and rapidly and as a result, it has become economical to load the entire operational dataset into memory with performance improvements of over 1000x faster.&amp;nbsp;&lt;i&gt;In-Memory Compute and Data Grids&lt;/i&gt; provide the core capabilities of an in-memory architecture.&lt;br /&gt;
&lt;br /&gt;
The goal of &lt;i&gt;In-Memory Data Grids&lt;/i&gt; (&lt;b&gt;IMDG&lt;/b&gt;) is to provide extremely high availability of data by keeping it in memory and in highly distributed (i.e. parallelized) fashion. By loading Terabytes of data into memory &lt;i&gt;IMDGs&lt;/i&gt; are able to support most of the &lt;b&gt;Big Data&lt;/b&gt; processing requirements today.&lt;br /&gt;
&lt;br /&gt;
At a very high level, an&amp;nbsp;&lt;i&gt;IMDG&lt;/i&gt; is a distributed object store similar in interface to a typical concurrent hash map. You store objects with keys. Unlike traditional systems where keys and values are often limited to byte arrays or strings, with &lt;i&gt;IMDGs&lt;/i&gt; you can use any domain object as either value or key. This gives tremendous flexibility by allowing you to keep exactly the same object your business logic is dealing with in the Data Grid without the extra step of marshaling and de-marshaling that alternative technologies would require. It also simplifies the usage of your data grid as you can, in most cases, interface with the distributed data store as you do with a simple hash map. Being able to work with domain objects directly is one of the main differences between &lt;i&gt;IMDGs&lt;/i&gt; and &lt;i&gt;In-Memory Databases&lt;/i&gt; (&lt;i&gt;IMDB&lt;/i&gt;). In the case of the latter,&amp;nbsp;users still need to perform &lt;i&gt;Object-To-Relational Mapping&lt;/i&gt; which typically adds significant performance overhead.&lt;br /&gt;
&lt;br /&gt;
There are also some other features in &lt;i&gt;IMDGs&lt;/i&gt; that distinguish them from other products, such as&amp;nbsp;&lt;i&gt;NoSql&lt;/i&gt; databases, &lt;i&gt;IMDBs&lt;/i&gt;, &amp;nbsp;or &lt;i&gt;NewSql&lt;/i&gt; databases. One of the main differences is truly scalable &lt;b&gt;Data Partitioning&lt;/b&gt; across the cluster. Essentially &lt;i&gt;IMDGs&lt;/i&gt; in their purest form can be viewed as distributed hash maps with every key cached on a particular cluster node - the bigger the cluster, the more data you can cache. The trick to this architecture is to make sure that you collocate your processing with the cluster nodes where data is cached to make sure that all cache operations become local and that there is no (or minimal) data movement within the cluster. In fact, when using well designed &lt;i&gt;IMDGs&lt;/i&gt;, there should be absolutely no data movement on stable topologies. The only time when some of the data is moved is when new nodes join in or some existing nodes leave the cluster, thus causing some data repartitioning within the cluster.&lt;br /&gt;
&lt;br /&gt;
The picture below shows a classic &lt;i&gt;IMDG&lt;/i&gt; with a key set of &lt;i&gt;{k1, k2, k3}&lt;/i&gt; where each key belongs to a different node. The external database component is optional. If present, then &lt;i&gt;IMDGs&lt;/i&gt; will usually automatically read data from the database or write data to it.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-4wmmdCIHBPU/UJNPc0-jGYI/AAAAAAAAAFs/Aj_KrXnQ01w/s1600/in_memory_data_grid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-4wmmdCIHBPU/UJNPc0-jGYI/AAAAAAAAAFs/Aj_KrXnQ01w/s1600/in_memory_data_grid.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Another distinguishing characteristic of &lt;i&gt;IMDGs&lt;/i&gt; is &lt;b&gt;Transactional&lt;/b&gt; &lt;b&gt;ACID&lt;/b&gt; support. Generally a &lt;i&gt;2-phase-commit&lt;/i&gt; (&lt;b&gt;2PC&lt;/b&gt;) protocol is used to ensure data consistency within cluster. Different &lt;i&gt;IMDGs&lt;/i&gt; will have different underlying locking mechanisms, but usually more advanced implementations will provide concurrent locking mechanisms (&lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt;, for instance, uses&amp;nbsp;&lt;i&gt;MVCC&lt;/i&gt; - multi-version concurrency control) and reduce network chattiness to a minimum, hence guaranteeing transactional &lt;i&gt;ACID&lt;/i&gt; consistency with very high performance.&lt;br /&gt;
&lt;br /&gt;
Data consistency is one of the main differences between &lt;i&gt;IMDGs&lt;/i&gt; and &lt;i&gt;NoSQL&lt;/i&gt; databases. &lt;i&gt;NoSQL&lt;/i&gt; databases are usually designed using an&amp;nbsp;&lt;i&gt;Eventual Consistency&lt;/i&gt; (&lt;i&gt;EC&lt;/i&gt;) approach where data is allowed to be inconsistent for a period of time as long as it will become consistent &lt;i&gt;*eventually*&lt;/i&gt;. Generally, the writes on &lt;i&gt;EC-based&lt;/i&gt; systems are somewhat fast, but reads are slow (or to be more precise, as fast as writes are). Latest IMDGs with an&amp;nbsp;&lt;i&gt;*optimized*&lt;/i&gt; 2PC should at least match if not outperform &lt;i&gt;EC-based&lt;/i&gt; systems on writes, and be significantly faster on reads. It is interesting to note that the industry has made a full circle moving from &amp;nbsp;a then-slow &lt;i&gt;2PC&lt;/i&gt; approach to the&amp;nbsp;&lt;i&gt;EC&lt;/i&gt; approach, and now from &lt;i&gt;EC&lt;/i&gt; to a much faster&amp;nbsp;&lt;i&gt;*optimized* 2PC&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Different products provide different &lt;i&gt;2PC&lt;/i&gt; optimizations, but generally the purpose of all optimizations is to increase concurrency, minimize network overhead, and reduce the number of locks a transaction requires to complete. As an example, Google's distributed global database, Spanner, is based on a transactional &lt;i&gt;2PC&lt;/i&gt; approach simply because &lt;i&gt;2PC&lt;/i&gt; provided a faster and more straightforward way to guarantee data&amp;nbsp;consistency&amp;nbsp;and high throughput compared to MapReduce or EC.&lt;br /&gt;
&lt;br /&gt;
Even though &lt;i&gt;IMDGs&lt;/i&gt; usually share some common basic functionality, there are many features and implementation details that are different between vendors. When evaluating an &lt;i&gt;IMDG&lt;/i&gt; product pay attention to eviction policies, (pre)loading techniques, concurrent repartitioning, memory overhead, etc... Also pay attention to the ability to query data at runtime. Some &lt;i&gt;IMDGs&lt;/i&gt;, such as&amp;nbsp;&lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt; for example, allow users to query in-memory data using standard &lt;i&gt;SQL&lt;/i&gt;, including support for distributed joins, which is pretty rare.&lt;br /&gt;
&lt;br /&gt;
Storing data in an IMDG is only half of the functionality required for an in-memory architecture. This data must also be processed in a high-performance and parallelized manner. The typical in-memory architecture&amp;nbsp;partitions data across the cluster using an IMDG, and then computations are sent to the nodes where the data is for collocated (local) execution. Since computations are usually part of &lt;i&gt;Compute Grids&lt;/i&gt; and have to be properly deployed, load-balanced, failed-over, or scheduled, the integration between &lt;i&gt;Compute Grids&lt;/i&gt; and &lt;i&gt;IMDGs&lt;/i&gt; is very important. It is especially beneficial if both &lt;i&gt;In-Memory Compute and Data Grids&lt;/i&gt; are part of the same product and utilize the same APIs which removes the burden of integration from the developer and usually renders the highest performance and reliable in-memory systems.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-ivAvo3BXjJA/UJNPsMmQ48I/AAAAAAAAAF0/4_vlUmmqjgE/s1600/datagrid_paper.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-ivAvo3BXjJA/UJNPsMmQ48I/AAAAAAAAAF0/4_vlUmmqjgE/s1600/datagrid_paper.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;IMDGs&lt;/i&gt; (together with &lt;i&gt;Compute Grids&lt;/i&gt;) are used throughout a wide spectrum of industries in applications as diverse as Risk Analytics, Trading Systems, real time Fraud Detection, Biometrics, eCommerce, or Online Gaming. Essentially every project that struggles with scalability and performance can benefit from &lt;i&gt;In-Memory Processing&lt;/i&gt; and&amp;nbsp;&lt;i&gt;IMDG&lt;/i&gt; architecture.&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/3276637018240757808/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=3276637018240757808" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/3276637018240757808?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/3276637018240757808?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/8SPotcNpXnY/in-memory-data-grids-explained.html" title="In-Memory Data Grids... Explained" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-4wmmdCIHBPU/UJNPc0-jGYI/AAAAAAAAAFs/Aj_KrXnQ01w/s72-c/in_memory_data_grid.png" height="72" width="72" /><thr:total>6</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/11/in-memory-data-grids-explained.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIHQXgyfip7ImA9WhJbFUw.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-2622680240389689554</id><published>2012-09-21T14:38:00.001-07:00</published><updated>2012-09-24T11:15:30.696-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-24T11:15:30.696-07:00</app:edited><title>MergeSort on GridGain</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Here is an example of how you can perform MergeSort on a distributed grid product like &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt;. This example is somewhat artificial, as you probably would never do the same thing in real life (executing the same code locally is most likely faster), but it does demonstrate some pretty cool features of GridGain, like &lt;b&gt;recursive task execution&lt;/b&gt; and &lt;b&gt;continuations&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
This is the task class which splits array in two and sends remote jobs to sort the new arrays. Remote jobs in their turn execute the same task over and over again until we get to array size of 1, after which we begin merge process.&lt;/div&gt;
&lt;pre class="brush: java"&gt;class GridMergeSortTask extends GridTaskSplitAdapter&amp;lt;int[], int[]&amp;gt; {
    // Injected Grid instance.
    @GridInstanceResource private Grid grid;

    @Override 
    protected Collection&amp;lt;GridJob&amp;gt; split(int gridSize, int[] initArr) {
        Collection&amp;lt;GridJob&amp;gt; jobs = new LinkedList&amp;lt;GridJob&amp;gt;();

        for (final int[] arr : splitArray(initArr)) {
            jobs.add(new GridJobAdapterEx() {
                // Auto-inject job context.
                @GridJobContextResource
                private GridJobContext jobCtx;

                // Task execution result future.
                private GridTaskFuture&amp;lt;int[]&amp;gt; fut;

                @Override public Object execute() throws GridException {
                    if (arr.length == 1)
                        return arr;

                    // Future is null before holdcc() is called and
                    // not null after callcc() is called.
                    if (fut == null) {
                        // Launch the recursive child task asynchronously.
                        fut = grid.execute(new GridMergeSortTask(), arr);

                        // Add a listener to the future, that will resume the
                        // parent task once the child one is completed.
                        fut.listenAsync(new GridInClosure&amp;lt;GridFuture&amp;lt;int[]&amp;gt;&amp;gt;() {
                            @Override public void apply(GridFuture&amp;lt;int[]&amp;gt; fut) {
                                // CONTINUATION:
                                // =============
                                // Resume suspended job execution.
                                jobCtx.callcc();
                            }
                        });

                        // CONTINUATION:
                        // =============
                        // Suspend job execution to be continued later and
                        // release the executing thread.
                        return jobCtx.holdcc();
                    }
                    else {
                        assert fut.isDone();

                        // Return the result of a completed child task.
                        return fut.get();
                    }
                }
            });
        }

        return jobs;
    }

    /**
     * GridTask reduce logic. This method is called when both child jobs
     * are completed, and is a Reduce step of Merge Sort algorithm.
     */
    @Override public int[] reduce(List&amp;lt;GridJobResult&amp;gt; results) {
        // This is in case we have a single-element array.
        if (results.size() == 1)
            return results.get(0).getData();

        assert results.size() == 2;

        int[] arr1 = results.get(0).getData();
        int[] arr2 = results.get(1).getData();

        return mergeArrays(arr1, arr2);
    }

    private static Iterable&amp;lt;int[]&amp;gt; splitArray(int[] arr) {
        int len1 = arr.length / 2;
        int len2 = len1 + arr.length % 2;

        int[] a1 = new int[len1];
        int[] a2 = new int[len2];

        System.arraycopy(arr, 0, a1, 0, len1);
        System.arraycopy(arr, len1, a2, 0, len2);

        System.out.println("Split array [arr1Len=" + a1.length + 
            ", arr2Len=" + a2.length + ']');

        return Arrays.asList(a1, a2);
    }

    private static int[] mergeArrays(int[] arr1, int[] arr2) {
        int[] ret = new int[arr1.length + arr2.length];

        int i1 = 0;
        int i2 = 0;

        // Merge 2 arrays into a resulting array
        for (int i = 0; i &amp;lt; ret.length; i++) {
            if (i1 &amp;gt;= arr1.length) {
                System.arraycopy(arr2, i2, ret, i, arr2.length - i2);

                break;
            }
            else if (i2 &amp;gt;= arr2.length) {
                System.arraycopy(arr1, i1, ret, i, arr1.length - i1); 

                break;
            }
            else
                ret[i] = arr1[i1] &amp;lt;= arr2[i2] ? arr1[i1++] : arr2[i2++];
        }

        System.out.println("Merged arrays [resLen=" + ret.length + 
            ", arr1Len=" + arr1.length + ", arr2Len=" + arr2.length + ']');

        return ret;
    }
}
&lt;/pre&gt;
And here is how you would call this task:
&lt;pre class="brush:java"&gt;
    public static void main(String[] args) throws GridException {
        Grid grid = G.start();

        try {
            int[] inArr = generateRandomArray(30);

            System.out.println("Unsorted array: " + Arrays.toString(inArr));

            int[] outArr = grid.execute(new GridMergeSortTask(), inArr).get();

            System.out.println("Sorted array: " + Arrays.toString(outArr));
        }
        finally {
            G.stop(true);
        }
    }

    private static int[] generateRandomArray(int size) {
        int[] ret = new int[size];

        Random rnd = new Random();

        for (int i = 0; i &amp;lt; ret.length; i++)
            ret[i] = rnd.nextInt(100);

        return ret;
    }
&lt;/pre&gt;
Enjoy!
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/2622680240389689554/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=2622680240389689554" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/2622680240389689554?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/2622680240389689554?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/hRCXzoIjiIE/mergesort-on-gridgain.html" title="MergeSort on GridGain" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/09/mergesort-on-gridgain.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IARXs_cCp7ImA9WhJUEEk.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-8240500093157045462</id><published>2012-09-05T14:15:00.002-07:00</published><updated>2012-09-07T12:19:04.548-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-07T12:19:04.548-07:00</app:edited><title>10 Useful Performance Tuning Tips For GridGain</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
I have been getting many questions of how to tune &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt;, so I decided to create a brief manual which covers most important tuning properties.&lt;br /&gt;
&lt;h4 style="text-align: left;"&gt;
1. GridGain is multi-threaded - Use It&lt;/h4&gt;
&lt;div&gt;
If you are experiencing somewhat slow performance for cache updates, you should ask yourselves whether you are utilizing full computing power (all the cores) on your machine. GridGain is multi-threaded internally, but if you are doing sequential operations one after another from a single thread, then you are not using multithreading. Generally it makes sense to use the amount of threads of about 2 or 3 times the number of cores for populating grid. All GridGain APIs are thread-safe, so you don't have to worry about any concurrency issue when populating data.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
2. Use Collocated Computations&lt;/h4&gt;
&lt;div style="text-align: left;"&gt;
GridGain enables you to execute MapReduce computations in memory. However, most computations usually work on some data which is cached on remote grid nodes. Loading that data from remote nodes is usually expensive and it is a lot more cheaper to send the computation to the node where the data is. The easiest way to do it is to use &lt;b&gt;GridProjection.affinityRun(...)&lt;/b&gt; method; however GridGain has plenty of "&lt;b&gt;mapKeysToNodes(...)&lt;/b&gt;" methods to help users figure out data ownership within Grid.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
3. Use Data Loader&lt;/h4&gt;
&lt;div&gt;
If you need to upload lots of data into cache, use &lt;b&gt;org.gridgain.grid.GridDataLoader &lt;/b&gt;to do it. Data loader will properly batch the updates prior to sending them to remote nodes and will properly control number of parallel operations taking place on each node to avoid thrashing. Generally it &amp;nbsp;provides performance of 10x than doing a bunch of single-threaded updates.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
4. Tune Initial Cache Size&lt;/h4&gt;
&lt;div&gt;
To avoid internal resizing of cache maps you should always provide proper cache start size - not doing so can significantly hurt performance as some CPU cycles will be spent on GridGain resizing internal cache maps instead of application logic. You can configure cache start size via &lt;b&gt;GridCacheConfiguration.getStartSize() &lt;/b&gt;configuration property.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
5. Tune Near Cache&lt;/h4&gt;
&lt;div&gt;
When using Partitioned cache, GridGain will front this cache with local Near cache to make sure that if entry does not belong to local partitions, it will still be cached in a smaller local cache for better performance on next access.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
However, most usages of GridGain happen from collocated computations, i.e. computations submitted to the grid are usually routed to the nodes where the data resides automatically. In cases like this, using Near cache is redundant, as all data access happens from memory anyway. To save on performance, you can disable Near cache by setting &lt;b&gt;GridCacheConfiguration.isNearEnabled()&lt;/b&gt; configuration property.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
6. Tune Off-Heap Memory&lt;/h4&gt;
&lt;div&gt;
If you plan to allocate large amounts of memory to your JVM for data caching (usually more than 10GB of memory), then your application will most likely suffer from prolonged lock-the-world GC pauses which can significantly hurt latencies. To avoid GC pauses use &lt;i&gt;off-heap&lt;/i&gt;&amp;nbsp;memory to cache data - essentially your data is still cached in memory, but JVM does not know about it and GC is not affected.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The only configuration property to set to enable off-heap memory is &lt;b&gt;GridCacheConfiguration.getMaxOffHeapMemory()&lt;/b&gt; which will tell GridGain how much off-heap memory to make available for your application. By default off-heap memory is disabled.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
7. Tune Swap Storage&lt;/h4&gt;
&lt;div&gt;
First of all, if you don't plan to use swap storage (i.e. disk overflow storage), you should not change any default swap settings (swap storage is disabled by default). If you do need to use swap storage, then you should enable it via &lt;b&gt;GridCacheConfiguration.isSwapEnabled()&lt;/b&gt; configuration property.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
8. Tune Query Indexing&lt;/h4&gt;
&lt;div&gt;
There are several configuration properties that you should watch out for here. First of all and most importantly, if you don't plan to use cache queries at all, you should disable indexing altogether via &lt;b&gt;GridCacheConfiguration.isQueryIndexEnabled() &lt;/b&gt;configuration property.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
If you do plan to use cache queries, you should properly enable/disable indexing of primitive keys and values on &lt;b&gt;GridH2IndexingSpi&lt;/b&gt;. You should enable indexing for primitive keys by setting &lt;b&gt;setDefaultIndexPrimitiveKey()&lt;/b&gt;&amp;nbsp;to &lt;i&gt;true&amp;nbsp;&lt;/i&gt;on the SPI only if you plan to use primitive cache keys in your cache queries. The same goes for indexing primitive values controlled by &lt;b&gt;setDefaultIndexPrimitiveValue(...)&lt;/b&gt; property.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Also, if for every value class you don't plan to have different key classes (essentially every value class has one key class), set &lt;b&gt;setDefaultIndexFixedTyping(...) &lt;/b&gt;on the SPI to &lt;i&gt;true&lt;/i&gt;. This way GridGain will store key types as corresponding SQL types instead of binary form which provides faster performance for key lookups.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
9. Tune Eviction Policy&lt;/h4&gt;
&lt;div&gt;
Again, if you don't plan to over-populate your cache, i.e. if you don't need any eviction policy at all, then you should disable eviction policy&amp;nbsp;altogether via &lt;b&gt;GridCacheConfiguration.isEvictionEnabled()&lt;/b&gt; configuration property.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
If you do need GridGain to make sure that data in cache does not overgrow beyond allowed memory limits, you should carefully choose the eviction policy you need. Most likely you will need either FIFO or LRU eviction policies shipped with GridGain, however depending on your application, you may need to configure LIRs or plugin your own custom eviction policy. Regardless of which eviction policy you use, you should carefully chose the maximum amount of entries in cache allowed by eviction policy - if cache size overgrows this limit, then evictions will start&amp;nbsp;occurring. Usually max size is controlled by&amp;nbsp;&lt;b&gt;setMaxSize(...)&lt;/b&gt; configuration property on the instance of eviction policy.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
You should also almost always configure "setAllowEmptyEntries(...)" configuration property to &lt;i&gt;false&lt;/i&gt;. By default GridGain will keep entries with null values in cache to preserve some other properties of the entry, like time-to-live for example. However, if you don't use time-to-live then most likely you should discard the entry once it gets expired or invalidated.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
10. Use Write-Behind Caching&lt;/h4&gt;
&lt;div&gt;
If you can afford for your persistent store to be behind your in-memory cache, then use &lt;i&gt;write-behind&lt;/i&gt;&amp;nbsp;caching. When &lt;i&gt;write-behind&lt;/i&gt;&amp;nbsp;is enabled, GridGain will batch up cache updates and flush them to database in batches in the background which can often provide significant performance benefits. You can enable &lt;i&gt;write-behind&lt;/i&gt; caching via &lt;b&gt;GridCacheConfiguration.isWriteBehindEnabled()&lt;/b&gt; configuration property.&lt;/div&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/8240500093157045462/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=8240500093157045462" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/8240500093157045462?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/8240500093157045462?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/h87vpa9-SIs/10-useful-performance-tuning-tips-for.html" title="10 Useful Performance Tuning Tips For GridGain" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>3</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/09/10-useful-performance-tuning-tips-for.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8MQH8yeyp7ImA9WhJRGE4.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-9169460631991728323</id><published>2012-07-18T20:19:00.002-07:00</published><updated>2012-07-20T17:34:41.193-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-20T17:34:41.193-07:00</app:edited><title>Can Delaying Events Boost Performance Of Your Cluster?</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Should you ever delay events in your cluster? Kind of interesting question. As engineers we are used to think that performance matters and delaying things goes directly against performance, right? Well, not always - there are quite a few cases in distributed environment when delaying things actually helps performance. For example, the most usual case is when you have a continuous stream of asynchronous computations on the grid. Since sending a computation is much faster than processing it, you can essentially overload grid and some sort of back pressure mechanism will be needed (usually you would just limit amount of active computations your grid can handle concurrently). However, in this blog I want to focus on delaying data operations rather than computations.&lt;br /&gt;
&lt;br /&gt;
If you have heard about &lt;i&gt;partitioned&lt;/i&gt;&amp;nbsp;caching, then you perhaps know that whenever a new node joins the grid or an existing node leaves the grid, cluster repartitioning happens. This basically means that, in case of new node, it has to take responsibility for some of the data cached on other nodes, and in case of node leaving the grid, other nodes have to take responsibility for the data cached on that node. Essentially this results in data movement between data grid nodes. Picture below illustrates how keys get partitioned among caching data nodes (share-nothing-architecture):&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.gridgain.com/images/in_memory_data_grid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="216" src="http://www.gridgain.com/images/in_memory_data_grid.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Now imagine that you need to bring multiple nodes up concurrently. The 1st node that comes up will take responsibility for some portion of the data cached on other nodes and will start loading that portion of the data from other nodes. When a 2nd node comes up, it will also take responsibility for some portion of the data, including some data from the 1st node that was just started, and now portion of the data that was moved to 1st node will have to be moved to the 2nd node. Ouch - wouldn't it be more efficient to wait till 2nd node comes up to start data preloading? The same happens when nodes &amp;nbsp;3, 4, etc... come up. So the most efficient way to do preloading of keys and to avoid extra network traffic causes by moving data between newly started nodes is to delay preloading until the last node starts.&lt;br /&gt;
&lt;br /&gt;
At &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt;, we introduced this&amp;nbsp;&lt;i&gt;Delayed Preloading&lt;/i&gt;&amp;nbsp;feature in our latest 4.2 release and now user is in full control of when data preloading happens - either right away upon node start, after a certain delay, or manually from our Visor Devops Console (note the Preload button on the right hand side):&lt;br /&gt;
&lt;span style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-YiX1_RF9Gwo/UAn5EqIuR5I/AAAAAAAAAFg/5Ri6PFswY2w/s1600/Screen+Shot+2012-07-20+at+5.33.52+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="72" src="http://2.bp.blogspot.com/-YiX1_RF9Gwo/UAn5EqIuR5I/AAAAAAAAAFg/5Ri6PFswY2w/s640/Screen+Shot+2012-07-20+at+5.33.52+PM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: white;"&gt;As you see it does help to delay certain events in distributed systems to achieve better performance.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/9169460631991728323/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=9169460631991728323" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/9169460631991728323?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/9169460631991728323?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/jwzjdcjt6Cs/can-delaying-events-boost-performance.html" title="Can Delaying Events Boost Performance Of Your Cluster?" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-YiX1_RF9Gwo/UAn5EqIuR5I/AAAAAAAAAFg/5Ri6PFswY2w/s72-c/Screen+Shot+2012-07-20+at+5.33.52+PM.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/07/can-delaying-events-boost-performance.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcMSXg8cSp7ImA9WhJSE0k.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-4894750222994305223</id><published>2012-06-28T14:06:00.000-07:00</published><updated>2012-07-03T13:08:08.679-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-03T13:08:08.679-07:00</app:edited><title>Segmenting Locks for Concurrency</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
A pretty cool locking mechanism which we use every now and then at&amp;nbsp;&lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt; is concurrent segmented "striped"  locks. Sometimes, your objects are constantly recreated, so you can't really attach a mutex to them. For cases like those you can partition the object space into multiple segments (often by object hashcode value) and only acquire the lock on the segment an object belongs to. This way the more segments you have, the more concurrency you have.&lt;br /&gt;
&lt;br /&gt;
Here is a code for our StripedLock that I thought would be good to share:&lt;br /&gt;
&lt;pre class="brush:java"&gt;public class StripedLock {
    // Array of underlying locks.
    private final Lock[] locks;

    public StripedLock(int concurrencyLevel) {
        locks = new Lock[concurrencyLevel];

        for (int i = 0; i &amp;lt; concurrencyLevel; i++)
            locks[i] = new ReentrantLock();
    }

    public int concurrencyLevel() {
        return locks.length;
    }

    public Lock getLock(int key) {
        return locks[abs(key) % locks.length];
    }

    public Lock getLock(long key) {
        return locks[abs((int)(key % locks.length))];
    }

    // Account for Math.abs() returning negative value.
    private int abs(int key) {
        return key == Integer.MIN_VALUE ? 0 : Math.abs(key);
    }

    public Lock getLock(@Nullable Object o) {
        return o == null ? locks[0] : getLock(o.hashCode());
    }

    public void lock(int key) {
        getLock(key).lock();
    }

    public void lock(long key) {
        getLock(key).lock();
    }

    public void unlock(int key) {
        getLock(key).unlock();
    }

    public void unlock(long key) {
        getLock(key).unlock();
    }

    public void lock(@Nullable Object o) {
        getLock(o).lock();
    }

    public void unlock(@Nullable Object o) {
        getLock(o).unlock();
    }
}
&lt;/pre&gt;
&lt;br /&gt;
Simple - yet powerful! Hope you find it useful.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/4894750222994305223/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=4894750222994305223" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/4894750222994305223?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/4894750222994305223?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/PolFVoLSAGQ/segmenting-locks-for-concurrency.html" title="Segmenting Locks for Concurrency" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>2</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/06/segmenting-locks-for-concurrency.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QARH8zeCp7ImA9WhJTGEo.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-7810408667584485549</id><published>2012-06-28T02:16:00.000-07:00</published><updated>2012-06-28T02:22:25.180-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-28T02:22:25.180-07:00</app:edited><title>HBase As Your Persistent Store?</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://hbase.apache.org/images/hbase_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="49" src="http://hbase.apache.org/images/hbase_logo.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
We have added many cool features in &lt;a href="http://www.gridgain.com/"&gt;GridGain 4.1&lt;/a&gt;. One of them is tight integration with Hadoop ecosystem. There are two ways you can integrate with Hadoop. One way is &lt;i&gt;upstream&lt;/i&gt; integration in which you efficiently load data from HDFS into In-Memory Cache (aka Data Grid) where it gets indexed for low-latency query access. Another way is &lt;i&gt;downstream&lt;/i&gt;&amp;nbsp;integration where HDFS is used as a persistent store and data gets flushed into it periodically from In-Memory Cache using &lt;i&gt;write-behind &lt;/i&gt;cache feature.&lt;br /&gt;
&lt;br /&gt;
With &lt;i&gt;downstream &lt;/i&gt;integration&amp;nbsp;users are able to hold the latest data in memory and use HDFS as historical data warehouse without any extra ETL process and without lags in data. Business applications can run queries and get instant analytical feedback on the whole data set which includes most recent data held in-memory and HDFS-based warehoused data, hence not loosing any data in query results at all.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how HDFS-based cache store would look like in this case. I show how HBase would be used, but you can write directly to HDFS if you like. Note that all we do here is override methods &lt;i&gt;&lt;b&gt;load(...)&lt;/b&gt;&lt;/i&gt;, &lt;i&gt;&lt;b&gt;put(...)&lt;/b&gt;&lt;/i&gt;, and &lt;i&gt;&lt;b&gt;remove(...)&lt;/b&gt;&lt;/i&gt;&amp;nbsp;to tell GridGain how to load and update entries in HBase.&lt;br /&gt;
&lt;br /&gt;
Full source of this example can also be found on &lt;a href="https://github.com/gridgain/gridgain/tree/master/examples/java/org/gridgain/examples/cache/store/hbase"&gt;GitHub GridGain Project&lt;/a&gt;:
&lt;br /&gt;
&lt;pre class="brush:java" title="Cache Store with HBase"&gt;public class GridCacheHBasePersonStore 
    extends GridCacheStoreAdapter&amp;lt;Long, Person&amp;gt; {
    // Default config path.
    private static final String CONFIG_PATH "/my/hbase/hbase-site.xml";

    // Table name.
    private static final String TABLE_NAME = "persons";

    // Maximum allowed pool size.
    private static final int MAX_POOL_SIZE = 4;

    // HBase table pool.
    private HTablePool tblPool;

    // HBase column descriptor for first name.
    private HColumnDescriptor first = new HColumnDescriptor("firstName");

    // HBase column descriptor for last name.
    private HColumnDescriptor last = new HColumnDescriptor("lastName");

    public GridCacheHBasePersonStore() throws Exception {
        prepareDb();
    }

    // Load entry from HBase.
    @Override 
    public Person load(String cacheName, GridCacheTx tx, Long key) 
        throws GridException {
        HTableInterface t = tblPool.getTable(TABLE_NAME);

        try {
            Result r = t.get(new Get(Bytes.toBytes(key)));

            if (r == null)
                throw new GridException("Failed to load key: " + key);

            if (r.isEmpty())
                return null;

            Person p = new Person();

            p.setId(Bytes.toLong(r.getRow()));
            p.setFirst(Bytes.toString(r.getValue(first.getName(), null)));
            p.setLast(Bytes.toString(r.getValue(last.getName(), null)));
            
            return p;
        }
        catch (IOException e) {
            throw new GridException(e);
        }
        finally {
            close(t);
        }
    }

    // Store entry in HBase.
    @Override 
    public void put(String cacheName, GridCacheTx tx, Long key, Person val)
        throws GridException {
        HTableInterface t = tblPool.getTable(TABLE_NAME);

        try {
            t.put(new Put(Bytes.toBytes(key))
                .add(first.getName(), null, Bytes.toBytes(val.getFirst()))
                .add(last.getName(), null, Bytes.toBytes(val.getLast()));
        }
        catch (IOException e) {
            throw new GridException(e);
        }
        finally {
            close(t);
        }
    }

    // Remove entry from HBase.
    @Override 
    public void remove(String cacheName, GridCacheTx tx, Long key) 
        throws GridException {
        HTableInterface t = tblPool.getTable(TABLE_NAME);

        try {
            t.delete(new Delete(Bytes.toBytes(key)));
        }
        catch (IOException e) {
            throw new GridException(e);
        }
        finally {
            close(t);
        }
    }

    // Initialize HBase database.
    private void prepareDb() throws IOException {
        Configuration cfg = new Configuration();

        cfg.addResource(CONFIG_PATH);

        HBaseAdmin admin = new HBaseAdmin(cfg);

        if (!admin.tableExists(TABLE_NAME)) {
            HTableDescriptor desc = new HTableDescriptor(TABLE_NAME);

            desc.addFamily(first);
            desc.addFamily(last);

            admin.createTable(desc);
        }

        tblPool = new HTablePool(cfg, MAX_POOL_SIZE);
    }

    // Close HBase Table.
    private void close(@Nullable HTableInterface t) {
        ...
    }
}
&lt;/pre&gt;
To configure this store you should simply specify it in cache configuration and enable write-behind if you need data to be periodically flushed to HBase like so:
&lt;br /&gt;
&lt;pre class="brush:xml" title="HBase Store Cache Configuration"&gt;&amp;lt;bean class="org.gridgain.grid.cache.GridCacheConfigurationAdapter"&amp;gt;
    ...
    &amp;lt;!-- Setup HBase Cache Store. --&amp;gt;
    &amp;lt;property name="store"&amp;gt;
        &amp;lt;bean class="GridCacheHBasePersonStore" scope="singleton"/&amp;gt;
    &amp;lt;/property&amp;gt;

    &amp;lt;!-- Enable write-behind. --&amp;gt;
    &amp;lt;property name="writeBehindEnabled" value="true"/&amp;gt;
    ...
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/7810408667584485549/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=7810408667584485549" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/7810408667584485549?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/7810408667584485549?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/e1c7GlT-do0/hdfs-as-your-persistent-store.html" title="HBase As Your Persistent Store?" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/06/hdfs-as-your-persistent-store.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcBQXkzeSp7ImA9WhJTE08.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-6514655321739647839</id><published>2012-06-21T16:37:00.000-07:00</published><updated>2012-06-21T16:57:30.781-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-21T16:57:30.781-07:00</app:edited><title>Adding LevelDB store for your In-Memory Cache?</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://code.google.com/p/leveldb/logo?cct=1317055944" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://code.google.com/p/leveldb/logo?cct=1317055944" /&gt;&lt;/a&gt;&lt;/div&gt;
Recently, at one of the customer meetings, I was asked whether &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt; comes with its own database. Naturally my reaction was - why?!? GridGain easily integrates pretty much with any persistent store you wish, including any RDBMS, NoSql, or HDFS stores. However, then I thought, why not? We already have cache swap space (disk overflow) storage based on &lt;a href="http://code.google.com/p/leveldb/"&gt;Google LevelDB&lt;/a&gt; key-value database implementation, so why not have the same for data store.&lt;br /&gt;
&lt;br /&gt;
Here is &lt;b&gt;how easy it was to add&lt;/b&gt; LevelDB based data store implementation for GridGain cache - literally took me 20 minutes to do, including unit tests. The store is based on GridGain swap space, but since swap space is based on LevelDB, you essentially get LevelDB local store for your cached data.
&lt;br /&gt;
&lt;pre class="brush:java" title="Swap Space Cache Store"&gt;public class GridCacheSwapSpaceStore&amp;lt;K, V&amp;gt; 
    extends GridCacheStoreAdapter&amp;lt;K, V&amp;gt; {
    // Default class loader.
    private ClassLoader dfltLdr = getClass().getClassLoader();

    @GridInstanceResource
    private Grid g; // Auto-injected grid instance

    @Override 
    public V load(String cacheName, GridCacheTx tx, K key) 
        throws GridException {
        return g.readFromSwap(spaceName(cacheName), key, classLoader(key));
    }

    @Override 
    public void put(String cacheName, GridCacheTx tx, K key, V val) 
        throws GridException {
        g.writeToSwap(spaceName(cacheName), key, val, classLoader(val, key));
    }

    @Override 
    public void remove(String cacheName, GridCacheTx tx, K key) 
        throws GridException {
        g.removeFromSwap(spaceName(cacheName), key, null, classLoader(key));
    }

    private String spaceName(String cacheName) {
        return cacheName == null ? 
            "gg-spacestore-default" : "gg-spacestore-" + cacheName;
    }

    private ClassLoader classLoader(Object... objs) {
        ClassLoader ldr = null;

        for (Object o : objs) {
            if (o != null) {
                // Detect class loader for given object.
                ldr = U.detectClassLoader(o.getClass());

                if (ldr != dfltLdr)
                    break;
            }
        }

        return ldr;
    }
}
&lt;/pre&gt;
Quite easily done in my view. It will become part of next release of GridGain, so you will have local persistent store out-of-the-box if needed.&lt;br /&gt;
&lt;br /&gt;
Plenty of more examples of different GridGain cache store implementations can be found on GitHub &lt;a href="https://github.com/gridgain/gridgain/tree/master/examples/java/org/gridgain/examples/cache/store"&gt;here&lt;/a&gt;.
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/6514655321739647839/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=6514655321739647839" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/6514655321739647839?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/6514655321739647839?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/SzRznFe9-Bo/adding-leveldb-store-for-your-in-memory.html" title="Adding LevelDB store for your In-Memory Cache?" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/06/adding-leveldb-store-for-your-in-memory.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcBRHYyfip7ImA9WhVbGE0.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-6181872445703027020</id><published>2012-06-04T02:44:00.001-07:00</published><updated>2012-06-04T02:44:15.896-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-04T02:44:15.896-07:00</app:edited><title>Can You Manage Your Grid From Code?</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-3sPQav7oiHA/T8yCrOlefhI/AAAAAAAAAEY/ouBp0tOTd00/s1600/monitor-icon.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-3sPQav7oiHA/T8yCrOlefhI/AAAAAAAAAEY/ouBp0tOTd00/s1600/monitor-icon.png" /&gt;&lt;/a&gt;&lt;/div&gt;
Most of the grid products on the market tout their GUI management consoles for managing and monitoring of their grids. Trying to use a grid without management is the same as trying to drive without GPS navigation - you can get from point A to point B, but it requires a lot more effort. For example, if you have more than a couple of nodes in your grid, how do you know which nodes are alive, what data they are caching, or what tasks they are executing? Management consoles would usually provide such functionality. At &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt;&amp;nbsp;we have built a very feature-rich management and monitoring GUI tool called &lt;i&gt;Visor&lt;/i&gt; (you can see screenshots &lt;a href="http://www.gridgain.com/features/management-and-monitoring/"&gt;here&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
However, while being able to manage grid from GUI is important, it is equally as important to be able to do the same from code. What if you need to start or stop nodes programmatically when reacting to certain parameters of your business logic? Or what if you need to free up some more memory before executing a memory-intensive task? GridGain Remote Closure Execution in combination with Zero Deployment makes it very easy.&lt;br /&gt;
&lt;br /&gt;
For example, here is how you would start or restart &amp;nbsp;multiple remote nodes at once:
&lt;br /&gt;
&lt;pre class="brush:java" title="Start Grid Nodes"&gt;// By specifying startup parameters directly
G.grid().startNodes(
    hostSpec, // Mappings of host related parameters
    null, // Common defaults for this start routine. 
    false, // Restart existing nodes, if any.
    2000, // Timeout to wait for nodes startup. 
    5 // Max connections to each host for concurrent startup.
);

// Or by specifying all startup parameters in a file.
G.grid().startNodes(
    new File("/my/grid/startup/specification.ini", 
    false // Restart flag.
);
&lt;/pre&gt;
Or here is how you can compact your in-memory distributed cache on all grid nodes by freeing up internal byte buffers:
&lt;br /&gt;
&lt;pre class="brush:java" title="Compact Caches"&gt;// Get all nodes on which "mycache" is enabled.
GridProjection gridPrj = G.grid().projectionForCache("mycache");

gridPrj.callAsync(new Callable&amp;lt;Object&amp;gt;() {
    public Object call() throws Exception {
        GridCache cache = G.grid().cache("mycache");

        // Compact all entries in cache.
        cache.compactAll(cache.keySet());

        return null;
    }
});
&lt;/pre&gt;
Or here is how you can free all memory used for cache entry backups on all grid nodes and move it onto disk storage:
&lt;br /&gt;
&lt;pre class="brush:java" title="Swap Backup Entries"&gt;// Get all nodes on which "mycache" is enabled.
GridProjection gridPrj = G.grid().projectionForCache("mycache");

gridPrj.callAsync(new Callable&amp;lt;Object&amp;gt;() {
    public Object call() throws Exception {
        GridCache cache = G.grid().cache("mycache");

        // Evict will move in-memory state onto swap storage on disk.
        // Note that we pass a predicate into evict method to make sure 
        // that only backup entries will be evicted.
        cache.evictAll(new GridPredicate&amp;lt;GridCacheEntry&amp;lt;Object, Object&amp;gt;&amp;gt;() {
            public boolean apply(GridCacheEntry&amp;lt;Object, Object&amp;gt; entry) {
                // Return true if entry is a backup of some other entry.
                return entry.backup();
            }
        });

        return null;
    }
});
&lt;/pre&gt;
&lt;br /&gt;
This is just a small subset of a rich set of management hooks available in &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt;. In the above examples we have been utilizing the same remote closure execution as used for basic MapReduce tasks (we have more advanced API for more complex MapReduce tasks). A cool thing to note is that our closures created above will be deployed on the grid automatically using GridGain Zero Deployment functionality - tasks and closures never have to be predeployed on remote grid nodes. 
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/6181872445703027020/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=6181872445703027020" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/6181872445703027020?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/6181872445703027020?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/o2xCgH3imUw/can-you-manage-your-grid-from-code.html" title="Can You Manage Your Grid From Code?" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-3sPQav7oiHA/T8yCrOlefhI/AAAAAAAAAEY/ouBp0tOTd00/s72-c/monitor-icon.png" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/06/can-you-manage-your-grid-from-code.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4DQHc5eyp7ImA9WhVVGUs.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-4969146455595457969</id><published>2012-05-13T19:22:00.001-07:00</published><updated>2012-05-13T19:36:11.923-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-13T19:36:11.923-07:00</app:edited><title>What does "Real Time" in "Real Time Big Data" mean?</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;br /&gt;
Lately there has been lots of noise about "Real Time" Big Data. Lots of companies that associate themselves with this term are generally in analytical space and to them it really means "low-latency" for analytical processing of data which is usually stored in some warehouse, like Hadoop Distributed File System (HDFS). To achieve this they usually create in-memory indexes over HDFS data which allows their customers run fast&amp;nbsp;queries&amp;nbsp;on it.&lt;br /&gt;
&lt;br /&gt;
Although low latencies are very important, they only cover one side of what "Real Time" really means. The part that is usually not covered is how current the analyzed data is, and in case of HDFS it is as current as the last snapshot copied into it. The need for snapshotting comes from the fact that most businesses are still running on&amp;nbsp;traditional&amp;nbsp;RDBMS systems (with NoSql gaining momentum where it fits), and data has to be at some point migrated into HDFS in order to be processed. Such snapshotting is currently part of most Hadoop deployments and it usually happens once or twice a day.&lt;br /&gt;
&lt;br /&gt;
So how can your business run in "Real Time" if most of the decisions are actually made based on yesterday's data? The architecture&amp;nbsp;needs&amp;nbsp;to be augmented to work with LIVE data, the data which has just been changed or created - not the data that is days old. This is where &lt;b&gt;In-Memory Data Grids&lt;/b&gt; (a.k.a. Distributed Partitioned Caches) come in. &lt;br /&gt;
&lt;br /&gt;
By putting a Data Grid in front of HDFS we can store recent or more relevant state in memory which allows instant access and fast queries on it. When the data is properly partitioned, you can treat your whole Data Grid as one huge memory space - you can literally cache Terabytes of data in memory. But even in this case, the memory space is still limited and when the data becomes less relevant, or simply old, it should still be&amp;nbsp;offloaded&amp;nbsp;onto RDBMS, HDFS, or any other storage. However, with this architecture, &lt;b&gt;businesses can now do processing of both, current and historic data - and this is very powerful&lt;/b&gt;. Now financial companies can quickly react to latest ticks in market data, gaming applications can react to latest player updates, businesses can analyze latest&amp;nbsp;performance&amp;nbsp;of&amp;nbsp;ad campaigns, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.gridgain.com/images/gridgain_overview.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.gridgain.com/images/gridgain_overview.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are some of the important benefits our customers get when deploying &lt;a href="http://www.gridgain.com/"&gt;GridGain In-MemoryCompute and Data Grid&lt;/a&gt; in the above architecture:&lt;br /&gt;
&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;Partitioning of data&lt;/li&gt;
&lt;li&gt;Real Time MapReduce&lt;/li&gt;
&lt;li&gt;Integration between Compute and Data Grids and ability to collocate your computations with data (a.k.a. data affinity)&lt;/li&gt;
&lt;li&gt;In-Memory data indexing and ability to run complex SQL queries, including ability to execute "SQL Joins" between different types of data&lt;/li&gt;
&lt;li&gt;Native affinity-aware clients for Java, .NET, C++, Android (with Objective-C client right around the corner)&lt;/li&gt;
&lt;li&gt;Tight integration with various storage systems, including any type of RDBMS, Hadoop HDFS, HBase, etc...&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Note that in this architecture In-Memory Data and/or Compute Grids really complement warehouse technologies, like HDFS - one is for in-memory processing of current data and another is for processing of historic data.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/4969146455595457969/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=4969146455595457969" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/4969146455595457969?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/4969146455595457969?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/eP6QcjZ-Zs0/what-does-real-time-in-real-time-big.html" title="What does &quot;Real Time&quot; in &quot;Real Time Big Data&quot; mean?" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/05/what-does-real-time-in-real-time-big.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QGQHgzeip7ImA9WhVVF0U.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-5232327306280875751</id><published>2012-05-11T17:08:00.000-07:00</published><updated>2012-05-11T17:08:41.682-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-11T17:08:41.682-07:00</app:edited><title>Distributed HPC with Scala and GridGain, June 5, NYC Scala Meetup</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.gridgain.com/images/meetup_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.gridgain.com/images/meetup_logo.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We’ll be talking about using &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt; for highly distributed HPC programming with Scala at NYC Scala Meetup on June 5th.&lt;br /&gt;
&lt;br /&gt;
As one of the main example we will be walking through a realtime word counting program with constantly changing text and will compare it with a Hadoop word counting example. You will see some cool features of GridGain such as Auto-Discovery, Streaming MapReduce, Zero Deployment, Distributed Data Partitioning, and In-Memory SQL Queries — all coded live in the presentation. Towards the end we will have an extensive Q&amp;amp;A session and cover some interesting real life use cases.&lt;br /&gt;
&lt;br /&gt;
All detailes are here:&lt;a href="http://www.meetup.com/ny-scala/events/63655442/"&gt; http://www.meetup.com/ny-scala/events/63655442/&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/5232327306280875751/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=5232327306280875751" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/5232327306280875751?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/5232327306280875751?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/XfmtCPOgyxI/distributed-hpc-with-scala-and-gridgain.html" title="Distributed HPC with Scala and GridGain, June 5, NYC Scala Meetup" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/05/distributed-hpc-with-scala-and-gridgain.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMBQXw6eCp7ImA9WhVWE0k.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-7515519623312100376</id><published>2012-04-25T02:12:00.001-07:00</published><updated>2012-04-25T02:34:10.210-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-25T02:34:10.210-07:00</app:edited><title>GridGain Drivers on Cruise Control</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-HrrQOgRc76g/TjliORYTTTI/AAAAAAAABow/7cBGUaBc8EM/s1600/driving+icon.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="86" src="http://1.bp.blogspot.com/-HrrQOgRc76g/TjliORYTTTI/AAAAAAAABow/7cBGUaBc8EM/s200/driving+icon.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
Latest &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt; releases have had a big focus on remote grid clients, or as we like to call them &lt;b&gt;remote drivers&lt;/b&gt;. We have recently added Java/Android and C#/.NET clients with C++ and Objective-C clients right around the corner. &amp;nbsp;The goal of remote drivers is to provide ability to use Grid API from environments where it does not make sense to start a node and join the grid, but yet it is still needed to access objects from cache or execute a MapReduce task on remote grid.&lt;br /&gt;
&lt;br /&gt;
The real trick when designing clients is to make sure that the API's are feature rich, but yet portable between different languages. We used &lt;a href="http://code.google.com/p/protobuf/"&gt;Google Protocol Buffers&lt;/a&gt; to ensure portability. This way an object can be stored in cache using .NET C# client and retrieved, for example, using Java or C++ clients.&lt;br /&gt;
&lt;br /&gt;
Another real important feature for remote drivers is &lt;b&gt;data affinity&lt;/b&gt;, especially when working with partitioned caches. Partition caches have a concept of data ownership where every node owns a certain chunk of data. This way data can be split across many nodes and the whole grid becomes one shared RAM storage. However, such approach only works well with collocation of computations and data. All client requests to data should come exactly to the node where the data is cached - otherwise there will be lots of redundant data movement (a.k.a. data noise) which will have adverse effect on scalability.&lt;br /&gt;
&lt;br /&gt;
At GridGain we took specific effort to make sure that &lt;b&gt;all remote GridGain drivers have an embedded notion of affinity&lt;/b&gt; - this way you can store an object in cache using Java and then retrieve it using C# client which will know exactly where to go to get it.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you would use GridGain remote Java or .NET C# clients for basic data and compute operations:&lt;/div&gt;
&lt;pre class="brush:java" title="Java Client Example"&gt;// Get all remote grid nodes
for (GridClientNode node: client.compute().nodes())
    System.out.println("External IP addresses: " + node.externalAddresses())

// Connect to partitioned cache.
GridClientData rmtCache = client.data("partitioned")

// Get and update 10 keys. All cache operations 
// will go exactly to the node where data is cached.
for (int key = 0; key &amp;lt; 10; key++) {
    // Get data.
    String val = rmtCache.get(key);

    // Update data if it is equal to the one we just got.
    rmtCache.cas(key, val + i, val);

    // Asynchronously remove data.
    rmtCache.removeAsync(key);
}

// Connect to remote grid.
GridClientCompute rmtCompute = client.compute();

// Execute map-reduce task on remote grid.
GridClientFuture fut = rmtCompute.executeAsync("MyTask", "myarg");

// Wait for completion.
fut.get();

...
&lt;/pre&gt;
&lt;pre class="brush:csharp" title=".NET C# Client Example"&gt;using X = System.Console;

// Get all remote grid nodes.
foreach (IGridClientNode node in client.Compute().Nodes())
    X.WriteLine("External IP addresses: " + node.ExternalIpAddresses);

// Connect to partitioned cache.
IGridClientData rmtCache = client.Data("partitioned");

// Get and update 10 keys. All cache operations 
// will go exactly to the node where data is cached.
for (int key = 0; key &amp;lt; 10; key++) {
    // Get data.
    String val = rmtCache.GetItem(key);

    // Update data if it is equal to the one we just got.
    rmtCache.Cas(key, val + i, val);

    // Asynchronously remove data.
    rmtCache.RemoveAsync(key);
}

// Connect to remote grid.
IGridClientCompute rmtCompute = client.Compute();

// Execute map-reduce task on remote grid.
IGridClientFuture fut = rmtCompute.ExecuteAsync("MyTask", "myarg");

// Wait for completion.
fut.Result;

...
&lt;/pre&gt;
Note how almost identical the client API's for Java and C# look. Also note that both, C# and Java clients use key affinity and send data operations exactly to the nodes where the data is.&lt;br /&gt;
&lt;br /&gt;
To try GridGain and it's new remote drivers, download GridGain 4.0.2 &lt;a href="http://www.gridgain.com/download/"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/7515519623312100376/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=7515519623312100376" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/7515519623312100376?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/7515519623312100376?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/pIGEzXQhemU/gridgain-drivers-on-cruise-control.html" title="GridGain Drivers on Cruise Control" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-HrrQOgRc76g/TjliORYTTTI/AAAAAAAABow/7cBGUaBc8EM/s72-c/driving+icon.JPG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/04/gridgain-drivers-on-cruise-control.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIDSH4_cCp7ImA9WhVXE0g.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-2141267570815598561</id><published>2012-04-13T16:06:00.000-07:00</published><updated>2012-04-13T16:09:39.048-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-13T16:09:39.048-07:00</app:edited><title>GridGain 4.0.2 Released!</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;a href="http://www.gridgain.com/"&gt;GridGain 4.0.2&lt;/a&gt; has been released today. This is a point release that includes several bug fixes as well as number of new features.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.gridgain.com/images/net_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.gridgain.com/images/net_logo.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With 4.0.1 we are introducing native support for .NET with our C# Client. C# Client provides native .NET/C# APIs for accessing both GridGain’s In-Memory Data Grid and Compute Grid from outside of the GridGain topology context. Internally it’s deferring to the REST protocol. Check out examples on GitHub.&lt;br /&gt;
&lt;br /&gt;
C# Client is one of many native clients we’ll be releasing shortly including Objective-C, C++, PHP, Scala, Ruby, and some others we’re already working on.&lt;br /&gt;
&lt;br /&gt;
&lt;h4 style="text-align: left;"&gt;


&lt;span style="font-size: large;"&gt;Improved Support for 32-bit and 64-bit Systems&lt;/span&gt;&lt;/h4&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;div&gt;
We’ve modified our scripts for better out-of-the-box support for 32-bit and 64-bit systems. We’ve had several clients complaint that additional configuration properties were required and specifically GridGain Visor didn’t work fully on 32-bit system with default configuration. All these issues have been resolved.&lt;/div&gt;
&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;


&lt;span style="font-size: large;"&gt;Enhancements to GridGain Visor&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
We are continuing making rapid improvements to GridGain Visor that is part of GridGain Enterprise and OEM editions.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
We’ve added ability to specific the time span for chart views:&lt;/div&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.gridgain.com/images/visor_chart_span.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.gridgain.com/images/visor_chart_span.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We’ve added nice in-place filtering for events in Dashboard:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.gridgain.com/images/visor_message_filter.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.gridgain.com/images/visor_message_filter.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
You can now double click on event and to see its details:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.gridgain.com/images/visor_double_click_event.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.gridgain.com/images/visor_double_click_event.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can download GridGain 4.0.2&amp;nbsp;&lt;a href="http://www.gridgian.com/download"&gt;here&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/2141267570815598561/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=2141267570815598561" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/2141267570815598561?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/2141267570815598561?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/qD5kV5dZ89I/gridgain-402-released.html" title="GridGain 4.0.2 Released!" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/04/gridgain-402-released.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIFR3k9fCp7ImA9WhVXE0k.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-2609737000527038510</id><published>2012-04-13T13:03:00.004-07:00</published><updated>2012-04-13T13:05:16.764-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-13T13:05:16.764-07:00</app:edited><title>Streaming MapReduce - GridGain Will Present at TriJug on April 16</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.trijug.org/" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="85" src="http://www.gridgain.com/images/trijuglogo.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: -webkit-auto; vertical-align: baseline;"&gt;
&lt;br /&gt;
Come and see me talk about&amp;nbsp;&lt;a href="http://www.trijug.org/"&gt;Streaming Map Reduce on GridGain&lt;/a&gt;&amp;nbsp;and do some live coding of famous Hadoop’s example of counting popular words… but in Real Time context on &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt;. As always – live coding from scratch in Scala is never dull!&lt;/div&gt;
&lt;div style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: -webkit-auto; vertical-align: baseline;"&gt;
See you there.&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/2609737000527038510/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=2609737000527038510" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/2609737000527038510?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/2609737000527038510?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/cHbjMYNLpUc/streaming-mapreduce-gridgain-will.html" title="Streaming MapReduce - GridGain Will Present at TriJug on April 16" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/04/streaming-mapreduce-gridgain-will.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUAR3c8fCp7ImA9WhVQEUs.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-6065566927250774588</id><published>2012-03-30T19:05:00.003-07:00</published><updated>2012-03-30T19:17:26.974-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-30T19:17:26.974-07:00</app:edited><title>Counting Words In Real Time On GridGain</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://img.timeinc.net/time/photoessays/2008/landspeedrecord/speed_bloodhound.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="131" src="http://img.timeinc.net/time/photoessays/2008/landspeedrecord/speed_bloodhound.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
I have promised a while back to publish the code from live coding &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt; presentation I did at QCon London. Since presentation was in Scala, the code I will be posting here is in Scala, but I will post Java version within a couple of days as well.&lt;br /&gt;
&lt;br /&gt;
First a brief intro. We all know Hadoop's counting words example which takes a file with words and then produces another file with number of&amp;nbsp;occurrences&amp;nbsp;next to each word. Hadoop does this example very well, however the main&amp;nbsp;caveat with Hadoop's example is that it is not real time.&lt;br /&gt;
&lt;br /&gt;
The counting words example I did at QCon actually counted words in real time. The program was split into two parts. First part is responsible for loading the words in real time into GridGain data grid, and the second part was querying the grid every 3 seconds to continuously print out top 10 words stored so far.&lt;br /&gt;
&lt;br /&gt;
The example was done using '&lt;i&gt;Scalar&lt;/i&gt;' - GridGain DSL for Scala, but it could have been done In Java as well using GridGain Java APIs.&lt;br /&gt;
&lt;h4 style="text-align: left;"&gt;




&lt;span style="font-size: large;"&gt;Continuously Populate Words In Real Time&lt;/span&gt;&lt;/h4&gt;
Let's start by continuously loading data grid with new words. To do that, I downloaded several books in text format and started concurrently reading them from the &lt;i&gt;populate(...)&lt;/i&gt;&amp;nbsp;method, one thread per book. For every word read, I store it in cache, having the word itself as a key and number of current occurrences as a value. Also note how we let grid asynchronously update cache using asynchronous run while reading the next line from the book file (in reality you would most likely have more than one asynchronous job or have GridGain data loading functionality do it for you).
&lt;br /&gt;
&lt;pre class="brush:scala"&gt;def populate(threadPool: CompletionService, dir: File) {
  val bookFileNames = dir.list()

  // For every book, start a new thread and start populating cache
  // with words and their counts.
  for (bookFileName &amp;lt;- bookFileNames) {
    threadPool.submit(new Callable {
      def call() = {
        val cache = grid$.cache[String, JInt]

        var fut: GridFuture[_] = null;

        Source.fromFile(new File(dir, name)).getLines().foreach(line =&amp;gt; {
          line.split("[^a-zA-Z0-9]").foreach(word =&amp;gt; {
            if (!word.isEmpty) {
              if (fut != null)
                fut.get()

              fut = grid$.affinityRunAsync(null, word, () =&amp;gt; {
                // Increment word counter and store it in cache.
                // We use cache transaction to make sure that
                // gets and puts are consistent and atomic.
                cache.inTx(
                  () =&amp;gt; cache += (word -&amp;gt; (cache.getOrElse(word, 0) + 1))
                )

                ()
              })
            }
          })
        })

        None // Return nothing.
      }
    })
  }

  // Wait for all threads to finish.
  books.foreach(_ =&amp;gt; threadPool.take().get())
}&lt;/pre&gt;
&lt;h4 style="text-align: left;"&gt;




&lt;span style="font-size: large;"&gt;Distributed SQL Query&lt;/span&gt;&lt;/h4&gt;
Now let's implement our distributed query against GridGain data grid which will run every 3 seconds. Note that we are using &lt;b&gt;standard SQL&lt;/b&gt; syntax to query remote grid nodes. Interesting enough that GridGain data grid allows you to use SQL virtually without any limitations. You can use any native SQL function and even SQL JOINs between different classes. Here, for example, we are using SQL &lt;i&gt;length(...)&lt;/i&gt; function to only query words greater than 3 letters long just to get rid of frequent short articles like "a" or "the" in our searches. We are also using &lt;i&gt;desc&lt;/i&gt; keyword to sort word counts in descending order and &lt;i&gt;limit&lt;/i&gt; keyword to limit our selection only to 10 words. &lt;br /&gt;
&lt;pre class="brush:scala"&gt;def queryPopularWords(cnt: Int) {
  // Type alias for sequences of strings (for readability only).
  type SSeq = Seq[String] 

  grid$.cache[String, JInt].sqlReduce(
    // PROJECTION (where to run):
    grid$.projectionForCaches(null),
    // SQL QUERY (what to run):
    "length(_key) &amp;gt; 3 order by _val desc limit " + cnt,
    // REMOTE REDUCER (how to reduce on remote nodes):
    (it: Iterable[(String, JInt)]) =&amp;gt;
      // Pre-reduce by converting 
      // Seq[(String, JInt)] to Map[JInt, Seq[String]].
      (it :\ Map.empty[JInt, SSeq])((e, m) =&amp;gt; 
        m + (e._2 -&amp;gt; (m.getOrElse(e._2, Seq.empty[String]) :+ e._1))),
    // LOCAL REDUCER (how to finally reduce on local node):
    (it: Iterable[Map[JInt, SSeq]]) =&amp;gt; {
      // Print 'cnt' of most popular words collected from all remote nodes.
      (new TreeMap()(implicitly[Ordering[JInt]].reverse) ++ it.flatten)
        .take(cnt).foreach(println _)

      println("------------") // Formatting.
    }
  )
}&lt;/pre&gt;
&lt;h4 style="text-align: left;"&gt;




&lt;span style="font-size: large;"&gt;Start Example&lt;/span&gt;&lt;/h4&gt;
And finally let's implement our &lt;i&gt;main(...)&lt;/i&gt; method our &lt;i&gt;populate(...)&lt;/i&gt; and &lt;i&gt;queryPopularWords(...)&lt;/i&gt; methods we just defined.&lt;br /&gt;
&lt;pre class="brush:scala"&gt;def main(args: Array[String]) {
  // Initialize book directory
  val bookDir = new File(BOOK_PATH);

  // Start GridGain with specified configuration file.
  scalar("examples/config/spring-cache-popularwords.xml") {
    // Create as many threads as we have book, so we can use
    // thread per book to load data grid concurrently.
    val threadPool = Executors.newFixedThreadPool(bookDir.list.length);

    val popWordsQryTimer = new Timer("words-query-worker");

    try {
      // Schedule word queries to run every 3 seconds.
      popWordsQryTimer.schedule(new TimerTask {
        def run() {
          queryPopularWords(10) // Query top 10 words from data grid.
        }
      }, 3000, 3000)

      // Populate cache with word counts.
      populate(new ExecutorCompletionService(threadPool), bookDir)

      // Force one more run to print final counts.
      queryPopularWords(POPULAR_WORDS_CNT)
    }
    finally {
      popWordsQryTimer.cancel() // Cancel timer.

      threadPool.shutdownNow() // Graceful shutdown.
    }
  }
}
&lt;/pre&gt;
&lt;br /&gt;
To execute the example, start several GridGain stand-alone nodes using&amp;nbsp;&lt;i&gt;examples/config/spring-cache-popularwords.xml&lt;/i&gt; configuration file and then start the example we just created from IDE. You may wish to add more printouts for better visibility of what's happening.&lt;br /&gt;
&lt;br /&gt;
This example is also shipped with &lt;a href="http://www.gridgain.com/"&gt;GridGain 4.0&lt;/a&gt; and also available in GridGain &lt;a href="https://github.com/gridgain/gridgain/blob/master/examples/scalar/org/gridgain/scalar/examples/ScalarPopularWordsRealTimeExample.scala"&gt;GitHub Repository&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/6065566927250774588/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=6065566927250774588" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/6065566927250774588?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/6065566927250774588?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/07R9kLQsf5A/counting-words-in-real-time-on-gridgain.html" title="Counting Words In Real Time On GridGain" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>1</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/03/counting-words-in-real-time-on-gridgain.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMMQXw8fip7ImA9WhVRF0U.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-4152332537937239351</id><published>2012-03-26T10:38:00.000-07:00</published><updated>2012-03-26T10:38:00.276-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-26T10:38:00.276-07:00</app:edited><title>GridGain 4.0 Released - Real Time Big Data Platform</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;br /&gt;
I’m pleased to announce that today we released &lt;a href="http://www.gridgain.com/"&gt;GridGain 4.0&lt;/a&gt; – latest edition of our platform for &lt;b&gt;Real Time Big Data&lt;/b&gt; processing. I’m proud that our team set this final deadline almost 5 months ago and we were able to hit without a single delay.&lt;br /&gt;
&lt;br /&gt;
I’m especially proud of this fact because of the enormous complexity of the development process involved in making software like GridGain – dozens of production clients, testing on serious massively distributed environments, set of new features, and the usual array of setbacks that we had to go through to get here.&lt;br /&gt;
&lt;br /&gt;
Needless to say that we have also grown significantly as a business in the last 6 months including more than doubling our team headcount, rolling out new website, new branding, sales team, messaging, press and analysts relationships, investment, and the whole scope of other business activities.&lt;br /&gt;
&lt;br /&gt;But… GridGain System is an engineering company first and foremost and I’ll talk about technology in GridGain 4.0:&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
Among other enhancements this release includes&lt;br /&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;
Visor Monitoring&lt;/span&gt;&amp;nbsp;&lt;/h4&gt;
&lt;div&gt;
One of the biggest additions in 4.0 release is our Visor - GUI-based Management &amp;amp; Monitoring Tool which is included int GridGain Enterprise and GridGain OEM editions. Visor provides you with GUI-based and scriptable environment for managing and monitoring GridGain distributed installations.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
With Visor you can perform various nodes actions&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;a href="http://4.bp.blogspot.com/-ECI-z5iSKlI/T2_FfFL_prI/AAAAAAAAAC4/HjY7GNepyJ0/s1600/visor_node_actions.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-ECI-z5iSKlI/T2_FfFL_prI/AAAAAAAAAC4/HjY7GNepyJ0/s1600/visor_node_actions.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
View topology with metrics&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;a href="http://3.bp.blogspot.com/-e8j6qbXLWQM/T2_FwkGWKzI/AAAAAAAAADA/nQIcZ__udO8/s1600/visor_nodes_table.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-e8j6qbXLWQM/T2_FwkGWKzI/AAAAAAAAADA/nQIcZ__udO8/s1600/visor_nodes_table.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2 style="text-align: left;"&gt;

&lt;/h2&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
View metrics for any logical subgrid&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-9N0Llqj9O5c/T2_HqiaC7hI/AAAAAAAAADQ/AcZReHqWKZ0/s1600/visor_node_metrics.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-9N0Llqj9O5c/T2_HqiaC7hI/AAAAAAAAADQ/AcZReHqWKZ0/s1600/visor_node_metrics.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
See comprehensive historical charts&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-gSoSgQs0Ebo/T2_H4lg18XI/AAAAAAAAADY/RVwb656MtXc/s1600/visor_charts.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-gSoSgQs0Ebo/T2_H4lg18XI/AAAAAAAAADY/RVwb656MtXc/s1600/visor_charts.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-DYHm_cE-HGk/T2_IZAqzgpI/AAAAAAAAADw/Pg8G0QCZKkA/s1600/visor_charts2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-DYHm_cE-HGk/T2_IZAqzgpI/AAAAAAAAADw/Pg8G0QCZKkA/s1600/visor_charts2.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
View advanced grid-wide events&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-04k2jjt7AS8/T2_ILYxeRUI/AAAAAAAAADo/xmNhAzZMuww/s1600/visor_events.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://2.bp.blogspot.com/-04k2jjt7AS8/T2_ILYxeRUI/AAAAAAAAADo/xmNhAzZMuww/s640/visor_events.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
And lots of other cool stuff...&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;
Affinity-Aware Clients&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
In GridGain 4.0 we are finally introducing native clients for various languages. The 4.0 release includes native Java and Android clients with rich APIs to support our Compute Grid and Data Grid connectivity. Our native .NET, C++, Groovy, and Scala clients are already in testing stage and will be coming out shortly as well. After that we will be adding Objective-C, Ruby, PHP, Python, and Node.js clients.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
All of our clients natively support&amp;nbsp;essentially&amp;nbsp;the same APIs specifically adapted to a certain language. &amp;nbsp;You can execute MapReduce tasks, perform bunch of data operations, like storing and&amp;nbsp;retrieving&amp;nbsp;values to/from remote caches, compare-and-set/replace/put-if-absent atomic operations, etc... You can also subscribe to topology updates and get very creative with partitioning remote data grid into logical subgrids.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
But one of the coolest features in our clients is &lt;b&gt;affinity-awareness&lt;/b&gt;. This basically means that when working with data grids, GridGain will automatically figure out on which node the data is stored and will route client requests to that node. Imagine the amount of network trips you can save by retrieving data directly from the node which is responsible for storing it (same goes for updates). This feature is available for all of our native clients, not only for Java, which makes GridGain into the only native cross -language distributed Real Time Big Data platform.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;
Memcached Binary Protocol Support&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
In GridGain 4.0 we significantly enhanced our REST support for HTTP(S) and added Binary protocol support as well. What's even cooler is that our binary protocol is fully &lt;b&gt;Memcached-compliant&lt;/b&gt;. As a matter of fact, during our testing we have been connecting to GridGain using available open source Memcached clients and executing commands on GridGain data grid.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Having said that, GridGain 4.0 Binary connectivity protocol supports a lot more than Memcached does. Essentially we have taken Memcached protocol as our starting point and significantly enhanced it with our own commands and features. For example, you can configure security with proper authentication and secure sessions for remote clients, or you can execute MapReduce tasks, get remote node topology, etc...&amp;nbsp;&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;
Security&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
In GridGain 4.0 we added a notion of secure grids. Grids can now request for nodes to be authenticated prior to joining them into topology. Authentication implementation is fully pluggable through our SPI-based architecture and comes with several implementations out of the box, such as Passcode or JAAS-based authentication.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Additionally remote clients can also be required to authenticate themselves and once authenticated, they establish a secure session with the server. &amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Both, authentication and secure-session SPIs are available in GridGain enterprise edition only.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;
Data Loaders + Hadoop HDFS Support&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
We have also added support for efficient concurrent data loading for our data grid. There are plenty of ways to load data into data grids, including using basic cache APIs or our support for bulk-loading of data from data stores. Data loaders make it easy to externally load data into grid by adding collocation with data nodes, sending concurrent data loading jobs and properly controlling the amount of memory consumed by data loading process.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
As a good use case, you can use data loader to preload data from Hadoop HDFS in order to process it in Real Time on GridGain. In fact GridGain 4.0 comes with HDFS data loading example, GridCacheHdfsLoaderExample, which reads data from HDFS and then uses GridGain data loader to load it into data grid.&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;
1000+ Nodes Guaranteed Discovery&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
In this release we enhanced our TCP-based discovery protocol with enterprise-proven support for network segmentation and &amp;nbsp;half-connected sockets. Our discovery protocol was tested on thousands of grid nodes on Amazon EC2 cloud by us and by our customers to make sure there are no cluster or data inconsistencies. This protocol is already running on customer sites in several deployments quite successfully.&amp;nbsp;&lt;/div&gt;
&lt;h4 style="text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;
LevelDB Swap Space Implementation&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
In GridGain 4.0 you can load&amp;nbsp;terabytes&amp;nbsp;of data into cache. GridGain will try to fit as much of the data in memory as possible - the more grid nodes you have, the more memory is available for caching data. However, if you have more data than fits into the whole memory of the grid, you can use LevelDB swap implementation which is based on Google LevelDB storage to swap infrequently used data to disk. We found that LevelDB can efficiently store large amounts of data with a fairly small disk footprint (using compression). We have also enhanced it with our swap eviction policy to prevent infinite disk growth.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href="http://www.gridgain.com/download/"&gt;Download GridGain 4.0&lt;/a&gt; and try it out.&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/4152332537937239351/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=4152332537937239351" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/4152332537937239351?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/4152332537937239351?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/Iee1zWg83To/gridgain-40-released-real-time-big-data.html" title="GridGain 4.0 Released - Real Time Big Data Platform" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-ECI-z5iSKlI/T2_FfFL_prI/AAAAAAAAAC4/HjY7GNepyJ0/s72-c/visor_node_actions.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/03/gridgain-40-released-real-time-big-data.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEBRXozcSp7ImA9WhRVFkQ.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-4232888386683636825</id><published>2012-01-15T22:00:00.000-08:00</published><updated>2012-01-15T22:00:54.489-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-15T22:00:54.489-08:00</app:edited><title>GridGain 3.6.0 Released!</title><content type="html">I am glad to announce that we have released &lt;a href="http://www.gridgain.com/"&gt;GridGain 3.6.0&lt;/a&gt; -&amp;nbsp;&lt;b style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #666666; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;Real Time Big Data&lt;/b&gt;&lt;span style="background-color: white; color: #666666; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: white; color: #666666; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px;"&gt;platform that allows anyone easily develop, scale and manage compute and data intensive big data applications using&lt;/span&gt;&lt;span style="background-color: white; color: #666666; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;b style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #666666; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;integrated Compute and In-Memory Data Grids&lt;/b&gt;&lt;span style="background-color: white; color: #666666; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: white; color: #666666; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px;"&gt;with Java, Scala and Groovy native APIs.&lt;/span&gt;&lt;div style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #666666; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;
Some of the key new features and enhancements:&lt;/div&gt;
&lt;ul style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #666666; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; list-style-image: initial; list-style-position: initial; margin-bottom: 15px; margin-left: 16px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;
&lt;li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;“Write From Behind Caching” was finally added to IMDGs&lt;/li&gt;
&lt;li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;REST batch operation support introduced (putAll, removeAll)&lt;/li&gt;
&lt;li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;Eviction filters added&lt;/li&gt;
&lt;li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;Segmentation handling for half-connected network sockets&lt;/li&gt;
&lt;li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;Improvements in GridGain Visor&lt;/li&gt;
&lt;li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;New eviction performance optimizations&lt;/li&gt;
&lt;li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;Significant IMDG preloading performance enhancements&lt;/li&gt;
&lt;li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;New optimization for lock-free reads and low contention writes&lt;/li&gt;
&lt;li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;Cumulative bug fixes and multitude of performance&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #666666; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;
You can download it &lt;a href="http://www.gridgain.com/downloads.html"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/4232888386683636825/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=4232888386683636825" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/4232888386683636825?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/4232888386683636825?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/_RRukZzjSYU/gridgain-360-released.html" title="GridGain 3.6.0 Released!" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>1</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2012/01/gridgain-360-released.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cBRnk9cSp7ImA9WhRSGU0.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-4868768840697900309</id><published>2011-11-21T12:55:00.001-08:00</published><updated>2011-11-21T12:57:37.769-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-21T12:57:37.769-08:00</app:edited><title>GridGain is hiring</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.gridgain.com/images/faces.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="36" src="http://www.gridgain.com/images/faces.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: white; color: #222222; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, sans-serif; font-size: 13px; line-height: 1.5; margin-bottom: 15px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;
&lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt; Systems is&amp;nbsp;&lt;strong style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;rapidly growing&lt;/strong&gt;&amp;nbsp;and we are&amp;nbsp;&lt;strong style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;a href="http://www.gridgain.com/careers.html" style="color: #004477; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;hiring&lt;/a&gt;&lt;/strong&gt;&amp;nbsp;talented Java/Scala top-level engineers in both of our locations:&lt;br /&gt;
- Saint Petersburg, Russia&lt;br /&gt;
- Foster City, CA, USA&lt;/div&gt;
&lt;div style="background-color: white; color: #222222; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, sans-serif; font-size: 13px; line-height: 1.5; margin-bottom: 15px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;
Come work for one of the&amp;nbsp;&lt;strong style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;hotest startups&lt;/strong&gt;&amp;nbsp;in the Silicon Valley! Cutting edge work and top level benefits and compensation. We also guarantee sleepless nights, unsolvable problems and insane debugging of complex distributed systems just in the first week&amp;nbsp;&lt;img alt=":)" class="wp-smiley" src="http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif?m=1305847871g" style="border-bottom-color: rgb(221, 221, 221); border-bottom-style: none; border-bottom-width: 2px; border-color: initial; border-left-color: rgb(221, 221, 221); border-left-style: none; border-left-width: 2px; border-right-color: rgb(221, 221, 221); border-right-style: none; border-right-width: 2px; border-top-color: rgb(221, 221, 221); border-top-style: none; border-top-width: 2px; border-width: initial; margin-bottom: 0px; margin-left: 5px; margin-right: 5px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" /&gt;&lt;/div&gt;
&lt;div style="background-color: white; color: #222222; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, sans-serif; font-size: 13px; line-height: 1.5; margin-bottom: 15px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;
All the&amp;nbsp;&lt;a href="http://www.gridgain.com/careers.html" style="color: #004477; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;details are here&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/4868768840697900309/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=4868768840697900309" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/4868768840697900309?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/4868768840697900309?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/vNQVtWYd_Y4/gridgain-is-hiring.html" title="GridGain is hiring" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2011/11/gridgain-is-hiring.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08BQn8_fSp7ImA9WhRSEE0.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-2913270628549012532</id><published>2011-11-11T00:53:00.001-08:00</published><updated>2011-11-11T00:57:33.145-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-11T00:57:33.145-08:00</app:edited><title>GridGain 3.5 Released!</title><content type="html">We’ve just released &lt;a href="http://www.gridgain.com/"&gt;GridGain 3.5&lt;/a&gt; – our latest stable release of GridGain’s Real Time Big Data platform that allows anyone easily develop, scale and manage compute and data intensive JVM based applications using integrated Compute and In-Memory Data Grid with Java, Scala and Groovy native APIs.&lt;br /&gt;
&lt;br /&gt;
Some of the key new features and enhancements:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Significant performance improvements throughout the product&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Previously deprecated APIs have been removed&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Improvements and bug fixes in GridGain Visor&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Enhancements to GridProjection interface&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Ability to programmatically start remote nodes in bulk&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Customizable closure-based MapReduce&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Enhancements in affinity and co-location&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Bug fixes in eviction policies in Data Grid&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Significant improvements and performance enhancements in Swap SPI&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.gridgain.com/downloads.shtml"&gt;Download&lt;/a&gt; &amp;nbsp;GridGain 3.5 today!&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/2913270628549012532/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=2913270628549012532" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/2913270628549012532?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/2913270628549012532?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/MsvwkczXdO8/gridgain-35-released.html" title="GridGain 3.5 Released!" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2011/11/gridgain-35-released.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYNRXw-eSp7ImA9WhdaEUU.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-8167068018476526144</id><published>2011-10-21T00:45:00.000-07:00</published><updated>2011-10-21T00:46:34.251-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-21T00:46:34.251-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="cloud" /><category scheme="http://www.blogger.com/atom/ns#" term="cache" /><category scheme="http://www.blogger.com/atom/ns#" term="grid" /><category scheme="http://www.blogger.com/atom/ns#" term="data grid" /><category scheme="http://www.blogger.com/atom/ns#" term="compute grid" /><title>PDC Theorem – The Underlying Principle of Real-Time Distributed Processing</title><content type="html">Nikita, CEO at &lt;a href="http://www.gridgain.com"&gt;GridGain Systems&lt;/a&gt;, wrote a cool blog on &lt;a href="http://gridgaintech.wordpress.com/2011/10/19/pdc-theorem-the-underlying-principle-of-real-time-distributed-processing/"&gt;PDC Theorem – The Underlying Principle of Real-Time Distributed Processing&lt;/a&gt; where he talks in some detail about important principles of distributed programming, such as real-time processing, data partitioning, and collocation of computations and data. Take a look at it - should be a good and interesting read.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/8167068018476526144/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=8167068018476526144" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/8167068018476526144?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/8167068018476526144?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/7wSamH9BX7Y/pdc-theorem-underlying-principle-of.html" title="PDC Theorem – The Underlying Principle of Real-Time Distributed Processing" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2011/10/pdc-theorem-underlying-principle-of.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk4ASH0zcSp7ImA9WhVQEUg.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-4024271401548236678</id><published>2011-08-29T16:39:00.000-07:00</published><updated>2012-03-30T17:49:09.389-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-30T17:49:09.389-07:00</app:edited><title>How about distributed queues?</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;a href="http://2.bp.blogspot.com/-RVx7t0pSyZc/TlwnUguhQbI/AAAAAAAAACw/7POL2WAijuM/s1600/queue-icon.png"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5646431266151678386" src="http://2.bp.blogspot.com/-RVx7t0pSyZc/TlwnUguhQbI/AAAAAAAAACw/7POL2WAijuM/s200/queue-icon.png" style="cursor: hand; cursor: pointer; float: left; height: 128px; margin: 0 10px 10px 0; width: 128px;" /&gt;&lt;/a&gt;Did you ever wish you could take a data structure you are familiar with and distribute it over grid? For example, why not take &lt;span style="font-style: italic;"&gt;java.util.concurrent.BlockingDeque&lt;/span&gt; and add something to it on one node and poll it from another node? Or why not have a distributed primary key generator which would guarantee uniqueness on all nodes? Or how about a distributed &lt;span style="font-style: italic;"&gt;java.util.concurrent.atomic.AtomicLong&lt;/span&gt; which can be updated and read from any node on the grid? GridGain gives you such capability. What &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt; did is actually take most of the data structures from &lt;span style="font-style: italic;"&gt;java.util.concurrent&lt;/span&gt; framework and made sure they could be used in distributed fashion.
&lt;br /&gt;
&lt;br /&gt;
In this blog I want to show how flexible GridGain distributed queues are. On top implementing &lt;span style="font-style: italic;"&gt;java.util.Collection&lt;/span&gt; interface and supporting different modes of operation, like collocated vs. non-collocated, or bounded vs. ubounded modes, you can actually control how elements are ordered within queues. GridGain supports &lt;span style="font-weight: bold;"&gt;FIFO&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;LIFO&lt;/span&gt;, and &lt;span style="font-weight: bold;"&gt;Priority&lt;/span&gt; based queues out of the box. 
&lt;br /&gt;
&lt;br /&gt;
FIFO queues (first-in-first-out) are the most traditional queues where elements are added from the tail and polled form the queue head. LIFO queues (last-in-first-out) resemble more of stack features instead of queues. In LIFO queues elements are added and polled from the tail. 
&lt;br /&gt;
&lt;br /&gt;
But the most interesting queue type is Priority queue where user can control the order of the elements. Priority queues order elements within the queue based on priority attribute specified by the user. Priority attribute of a queue element is annotated via &lt;a href="http://www.gridgain.com/javadoc30E/org/gridgain/grid/cache/datastructures/GridCacheQueuePriority.html"&gt;@GridCacheQueuePriority&lt;/a&gt; annotation. Here is an example of how priority queue can be created and used.
&lt;br /&gt;
&lt;pre class="brush:java"&gt;public void priorityQueueExample() {
    Random rand = new Random();

    Grid grid = G.grid();

    // Initialize new unbounded collocated priority queue.
    GridCacheQueue&amp;lt;PriorityItem&amp;gt; queue = 
        grid.cache().queue("myqueue", PRIORITY);

    // Store 20 elements in queue with random priority.
    for (int i = 0; i &amp;lt; 20; i++) {
        int priority = rand.nextInt(20);

        queue.put(new PriorityItem(priority, "somedata-" + i));
    }

    PriorityItem item = null;

    int lastPriority = 0;

    do {
        item = queue.poll();

        // Ensure the elements are correctly ordered based on priority.
        assert lastPriority &amp;lt;= item.priority();

        lastPriority = item.priority();
    }
    while (item != null);
}

...

// Class defining sample queue element with its priority specified via
// @GridCacheQueuePriority annotation attached to priority field.
private static class PriorityItem implements Serializable {
    // Priority of queue item.
    @GridCacheQueuePriority
    private final int priority;

    private final String data;

    private SampleItem(int priority, String data) {
        this.priority = priority;
        this.data = data;
    }

    public int priority() {
        return priority;
    }
}
&lt;/pre&gt;
&lt;br /&gt;
Read more about GridGain queues &lt;a href="http://www.gridgain.com/book/book.html#_distributed_data_structures"&gt;here&lt;/a&gt;.
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/4024271401548236678/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=4024271401548236678" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/4024271401548236678?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/4024271401548236678?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/pgfFqRFTwdo/how-about-distributed-queues.html" title="How about distributed queues?" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-RVx7t0pSyZc/TlwnUguhQbI/AAAAAAAAACw/7POL2WAijuM/s72-c/queue-icon.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2011/08/how-about-distributed-queues.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UCQ3w7fCp7ImA9WhdXFks.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-8741443874683675463</id><published>2011-08-15T11:47:00.000-07:00</published><updated>2011-08-29T17:47:42.204-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-29T17:47:42.204-07:00</app:edited><title>Clever Singletons on the Grid</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-CVd33L-jNrQ/TklwVvqEoRI/AAAAAAAAAB8/KfZaJptaGUM/s1600/Alien-smoking-icon.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 96px; height: 96px;" src="http://2.bp.blogspot.com/-CVd33L-jNrQ/TklwVvqEoRI/AAAAAAAAAB8/KfZaJptaGUM/s200/Alien-smoking-icon.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5641163527130751250" /&gt;&lt;/a&gt;When working in distributed environment often you need to have a consistent local state per grid node that is reused between various job executions. For example, what if multiple jobs require database connection pool for their execution - how do they get this connection pool to be initialized once and then reused by all jobs running on the same grid node? Essentially you can think about it as a per-grid-node singleton service, but the idea is not limited to services only, it can be just a regular Java bean that holds some state to be shared by all jobs running on the same grid node.
&lt;br /&gt;
&lt;br /&gt;In &lt;a href="http://www.gridgain.com"&gt;GridGain&lt;/a&gt; versions 2.x and earlier this approach was handled by using &lt;a href="http://www.gridgain.com/javadoc30E/org/gridgain/grid/resources/GridUserResource.html"&gt;@GridUserResource&lt;/a&gt; annotation to annotate fields within &lt;a href="http://www.gridgain.com/javadoc30E/org/gridgain/grid/GridTask.html"&gt;GridTask&lt;/a&gt; or &lt;a href="http://www.gridgain.com/javadoc30E/org/gridgain/grid/GridJob.html"&gt;GridJob&lt;/a&gt; classes to specify singleton beans. However, this approach was dependent on &lt;a href="http://www.gridgain.com/javadoc30E/org/gridgain/grid/GridDeploymentMode.html"&gt;GridDeploymentMode&lt;/a&gt; configuration and, for &lt;span style="font-style:italic;"&gt;ISOLATED&lt;/span&gt; or &lt;span style="font-style:italic;"&gt;PRIVATE&lt;/span&gt; deployment modes, resource could be initialized multiple times, once per &lt;span style="font-style:italic;"&gt;GridTask&lt;/span&gt;. This forced users to use various hacks in their logic and generally was not very convenient to use.
&lt;br /&gt;
&lt;br /&gt;Starting with GridGain 3.0, &lt;a href="http://www.gridgain.com/javadoc30E/org/gridgain/grid/GridNodeLocal.html"&gt;GridNodeLocal&lt;/a&gt; per-grid-node local storage was introduced. The name was borrowed from &lt;a href="http://download.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html"&gt;ThreadLocal&lt;/a&gt; class in Java, because just like &lt;span style="font-style:italic;"&gt;ThreadLocal&lt;/span&gt; provides unique per-thread space in Java, &lt;span style="font-style:italic;"&gt;GridNodeLocal&lt;/span&gt; provides unique per-grid-node space in GridGain. &lt;span style="font-style:italic;"&gt;GridNodeLocal&lt;/span&gt; implements &lt;span style="font-style:italic;"&gt;java.util.concurrent.ConcurrentMap&lt;/span&gt; interface and is absolutely lock-free. In fact, it simply extends &lt;a href="http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html"&gt;java.util.concurrent.ConcurrentHashMap&lt;/a&gt; implementation and, therefore, inherits all the methods available there.
&lt;br /&gt;
&lt;br /&gt;Here is an example of how &lt;span style="font-style:italic;"&gt;GridNodeLocal&lt;/span&gt; could be used to create some user specific singleton service from a simple GridGain job:&lt;pre name="code" class="java:nogutter"&gt;final Grid grid = G.start(..);

// Execute runnable job on some remote grid node.
grid.run(BALANCE, new Runnable() {
  public void run() {
    GridNodeLocal&amp;lt;String, MySingleton&amp;gt; nodeLocal = grid.nodeLocal();

    // 1. Check if f someone already created our singleton service. 
    MySingleton service = nodeLocal.get(&amp;quot;myservice&amp;quot;);

    if (service == null) {
      // 2. Create new singleton service.
      MySingleton other = 
        nodeLocal.putIfAbsent(&amp;quot;myservice&amp;quot;, service = new MySingleton(..));

      if (other != null) 
        service = other;
    }

    // Perform operations with our singleton service.
    ...
  }
});&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/8741443874683675463/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=8741443874683675463" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/8741443874683675463?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/8741443874683675463?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/TvRbQSDLIuE/clever-singletons-on-grid.html" title="Clever Singletons on the Grid" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-CVd33L-jNrQ/TklwVvqEoRI/AAAAAAAAAB8/KfZaJptaGUM/s72-c/Alien-smoking-icon.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2011/08/clever-singletons-on-grid.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ENSHs5fyp7ImA9WhdXFks.&quot;"><id>tag:blogger.com,1999:blog-1680085285488970412.post-1336885854170585581</id><published>2011-06-22T20:03:00.000-07:00</published><updated>2011-08-29T17:54:59.527-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-29T17:54:59.527-07:00</app:edited><title>Even better AtomicInteger and AtomicLong in Java</title><content type="html">Last week I blogged about &lt;a href="http://gridgain.blogspot.com/2011/06/better-atomiclong-and-atomicinteger-in.html"&gt;"Better AtomicInteger and AtomicLong in Java"&lt;/a&gt; and how I added it to &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt; &lt;span style="font-style:italic;"&gt;'lang.utils'&lt;/span&gt; package to be used within GridGain project and by our user base. Recently I made it even better. The standard JDK atomic &lt;span style="font-style:italic;"&gt;'compareAndSet(..)'&lt;/span&gt; operations always check for some 'expected' value and if it matches, then the set happens. What if you simply want to set a value if its greater or less than current value, or if it simply does not match the current value?
&lt;br /&gt;
&lt;br /&gt;Again, code looks pretty simple:
&lt;pre class="java" name="code"&gt;
public class MyAtomicInteger extends AtomicInteger {
  ... // Omitting methods from previous blog
  public boolean setIfGreater(int update) {         
     while (true) {             
          int cur = get();

          if (update &amp;gt; cur) {
              if (compareAndSet(cur, update))
                  return true;
          }
          else
              return false;
      }
  }

  public boolean setIfGreaterEquals(int update) {
      while (true) {
          int cur = get();

          if (update &amp;gt;= cur) {
              if (compareAndSet(cur, update))
                  return true;
          }
          else
              return false;
      }
  }

  public boolean setIfLess(int update) {
      while (true) {
          int cur = get();
          
          if (update &amp;lt; cur) {
              if (compareAndSet(cur, update))
                 return true;
          }
          else
              return false;
      }
  }      
  
  public boolean setIfLessEquals(int update) {
      while (true) {
          int cur = get();

          if (update &amp;lt;= cur) {
              if (compareAndSet(cur, update))
                  return true;
          }
          else
              return false;
      }
  }

  public boolean setIfNotEquals(int update) {
      while (true) {
        int cur = get();

        if (update != cur) {
            if (compareAndSet(cur, update))
                return true;
        }
        else
            return false;
      }
  }
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://www.gridgain.com"&gt;GridGain - Cloud Computing With Zero Deployment&lt;/a&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gridgain.blogspot.com/feeds/1336885854170585581/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1680085285488970412&amp;postID=1336885854170585581" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/1336885854170585581?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1680085285488970412/posts/default/1336885854170585581?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gridify/~3/Zahv6SS2bNQ/even-better-atomicinteger-and.html" title="Even better AtomicInteger and AtomicLong in Java" /><author><name>Dmitriy Setrakyan</name><uri>http://www.blogger.com/profile/01141522474656442760</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="28" height="32" src="http://3.bp.blogspot.com/-zwDgFtZV3JE/TlgqqlQG-4I/AAAAAAAAACQ/sNMg3tg-bSI/s220/dsetrakyan.png" /></author><thr:total>13</thr:total><feedburner:origLink>http://gridgain.blogspot.com/2011/06/even-better-atomicinteger-and.html</feedburner:origLink></entry></feed>
