使用自定义缓存模板时无法通过关联键查询缓存
Cannot query cache by affinity key when custom cache template is used
我注意到,当我查询使用自定义缓存模板创建的缓存并将缓存的关联键包含在 WHERE 子句中时,没有返回任何结果。
我 运行ning 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 个缓存。第一个是 "root" 缓存,它为其他缓存定义了托管。另外两个是由根密钥共同定位的缓存。第一个并置缓存 (colocated_default) 使用 PARTITIONED 模板并按预期工作。第二个 (colocated_custom) 使用在上述配置中创建的 "myCacheTemplate"。我在每个缓存中插入一个缓存条目,其中并置缓存中的条目具有与根缓存条目的键相同的关联键。
然后我查询缓存。我首先 运行 查询以确保每个缓存中都有一个条目。然后我 运行 查询每个键,其中亲和键等于插入记录的亲和键。我的结果表明我能够从两个 PARTITIONED 缓存中通过亲和力 select,但没有获得 "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()
放置数据时才会出现此问题。如果您改用 SQL INSERT
,则 SELECT
可以正常工作。
我建议您使用 INSERT
而不是手动构建 BinaryObject
s - 它更容易并且可以解决该错误。如果你必须使用 BinaryObject
s 那么你可以尝试通过 INSERT
添加第一行然后使用二进制 - 这在我的测试中也有效。
我注意到,当我查询使用自定义缓存模板创建的缓存并将缓存的关联键包含在 WHERE 子句中时,没有返回任何结果。
我 运行ning 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 个缓存。第一个是 "root" 缓存,它为其他缓存定义了托管。另外两个是由根密钥共同定位的缓存。第一个并置缓存 (colocated_default) 使用 PARTITIONED 模板并按预期工作。第二个 (colocated_custom) 使用在上述配置中创建的 "myCacheTemplate"。我在每个缓存中插入一个缓存条目,其中并置缓存中的条目具有与根缓存条目的键相同的关联键。
然后我查询缓存。我首先 运行 查询以确保每个缓存中都有一个条目。然后我 运行 查询每个键,其中亲和键等于插入记录的亲和键。我的结果表明我能够从两个 PARTITIONED 缓存中通过亲和力 select,但没有获得 "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()
放置数据时才会出现此问题。如果您改用 SQL INSERT
,则 SELECT
可以正常工作。
我建议您使用 INSERT
而不是手动构建 BinaryObject
s - 它更容易并且可以解决该错误。如果你必须使用 BinaryObject
s 那么你可以尝试通过 INSERT
添加第一行然后使用二进制 - 这在我的测试中也有效。