前言
Apache Ignite系列:
- Apache Ignite基本概念及最佳实践(一)——概念篇
- Apache Ignite基本概念及最佳实践(二)——实战篇
- Apache Ignite基本概念及最佳实践(三)——监测篇
- Apache Ignite基本概念及最佳实践(四)——问答篇
一、数据分区LOCAL模式是否可用
答:不可用
- 在2.12.0版本被标记为即将废弃
- 在最新的2.15.0版本中已经不存在CacheMode#LOCAL
- 官方文档参考:Data Partitioning
二、存储big data限制是否有限制
答:有限制
- 单个条目必须小于64MB(默认)
- 可以通过配置dataStorageConfiguration中的walSegmentSize的值来保存更大的条目
- 官方文档参考:Changing WAL Segment Size
<bean class="org.apache.ignite.configuration.IgniteConfiguration" id="ignite.cfg">
<property name="dataStorageConfiguration">
<bean class="org.apache.ignite.configuration.DataStorageConfiguration">
<!-- set the size of wal segments to 128MB -->
<property name="walSegmentSize" value="#{128 * 1024 * 1024}"/>
<property name="defaultDataRegionConfiguration">
<bean class="org.apache.ignite.configuration.DataRegionConfiguration">
<property name="persistenceEnabled" value="true"/>
</bean>
</property>
</bean>
</property>
</bean>
三、是否可以保存复杂对象
答:如果使用SQL索引,是不可以的,不能保存嵌套对象,List,Map等复杂对象
- 如果不使用SQL创建索引,查询数据,是可以保存的
- 如果使用SQL创建索引和查询,预定义的数据类型如下:
- 所有的基本类型和包装类,除了char和Character
- String
- BigDecimal
- byte[]
- java.util.Date, java.sql.Date, java.sql.Timestamp
- java.util.UUID
- 官方文档参考:Defining Indexes
四、查询缓存的返回值,是否可以返回真正的对象
答:SqlFieldQuery不可以,ScanQuery和IndexQuery可以
- SqlFieldQuery:不能直接返回实体,只支持按序号获取字段值
- ScanQuery:可以直接返回实体,缺点是需要全表扫描,执行较慢
- IndexQuery:可以直接返回实体,遍历部分索引树即可,返回的是构建索引时的对象
- 官方文档参考:Using Cache Queries
// SqlFieldQuery
IgniteCache<Integer, Student> cache = ignite.getOrCreateCache("myCache");
SqlFieldsQuery sql = new SqlFieldsQuery("select concat(classId, '----', name) from STUDENT");
QueryCursor<List<?>> cursor = cache.query(sql);
for (List<?> row : cursor) {
System.out.println("学生信息:" + row.get(0));
}
// ScanQuery
IgniteCache<Integer, Person> cache = ignite.getOrCreateCache("myCache");
IgniteBiPredicate<Integer, Person> filter = (key, p) -> p.getSalary() > 1000;
try (QueryCursor<Cache.Entry<Integer, Person>> qryCursor = cache.query(new ScanQuery<>(filter))) {
qryCursor.forEach(
entry -> System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()));
}
// IndexQuery
QueryEntity personEntity = new QueryEntity(Integer.class, Person.class)
.setFields(new LinkedHashMap<String, String>() {{
put("orgId", Integer.class.getName());
put("salary", Integer.class.getName());
}})
.setIndexes(Collections.singletonList(
new QueryIndex(Arrays.asList("orgId", "salary"), QueryIndexType.SORTED)
.setName("ORG_SALARY_IDX")
));
CacheConfiguration<Integer, Person> ccfg = new CacheConfiguration<Integer, Person>("entityCache")
.setQueryEntities(Collections.singletonList(personEntity));
IgniteCache<Integer, Person> cache = ignite.getOrCreateCache(ccfg);
QueryCursor<Cache.Entry<Integer, Person>> cursor = cache.query(
new IndexQuery<Integer, Person>(Person.class, "ORG_SALARY_IDX")
.setCriteria(eq("orgId", 1))
);
五、是否有权限控制,节点访问权限,restapi访问权限
答:是有的
- 有Authentication,用户级别的权限控制
- 可以在数据库中配置用户名和密码(CREATE USER, ALTER USER, DROP USER)
- 在节点的配置文件中,设置authenticationEnabled为true,同时要开启持久化功能才可生效
- 官方文档参考:authentication
- 不支持对增删改查语句及用户角色做细粒度的权限控制
六、ignite是否可以集成hibernate做二级缓存
答:是可以的
- hibernate的L1缓存是会话级别的,由内部实现
- hibernate的L2缓存有很多可插拔的实现,Ignite可以作为L2缓存
- 官方文档参考:Hibernate L2 Cache
七、Parititioned是否可以根据某个字段分区
答:是可以的
- 如果没有显式指定关联键,默认缓存的key是关联键;如果用SQL语句,默认主键是关联键
- 想要让两个不同缓存的数据在同一个分区需要以下条件:
- 必须使用一个复杂对象作为Key
- 在想用作关联键的字段上加
@AffinityKeyMapped注解
- 实际使用时,可以对每一个Value创建一个对应的key,例:PersonKey,一个字段为id,另一个加注解的字段为要分区的字段
- 官方文档参考:Affinity Colocation
static class Person {
private int id;
private String companyId;
private String name;
public Person(int id, String companyId, String name) {
this.id = id;
this.companyId = companyId;
this.name = name;
}
public int getId() {
return id;
}
}
static class PersonKey {
private int id;
@AffinityKeyMapped
private String companyId;
public PersonKey(int id, String companyId) {
this.id = id;
this.companyId = companyId;
}
}
八、thin Client如何连接server节点
答:client连接server节点默认端口是47500,thin Client连接server节点默认端口是10800
- 在server节点配置ClientConnectorConfiguration来制定thin Client连接端口,默认是10800
- 官方文档参考:Thin Clients