influxdb的安装和语法这边不加以说明,本文主要讲解influxdb在java大数据量存储的应用。
该项目的场景是存储设备的历史数据。(针对时序数据库influxdb是个比较好的选择)
一。流程图
项目启动流程:
存储流程如下:
二,数据库及表设计
数据库:
rt_necp_history 短期数据库
key_necp_history 长期数据库
表:
AI_RESULT 存储数字类型的表(double,int),方面以后统计计算
MIX_RESULT 混合表(存储字符串类型)
字段:tid 数据的唯一标识(对应平台的设备的测点) value 值 ,time 创建时间
总共三个字段即将设备的每个测点当做一条数据存储,该种方案可能会造成influxdb的series数量庞大。
实际压测过:内存8g,能存储的数据量在5000万条左右,还是可以满足一定的需求。
若对数据量要求较大时建议用一个设备作为一条数据,表的字段将会比较多。
实际压测过:内存8g,表字段在500个左右,能存储数据量在1000万左右。
存储策略:
LONG_YEAR 长期数据
String commandLong = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT",
keyPolicy, keyDataBase, "1300w", 1); //25年 一年有52周,52*25 =1300w
this.query(commandLong,keyDataBase);
ONE_MONTH 短期数据
String command = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT",
rtPolicy, rtDataBase, "30d", 1); //30天
this.query(command,rtDataBase);
分为两种策略分别设置为长期数据库和短期数据库的默认存储策略。
三,实践。
1.在influxdb配置文件中打开这个两个参数并设置为0(批量存储无限)。
配置文件中的参数看实际情况打开,具体可参考如下:
https://www.cnblogs.com/mafeng/p/6848166.html
2.pom.xml中导入jar包依赖
3.influxdb工具类
@Component
public class InfluxBaseDao implements InitializingBean {
private static InfluxDB influxDB;
private static final int maxActiveNum = 1000;//最大初始化时连接数
private static BlockingQueue<InfluxDB> connPool;
@Value("${spring.influx.user}")
private String username;// 用户名
@Value("${spring.influx.password}")
private String password;// 密码
@Value("${spring.influx.url}")
private String openurl;// 连接地址
@Value("${spring.influx.dataBase}")
private String database;// 数据库
@Value("${spring.influx.table.analog}")
private String analogtable;//数值表
@Value("${spring.influx.table.mix}")
private String mixtable;//混合表(存字符串等数据)
void initPool() {
connPool = new LinkedBlockingQueue<>(maxActiveNum);
while (connPool.size()<maxActiveNum) {
if (influxDbBuild() != null) {
try {
connPool.put(influxDbBuild());
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
break;
}
}
}
@Override
public void afterPropertiesSet() throws Exception {
initPool();
influxDbBuild();
//createRetentionPolicy();
}
/**
* 连接时序数据库;获得InfluxDB
**/
@SuppressWarnings("deprecation")
public InfluxDB influxDbBuild() {
try {
if (influxDB == null) {
if (openurl != null) {
influxDB = InfluxDBFactory.connect(openurl, username, password);
if (influxDB != null) {
boolean flag = influxDB.databaseExists(database);
if (!flag) {
influxDB.createDatabase(database);
createRetentionPolicy(); //初始化创建保存策略
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return influxDB;
}
public InfluxDB getInfluxDB() {
if (connPool.size() > 0) {
InfluxDB conn = null;
try {
conn = connPool.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (conn == null) {
initPool();
// System.out.println(openurl + "--" + database);
}
return conn;
} else {
return influxDbBuild();
}
}
public static void setInfluxDB(InfluxDB influxDB) {
InfluxBaseDao.influxDB = influxDB;
}
/**
* 设置数据保存策略
* defalut 策略名 /database 数据库名/ 1095d 数据保存时限3年/ 1 副本个数为1/ 结尾DEFAULT 表示 设为默认的策略
*/
public void createRetentionPolicy() {
String command = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT",
"defalut", database, "1095d", 1); //3年
this.query(command);
}
public void createRetentionPolicyDefault() {
String command = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT",
"defalut", database, "0s", 1); //无限制
this.query(command);
}
//删除策略
public void dropRetentionPolicyDefault() {
String command = String.format("DROP RETENTION POLICY \"%s\" ON \"%s\"",
"defalut", database);
this.query(command);
}
/**
* 查询
*
* @param command 查询语句
* @return
*/
public QueryResult query(String command) {
return getInfluxDB().query(new Query(command, database));
}
public QueryResult query(String command, String database) {
return getInfluxDB().query(new Query(command, database));
}
/**
* 插入
*
* @param measurement 表
* @param tags 标签
* @param fields 字段