Influxdb批量插入,怎么解决内容不被覆盖问题?

问题一:

java代码批量插入一批数据到disk表,去influxdb上看只有一条数据,到底问题出在哪?

第一步:
了解influxdb的机制,它是基于时间的时序性数据库,每一条记录都会默认给一个时间标识,这个时间标识是不可以重复的,如果重复,后面的将覆盖前面的,根据机制很快就定位到了问题的主要原因。

第二步
我插入一批数据,为什么会插入时间相同呢?直接上代码

for(BdmpTenantUsage bdmpTenantUsage :bdmpTenantUsages ){
            String tenantName = bdmpTenantUsage.getTenantName();
            if(StringUtils.isNotBlank(tenantName)) {
                if( bdmpTenantUsage.getCpuUsageRate() )
                Point cpu_point = Point.measurement("disk")
                        .time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
                        .addField("unit_id", "cpu_usage")
                        .addField("value", bdmpTenantUsage.getCpuUsageRate())
                        .addField("tenant_name", tenantName)
                        .build();
                Point memory_point = Point.measurement("disk")
                        .time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
                        .addField("unit_id", "memory_usage")
                        .addField("value", bdmpTenantUsage.getMemoryUsageRate())
                        .addField("tenant_name", tenantName)
                        .build();
                Point storage_point = Point.measurement("disk")
                        .time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
                        .addField("unit_id", "storage_usage")
                        .addField("value", bdmpTenantUsage.getStorageUsageRate())
                        .addField("tenant_name", tenantName)
                        .build();
                batchPoints.point(cpu_point).point(memory_point).point(storage_point);
            }
        }
        influxDB.write(batchPoints);

直接看时间的代码: .time(System.currentTimeMillis(), TimeUnit.MILLISECONDS);
代码执行的效率比较高且数据量小(我的数据仅有100个)的情况下,System.currentTimeMillis()获取的时间戳可能会相同,导致我这一批数据的时间都是相同的,所有后一个值覆盖了前面的值,最终influxdb表里只能查询到一条数据。

第三步
解决方案:
既然知道是时间的问题,那就从时间入手。我在解决的时候并没有思路这么清晰,中间走了个弯路。
我起先任务修改插入时间的单位就行了。直接将TimeUnit.MILLISECONDS修改成TimeUnit.MICROSECONDS(也就是将毫秒改成微秒),然后运行代码来了另一个错误:
partial write: points beyond retention policy dropped=140
这个是什么意思呢 what?
插入的数据点中有时间戳在此范围之外的,就会导致这个错误。
为什么呢 why?
System.currentTimeMillis()返回的是毫秒,后面要求的单位是微秒,两者不对应造成的错误。

下面附上两段代码:

// 获取毫秒, 网上百度都有
 public static Long getmicTime() {
        Long cutime = System.currentTimeMillis() * 1000; // 微秒
        Long nanoTime = System.nanoTime(); // 纳秒
        return cutime + (nanoTime - nanoTime / 1000000 * 1000000) / 1000;
    }
    
InfluxdbConnection conn = InfluxdbConnection.builder()
                .openurl(openurl)
                .username(username)
                .password(password)
                .database(database)
                .build();
        InfluxDB influxDB = InfluxdbConnectionUtils.influxDBBuild(conn);
        String rpName = "aRetentionPolicy";
        BatchPoints batchPoints = BatchPoints
                .database(database)
                .tag("aync", "true")
                .retentionPolicy(rpName)
                .consistency(InfluxDB.ConsistencyLevel.ALL)
                .build();
        for(BdmpTenantUsage bdmpTenantUsage :bdmpTenantUsages ){
            String tenantName = bdmpTenantUsage.getTenantName();
            if(StringUtils.isNotBlank(tenantName)) {
                Point cpu_point = null;
                Point memory_point = null;
                Point storage_point = null;
                String cpuUsageRate = bdmpTenantUsage.getCpuUsageRate();
                String memoryUsageRate = bdmpTenantUsage.getMemoryUsageRate();
                String storageUsageRate = bdmpTenantUsage.getStorageUsageRate();
                if(StringUtils.isNotBlank(cpuUsageRate)) {
                    cpu_point = Point.measurement("disk")
                            .time(DateUtils.getmicTime(), TimeUnit.MICROSECONDS)
                            .addField("unit_id", "cpu_usage")
                            .addField("value", cpuUsageRate)
                            .addField("tenant_name", tenantName)
                            .build();
                    batchPoints.point(cpu_point);
                }
                if(StringUtils.isNotBlank(memoryUsageRate)) {
                    memory_point = Point.measurement("disk")
                            .time(DateUtils.getmicTime(), TimeUnit.MICROSECONDS)
                            .addField("unit_id", "memory_usage")
                            .addField("value", bdmpTenantUsage.getMemoryUsageRate())
                            .addField("tenant_name", tenantName)
                            .build();
                    batchPoints.point(memory_point);
                }
                if(StringUtils.isNotBlank(storageUsageRate)) {
                    storage_point = Point.measurement("disk")
                            .time(DateUtils.getmicTime(), TimeUnit.MICROSECONDS)
                            .addField("unit_id", "storage_usage")
                            .addField("value", bdmpTenantUsage.getStorageUsageRate())
                            .addField("tenant_name", tenantName)
                            .build();
                    batchPoints.point(storage_point);
                }
            }
        }
        influxDB.write(batchPoints);

你可能感兴趣的:(Java,知识体系,java,inflxdb)