@aloxc
2017-08-28T03:41:54.000000Z
字数 31198
阅读 952
ignite cache cachestore mapreduce
随着研究ignite的深入,发现ignite还是很多坑(我说的坑不是指bug,是指一些难以理解的概念或者范围)。
对于初学者来说,这些坑比较难理解,或者需要经过大量试验后才能理解其中的含义。
1、不知道什么代码是在客户端执行,什么代码在服务端执行,概括下就是不知道什么代码充当map功能,什么代码充当reduce功能。
这个问题我举个例子,我们在客户端的需要读取缓存表person中的相关数据的时候,可能是通过BinaryObject来筛选数据,如下代码
IgniteCache<Long, BinaryObject> biCache = cache.withKeepBinary();ScanQuery<Long, BinaryObject> scan = new ScanQuery<>(new IgniteBiPredicate<Long, BinaryObject>() {@Overridepublic boolean apply(Long id, BinaryObject person) {boolean isTrue = person.<String>field("firstName").equals("Robert");if (isTrue) {System.out.println("找到结果 id = " + id + "\t" + person);} else {System.out.println(">>错误结果 id = " + id);}return isTrue;}});QueryCursor cursor = biCache.query(scan);logger.error("执行二进制查找结果" + cursor.getAll());
代码中apply方法里面代码是在服务端执行(每个服务端都在执行该方法,但是返回的数据不一致)的,其它的代码是在客户端执行(reduce)的。
2、关于配置文件不生效的问题
这个问题主要是没搞明白客户端和服务端使用的可能不是同一个配置文件,服务端通常是$IGNITE_HOME/config/default_config.xml,而客户端可能是我们运行代码的时候指定的配置文件,如Ignite ignite = Ignition.start("com/github/aloxc/ignite/datagrid/store/CacheLoadOnlyStoreExampleUsingMysql.xml",如果是这样的情况,就算我们把我们的代码及配置文件打成jar包放到服务端,服务端依然不解析这个问题的。这个原因是由于服务端根本就不执行Ignite ignite = Ignition.start("com/github/aloxc/ignite/datagrid/store/CacheLoadOnlyStoreExampleUsingMysql.xml"这句话。说白了还是没搞清楚第一个问题。
3、关于使用cacheStore的时候初始化从别的资源加载数据后出现的问题
@Overridepublic void loadCache(final IgniteBiInClosure<Long, Person> igniteBiInClosure, @Nullable Object... objects) throws CacheLoaderException {StringBuffer sql = new StringBuffer();sql.append("SELECT `id`,");sql.append("`first_name`, `last_name`");sql.append(" FROM `").append(TABLE_NAME).append("` WHERE 1 = 1");sql.append(" ORDER BY `id` DESC");logger.error("beanFactory 是否为空 " + (factory == null));logger.error("spring jdbc Template 是否为空 " + (this.getJdbcTemplate() == null));List<Person> list = this.getJdbcTemplate().query(sql.toString(), new RowMapper<Person>() {@Overridepublic Person mapRow(ResultSet rs, int i) throws SQLException {Person person = new Person();person.setId(rs.getLong("id"));person.setFirstName(rs.getString("first_name"));person.setLastName(rs.getString("last_name"));logger.error("从数据库加载数据" + person);return person;}});for(Person person : list){igniteBiInClosure.apply(person.getId(),person);}}
假定如下场景:数据库中的tb_person表中有5条Person数据;有Person这个bean,字段分别是id,firstName,lastName;服务端有2个节点。
那么在服务端的2个节点上会输出5条[从数据库加载数据****]这样的日志的,也就是全部的5条数据全都缓存到2个服务端节点上了。
接下来我们通过客户端代码读取id<10的数据(全部的5条),我们可以通过BinaryObject来读取所有数据
IgniteCache<Long, BinaryObject> biCache = cache.withKeepBinary();ScanQuery<Long, BinaryObject> scan = new ScanQuery<>(new IgniteBiPredicate<Long, BinaryObject>() {@Overridepublic boolean apply(Long id, BinaryObject person) {System.out.println("找到结果 id = " + id + "\t" + person);return true;}});QueryCursor cursor = biCache.query(scan);logger.error("执行二进制查找结果" + cursor.getAll());
可以在每个服务段节点上看到输出5条数据,而客户端也只有5条,这就是客户端做了reduce了
4、关于配置h2数据的问题
ignite默认是使用h2嵌入式数据库来“存储”缓存的,这个解释不知道正确不正确,如下面操作错误的时候的异常
Caused by: javax.cache.CacheException: Failed to execute map query on the node: 16e9ded4-efd5-47c1-b9f7-00d09297b93f, class org.apache.ignite.IgniteCheckedException:Failed to parse SQL query: SELECT"cacheOnlyUsingMysql".PERSON._KEY __C0,"cacheOnlyUsingMysql".PERSON._VAL __C1,ID __C2FROM "cacheOnlyUsingMysql".PERSONWHERE ID < 10ORDER BY 3 DESC LIMIT 2 + 2at org.apache.ignite.internal.processors.query.h2.twostep.GridReduceQueryExecutor.fail(GridReduceQueryExecutor.java:277)at org.apache.ignite.internal.processors.query.h2.twostep.GridReduceQueryExecutor.onFail(GridReduceQueryExecutor.java:267)at org.apache.ignite.internal.processors.query.h2.twostep.GridReduceQueryExecutor.onMessage(GridReduceQueryExecutor.java:248)at org.apache.ignite.internal.processors.query.h2.twostep.GridReduceQueryExecutor$2.onMessage(GridReduceQueryExecutor.java:196)
5、关于在cachestore中使用cache.get(xx)无数据异常
在测试的时候通过cache.get(7L)来读取id=7的person对象,下面的java代码是CacheStore中的load方法:
@Overridepublic Person load(Long id) throws CacheLoaderException {logger.error("从数据库加载数据" + id);long start = System.currentTimeMillis();StringBuffer sql = new StringBuffer();sql.append("SELECT `id`,");sql.append("`first_name`, `last_name`");sql.append(" FROM `").append(TABLE_NAME).append("` WHERE id = ?");Person person = this.getJdbcTemplate().queryForObject(sql.toString(),new CacheLoadOnlyStoreRowMapper<Person>(),id);logger.error("从数据库加载数据花费" + (System.currentTimeMillis() - start) + "毫秒");return person;}public class CacheLoadOnlyStoreRowMapper<T extends Person> implements RowMapper<Person> {private static Log logger = LogFactory.getLog(CacheLoadOnlyStoreRowMapper.class);@Overridepublic Person mapRow(ResultSet rs, int i) throws SQLException {Person person = new Person();person.setId(rs.getLong("id"));person.setFirstName(rs.getString("first_name"));person.setLastName(rs.getString("last_name"));logger.error("从数据库加载数据" + person);return person;}}
数据库中无这条数据,会发生如下异常
[17:33:03,254][SEVERE][sys-#31%null%][GridDhtAtomicCache] <cacheOnlyUsingMysql> Failed processing get request: GridNearSingleGetRequest [futId=1480671238317, key=KeyCacheObjectImpl [val=7, hasValBytes=true], partId=7, flags=1, topVer=AffinityTopologyVersion [topVer=3, minorTopVer=0], subjId=b481c59b-0104-4060-a25d-74e473a98402, taskNameHash=0, accessTtl=-1]class org.apache.ignite.IgniteCheckedException: org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadFromStore(GridCacheStoreManagerAdapter.java:337)at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.load(GridCacheStoreManagerAdapter.java:293)at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadAllFromStore(GridCacheStoreManagerAdapter.java:426)at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadAll(GridCacheStoreManagerAdapter.java:392)at org.apache.ignite.internal.processors.cache.GridCacheAdapter$16.call(GridCacheAdapter.java:1985)at org.apache.ignite.internal.processors.cache.GridCacheAdapter$16.call(GridCacheAdapter.java:1983)at org.apache.ignite.internal.util.IgniteUtils.wrapThreadLoader(IgniteUtils.java:6521)at org.apache.ignite.internal.processors.closure.GridClosureProcessor$2.body(GridClosureProcessor.java:922)at org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:110)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)Caused by: javax.cache.integration.CacheLoaderException: org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0... 12 moreCaused by: org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0at org.springframework.dao.support.DataAccessUtils.requiredSingleResult(DataAccessUtils.java:71)at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:809)at com.github.aloxc.ignite.datagrid.store.CacheOnlyStoreFactoryExampleUsingMysql.load(CacheOnlyStoreFactoryExampleUsingMysql.java:81)at com.github.aloxc.ignite.datagrid.store.CacheOnlyStoreFactoryExampleUsingMysql.load(CacheOnlyStoreFactoryExampleUsingMysql.java:25)at org.apache.ignite.internal.processors.cache.CacheStoreBalancingWrapper.load(CacheStoreBalancingWrapper.java:97)at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadFromStore(GridCacheStoreManagerAdapter.java:326)... 11 more
异常里指明了是期望数据为1,实际返回0条数据,可以这么理解通过sql语句查询mysql数据库中返回0条数据,那不缓存直接返回null就应该可以了,可ignite不这么做直接抛异常,不知道这个是ignite的bug还是有意这样为之。
6、执行缓存查询的时候,查询结果强制转换为不能转换的动异常后调整客户端的代码但是不重启服务端的异常
查询结果强制转换为不能转换的代码及异常堆栈如下
private Person getMaxPerson(){IgniteCache<Long,Person> cache = Ignition.ignite().cache(CACHE_NAME);SqlFieldsQuery query = new SqlFieldsQuery("SELECT * FROM person order by id desc limit 1");QueryCursor<List<?>> cursor = cache.query(query);List<List<?>> list = cursor.getAll();logger.error(list);//list数据格式如下//[[6, Person [id=6, orgId=null, lastName=Leibniz, firstName=Wilhelm, salary=0.0, resume=null], 6, null, null]]Person person = (Person) list.get(0);return person;}
Exception in thread "main" java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.github.aloxc.ignite.model.Personat com.github.aloxc.ignite.datagrid.store.CacheLoadOnlyStoreExampleUsingMysql.getMaxPerson(CacheLoadOnlyStoreExampleUsingMysql.java:131)at com.github.aloxc.ignite.datagrid.store.CacheLoadOnlyStoreExampleUsingMysql.doit(CacheLoadOnlyStoreExampleUsingMysql.java:100)at com.github.aloxc.ignite.datagrid.store.CacheLoadOnlyStoreExampleUsingMysql.main(CacheLoadOnlyStoreExampleUsingMysql.java:48)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
调整为正确代码并且不重启服务端的异常及代码如下
private Person getMaxPerson(){IgniteCache<Long,Person> cache = Ignition.ignite().cache(CACHE_NAME);SqlFieldsQuery query = new SqlFieldsQuery("SELECT * FROM person order by id desc limit 1");QueryCursor<List<?>> cursor = cache.query(query);List<List<?>> list = cursor.getAll();logger.error(list);//list数据格式如下//[[6, Person [id=6, orgId=null, lastName=Leibniz, firstName=Wilhelm, salary=0.0, resume=null], 6, null, null]]Person person = (Person) list.get(0).get(1);return person;}
class org.apache.ignite.IgniteException: Remote job threw user exception (override or implement ComputeTask.result(..) method if you would like to have automatic failover for this exception).at org.apache.ignite.compute.ComputeTaskAdapter.result(ComputeTaskAdapter.java:101)at org.apache.ignite.internal.processors.task.GridTaskWorker$4.apply(GridTaskWorker.java:946)at org.apache.ignite.internal.processors.task.GridTaskWorker$4.apply(GridTaskWorker.java:939)at org.apache.ignite.internal.util.IgniteUtils.wrapThreadLoader(IgniteUtils.java:6553)at org.apache.ignite.internal.processors.task.GridTaskWorker.result(GridTaskWorker.java:939)at org.apache.ignite.internal.processors.task.GridTaskWorker.onResponse(GridTaskWorker.java:810)at org.apache.ignite.internal.processors.task.GridTaskProcessor.processJobExecuteResponse(GridTaskProcessor.java:995)at org.apache.ignite.internal.processors.task.GridTaskProcessor$JobMessageListener.onMessage(GridTaskProcessor.java:1220)at org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1238)at org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:866)at org.apache.ignite.internal.managers.communication.GridIoManager.access$1700(GridIoManager.java:106)at org.apache.ignite.internal.managers.communication.GridIoManager$5.run(GridIoManager.java:829)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)Caused by: class org.apache.ignite.IgniteException: java.lang.NullPointerExceptionat org.apache.ignite.internal.processors.closure.GridClosureProcessor$C2V2.execute(GridClosureProcessor.java:2009)at org.apache.ignite.internal.processors.job.GridJobWorker$2.call(GridJobWorker.java:509)at org.apache.ignite.internal.util.IgniteUtils.wrapThreadLoader(IgniteUtils.java:6521)at org.apache.ignite.internal.processors.job.GridJobWorker.execute0(GridJobWorker.java:503)at org.apache.ignite.internal.processors.job.GridJobWorker.body(GridJobWorker.java:456)at org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:110)at org.apache.ignite.internal.processors.job.GridJobProcessor.processJobExecuteRequest(GridJobProcessor.java:1095)at org.apache.ignite.internal.processors.job.GridJobProcessor$JobExecutionListener.onMessage(GridJobProcessor.java:1766)... 7 moreCaused by: class org.apache.ignite.IgniteException: java.lang.NullPointerExceptionat org.apache.ignite.internal.util.IgniteUtils.convertException(IgniteUtils.java:908)at org.apache.ignite.internal.processors.cache.GridCacheAdapter$LoadCacheJob.localExecute(GridCacheAdapter.java:5758)at org.apache.ignite.internal.processors.cache.GridCacheAdapter$LoadCacheJobV2.localExecute(GridCacheAdapter.java:5802)at org.apache.ignite.internal.processors.cache.GridCacheAdapter$TopologyVersionAwareJob.execute(GridCacheAdapter.java:6473)at org.apache.ignite.compute.ComputeJobAdapter.call(ComputeJobAdapter.java:132)at org.apache.ignite.internal.processors.closure.GridClosureProcessor$C2V2.execute(GridClosureProcessor.java:2006)... 14 moreCaused by: class org.apache.ignite.IgniteCheckedException: java.lang.NullPointerExceptionat org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadCache(GridCacheStoreManagerAdapter.java:538)at org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.localLoadCache(GridDhtCacheAdapter.java:497)at org.apache.ignite.internal.processors.cache.GridCacheProxyImpl.localLoadCache(GridCacheProxyImpl.java:228)at org.apache.ignite.internal.processors.cache.GridCacheAdapter$LoadCacheJob.localExecute(GridCacheAdapter.java:5753)... 18 moreCaused by: javax.cache.integration.CacheLoaderException: java.lang.NullPointerException... 22 moreCaused by: java.lang.NullPointerExceptionat com.github.aloxc.ignite.datagrid.store.CacheOnlyStoreFactoryExampleUsingMysql.loadCache(CacheOnlyStoreFactoryExampleUsingMysql.java:50)at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadCache(GridCacheStoreManagerAdapter.java:512)... 21 more[00:16:01] (err) Failed to execute compound future reducer: GridCompoundFuture [rdc=null, initFlag=1, lsnrCalls=0, done=false, cancelled=false, err=null, futs=[true]]class org.apache.ignite.IgniteCheckedException: java.lang.NullPointerExceptionat org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadCache(GridCacheStoreManagerAdapter.java:538)at org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.localLoadCache(GridDhtCacheAdapter.java:497)at org.apache.ignite.internal.processors.cache.GridCacheProxyImpl.localLoadCache(GridCacheProxyImpl.java:228)at org.apache.ignite.internal.processors.cache.GridCacheAdapter$LoadCacheJob.localExecute(GridCacheAdapter.java:5753)at org.apache.ignite.internal.processors.cache.GridCacheAdapter$LoadCacheJobV2.localExecute(GridCacheAdapter.java:5802)at org.apache.ignite.internal.processors.cache.GridCacheAdapter$TopologyVersionAwareJob.execute(GridCacheAdapter.java:6473)at org.apache.ignite.compute.ComputeJobAdapter.call(ComputeJobAdapter.java:132)at org.apache.ignite.internal.processors.closure.GridClosureProcessor$C2V2.execute(GridClosureProcessor.java:2006)at org.apache.ignite.internal.processors.job.GridJobWorker$2.call(GridJobWorker.java:509)at org.apache.ignite.internal.util.IgniteUtils.wrapThreadLoader(IgniteUtils.java:6521)at org.apache.ignite.internal.processors.job.GridJobWorker.execute0(GridJobWorker.java:503)at org.apache.ignite.internal.processors.job.GridJobWorker.body(GridJobWorker.java:456)at org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:110)at org.apache.ignite.internal.processors.job.GridJobProcessor.processJobExecuteRequest(GridJobProcessor.java:1095)at org.apache.ignite.internal.processors.job.GridJobProcessor$JobExecutionListener.onMessage(GridJobProcessor.java:1766)at org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1238)at org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:866)at org.apache.ignite.internal.managers.communication.GridIoManager.access$1700(GridIoManager.java:106)at org.apache.ignite.internal.managers.communication.GridIoManager$5.run(GridIoManager.java:829)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)Caused by: javax.cache.integration.CacheLoaderException: java.lang.NullPointerException... 22 moreCaused by: java.lang.NullPointerExceptionat com.github.aloxc.ignite.datagrid.store.CacheOnlyStoreFactoryExampleUsingMysql.loadCache(CacheOnlyStoreFactoryExampleUsingMysql.java:50)at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadCache(GridCacheStoreManagerAdapter.java:512)... 21 moreException in thread "main" javax.cache.integration.CacheLoaderException: java.lang.NullPointerExceptionat org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadCache(GridCacheStoreManagerAdapter.java:538)at org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.localLoadCache(GridDhtCacheAdapter.java:497)at org.apache.ignite.internal.processors.cache.GridCacheProxyImpl.localLoadCache(GridCacheProxyImpl.java:228)at org.apache.ignite.internal.processors.cache.GridCacheAdapter$LoadCacheJob.localExecute(GridCacheAdapter.java:5753)at org.apache.ignite.internal.processors.cache.GridCacheAdapter$LoadCacheJobV2.localExecute(GridCacheAdapter.java:5802)at org.apache.ignite.internal.processors.cache.GridCacheAdapter$TopologyVersionAwareJob.execute(GridCacheAdapter.java:6473)at org.apache.ignite.compute.ComputeJobAdapter.call(ComputeJobAdapter.java:132)at org.apache.ignite.internal.processors.closure.GridClosureProcessor$C2V2.execute(GridClosureProcessor.java:2006)at org.apache.ignite.internal.processors.job.GridJobWorker$2.call(GridJobWorker.java:509)at org.apache.ignite.internal.util.IgniteUtils.wrapThreadLoader(IgniteUtils.java:6521)at org.apache.ignite.internal.processors.job.GridJobWorker.execute0(GridJobWorker.java:503)at org.apache.ignite.internal.processors.job.GridJobWorker.body(GridJobWorker.java:456)at org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:110)at org.apache.ignite.internal.processors.job.GridJobProcessor.processJobExecuteRequest(GridJobProcessor.java:1095)at org.apache.ignite.internal.processors.job.GridJobProcessor$JobExecutionListener.onMessage(GridJobProcessor.java:1766)at org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1238)at org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:866)at org.apache.ignite.internal.managers.communication.GridIoManager.access$1700(GridIoManager.java:106)at org.apache.ignite.internal.managers.communication.GridIoManager$5.run(GridIoManager.java:829)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)Caused by: java.lang.NullPointerExceptionat com.github.aloxc.ignite.datagrid.store.CacheOnlyStoreFactoryExampleUsingMysql.loadCache(CacheOnlyStoreFactoryExampleUsingMysql.java:50)at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadCache(GridCacheStoreManagerAdapter.java:512)... 21 more
7、cacheStore的write方法中发生sql异常输出也不报异常,这个貌似是bug了
如下代码
public void write(Cache.Entry<? extends Long, ? extends Person> entry) throws CacheWriterException {logger.error("开始更新数据到数据库中" + entry.getKey()) ;long start = System.currentTimeMillis();long id = entry.getKey();Person p = entry.getValue();StringBuffer sql = new StringBuffer();sql.append("update `").append(TABLE_NAME).append("` set first_name = ? ").append(" , last_name = ? where id = ? ");int result = this.getJdbcTemplate().update(sql.toString(),p.firstName,p.lastName,p.getId());logger.error("更新数据到数据库中,花费" + (System.currentTimeMillis() - start) + "毫秒,影响行数 = " + result);if(result == 0){//是新增数据,需要使用insert语句start = System.currentTimeMillis();sql.delete(0,sql.length() - 1);sql.append("insert into `").append(TABLE_NAME).append(" (`id`,`first_name`,`last_name`) values(?,?,?);");result = this.getJdbcTemplate().update(sql.toString(),p.getId(),p.firstName,p.lastName);logger.error("插入数据到数据库中,花费" + (System.currentTimeMillis() - start) + "毫秒,影响行数 = " + result);}}
注意insert语句的表名前面加了`,而表名后面没有加`,这个语句是不正确的,并且没使用try catch捕获异常,执行测试代码后无异常堆栈的。
下面在执行sql语句的时候加上try catch 后在catch中输出的异常堆栈信息的代码和堆栈信息如下:
public void write(Cache.Entry<? extends Long, ? extends Person> entry) throws CacheWriterException {logger.error("开始更新数据到数据库中" + entry.getKey()) ;long start = System.currentTimeMillis();long id = entry.getKey();Person p = entry.getValue();StringBuffer sql = new StringBuffer();sql.append("update `").append(TABLE_NAME).append("` set first_name = ? ").append(" , last_name = ? where id = ? ");int result = this.getJdbcTemplate().update(sql.toString(),p.firstName,p.lastName,p.getId());logger.error("更新数据到数据库中,花费" + (System.currentTimeMillis() - start) + "毫秒,影响行数 = " + result);if(result == 0){//是新增数据,需要使用insert语句start = System.currentTimeMillis();sql.delete(0,sql.length() - 1);try {sql.append("insert into `").append(TABLE_NAME).append(" (`id`,`first_name`,`last_name`) values(?,?,?);");result = this.getJdbcTemplate().update(sql.toString(),p.getId(),p.firstName,p.lastName);logger.error("插入数据到数据库中,花费" + (System.currentTimeMillis() - start) + "毫秒,影响行数 = " + result);}catch (Exception e){logger.error("发生异常",e);}}}
注意insert语句的表名前面加了`,而表名后面没有加`,这个语句是不正确的,加了catch后的堆栈:
[00:43:03,311][SEVERE][sys-#32%null%][CacheOnlyStoreFactoryExampleUsingMysql] 发生异常org.springframework.dao.TransientDataAccessResourceException: PreparedStatementCallback; SQL [ insert into `ignite_person (`id`,`first_name`,`last_name`) values(?,?,?);]; Parameter index out of range (1 > number of parameters, which is 0).; nested exception is java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:108)at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:657)at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:906)at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:967)at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:977)at com.github.aloxc.ignite.datagrid.store.CacheOnlyStoreFactoryExampleUsingMysql.write(CacheOnlyStoreFactoryExampleUsingMysql.java:107)at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.put(GridCacheStoreManagerAdapter.java:575)at org.apache.ignite.internal.processors.cache.GridCacheMapEntry.innerUpdate(GridCacheMapEntry.java:2425)at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateSingle(GridDhtAtomicCache.java:2252)at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateAllAsyncInternal0(GridDhtAtomicCache.java:1652)at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateAllAsyncInternal(GridDhtAtomicCache.java:1490)at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.processNearAtomicUpdateRequest(GridDhtAtomicCache.java:2950)at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.access$600(GridDhtAtomicCache.java:130)at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache$5.apply(GridDhtAtomicCache.java:268)at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache$5.apply(GridDhtAtomicCache.java:266)at org.apache.ignite.internal.processors.cache.GridCacheIoManager.processMessage(GridCacheIoManager.java:748)at org.apache.ignite.internal.processors.cache.GridCacheIoManager.onMessage0(GridCacheIoManager.java:353)at org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:277)at org.apache.ignite.internal.processors.cache.GridCacheIoManager.access$000(GridCacheIoManager.java:88)at org.apache.ignite.internal.processors.cache.GridCacheIoManager$1.onMessage(GridCacheIoManager.java:231)at org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1238)at org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:866)at org.apache.ignite.internal.managers.communication.GridIoManager.access$1700(GridIoManager.java:106)at org.apache.ignite.internal.managers.communication.GridIoManager$5.run(GridIoManager.java:829)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)Caused by: java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1086)at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)at com.mysql.jdbc.PreparedStatement.checkBounds(PreparedStatement.java:3796)at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3778)at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3823)at com.mysql.jdbc.PreparedStatement.setLong(PreparedStatement.java:3840)at com.mysql.jdbc.PreparedStatement.setObject(PreparedStatement.java:4037)at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:401)at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:233)at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:164)at org.springframework.jdbc.core.ArgumentPreparedStatementSetter.doSetValue(ArgumentPreparedStatementSetter.java:66)at org.springframework.jdbc.core.ArgumentPreparedStatementSetter.setValues(ArgumentPreparedStatementSetter.java:47)at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:911)at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:906)at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:641)... 25 more[00:43:03] Topology snapshot [ver=4, servers=2, clients=0, CPUs=2, heap=2.0GB]^C[00:43:34] Ignite node stopped OK [uptime=00:01:06:517]
8、关于cache.getOrCreateCache(CacheConfigure config)和cache.getOrCreateCache(String cacheName)的区别
当一个缓存名称xxx在没有使用cacheConfigure到缓存中的时候,正常的put和get没问题,但是如果使用sql查询会发生异常,堆栈信息如下
javax.cache.CacheException: class org.apache.ignite.internal.processors.query.IgniteSQLException: Failed to parse query: select concat(p.name, '----', p.resume) as info from Person as p where id=1at org.apache.ignite.internal.processors.cache.IgniteCacheProxy.query(IgniteCacheProxy.java:807)at org.apache.ignite.internal.processors.cache.IgniteCacheProxy.query(IgniteCacheProxy.java:765)at com.github.aloxc.ignite.datagrid.person.PersonCacheTest.test2(PersonCacheTest.java:91)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)at org.junit.runners.ParentRunner.run(ParentRunner.java:363)at org.junit.runner.JUnitCore.run(JUnitCore.java:137)at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)Caused by: class org.apache.ignite.internal.processors.query.IgniteSQLException: Failed to parse query: select concat(p.name, '----', p.resume) as info from Person as p where id=1at org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.queryDistributedSqlFields(IgniteH2Indexing.java:1293)at org.apache.ignite.internal.processors.query.GridQueryProcessor$5.applyx(GridQueryProcessor.java:1815)at org.apache.ignite.internal.processors.query.GridQueryProcessor$5.applyx(GridQueryProcessor.java:1813)at org.apache.ignite.internal.util.lang.IgniteOutClosureX.apply(IgniteOutClosureX.java:36)at org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuery(GridQueryProcessor.java:2293)at org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:1820)at org.apache.ignite.internal.processors.cache.IgniteCacheProxy.query(IgniteCacheProxy.java:795)... 24 moreCaused by: org.h2.jdbc.JdbcSQLException: Table "PERSON" not found; SQL statement:select concat(p.name, '----', p.resume) as info from Person as p where id=1 [42102-195]at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)at org.h2.message.DbException.get(DbException.java:179)at org.h2.message.DbException.get(DbException.java:155)at org.h2.command.Parser.readTableOrView(Parser.java:5506)at org.h2.command.Parser.readTableFilter(Parser.java:1260)at org.h2.command.Parser.parseSelectSimpleFromPart(Parser.java:1940)at org.h2.command.Parser.parseSelectSimple(Parser.java:2089)at org.h2.command.Parser.parseSelectSub(Parser.java:1934)at org.h2.command.Parser.parseSelectUnion(Parser.java:1749)at org.h2.command.Parser.parseSelect(Parser.java:1737)at org.h2.command.Parser.parsePrepared(Parser.java:448)at org.h2.command.Parser.parse(Parser.java:320)at org.h2.command.Parser.parse(Parser.java:292)at org.h2.command.Parser.prepareCommand(Parser.java:257)at org.h2.engine.Session.prepareLocal(Session.java:573)at org.h2.engine.Session.prepareCommand(Session.java:514)at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1204)at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:73)at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:288)at org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.prepareStatement(IgniteH2Indexing.java:398)at org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.queryDistributedSqlFields(IgniteH2Indexing.java:1273)... 30 more
但如果已经使用CacheConfigure初始化过缓存后再使用ignite.getOrCreateCache(cacheName)后通过sql查询不会发生异常,我估计这个原因是由于需要做sql查询的时候没定义indexedTypes
IgniteCache<Integer, Person> cache =IgniteCache<Integer, Person> cacheByName= ignite.getOrCreateCache(CACHE_NAME);QueryCursor<Cache.Entry<Integer, Person>> textQueryR = cacheByName.query(textQuery);for (Cache.Entry entry : textQueryR.getAll()){System.out.println("信息:" + entry);}
通过两段测试代码可以下这样的结论,在CacheStore的所有方法中需要自己捕获除CacheStore接口类中的方法定义上的异常,否则可能会出现一些预料外的情况。
最新和ignite耗上了,主要是耗在cachestore,
做个广告,我家媳妇是做翡翠生意的,如有需要购买翡翠的请加微信yaoyfc,
或者通过二维码扫描,保证一手A货,价格很实惠。
