使用自定义缓存模板时,无法通过关联键查询缓存



我注意到,当我查询使用自定义缓存模板创建的缓存并在 WHERE 子句中包含缓存的亲和键时,没有返回任何结果。

我正在运行具有以下配置的 Ignite 2.5:

<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="cacheConfiguration"> 
<list> 
<bean id="cache-template-bean" abstract="true" class="org.apache.ignite.configuration.CacheConfiguration"> 
<property name="name" value="myCacheTemplate*"/> 
<property name="cacheMode" value="PARTITIONED" /> 
</bean> 
</list> 
</property> 
</bean>

这是我的测试代码。该代码创建 3 个缓存。第一个是"根"缓存,它定义了其他缓存的共置。另外两个是由根键共置的缓存。第一个共置缓存 (colocated_default( 使用 PARTITIONED 模板并按预期工作。第二个 (colocated_custom( 使用在上述配置中创建的"myCacheTemplate"。我在每个缓存中插入一个缓存条目,其中共置缓存中的条目具有与根缓存条目的键相等的关联键。

然后,我查询缓存。我首先运行一个查询以确保每个缓存中都有一个条目。然后,我为每个键运行查询,其中亲和键等于插入记录的亲和键。对我来说,结果表明我能够从两个分区缓存中按相关性中进行选择,但没有得到"colocated_custom"缓存的结果。这是代码:

/**
* Test which shows that creating a cache with a custom cache configuration template doesn't allow
* for SQL queries to use an affinity key in the WHERE clause.
*/
public class App {
public static void main(String[] args) {
// Start Ignite.
Ignition.setClientMode(true);
final Ignite ignite = Ignition.start(new IgniteConfiguration());
// Create caches. Create a root entity, and two entities which are colocated by the root's ID.
// One uses the custom cache template and one just uses the PARTITIONED template.
final List<StringBuilder> createTableStringBuilders = new ArrayList<>();
final StringBuilder createRoot = new StringBuilder();
createRoot.append("CREATE TABLE IF NOT EXISTS root (n");
createRoot.append("  "key" VARCHAR(24) NOT NULL,n");
createRoot.append("  "data" VARCHAR(100),n");
createRoot.append("  PRIMARY KEY("key"))n");
createRoot.append(
"WITH "template=PARTITIONED, affinity_key=key, cache_name=root, value_type=root";");
createTableStringBuilders.add(createRoot);
final StringBuilder createColocatedDefault = new StringBuilder();
createColocatedDefault.append("CREATE TABLE IF NOT EXISTS colocated_default (n");
createColocatedDefault.append("  "root_key" VARCHAR(24) NOT NULL,n");
createColocatedDefault.append("  "key" VARCHAR(24) NOT NULL,n");
createColocatedDefault.append("  "data" VARCHAR(100),n");
createColocatedDefault.append("  PRIMARY KEY("root_key", "key"))n");
createColocatedDefault.append(
"WITH "template=PARTITIONED, affinity_key=root_key, cache_name=colocated_default, key_type=colocated_default_key, value_type=colocated_default";");
createTableStringBuilders.add(createColocatedDefault);
final StringBuilder createColocatedCustom = new StringBuilder();
createColocatedCustom.append("CREATE TABLE IF NOT EXISTS colocated_custom (n");
createColocatedCustom.append("  "root_key" VARCHAR(24) NOT NULL,n");
createColocatedCustom.append("  "key" VARCHAR(24) NOT NULL,n");
createColocatedCustom.append("  "data" VARCHAR(100),n");
createColocatedCustom.append("  PRIMARY KEY("root_key", "key"))n");
createColocatedCustom.append(
"WITH "template=myCacheTemplate, affinity_key=root_key, cache_name=colocated_custom, key_type=colocated_custom_key, value_type=colocated_custom";");
createTableStringBuilders.add(createColocatedCustom);
try (Connection connection =
DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1:10800"))
{
for (final StringBuilder createTableStringBuilder : createTableStringBuilders) {
try (PreparedStatement createTableStatement =
connection.prepareStatement(createTableStringBuilder.toString()))
{
System.out.println(createTableStringBuilder.toString());
createTableStatement.execute();
System.out.println();
}
}
}
catch (final SQLException e) {
throw new AssertionError(e);
}
// Create the root entity.
final BinaryObject root1 = ignite.binary().builder("root")
.setField("key", "1")
.setField("data", "Data for 1")
.build();
System.out.println("Inserting into "root": ["1", " + root1 + "]");
ignite.cache("root").withKeepBinary().put("1", root1);
// Create the colocated entity which uses the PARTITIONED template.
final BinaryObject colocatedDefault1 = ignite.binary().builder("colocated_default")
.setField("root_key", "1")
.setField("key", "2")
.build();
final BinaryObject colocatedDefault1Key = ignite.binary().builder("colocated_default_key")
.setField("root_key", "1")
.setField("key", "2")
.build();
System.out.println("Inserting into "colocated_default": [" + colocatedDefault1Key + ", " +
colocatedDefault1 + "]");
ignite.cache("colocated_default").withKeepBinary().put(colocatedDefault1Key,
colocatedDefault1);
// Create the colocated entity which uses the custom template.
final BinaryObject colocatedCustom1 = ignite.binary().builder("colocated_custom")
.setField("root_key", "1")
.setField("key", "3")
.build();
final BinaryObject colocatedCustom1Key = ignite.binary().builder("colocated_custom_key")
.setField("root_key", "1")
.setField("key", "3")
.build();
System.out.println("Inserting into "colocated_custom": [" + colocatedCustom1Key + ", " +
colocatedCustom1 + "]");
ignite.cache("colocated_custom").withKeepBinary().put(colocatedCustom1Key,
colocatedCustom1);
// SELECT COUNT(*) on all caches to ensure data exists.
System.out.println();
final List<String> selectAllStrings = new ArrayList<>();
selectAllStrings.add("SELECT COUNT(*) FROM root;");
selectAllStrings.add("SELECT COUNT(*) FROM colocated_default;");
selectAllStrings.add("SELECT COUNT(*) FROM colocated_custom;");
try (Connection connection =
DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1:10800"))
{
for (final String selectAllString : selectAllStrings) {
try (PreparedStatement selectAllStatement =
connection.prepareStatement(selectAllString))
{
System.out.println(selectAllString);
selectAllStatement.execute();
final ResultSet resultSet = selectAllStatement.getResultSet();
resultSet.next();
System.out.println(resultSet.getInt(1));
System.out.println();
}
}
}
catch (final SQLException e) {
throw new AssertionError(e);
}
// SELECT COUNT(*) with affinity key in WHERE clause.
final List<String> selectWhereStrings = new ArrayList<>();
// Returns 1.
selectWhereStrings.add("SELECT COUNT(*) FROM root WHERE "key" = '1';");
// Returns 1.
selectWhereStrings.add("SELECT COUNT(*) FROM colocated_default WHERE "root_key" = '1';");
// Returns 0.
selectWhereStrings.add("SELECT COUNT(*) FROM colocated_custom WHERE "root_key" = '1';");
try (Connection connection =
DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1:10800"))
{
for (final String selectWhereString : selectWhereStrings) {
try (PreparedStatement selectWhereStatement =
connection.prepareStatement(selectWhereString))
{
System.out.println(selectWhereString);
selectWhereStatement.execute();
final ResultSet resultSet = selectWhereStatement.getResultSet();
resultSet.next();
System.out.println(resultSet.getInt(1));
System.out.println();
}
}
}
catch (final SQLException e) {
throw new AssertionError(e);
}
}
}

这是输出:

...Ignite startup logs...
[10:28:05] Ignite node started OK (id=7393583b)
[10:28:05] Topology snapshot [ver=8, servers=1, clients=1, CPUs=8, offheap=3.2GB, heap=8.1GB]
[10:28:05]   ^-- Node [id=7393583B-90FB-4D04-8D51-595F7C4DD4B6, clusterState=ACTIVE]
CREATE TABLE IF NOT EXISTS root (
"key" VARCHAR(24) NOT NULL,
"data" VARCHAR(100),
PRIMARY KEY("key"))
WITH "template=PARTITIONED, affinity_key=key, cache_name=root, value_type=root";
CREATE TABLE IF NOT EXISTS colocated_default (
"root_key" VARCHAR(24) NOT NULL,
"key" VARCHAR(24) NOT NULL,
"data" VARCHAR(100),
PRIMARY KEY("root_key", "key"))
WITH "template=PARTITIONED, affinity_key=root_key, cache_name=colocated_default, key_type=colocated_default_key, value_type=colocated_default";
CREATE TABLE IF NOT EXISTS colocated_custom (
"root_key" VARCHAR(24) NOT NULL,
"key" VARCHAR(24) NOT NULL,
"data" VARCHAR(100),
PRIMARY KEY("root_key", "key"))
WITH "template=myCacheTemplate, affinity_key=root_key, cache_name=colocated_custom, key_type=colocated_custom_key, value_type=colocated_custom";
Inserting into "root": ["1", root [idHash=362827515, hash=1928708473, data=Data for 1, key=1]]
Inserting into "colocated_default": [colocated_default_key [idHash=44559647, hash=-132016556, root_key=1, key=2], colocated_default [idHash=1067599825, hash=-132016556, root_key=1, key=2]]
Inserting into "colocated_custom": [colocated_custom_key [idHash=1336001042, hash=-132016555, root_key=1, key=3], colocated_custom [idHash=1856158867, hash=-132016555, root_key=1, key=3]]
SELECT COUNT(*) FROM root;
1
SELECT COUNT(*) FROM colocated_default;
1
SELECT COUNT(*) FROM colocated_custom;
1
SELECT COUNT(*) FROM root WHERE "key" = '1';
1
SELECT COUNT(*) FROM colocated_default WHERE "root_key" = '1';
1
SELECT COUNT(*) FROM colocated_custom WHERE "root_key" = '1';
0

我想知道这是我的错误配置,还是 Ignite 中的错误。

显然,这是 Ignite 中的一个错误。提交 https://issues.apache.org/jira/browse/IGNITE-9964。感谢您的举报!

仅当您通过withKeepBinary()放置数据时,才会出现此问题。如果改用 SQLINSERTSELECT工作正常。

我建议您使用INSERT而不是手动构建BinaryObject- 它要容易得多,并且可以解决错误。如果您必须使用BinaryObjects,那么您可以尝试通过INSERT添加第一行,然后使用二进制 - 这在我的测试中也有效。

最新更新