You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ignite.apache.org by Dmitry Pryakhin <dm...@nextmail.ru> on 2017/10/04 11:32:08 UTC

Very low performance

Dear colleagues, 

I consider using Ignite, and now do some testing. Cache performance test has
shown ridiculously low performance. Same test was done against PostgreSQL on
the same computer, with much better result. Now I'm trying to figure out if
it's supposed to work that way, or maybe I've done something wrong. Could
anyone verify my tesging approach and configuration? Details are below.


Task: insert 10000 items; keys and values are strings.

Environment: Intel, Windows, Oracle JRE 1.8.

Configuration 1: Ignite 2.2, 1 server node and 1 client node deployed on the
same computer, both have default configuration. In-memory cache.
Average execution time = 1.95 sec.

Configuration 2: Ignite 2.2, 1 server node and 1 client node, deployed on
the same computer. A persistent cache was set up in the server configuration
file.
Best execution time = 510 sec.

Configuration 3: PosgtreSQL, deployed on the same computer as the client.
Average execution time = 3 sec.

Server configuration file for configuration 2:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
	   
    <bean id="grid.cfg"
class="org.apache.ignite.configuration.IgniteConfiguration">
	  <property name="persistentStoreConfiguration">
	    <bean
class="org.apache.ignite.configuration.PersistentStoreConfiguration"/>
	  </property>
	  <property name="cacheConfiguration">
	  	<bean class="org.apache.ignite.configuration.CacheConfiguration">
	  		<property name="name" value="CacheOne"/>
	  	</bean>
	  </property>
    </bean>
</beans>


Client code:

public class PopulateMap {
	private static final char[] LETTERS = {'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'x',
'y', 'z'};
	private static final int L_SIZE = LETTERS.length;

	public static void main(String argv[]) throws Exception {
		Ignition.setClientMode(true);
		
		int idx0 = 0, idx1 = 0, idx2 = 0;
		StringBuilder bf = new StringBuilder();
		
		try (Ignite ignite = Ignition.start("default-config.xml")) {
			ignite.active(true);
			
			CacheConfiguration<String, String> cacheConf = new
CacheConfiguration<>("CacheOne");
			Cache<String, String> cache = ignite.getOrCreateCache(cacheConf);
			cache.clear();
			
			long start = System.currentTimeMillis();
			
			for (int i = 1; i <= 10000; i++) {
				bf.setLength(0);
				bf.append(LETTERS[idx0]).append(LETTERS[idx1]).append(LETTERS[idx2]);
				
				if (++idx2 == L_SIZE) {
					idx2 = 0;
					if (++idx1 == L_SIZE) {
						idx1 = 0;
						if (++idx0 == L_SIZE) {
							idx0 = 0;
						}
					}
				}

				cache.put(String.valueOf(i), bf.toString());
			}
			long end = System.currentTimeMillis();
			System.out.println("=== Execution time is " + (end - start) + " ms.");
		}
	}
}




--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/

Re: Very low performance

Posted by Dmitry Pryakhin <dm...@nextmail.ru>.
Ilya, thanks a lot! With WAL mode = BACKGROUND it takes less than 3 seconds
in average. 
putAll is not what I needed in this particular case. The goal was to test
how fast it can process individual requests.



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/

Re: Very low performance

Posted by Ilya Kasnacheev <il...@gmail.com>.
Hello Dmitry!

The performance drop that you describe is too severe to answer outright,
but I will outline a few settings that should make some difference.

See below in your examples. The main suggestion is walMode setting.

Note that Ignite is a distributed system, so its performance doesn't
compare directly with single-server DB like PostgreSQL.

2017-10-04 14:32 GMT+03:00 Dmitry Pryakhin <dm...@nextmail.ru>:

<?xml version="1.0" encoding="UTF-8"?>
> <beans xmlns="http://www.springframework.org/schema/beans"
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>        xsi:schemaLocation="
>        http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans.xsd">
>
>     <bean id="grid.cfg"
> class="org.apache.ignite.configuration.IgniteConfiguration">
>           <property name="persistentStoreConfiguration">

        <bean
class="org.apache.ignite.configuration.PersistentStoreConfiguration">
           <!-- In LOG_ONLY mode, as long as operating system on the node
is functioning correctly and there's no power failure, the data is
guaranteed to be in persistent store after put.
                 In BACKGROUND mode, Ignite instance on node has to
continue running (or be stopped correctly) to guarantee that the data is in
persistent store.
                 In default mode, fsync() is done after every operation on
cache, which is most reliable but makes no sense for bulk data loading. -->
           <property name="walMode" value="BACKGROUND"/>
        </bean>
       </property>

        <property name="memoryConfiguration">
            <bean
class="org.apache.ignite.configuration.MemoryConfiguration">
                <!-- Set the size of default memory region to 4GB. -->
                <property name="defaultMemoryPolicySize" value="#{4L * 1024
* 1024 * 1024}"/>
                <!-- Setting the page size to 4 KB -->
                <property name="pageSize" value="#{4 * 1024}"/>
            </bean>
        </property>

          <property name="cacheConfiguration">
>                 <bean class="org.apache.ignite.configuration.
> CacheConfiguration">
>                         <property name="name" value="CacheOne"/>
>                 </bean>
>           </property>
>     </bean>
> </beans>
>
>
> Client code:
>
>                                 cache.put(String.valueOf(i),
> bf.toString());
>
Consider also batching this operation by calling putAll() on a big chunk of
data (for example, only doing putAll on collected entries every 1000
iterations).


-- 
Ilya Kasnacheev

Re: Very low performance

Posted by Konstantin Dudkov <kd...@ya.ru>.
Dmitry,

Is is not quite correct to compare Ignite vs Postgre in this 
configuration: Apache Ignite is distributed system and you can't feel 
it's advantages in one-node configuration.

04/10/2017 14:32, Dmitry Pryakhin пишет:
> Dear colleagues,
> 
> I consider using Ignite, and now do some testing. Cache performance test has
> shown ridiculously low performance. Same test was done against PostgreSQL on
> the same computer, with much better result. Now I'm trying to figure out if
> it's supposed to work that way, or maybe I've done something wrong. Could
> anyone verify my tesging approach and configuration? Details are below.
> 
> 
> Task: insert 10000 items; keys and values are strings.
> 
> Environment: Intel, Windows, Oracle JRE 1.8.
> 
> Configuration 1: Ignite 2.2, 1 server node and 1 client node deployed on the
> same computer, both have default configuration. In-memory cache.
> Average execution time = 1.95 sec.
> 
> Configuration 2: Ignite 2.2, 1 server node and 1 client node, deployed on
> the same computer. A persistent cache was set up in the server configuration
> file.
> Best execution time = 510 sec.
> 
> Configuration 3: PosgtreSQL, deployed on the same computer as the client.
> Average execution time = 3 sec.
> 
> Server configuration file for configuration 2:
> <?xml version="1.0" encoding="UTF-8"?>
> <beans xmlns="http://www.springframework.org/schema/beans"
>         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>         xsi:schemaLocation="
>         http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans.xsd">
> 	
>      <bean id="grid.cfg"
> class="org.apache.ignite.configuration.IgniteConfiguration">
> 	  <property name="persistentStoreConfiguration">
> 	    <bean
> class="org.apache.ignite.configuration.PersistentStoreConfiguration"/>
> 	  </property>
> 	  <property name="cacheConfiguration">
> 	  	<bean class="org.apache.ignite.configuration.CacheConfiguration">
> 	  		<property name="name" value="CacheOne"/>
> 	  	</bean>
> 	  </property>
>      </bean>
> </beans>
> 
> 
> Client code:
> 
> public class PopulateMap {
> 	private static final char[] LETTERS = {'a', 'b', 'c', 'd', 'e', 'f', 'g',
> 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'x',
> 'y', 'z'};
> 	private static final int L_SIZE = LETTERS.length;
> 
> 	public static void main(String argv[]) throws Exception {
> 		Ignition.setClientMode(true);
> 		
> 		int idx0 = 0, idx1 = 0, idx2 = 0;
> 		StringBuilder bf = new StringBuilder();
> 		
> 		try (Ignite ignite = Ignition.start("default-config.xml")) {
> 			ignite.active(true);
> 			
> 			CacheConfiguration<String, String> cacheConf = new
> CacheConfiguration<>("CacheOne");
> 			Cache<String, String> cache = ignite.getOrCreateCache(cacheConf);
> 			cache.clear();
> 			
> 			long start = System.currentTimeMillis();
> 			
> 			for (int i = 1; i <= 10000; i++) {
> 				bf.setLength(0);
> 				bf.append(LETTERS[idx0]).append(LETTERS[idx1]).append(LETTERS[idx2]);
> 				
> 				if (++idx2 == L_SIZE) {
> 					idx2 = 0;
> 					if (++idx1 == L_SIZE) {
> 						idx1 = 0;
> 						if (++idx0 == L_SIZE) {
> 							idx0 = 0;
> 						}
> 					}
> 				}
> 
> 				cache.put(String.valueOf(i), bf.toString());
> 			}
> 			long end = System.currentTimeMillis();
> 			System.out.println("=== Execution time is " + (end - start) + " ms.");
> 		}
> 	}
> }
> 
> 
> 
> 
> --
> Sent from: http://apache-ignite-users.70518.x6.nabble.com/
> 

-- 
Regards, Konstantin.

Re: Very low performance

Posted by Gaurav Bajaj <ga...@gmail.com>.
Hello Dmitry,

Try using data streamer to add data in cache using parallel threads.
It will give huge performance boost. Also make sure you understand
walSetting=BACKGROUND implications before relaying on it.

Thanks,
Gaurav

On Wed, Oct 4, 2017 at 3:43 PM, Dmitry Pryakhin <dmitry.pryakhin@nextmail.ru
> wrote:

> Hi Alexey,
>
> As Ilya suggested, setting walMode = BACKGROUND has brought performance
> into
> the area of expected values. My code that populates Postgre is below.
> Thanks
> a log for your reply.
>
> public class PopulatePostgre {
>         private static final char[] LETTERS = {'a', 'b', 'c', 'd', 'e',
> 'f', 'g',
> 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'x',
> 'y', 'z'};
>         private static final int L_SIZE = LETTERS.length;
>
>         public static void main(String argv[]) throws Exception {
>                 int idx0 = 0, idx1 = 0, idx2 = 0;
>                 StringBuilder bf = new StringBuilder();
>
>                 Class.forName("org.postgresql.Driver");
>                 try (Connection con =
> DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres",
> "postgres", "postgres")) {
>                         con.setAutoCommit(false);
>                         try (Statement st = con.createStatement()) {
>                                 st.execute("create table test(kkey
> varchar(10) primary key, val
> varchar(200))");
>                                 con.commit();
>                         }
>
>                         try (PreparedStatement pst =
> con.prepareStatement("insert into test(kkey,
> val) values(?, ?)")) {
>                                 long start = System.currentTimeMillis();
>                                 for (int i = 0; i < 10000; i++) {
>                                         bf.setLength(0);
>                                         bf.append(LETTERS[idx0]).
> append(LETTERS[idx1]).append(LETTERS[idx2]);
>
>                                         if (++idx2 == L_SIZE) {
>                                                 idx2 = 0;
>                                                 if (++idx1 == L_SIZE) {
>                                                         idx1 = 0;
>                                                         if (++idx0 ==
> L_SIZE) {
>                                                                 idx0 = 0;
>                                                         }
>                                                 }
>                                         }
>
>                                         pst.setString(1,
> String.valueOf(i));
>                                         pst.setString(2, bf.toString());
>                                         pst.executeUpdate();
>                                         con.commit();
>                                 }
>                                 long end = System.currentTimeMillis();
>                                 System.out.println("=== Execution time is
> " + (end - start) + " ms.");
>                         }
>                 }
>         }
> }
>
>
>
>
> --
> Sent from: http://apache-ignite-users.70518.x6.nabble.com/
>

Re: Very low performance

Posted by Dmitry Pryakhin <dm...@nextmail.ru>.
Hi Alexey, 

As Ilya suggested, setting walMode = BACKGROUND has brought performance into
the area of expected values. My code that populates Postgre is below. Thanks
a log for your reply.

public class PopulatePostgre {
	private static final char[] LETTERS = {'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'x',
'y', 'z'};
	private static final int L_SIZE = LETTERS.length;
	
	public static void main(String argv[]) throws Exception {
		int idx0 = 0, idx1 = 0, idx2 = 0;
		StringBuilder bf = new StringBuilder();
		
		Class.forName("org.postgresql.Driver");
		try (Connection con =
DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres",
"postgres", "postgres")) {
			con.setAutoCommit(false);
			try (Statement st = con.createStatement()) {
				st.execute("create table test(kkey varchar(10) primary key, val
varchar(200))");
				con.commit();
			}
			
			try (PreparedStatement pst = con.prepareStatement("insert into test(kkey,
val) values(?, ?)")) {
				long start = System.currentTimeMillis();
				for (int i = 0; i < 10000; i++) {
					bf.setLength(0);
					bf.append(LETTERS[idx0]).append(LETTERS[idx1]).append(LETTERS[idx2]);
					
					if (++idx2 == L_SIZE) {
						idx2 = 0;
						if (++idx1 == L_SIZE) {
							idx1 = 0;
							if (++idx0 == L_SIZE) {
								idx0 = 0;
							}
						}
					}

					pst.setString(1, String.valueOf(i));
					pst.setString(2, bf.toString());
					pst.executeUpdate();
					con.commit();
				}
				long end = System.currentTimeMillis();
				System.out.println("=== Execution time is " + (end - start) + " ms.");
			}
		}
	}
}




--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/

Re: Very low performance

Posted by Alexey Goncharuk <al...@gmail.com>.
Hi,

In default WAL mode each cache put() is fsynced to the disk, which causes a
major performance penalty.
You can do either: batch your updates using putAll or using a data streamer.

BTW, how do you insert data to postgres?

2017-10-04 14:32 GMT+03:00 Dmitry Pryakhin <dm...@nextmail.ru>:

> Dear colleagues,
>
> I consider using Ignite, and now do some testing. Cache performance test
> has
> shown ridiculously low performance. Same test was done against PostgreSQL
> on
> the same computer, with much better result. Now I'm trying to figure out if
> it's supposed to work that way, or maybe I've done something wrong. Could
> anyone verify my tesging approach and configuration? Details are below.
>
>
> Task: insert 10000 items; keys and values are strings.
>
> Environment: Intel, Windows, Oracle JRE 1.8.
>
> Configuration 1: Ignite 2.2, 1 server node and 1 client node deployed on
> the
> same computer, both have default configuration. In-memory cache.
> Average execution time = 1.95 sec.
>
> Configuration 2: Ignite 2.2, 1 server node and 1 client node, deployed on
> the same computer. A persistent cache was set up in the server
> configuration
> file.
> Best execution time = 510 sec.
>
> Configuration 3: PosgtreSQL, deployed on the same computer as the client.
> Average execution time = 3 sec.
>
> Server configuration file for configuration 2:
> <?xml version="1.0" encoding="UTF-8"?>
> <beans xmlns="http://www.springframework.org/schema/beans"
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>        xsi:schemaLocation="
>        http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans.xsd">
>
>     <bean id="grid.cfg"
> class="org.apache.ignite.configuration.IgniteConfiguration">
>           <property name="persistentStoreConfiguration">
>             <bean
> class="org.apache.ignite.configuration.PersistentStoreConfiguration"/>
>           </property>
>           <property name="cacheConfiguration">
>                 <bean class="org.apache.ignite.configuration.
> CacheConfiguration">
>                         <property name="name" value="CacheOne"/>
>                 </bean>
>           </property>
>     </bean>
> </beans>
>
>
> Client code:
>
> public class PopulateMap {
>         private static final char[] LETTERS = {'a', 'b', 'c', 'd', 'e',
> 'f', 'g',
> 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'x',
> 'y', 'z'};
>         private static final int L_SIZE = LETTERS.length;
>
>         public static void main(String argv[]) throws Exception {
>                 Ignition.setClientMode(true);
>
>                 int idx0 = 0, idx1 = 0, idx2 = 0;
>                 StringBuilder bf = new StringBuilder();
>
>                 try (Ignite ignite = Ignition.start("default-config.xml"))
> {
>                         ignite.active(true);
>
>                         CacheConfiguration<String, String> cacheConf = new
> CacheConfiguration<>("CacheOne");
>                         Cache<String, String> cache =
> ignite.getOrCreateCache(cacheConf);
>                         cache.clear();
>
>                         long start = System.currentTimeMillis();
>
>                         for (int i = 1; i <= 10000; i++) {
>                                 bf.setLength(0);
>                                 bf.append(LETTERS[idx0]).
> append(LETTERS[idx1]).append(LETTERS[idx2]);
>
>                                 if (++idx2 == L_SIZE) {
>                                         idx2 = 0;
>                                         if (++idx1 == L_SIZE) {
>                                                 idx1 = 0;
>                                                 if (++idx0 == L_SIZE) {
>                                                         idx0 = 0;
>                                                 }
>                                         }
>                                 }
>
>                                 cache.put(String.valueOf(i),
> bf.toString());
>                         }
>                         long end = System.currentTimeMillis();
>                         System.out.println("=== Execution time is " + (end
> - start) + " ms.");
>                 }
>         }
> }
>
>
>
>
> --
> Sent from: http://apache-ignite-users.70518.x6.nabble.com/
>