ã¡ãã£ãšèå³ããããŸããŠãHazelcastã®ã€ã³ããã¯ã¹ã®å©çšã®æ§åãšãã¯ãšãªå®è¡æã®æåã調ã¹ãŠã¿ãŸããã
Hazelcastã¯ãDistributed Mapã«æ ŒçŽãããªããžã§ã¯ãã®ããããã£ã«å¯ŸããŠãã€ã³ããã¯ã¹ã匵ãããšãã§ããŸãã
Indexing
http://docs.hazelcast.org/docs/3.5/manual/html-single/hazelcast-documentation.html#indexing
ãŸãã¯ãšãªå®è¡æã®æåã®ç¢ºèªã«ã¯ãSQL Queryã䜿ãããšã«ããŸãã
Distributed SQL Query
http://docs.hazelcast.org/docs/3.5/manual/html-single/hazelcast-documentation.html#distributed-sql-query
ã§ã¯ãèŠãŠãã£ãŠã¿ãŸãããã
æºå
ãã«ãå®çŸ©ã
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.llittlewings.hazelcast.indexing</groupId> <artifactId>hazelcast-indexing</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>hazelcast-indexing</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.hazelcast</groupId> <artifactId>hazelcast</artifactId> <version>3.5</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.0.0</version> <scope>test</scope> </dependency> </dependencies> </project>
Hazelcast 3.5ããªãªãŒã¹ãããŠããã®ã§ãä»åå©çšããŠã¿ãŸããããã¹ãã³ãŒãçšã«JUnitãšAssertJãå©çšããŸãã
Distributed Mapã®å€ãšããŠæ ŒçŽããã¯ã©ã¹ã¯ã以äžãšããŸãã
src/main/java/org/llittlewings/hazelcast/indexing/Book.java
package org.llittlewings.hazelcast.indexing; import java.io.Serializable; import java.util.Objects; public class Book implements Serializable { private static final long serialVersionUID = 1L; private String isbn; private String title; private int price; public Book(String isbn, String title, int price) { this.isbn = isbn; this.title = title; this.price = price; } public String getIsbn() { return isbn; } public String getTitle() { return title; } public int getPrice() { return price; } @Override public boolean equals(Object o) { if (o instanceof Book) { Book other = (Book) o; return isbn.equals(other.isbn) && title.equals(other.title) && price == other.price; } return false; } @Override public int hashCode() { return Objects.hash(isbn, title, price); } }
ãŸããHazelcastã®èšå®ã¯ãã®ããã«ããŸããã
src/test/resources/hazelcast.xml
<?xml version="1.0" encoding="UTF-8"?> <hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.5.xsd" xmlns="http://www.hazelcast.com/schema/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <group> <name>my-cluster</name> <password>my-cluster-pass</password> </group> <network> <port auto-increment="true" port-count="100">5701</port> <join> <multicast enabled="true"> <multicast-group>224.2.2.3</multicast-group> <multicast-port>54327</multicast-port> </multicast> </join> </network> <map name="default"> <indexes> <index ordered="false">title</index> <index ordered="true">price</index> </indexes> </map> </hazelcast>
ããã©ã«ãã®Distributed Mapã«å¯Ÿããèšå®ã§ãããtitleãšpriceã«ã€ã³ããã¯ã¹ã匵ã£ãŠããŸãããŸããpriceã«ã€ããŠã¯é åºãæèãã圢ã§ã€ã³ããã¯ã¹å®çŸ©ããŠããŸãã
<map name="default"> <indexes> <index ordered="false">title</index> <index ordered="true">price</index> </indexes> </map>
ãã¹ãã³ãŒãã§å©çšãããç°¡åãªã¯ã©ã¹ã¿æ§ç¯çšã®ã¯ã©ã¹ã
src/test/java/org/llittlewings/hazelcast/indexing/HazelcastTestSupport.java
package org.llittlewings.hazelcast.indexing; import java.util.List; import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.IntStream; import com.hazelcast.config.ClasspathXmlConfig; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; public abstract class HazelcastTestSupport { protected void withHazelcast(int numInstances, Consumer<HazelcastInstance> f) { int initialPort = 5701; List<HazelcastInstance> instances = IntStream .rangeClosed(1, numInstances) .mapToObj(i -> { ClasspathXmlConfig config = new ClasspathXmlConfig("hazelcast.xml"); config.setInstanceName("MyHazelcastInstance-" + (initialPort + i - 1)); return Hazelcast.newHazelcastInstance(config); }) .collect(Collectors.toList()); try { f.accept(instances.get(0)); } finally { instances .stream() .forEach(h -> h.getLifecycleService().shutdown()); Hazelcast.shutdownAll(); } } }
æå®æ°åã ããJavaVMå ã§Hazelcastã®Nodeãèµ·åããããšãã§ããŸããHazelcastInstanceã«ã¯ãããããããããã«ããŒãçªå·ãã€ã³ã¹ã¿ã³ã¹åã«å«ããããã«ããŸããã
ã€ã³ããã¯ã¹ã¯ãã©ãã§ã誰ãä¿æããã®ãïŒ
ãŸãã¯ãã€ã³ããã¯ã¹ãã©ãã§ä¿æãããã®ããšãããšããã確èªããããšæããŸãã
å®è£ ãããããšã以äžã®ã¯ã©ã¹ã§æã€ããšã«ãªãããã§ãã
é åºä»ããæèããªãå Žåã
https://github.com/hazelcast/hazelcast/blob/v3.5/hazelcast/src/main/java/com/hazelcast/query/impl/UnsortedIndexStore.java
é åºãæèããå Žåã
https://github.com/hazelcast/hazelcast/blob/v3.5/hazelcast/src/main/java/com/hazelcast/query/impl/SortedIndexStore.java
é åºäžèŠã®å Žåã¯ConcurrentHashMapãé åºä»ããå¿ èŠãªå Žåã¯ConcurrentSkipListMapïŒConcurrentHashMapã§æã€ããã«ãªã£ãŠããŸããã¯ã©ã¹ã¿åãããŠããããã§ããªããããŒã«ã«ã®ã¡ã¢ãªã®ã¿ã«æã£ãŠãããšããæãã§ããã
ããšã¯ãããã®ã€ã³ããã¯ã¹ã誰ãæã£ãŠããã®ããšããããšã§ããã
ãã®ç¢ºèªã®ããã«ããããªãã¹ãã¯ã©ã¹ãçšæããŸããã
src/test/java/org/llittlewings/hazelcast/indexing/IndexingTest.java
package org.llittlewings.hazelcast.indexing; import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; import com.hazelcast.core.IMap; import com.hazelcast.core.PartitionService; import org.junit.Test; public class IndexingTest extends HazelcastTestSupport { @Test public void indexingTest() { List<Book> books = Arrays.asList( new Book("978-4774169316", "Javaãšã³ãžãã¢é€æèªæ¬", 2138), new Book("978-4798124605", "Beginning Java EE 6 GlassFish 3ã§å§ãããšã³ã¿ãŒãã©ã€ãºJava", 4536), new Book("978-4873117188", "Javaããã©ãŒãã³ã¹", 4212) ); withHazelcast(3, hazelcast -> { IMap<String, Book> map = hazelcast.getMap("default"); books.stream().forEach(b -> map.put(b.getIsbn(), b)); try { System.out.println("Sleeping..."); TimeUnit.SECONDS.sleep(10L); } catch (InterruptedException e) { } PartitionService ps = hazelcast.getPartitionService(); System.out.printf( "%s:%s => %s%n", "978-4774169316", "Javaãšã³ãžãã¢é€æèªæ¬", ps.getPartition("978-4774169316").getOwner() ); System.out.printf( "%s:%s => %s%n", "978-4798124605", "Beginning Java EE 6 GlassFish 3ã§å§ãããšã³ã¿ãŒãã©ã€ãºJava", ps.getPartition("978-4798124605").getOwner() ); System.out.printf( "%s:%s => %s%n", "978-4873117188", "Javaããã©ãŒãã³ã¹", ps.getPartition("978-4873117188").getOwner() ); }); } }
ãã¹ãã¯ããŠããŸãããã©âŠã
Distributed Mapã«ããŒã¿ç»é²åŸãå°ãã¹ãªãŒãããŠãããå®éã«ããŒã«å¯Ÿå¿ãããšã³ããªãã©ã®Nodeã«é 眮ãããŠãããã衚瀺ããŠããŸãã
ãšã¯ãããããã ãã ãšããããªãã®ã§Bytemanã®ã¹ã¯ãªãããæžããŠãã€ã³ããã¯ã¹ãžã®ç»é²æã«ã³ã³ãœãŒã«åºåããããã«ããŠã¿ãŸããã
â»è€æ°Nodeãããããããããã¬ãŒã ãšã¡ãã£ãšèŠããã£ãã§ã
indexing-trace.btm
RULE trace UnsortedIndexStore CLASS com.hazelcast.query.impl.UnsortedIndexStore METHOD newIndex AT ENTRY IF TRUE DO traceln("[Trace UnsortedIndexStore] UnsortedIndexStore, newValue = " + $1 + " :: Thread[" + Thread.currentThread().getName() + "]") ENDRULE RULE trace SortedIndexStore CLASS com.hazelcast.query.impl.SortedIndexStore METHOD newIndex AT ENTRY IF TRUE DO traceln("[Trace SortedIndexStore] SortedIndexStore, newValue = " + $1 + " :: Thread[" + Thread.currentThread().getName() + "]") ENDRULE
ãã®Bytemanã¹ã¯ãªãããå«ããŠããã¹ãã³ãŒããåãããŠã¿ãŸãã
$ mvn test -Dtest=*IndexingTest -DargLine=-javaagent:$BYTEMAN_HOME/lib/byteman.jar=script:indexing-trace.btm
ä»åã¯3 Nodeã«ãªãããã«ããŠããã®ã§ãã¯ã©ã¹ã¿ã3ã€ã®Nodeã§æ§æãããŸãã
Members [3] { Member [192.168.254.129]:5701 this Member [192.168.254.129]:5702 Member [192.168.254.129]:5703 } 6 20, 2015 6:59:33 ååŸ com.hazelcast.cluster.ClusterService æ å ±: [192.168.254.129]:5702 [my-cluster] [3.5] Members [3] { Member [192.168.254.129]:5701 Member [192.168.254.129]:5702 this Member [192.168.254.129]:5703 } 6 20, 2015 6:59:33 ååŸ com.hazelcast.cluster.ClusterService æ å ±: [192.168.254.129]:5703 [my-cluster] [3.5] Members [3] { Member [192.168.254.129]:5701 Member [192.168.254.129]:5702 Member [192.168.254.129]:5703 this }
ãããŠãã€ã³ããã¯ã¹ç»é²æã®ãã°ãåºåãããŸãã
[Trace UnsortedIndexStore] UnsortedIndexStore, newValue = Javaãšã³ãžãã¢é€æèªæ¬ :: Thread[hz.MyHazelcastInstance-5702.partition-operation.thread-1] [Trace SortedIndexStore] SortedIndexStore, newValue = 2138 :: Thread[hz.MyHazelcastInstance-5702.partition-operation.thread-1] [Trace UnsortedIndexStore] UnsortedIndexStore, newValue = Javaãšã³ãžãã¢é€æèªæ¬ :: Thread[hz.MyHazelcastInstance-5702.partition-operation.thread-1] [Trace UnsortedIndexStore] UnsortedIndexStore, newValue = Beginning Java EE 6 GlassFish 3ã§å§ãããšã³ã¿ãŒãã©ã€ãºJava :: Thread[hz.MyHazelcastInstance-5703.partition-operation.thread-0] [Trace SortedIndexStore] SortedIndexStore, newValue = 4536 :: Thread[hz.MyHazelcastInstance-5703.partition-operation.thread-0] [Trace SortedIndexStore] SortedIndexStore, newValue = 4536 :: Thread[hz.MyHazelcastInstance-5703.partition-operation.thread-0] [Trace UnsortedIndexStore] UnsortedIndexStore, newValue = Javaããã©ãŒãã³ã¹ :: Thread[hz.MyHazelcastInstance-5703.partition-operation.thread-6] [Trace SortedIndexStore] SortedIndexStore, newValue = 4212 :: Thread[hz.MyHazelcastInstance-5703.partition-operation.thread-6] Sleeping... [Trace SortedIndexStore] SortedIndexStore, newValue = 4212 :: Thread[hz.MyHazelcastInstance-5703.partition-operation.thread-6] [Trace SortedIndexStore] SortedIndexStore, newValue = 2138 :: Thread[hz.MyHazelcastInstance-5702.partition-operation.thread-1] [Trace SortedIndexStore] SortedIndexStore, newValue = 4536 :: Thread[hz.MyHazelcastInstance-5703.partition-operation.thread-0] [Trace SortedIndexStore] SortedIndexStore, newValue = 2138 :: Thread[hz.MyHazelcastInstance-5702.partition-operation.thread-1] [Trace SortedIndexStore] SortedIndexStore, newValue = 4212 :: Thread[hz.MyHazelcastInstance-5703.partition-operation.thread-6]
æåŸã«ã¹ã¬ããåãåºåããŠããŠãã¹ã¬ããåã«Hazelcastã®ã€ã³ã¹ã¿ã³ã¹åãå
¥ããããã©ã®Nodeã«ã€ã³ããã¯ã¹ãå
¥ã£ãããå°ãã¯èŠããããšæããŸãã
â»å®è¡ããšã«ãçµæã¯å€ãããŸã
ãŸããããŒã®é 眮ç¶æ³ã¯ããã®ããã«ãªã£ãŠããŸãã
978-4774169316:Javaãšã³ãžãã¢é€æèªæ¬ => Member [192.168.254.129]:5702 978-4798124605:Beginning Java EE 6 GlassFish 3ã§å§ãããšã³ã¿ãŒãã©ã€ãºJava => Member [192.168.254.129]:5703 978-4873117188:Javaããã©ãŒãã³ã¹ => Member [192.168.254.129]:5703
ãšããããšã¯ãããŒã¿ã®ãªãŒããŒãšãªã£ãNodeã«ã€ã³ããã¯ã¹ãäœæããããšããããšã§ããã
ããã«ããŠããSortedIndexStoreã«ã¯ãããã€ã³ããã¯ã¹ç»é²ã®ãªã¯ãšã¹ããçºè¡ããããã§ãããâŠã
ãŸãããã®åŸã¯ã©ã¹ã¿å ã®Nodeãæžã£ãŠãããŸãã
Members [2] { Member [192.168.254.129]:5702 this Member [192.168.254.129]:5703 } 6 20, 2015 7:03:42 ååŸ com.hazelcast.cluster.ClusterService æ å ±: [192.168.254.129]:5703 [my-cluster] [3.5] Members [2] { Member [192.168.254.129]:5702 Member [192.168.254.129]:5703 this }
ããã«äŒŽãå床ã€ã³ããã¯ã¹äœæã®ãã°ãåºåãããŸãã
æ å ±: [192.168.254.129]:5703 [my-cluster] [3.5] Removing Member [192.168.254.129]:5702 [Trace UnsortedIndexStore] UnsortedIndexStore, newValue = Javaãšã³ãžãã¢é€æèªæ¬ :: Thread[hz.MyHazelcastInstance-5703.partition-operation.thread-1] [Trace SortedIndexStore] SortedIndexStore, newValue = 2138 :: Thread[hz.MyHazelcastInstance-5703.partition-operation.thread-1]
ããã¯ãNodeãæžã£ãæã«ããŒã¿ã®åé 眮ãçºçããã®ã§ãããæžã£ãŠããŸã£ãNodeããã®ãšã³ããªã®ãªãŒããŒã ã£ãå Žåã«ã¯å¥ã®NodeããªãŒããŒã«ãªã£ãéã«ã€ã³ããã¯ã¹ãåäœæããããšããããšã§ããã
ãã®äŸã ãšã5702ããŒãã䜿çšããŠããNodeãããŠã³ããããã§ããããJavaãšã³ãžãã¢é€æèªæ¬ãã®ãšã³ããªã®ãªãŒããŒãšãªã£ãŠããã®ã¯ãã®Nodeã§ããã
ã¯ãšãªãå®è¡ããŠã¿ã
ããã§ã¯ç¶ããŠãã¯ãšãªãæããŠã¿ãŸãããã
ä»åºŠã¯ããã®ãããªãã¹ãã³ãŒããçšæããŸããã
src/test/java/org/llittlewings/hazelcast/indexing/QueryTest.java
package org.llittlewings.hazelcast.indexing; import java.util.Arrays; import java.util.Collection; import java.util.List; import com.hazelcast.core.IMap; import com.hazelcast.core.PartitionService; import com.hazelcast.query.SqlPredicate; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; public class QueryTest extends HazelcastTestSupport { @Test public void testQuery() { List<Book> books = Arrays.asList( new Book("978-4774169316", "Javaãšã³ãžãã¢é€æèªæ¬", 2138), new Book("978-4798124605", "Beginning Java EE 6 GlassFish 3ã§å§ãããšã³ã¿ãŒãã©ã€ãºJava", 4536), new Book("978-4873117188", "Javaããã©ãŒãã³ã¹", 4212) ); withHazelcast(3, hazelcast -> { IMap<String, Book> map = hazelcast.getMap("default"); books.stream().forEach(b -> map.put(b.getIsbn(), b)); PartitionService ps = hazelcast.getPartitionService(); System.out.printf( "%s:%s => %s%n", "978-4774169316", "Javaãšã³ãžãã¢é€æèªæ¬", ps.getPartition("978-4774169316").getOwner() ); System.out.printf( "%s:%s => %s%n", "978-4798124605", "Beginning Java EE 6 GlassFish 3ã§å§ãããšã³ã¿ãŒãã©ã€ãºJava", ps.getPartition("978-4798124605").getOwner() ); System.out.printf( "%s:%s => %s%n", "978-4873117188", "Javaããã©ãŒãã³ã¹", ps.getPartition("978-4873117188").getOwner() ); SqlPredicate titleQuery = new SqlPredicate("title = 'Javaãšã³ãžãã¢é€æèªæ¬'"); Collection<Book> booksByTitleQuery = map.values(titleQuery); assertThat(booksByTitleQuery) .hasSize(1) .containsOnly(new Book("978-4774169316", "Javaãšã³ãžãã¢é€æèªæ¬", 2138)); SqlPredicate titleWithLikeQuery = new SqlPredicate("title LIKE '%Java%' AND title LIkE '%é€æèªæ¬'"); Collection<Book> booksByTitleWithLikeQuery = map.values(titleWithLikeQuery); assertThat(booksByTitleWithLikeQuery) .hasSize(1) .containsOnly(new Book("978-4774169316", "Javaãšã³ãžãã¢é€æèªæ¬", 2138)); SqlPredicate priceQuery = new SqlPredicate("price > 4000"); Collection<Book> booksByPriceQuery = map.values(priceQuery); assertThat(booksByPriceQuery) .hasSize(2) .containsSequence( new Book("978-4873117188", "Javaããã©ãŒãã³ã¹", 4212), new Book("978-4798124605", "Beginning Java EE 6 GlassFish 3ã§å§ãããšã³ã¿ãŒãã©ã€ãºJava", 4536) ); }); } }
ä»åºŠã¯ããã¹ããå ¥ã£ãŠããŸãïŒç¬ïŒã
å ã»ã©ãšåæ§ããšã³ããªã®ãªãŒããŒã®ç¶æ³ã衚瀺ããåŸãã¯ãšãªã3åå®è¡ããŸãããã®æã®æ§åããã¬ãŒã¹ããããšæããŸãã
Bytemanã¹ã¯ãªããããã¯ãšãªå®è¡æã®æ§åãè¿œããããã«è¿œå ããŸããã
indexing-trace.btm
RULE trace UnsortedIndexStore CLASS com.hazelcast.query.impl.UnsortedIndexStore METHOD newIndex AT ENTRY IF TRUE DO traceln("[Trace UnsortedIndexStore] UnsortedIndexStore, newValue = " + $1 + " :: Thread[" + Thread.currentThread().getName() + "]") ENDRULE RULE trace SortedIndexStore CLASS com.hazelcast.query.impl.SortedIndexStore METHOD newIndex AT ENTRY IF TRUE DO traceln("[Trace SortedIndexStore] SortedIndexStore, newValue = " + $1 + " :: Thread[" + Thread.currentThread().getName() + "]") ENDRULE RULE trace QueryOperation CLASS com.hazelcast.map.impl.operation.QueryOperation METHOD run AT ENTRY IF TRUE DO traceln("[Trace Query] " + $0.predicate + " :: Thread[" + Thread.currentThread().getName() + "]") ENDRULE RULE trace IndexService CLASS com.hazelcast.query.impl.IndexService METHOD query AT EXIT IF TRUE DO traceln("[Trace IndexService] " + $1 + ", " + $! + " :: Thread[" + Thread.currentThread().getName() + "]") ENDRULE RULE trace BasicMapContextQuerySupport CLASS com.hazelcast.map.impl.BasicMapContextQuerySupport METHOD queryOnPartition AT EXIT IF TRUE DO traceln("[Trace BasicMapContextQuerySupport] " + $2 + ", " + $! + " :: Thread[" + Thread.currentThread().getName() + "]") ENDRULE
è¿œå ããã¯ã©ã¹ã«ã€ããŠã¯ããŸãåŸã§ã
ã§ã¯ãå®è¡ããŠã¿ãŸãã
$ mvn test -Dtest=*QueryTest -DargLine=-javaagent:$BYTEMAN_HOME/lib/byteman.jar=script:indexing-trace.btm
ã¯ã©ã¹ã¿ãæ§æãããåŸãã€ã³ããã¯ã¹ç»é²ãšãšã³ããªã®é 眮ç¶æ³ããã®ããã«è¡šç€ºãããŸãã
[Trace UnsortedIndexStore] UnsortedIndexStore, newValue = Javaãšã³ãžãã¢é€æèªæ¬ :: Thread[hz.MyHazelcastInstance-5702.partition-operation.thread-1] [Trace SortedIndexStore] SortedIndexStore, newValue = 2138 :: Thread[hz.MyHazelcastInstance-5702.partition-operation.thread-1] [Trace SortedIndexStore] SortedIndexStore, newValue = 2138 :: Thread[hz.MyHazelcastInstance-5702.partition-operation.thread-1] [Trace UnsortedIndexStore] UnsortedIndexStore, newValue = Beginning Java EE 6 GlassFish 3ã§å§ãããšã³ã¿ãŒãã©ã€ãºJava :: Thread[hz.MyHazelcastInstance-5701.partition-operation.thread-0] [Trace SortedIndexStore] SortedIndexStore, newValue = 2138 :: Thread[hz.MyHazelcastInstance-5702.partition-operation.thread-1] [Trace SortedIndexStore] SortedIndexStore, newValue = 4536 :: Thread[hz.MyHazelcastInstance-5701.partition-operation.thread-0] [Trace SortedIndexStore] SortedIndexStore, newValue = 4536 :: Thread[hz.MyHazelcastInstance-5701.partition-operation.thread-0] [Trace UnsortedIndexStore] UnsortedIndexStore, newValue = Javaããã©ãŒãã³ã¹ :: Thread[hz.MyHazelcastInstance-5702.partition-operation.thread-6] [Trace SortedIndexStore] SortedIndexStore, newValue = 4212 :: Thread[hz.MyHazelcastInstance-5702.partition-operation.thread-6] 978-4774169316:Javaãšã³ãžãã¢é€æèªæ¬ => Member [192.168.254.129]:5702 978-4798124605:Beginning Java EE 6 GlassFish 3ã§å§ãããšã³ã¿ãŒãã©ã€ãºJava => Member [192.168.254.129]:5701 this 978-4873117188:Javaããã©ãŒãã³ã¹ => Member [192.168.254.129]:5702
ä»åºŠã¯ã5702ã«å¯ããŸããâŠã
æåã®ã¯ãšãªããtitle = 'Javaãšã³ãžãã¢é€æèªæ¬'ãã§ãã
SqlPredicate titleQuery = new SqlPredicate("title = 'Javaãšã³ãžãã¢é€æèªæ¬'"); Collection<Book> booksByTitleQuery = map.values(titleQuery); assertThat(booksByTitleQuery) .hasSize(1) .containsOnly(new Book("978-4774169316", "Javaãšã³ãžãã¢é€æèªæ¬", 2138));
ãã®æã®ãã°ã¯ããã®ããã«ãªããŸãããªããtitleã¯é åºä»ãã«ã€ããŠã®ã€ã³ããã¯ã¹å®çŸ©ã¯ããŠããŸããã
[Trace Query] title=Javaãšã³ãžãã¢é€æèªæ¬ :: Thread[main] [Trace IndexService] title=Javaãšã³ãžãã¢é€æèªæ¬, [] :: Thread[main] [Trace Query] title=Javaãšã³ãžãã¢é€æèªæ¬ :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-0] [Trace Query] title=Javaãšã³ãžãã¢é€æèªæ¬ :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-3] [Trace IndexService] title=Javaãšã³ãžãã¢é€æèªæ¬, [] :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-0] [Trace IndexService] title=Javaãšã³ãžãã¢é€æèªæ¬, [com.hazelcast.query.impl.QueryEntry@eba933f0] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-3]
ããã§ãmainã¹ã¬ããã¯å®è¡ããæ¬äººã®ããã§ãïŒ5701ããŒãã®Nodeãšå矩ïŒã
ã¯ãšãªã¯ãåNodeã§åæ£å®è¡ãããã¿ããã§ããã
ããèŠããšã3ã€ã®Nodeã§æ€çŽ¢ãå®è¡ããããã¡5702ã®ããŒãã䜿çšããNodeã§çµæãèŠã€ãã£ãããã§ãïŒãªãŒããŒã§ããïŒã
[Trace IndexService] title=Javaãšã³ãžãã¢é€æèªæ¬, [com.hazelcast.query.impl.QueryEntry@eba933f0] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-3]
ç¶ããŠãLIKEã®å Žåã
SqlPredicate titleWithLikeQuery = new SqlPredicate("title LIKE '%Java%' AND title LIkE '%é€æèªæ¬'"); Collection<Book> booksByTitleWithLikeQuery = map.values(titleWithLikeQuery); assertThat(booksByTitleWithLikeQuery) .hasSize(1) .containsOnly(new Book("978-4774169316", "Javaãšã³ãžãã¢é€æèªæ¬", 2138));
ãã¡ãã¯ãããªãèšå€§ãªãã°ãåºåãããŸãã
[Trace Query] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬') :: Thread[main] [Trace IndexService] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), null :: Thread[main] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[main] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[main] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[main] ãçç¥ã [Trace Query] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬') :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace IndexService] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), null :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace Query] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬') :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-2] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace IndexService] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), null :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-2] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [com.hazelcast.query.impl.QueryEntry@eba933f0] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] ãçç¥ã [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-2] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-2] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-2] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-2] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-2] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-2] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-2] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-2] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0] [Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0]
ãããèŠããšãããã§ãšã³ããªãèŠã€ããŠããŸãã
[Trace BasicMapContextQuerySupport] (title LIKE '%Java%' AND title LIKE '%é€æèªæ¬'), [com.hazelcast.query.impl.QueryEntry@eba933f0] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-0]
æåã«ã€ã³ããã¯ã¹ããæ¢ããŠããã®åŸã«ãã«ã¹ãã£ã³ããŠããã¿ããã§ããã
â»æã£ãŠããããŒã¿æ°ã®å²ã«ã¯ããã«ã¹ãã£ã³æã®ãã°ããããå€ãã®ãæ°ã«ãªããŸããâŠã
å®éããã®ãããªå®è£
ã«ãªã£ãŠããããã§ããæåã«ã€ã³ããã¯ã¹ããæ¢ããããã§çµæãåŸãããªããã°ãã«ã¹ãã£ã³ã«ç§»è¡ããŸãã
https://github.com/hazelcast/hazelcast/blob/v3.5/hazelcast/src/main/java/com/hazelcast/map/impl/operation/QueryOperation.java#L92
ãã®æãã€ã³ããã¯ã¹ã䜿ã£ãæ€çŽ¢æã«ã¯ä»¥äžã®ã¯ã©ã¹ã䜿çšããã
https://github.com/hazelcast/hazelcast/blob/v3.5/hazelcast/src/main/java/com/hazelcast/query/impl/IndexService.java
ãã«ã¹ãã£ã³ã®æã«ã¯ä»¥äžã®ã¯ã©ã¹ã䜿çšãããããã§ãã
https://github.com/hazelcast/hazelcast/blob/v3.5/hazelcast/src/main/java/com/hazelcast/map/impl/BasicMapContextQuerySupport.java
ãªãã»ã©ã
ãªãããã«ã¹ãã£ã³ãåNodeã§å®è¡ãããŸãããšã
è¿œèšïŒ
ããã©ã«ãã¯Nodeåäœã®ã¹ãã£ã³ã¯ã·ã³ã°ã«ã¹ã¬ããã§åäœãããhazelcast.query.predicate.parallel.evaluationããtrueã«ããããšã§äžŠåå®è¡ã«ãªããããã§ããããã©ã«ãã¯falseãããã®ã§ãããä»åèŠãŠãããšã¹ã¬ããåãéäžã§å€ãã£ãŠããããã«ãèŠããŸãããâŠïŒ
System Properties
http://docs.hazelcast.org/docs/3.5/manual/html-single/hazelcast-documentation.html#system-properties
æåŸã¯ããprice > 4000ãã
SqlPredicate priceQuery = new SqlPredicate("price > 4000"); Collection<Book> booksByPriceQuery = map.values(priceQuery); assertThat(booksByPriceQuery) .hasSize(2) .containsSequence( new Book("978-4873117188", "Javaããã©ãŒãã³ã¹", 4212), new Book("978-4798124605", "Beginning Java EE 6 GlassFish 3ã§å§ãããšã³ã¿ãŒãã©ã€ãºJava", 4536) );
åºåããããã°ã
[Trace Query] price>4000 :: Thread[main] [Trace IndexService] price>4000, [com.hazelcast.query.impl.QueryEntry@b8dbfd77] :: Thread[main] [Trace Query] price>4000 :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-2] [Trace IndexService] price>4000, [com.hazelcast.query.impl.QueryEntry@5a52fd10] :: Thread[hz.MyHazelcastInstance-5702.generic-operation.thread-2] [Trace Query] price>4000 :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-1] [Trace IndexService] price>4000, [] :: Thread[hz.MyHazelcastInstance-5703.generic-operation.thread-1]
ãã¡ãã¯ãã€ã³ããã¯ã¹ãå©çšããæ€çŽ¢ã§å®çµããã¿ããã§ããã
ãªããšãªããæåãèŠããæãã§ããã
ãŸãšã
Hazelcastã®ã€ã³ããã¯ã¹ã®æã¡æ¹ãšãã¯ãšãªå®è¡æã®æåãè¿œã£ãŠã¿ãŸããã
ã€ã³ããã¯ã¹ã¯ããŸãšãããšä»¥äžã®ãããªæãã§ããã
- é åºãæèããªãã®ã§ããã°ãUnsortedIndexStoreã§ä¿æãããïŒConcurrentHashMapã§ä¿æïŒ
- é åºãæèããã®ã§ããã°ãSortedIndexStoreã§ä¿æãããïŒConcurrentSkipListMapïŒConcurrentHashMapã§ä¿æïŒ
- ã€ã³ããã¯ã¹ãã®ãã®ã¯ãããŒã¿ã®ãªãŒããŒãšãªãNodeãããŒã«ã«ã¡ã¢ãªã«ä¿æãã
- ãªãŒããŒã®Nodeãããªããªã£ãå Žåã¯ãããŒã¿ã®ãã€ã°ã¬ãŒã·ã§ã³æã«åã€ã³ããã¯ã¹ããã
ã¯ãšãªå®è¡æã«ã€ããŠã¯ã以äžã®æãã§ããã
- ã¯ãšãªã¯ãåNodeã§åæ£å®è¡
- æåã«ãã€ã³ããã¯ã¹ã䜿ã£ãŠæ€çŽ¢ãèŠã€ããã°ããã§çµäº
- ã€ã³ããã¯ã¹ã䜿ã£ãŠèŠã€ãããªãã£ãå Žåã¯ããã«ã¹ãã£ã³ãžç§»è¡
- ãã«ã¹ãã£ã³ã¯åNodeã§ããããå®è¡ããã
- Nodeå ã§äžŠåå®è¡ãããå Žåã¯ããhazelcast.query.predicate.parallel.evaluationããtrueã«ãã
â»ãŸãããhazelcast.query.result.size.limitãã§ã¯ãšãªãæ»ãæ倧件æ°ãå¶åŸ¡ã§ããããã§ãïŒããã©ã«ãã¯ã-1ã§ãå¶éãªãïŒ
ä»åããœãŒã¹ãæåããè¿œã£ãŠã¿ãŸããããããå匷ã«ãªããŸããã
ä»åäœæãããœãŒã¹ã³ãŒãã¯ããã¡ãã«çœ®ããŠããŸãã
https://github.com/kazuhira-r/hazelcast-examples/tree/master/hazelcast-indexing