最近公司需要更改一个旧项目,其中涉及到Ignite作为缓存体系,之前使用的缓存框架通常是redis集群,第一次接触Ignite,想把学习、认知过程记录下来。
ignite作为分布式缓存框架, 首先了解到本来项目是分布式,ignite是直接嵌入项目(java)中,ignite是基于JVM的,所以可以完全嵌入java项目中,随着项目启动而启动关闭而关闭 (我理解为相当于java编写了一个map缓存数据,当然别人是可以分布式的、并且可以做分布式计算的),目前遇到的问题是有时候程序运行中 但是ignite线程挂了,失去功能,并且某个节点挂掉 不能转到其他节点(后续发现问题是集群保存数据有三种模式导致部分数据丢失现象)。目标计划把服务独立出来不再嵌入项目中,构建独立的Ignite服务端集群,项目作为一个客户端。
Ignite是轻量级分布式内存HTAP数据库及计算平台,中文官网https://liyuj.gitee.io/。
发一张我的脑图:
Ignite是一个大容器(相当于mysql的一个连接服务,cache就是一个数据库),里面可以创建cache,数据放在cache里面。Ignite支持完整的SQL、DDL和DML,键-值形式存储数据,其中值得类型可以基本数据类型,也可以是对象Object映射成table-column。
Ignite可以通过key键来取数据,也支持sql语句取数据:
1、创建一个容器cache
2、通过key查询:调用cache.get()/cache.getAll()方法
3、通过sql查询:调用cache.query()
Ignite本身有原生的持久化机制,可以选择是否开启,也可以集成到第三方数据库进行持久化。缓存策略:部门常用的数据可以放在内存中,通过重写CacheStoreAdapter这个类进行自定义持久化策略,如果在内存取不到数据会通过load/loadAll进行查询。举个例子(目前例子都是基于独立服务启动):
server-cache.xml配置文件:
XXX.1.8.1:48500..48503
XXX.1.8.2:48500..48503
java.lang.String
com.xx.xx.cache.model.PureCache
Object-table映射PureCache类:
package com.xx.xx.cache.model;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
import java.io.Serializable;
import java.util.Date;
@SuppressWarnings("serial")
public class PureCache implements Serializable {
@QuerySqlField(index = true)
private Long id;
@QuerySqlField
private String name;
@QuerySqlField
private String adapterEnglishName;
@QuerySqlField
private String interfaceType;
@QuerySqlField
private Integer collAdapterType;
@QuerySqlField
private String startupPath;
@QuerySqlField
private String shutdownPath;
@QuerySqlField
private String params;
@QuerySqlField
private String memo;
@QuerySqlField
private Integer dataType;
@QuerySqlField
private String developFactory;
@QuerySqlField
private String adapterVersion;
@QuerySqlField
private Integer adapterExecuteType;
@QuerySqlField
private Date createTime;
@QuerySqlField
private Date updateTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAdapterEnglishName() {
return adapterEnglishName;
}
public void setAdapterEnglishName(String adapterEnglishName) {
this.adapterEnglishName = adapterEnglishName;
}
public String getInterfaceType() {
return interfaceType;
}
public void setInterfaceType(String interfaceType) {
this.interfaceType = interfaceType;
}
public Integer getCollAdapterType() {
return collAdapterType;
}
public void setCollAdapterType(Integer collAdapterType) {
this.collAdapterType = collAdapterType;
}
public String getStartupPath() {
return startupPath;
}
public void setStartupPath(String startupPath) {
this.startupPath = startupPath;
}
public String getShutdownPath() {
return shutdownPath;
}
public void setShutdownPath(String shutdownPath) {
this.shutdownPath = shutdownPath;
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
public Integer getDataType() {
return dataType;
}
public void setDataType(Integer dataType) {
this.dataType = dataType;
}
public String getDevelopFactory() {
return developFactory;
}
public void setDevelopFactory(String developFactory) {
this.developFactory = developFactory;
}
public String getAdapterVersion() {
return adapterVersion;
}
public void setAdapterVersion(String adapterVersion) {
this.adapterVersion = adapterVersion;
}
public Integer getAdapterExecuteType() {
return adapterExecuteType;
}
public void setAdapterExecuteType(Integer adapterExecuteType) {
this.adapterExecuteType = adapterExecuteType;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
//
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("CollAdapterCache{");
sb.append("id=").append(id);
sb.append(", name='").append(name).append('\'');
sb.append(", adapterEnglishName='").append(adapterEnglishName).append('\'');
sb.append(", interfaceType='").append(interfaceType).append('\'');
sb.append(", collAdapterType=").append(collAdapterType);
sb.append(", startupPath='").append(startupPath).append('\'');
sb.append(", shutdownPath='").append(shutdownPath).append('\'');
sb.append(", params='").append(params).append('\'');
sb.append(", memo='").append(memo).append('\'');
sb.append(", dataType=").append(dataType);
sb.append(", developFactory='").append(developFactory).append('\'');
sb.append(", adapterVersion='").append(adapterVersion).append('\'');
sb.append(", adapterExecuteType=").append(adapterExecuteType);
sb.append(", createTime=").append(createTime);
sb.append(", updateTime=").append(updateTime);
sb.append('}');
return sb.toString();
}
}
持久化对象CollAdapterStoreMgr:
package com.xx.xx.cache.manager.store;
import org.apache.commons.lang3.StringUtils;
import org.apache.ignite.cache.store.CacheStoreAdapter;
import org.apache.ignite.lang.IgniteBiInClosure;
import org.apache.ignite.resources.SpringResource;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.cache.Cache;
import javax.cache.integration.CacheLoaderException;
import javax.cache.integration.CacheWriterException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
public class PureCacheStoreMgr extends CacheStoreAdapter {
private static Logger logger = LogManager.getLogger(PureCacheStoreMgr .class.getName());
@Override
public void loadCache(IgniteBiInClosure clo, Object... args) {
}
@Override
public Map loadAll(Iterable extends String> keys) {
/**
实现多key个查询
**/
return super.loadAll(keys);
}
@Override
public ParserAdapterCache load(String key) throws CacheLoaderException {
/**
实现单个key查询
**/
return result;
}
@Override
public void write(Cache.Entry extends String, ? extends ParserAdapterCache> entry) throws CacheWriterException {
/**
持久化
**/
}
@Override
public void delete(Object key) throws CacheWriterException {
/**
删除
**/
}
}
对Ignite的初始化cache配置,如果服务器独立运行的时候,需要把自己额外的jar放进apache-ignite-fabric-2.5.0-bin\libs里面。
Ignite运行有三种角色
1、服务端(server节点)
数据存储,参与缓存,参与分布式计算...,并且可以嵌入java代码,使项目本身是一个服务节点,也可以独立节点运行部署。集群节点挂了,其他节点会感知。
2、客户端(client节点)
本身不存储数据,可以通过api对服务器节点进行数据存储,参与分布式计算...集群节点挂了,其他节点会感知。
3、瘦客户端(thin client)
thin client不会加入Ignite的集群拓扑,它也不存储数据,也不参与执行计算和流处理。和Ignite原生的client节点不同,它并不感知集群的拓扑结构变化(增加/删除节点后,thin client并不知道),而且一次只能和Ignite集群中的一个节点连接通讯,当该节点失效后,它会从事先配置好节点列表中挑选一个新的节点,重新连接
ignite集群cache数据保存三种模式:
1、LOCAL:本地模式,数据都存储在本地,无数据再平衡,类似常见的存储服务;(查不到数据再做处理)
2、PARTITIONED:分区模式,数据分散到集群中的各个节点,分区模式适合存储数量庞大的数据
3、REPLICATED:复制模式,有数据再平衡过程,主节点(Primary)数据与分区模式的一致,只是复制模式默认备 份了除主节点数据外的其余数据。复制模式适合存储数据量小,增长不快的数据。
安装包下载地址:百度云,提取码:sv74,也可以官网自行下载:https://ignite.apache.org/download.cgi
部署服务器 |
部署根路径 |
x.1.8.1 |
/home/xx/xx/ignite |
x.1.8.2 |
/home/xx/xx/ignite |
修改配置文件 /home/xx/xx/ignite/ignite2.5/config/server-cache.xml
进入目录 /home/xx/xx/ignite/ignite2.5/bin
命令:nohup bash ignite.sh ../config/server-cache.xml &
成功标识:输入tail -1000 nohup.out
找到config/server-cache.xml选择,输入该选择前面的编号,比如:10
3、top --查看所有节点信息
4、cache -a --查看所有库信息
下载DBeaver5.0.2
下载ignite-core-2.5.0.jar
安装DBeaver5.0.2
数据库 > 驱动管理 > 新建
URL模板:jdbc:ignite:thin://可用的服务器节点IP/
端口:10800
添加文夹:选择下载好的ignite-core-2.5.0.jar
点击查找类选择:org.apache.ignite.IgniteJdbcThinDriver
确认
数据量 > 新建连接 > 选择ignite
不填写账号、密码
测试链接,显示OK
下一步、完成。