持久性和裂脑场景
Persistence and Split brains Scenario
1.How ignite 是否在集群模式下处理裂脑场景?
2.Incase 的 putAll,它是为每个条目命中持久存储还是立即将所有内容放入存储?
3.How 如果我们设置批量大小,putAll 是否适用于持久存储?
4.In分区备份的情况下,数据移动的顺序是什么? primary->backup->persistence 或 primary->backup 同时异步进入持久化?
5.If在持久性存储中完成了更新,必须做什么才能在不重新加载的情况下将其反映在缓存中?(如何处理后端更新)
6.On 在后端进行更新并反映缓存中的更改如果我们使用 loadCache 重新加载缓存,则更改不会在缓存中更新,或者如果我们直接使用 get() 也会更新没有反映出来。只有在清除缓存一次然后调用 loadcache 或 get api 后才会反映更新。这是重新加载缓存的正确方法吗?
Person p1 = new Person(1, "Benakaraj", "KS", 11, 26, 1000);
Person p2 = new Person(2, "Ashwin", "Konale", 13, 26, 10000);
Connection con = null;
Statement stmt = null;
con = ds.getConnection();
stmt = con.createStatement();
String sql =
"create table Person(per_id int,name varchar(20),last_name varchar(20),org_id int,age int,salary REAL,primary key(per_id))";
stmt.executeUpdate(sql);
ROCCacheConfiguration<Integer, Person> pesonConfig = new ROCCacheConfiguration<>();
pesonConfig.setName("bkendupdtCache");
pesonConfig.setCacheMode(CacheMode.PARTITIONED);
JdbcType jdbcType = new JdbcType();
jdbcType.setCacheName("bkendupdtCache");
jdbcType.setDatabaseSchema("ROC4Test");
jdbcType.setDatabaseTable("Person");
jdbcType.setKeyType(Integer.class);
jdbcType.setValueType(Person.class);
// Key fields for PERSON.
Collection<JdbcTypeField> keys = new ArrayList<>();
keys.add(new JdbcTypeField(Types.INTEGER, "per_id", int.class, "perId"));
jdbcType.setKeyFields(keys.toArray(new JdbcTypeField[keys.size()]));
// Value fields for PERSON.
Collection<JdbcTypeField> vals = new ArrayList<>();
vals.add(new JdbcTypeField(Types.INTEGER, "per_id", int.class, "perId"));
vals.add(new JdbcTypeField(Types.VARCHAR, "name", String.class, "name"));
vals.add(new JdbcTypeField(Types.VARCHAR, "last_name", String.class, "lastName"));
vals.add(new JdbcTypeField(Types.INTEGER, "org_id", int.class, "orgId"));
vals.add(new JdbcTypeField(Types.INTEGER, "age", int.class, "age"));
vals.add(new JdbcTypeField(Types.FLOAT, "salary", Float.class, "salary"));
jdbcType.setValueFields(vals.toArray(new JdbcTypeField[vals.size()]));
Collection<JdbcType> jdbcTypes = new ArrayList<>();
jdbcTypes.add(jdbcType);
CacheJdbcPojoStoreFactory<Integer, Organization> cacheJdbcdPojoStorefactory4 =
context.getBean(CacheJdbcPojoStoreFactory.class);
cacheJdbcdPojoStorefactory4.setTypes(jdbcTypes.toArray(new JdbcType[jdbcTypes.size()]));
pesonConfig.setCacheStoreFactory((Factory<? extends CacheStore<Integer, Person>>) cacheJdbcdPojoStorefactory4);
pesonConfig.setReadThrough(true);
pesonConfig.setWriteThrough(true);
ROCCache<Integer, Person> personCache2 = rocCachemanager.createCache(pesonConfig);
personCache2.put(1, p1);
personCache2.put(2, p2);
assertEquals(personCache2.get(2).getName(), "Ashwin");
sql = assertEquals(personCache2.get(2).getName(), "Abhi");
"update Person set name='Abhi' where per_id=2";
stmt.execute(sql);
//fails and asks for assertion with the stale value
personCache.loadcache(null);
assertEquals(personCache2.get(2).getName(), "Abhi");
//works fine
personCache2.clear(2);
assertEquals(personCache2.get(2).getName(), "Abhi");
//works fine
personCache2.clear();
personCache2.loadcache(null);
assertEquals(personCache2.get(2).getName(), "Abhi");
sql = "drop table Person";
stmt.executeUpdate(sql);
con.close();
stmt.close();
rocCachemanager.destroyCache("bkendupdtCache");
默认情况下你会得到两个独立的集群,它们永远不会再相互连接(否则可能会出现数据不一致)。您将必须手动停止其中一个集群并在网络恢复后重新启动。但是,自动解析可以作为插件实现。例如,GridGain 提供开箱即用的功能:https://gridgain.readme.io/docs/network-segmentation
Ignites 尝试尽可能减少持久性存储调用。如果您的存储支持批量读取和写入,那么在实现 loadAll
、writeAll
和 removeAll
方法时最好利用这一点。
批量更新操作将根据节点映射拆分批量。批处理的每个部分将立即保存在相应的主节点上。
存储与主节点自动更新(如果写入存储失败,则不会更新缓存,反之亦然)。默认情况下,备份在后台异步更新。
如果可能,您应该避免这种情况并将 Ignite 视为主要数据存储,在后端有一个可选存储(即始终通过 Ignite API 访问数据)。没有简单的方法将数据库更新传播到 Ignite。
您可以使用 clear/clearAll
方法使条目无效,或使用 loadAll
方法重新加载它们。另一种选择是使用过期:https://apacheignite.readme.io/docs/expiry-policies
1.How ignite 是否在集群模式下处理裂脑场景?
2.Incase 的 putAll,它是为每个条目命中持久存储还是立即将所有内容放入存储?
3.How 如果我们设置批量大小,putAll 是否适用于持久存储?
4.In分区备份的情况下,数据移动的顺序是什么? primary->backup->persistence 或 primary->backup 同时异步进入持久化?
5.If在持久性存储中完成了更新,必须做什么才能在不重新加载的情况下将其反映在缓存中?(如何处理后端更新)
6.On 在后端进行更新并反映缓存中的更改如果我们使用 loadCache 重新加载缓存,则更改不会在缓存中更新,或者如果我们直接使用 get() 也会更新没有反映出来。只有在清除缓存一次然后调用 loadcache 或 get api 后才会反映更新。这是重新加载缓存的正确方法吗?
Person p1 = new Person(1, "Benakaraj", "KS", 11, 26, 1000);
Person p2 = new Person(2, "Ashwin", "Konale", 13, 26, 10000);
Connection con = null;
Statement stmt = null;
con = ds.getConnection();
stmt = con.createStatement();
String sql =
"create table Person(per_id int,name varchar(20),last_name varchar(20),org_id int,age int,salary REAL,primary key(per_id))";
stmt.executeUpdate(sql);
ROCCacheConfiguration<Integer, Person> pesonConfig = new ROCCacheConfiguration<>();
pesonConfig.setName("bkendupdtCache");
pesonConfig.setCacheMode(CacheMode.PARTITIONED);
JdbcType jdbcType = new JdbcType();
jdbcType.setCacheName("bkendupdtCache");
jdbcType.setDatabaseSchema("ROC4Test");
jdbcType.setDatabaseTable("Person");
jdbcType.setKeyType(Integer.class);
jdbcType.setValueType(Person.class);
// Key fields for PERSON.
Collection<JdbcTypeField> keys = new ArrayList<>();
keys.add(new JdbcTypeField(Types.INTEGER, "per_id", int.class, "perId"));
jdbcType.setKeyFields(keys.toArray(new JdbcTypeField[keys.size()]));
// Value fields for PERSON.
Collection<JdbcTypeField> vals = new ArrayList<>();
vals.add(new JdbcTypeField(Types.INTEGER, "per_id", int.class, "perId"));
vals.add(new JdbcTypeField(Types.VARCHAR, "name", String.class, "name"));
vals.add(new JdbcTypeField(Types.VARCHAR, "last_name", String.class, "lastName"));
vals.add(new JdbcTypeField(Types.INTEGER, "org_id", int.class, "orgId"));
vals.add(new JdbcTypeField(Types.INTEGER, "age", int.class, "age"));
vals.add(new JdbcTypeField(Types.FLOAT, "salary", Float.class, "salary"));
jdbcType.setValueFields(vals.toArray(new JdbcTypeField[vals.size()]));
Collection<JdbcType> jdbcTypes = new ArrayList<>();
jdbcTypes.add(jdbcType);
CacheJdbcPojoStoreFactory<Integer, Organization> cacheJdbcdPojoStorefactory4 =
context.getBean(CacheJdbcPojoStoreFactory.class);
cacheJdbcdPojoStorefactory4.setTypes(jdbcTypes.toArray(new JdbcType[jdbcTypes.size()]));
pesonConfig.setCacheStoreFactory((Factory<? extends CacheStore<Integer, Person>>) cacheJdbcdPojoStorefactory4);
pesonConfig.setReadThrough(true);
pesonConfig.setWriteThrough(true);
ROCCache<Integer, Person> personCache2 = rocCachemanager.createCache(pesonConfig);
personCache2.put(1, p1);
personCache2.put(2, p2);
assertEquals(personCache2.get(2).getName(), "Ashwin");
sql = assertEquals(personCache2.get(2).getName(), "Abhi");
"update Person set name='Abhi' where per_id=2";
stmt.execute(sql);
//fails and asks for assertion with the stale value
personCache.loadcache(null);
assertEquals(personCache2.get(2).getName(), "Abhi");
//works fine
personCache2.clear(2);
assertEquals(personCache2.get(2).getName(), "Abhi");
//works fine
personCache2.clear();
personCache2.loadcache(null);
assertEquals(personCache2.get(2).getName(), "Abhi");
sql = "drop table Person";
stmt.executeUpdate(sql);
con.close();
stmt.close();
rocCachemanager.destroyCache("bkendupdtCache");
默认情况下你会得到两个独立的集群,它们永远不会再相互连接(否则可能会出现数据不一致)。您将必须手动停止其中一个集群并在网络恢复后重新启动。但是,自动解析可以作为插件实现。例如,GridGain 提供开箱即用的功能:https://gridgain.readme.io/docs/network-segmentation
Ignites 尝试尽可能减少持久性存储调用。如果您的存储支持批量读取和写入,那么在实现
loadAll
、writeAll
和removeAll
方法时最好利用这一点。批量更新操作将根据节点映射拆分批量。批处理的每个部分将立即保存在相应的主节点上。
存储与主节点自动更新(如果写入存储失败,则不会更新缓存,反之亦然)。默认情况下,备份在后台异步更新。
如果可能,您应该避免这种情况并将 Ignite 视为主要数据存储,在后端有一个可选存储(即始终通过 Ignite API 访问数据)。没有简单的方法将数据库更新传播到 Ignite。
您可以使用
clear/clearAll
方法使条目无效,或使用loadAll
方法重新加载它们。另一种选择是使用过期:https://apacheignite.readme.io/docs/expiry-policies