实验目的

  • 测试时间序列ID化后内存空间占用
  • 测试SHA256 java版本性能


实验场景

每时间序列标识长度为200字节,共有100万时间序列,其中measurement占用20字节

每个时间序列通过SHA256算法ID化成32字节的ID,使用哈希表存储,键为ID,值为数据类型及磁盘指针


内存占用

理论分析

ID占用32字节,数据类型占用1字节,磁盘指针占用4字节

纯数据内存 = 1M * (32 + 1 + 4) = 37MB

必须的JAVA对象(HashMap Node对象,Key对象, Value对象)= 1M * (32 + 16 + 16) = 64MB

理论最小空间占用 = 纯数据内存 + 必须的JAVA对象 = 37 + 64 = 101 MB


实验结果

实际内存占用:104MB


原因分析

JVM虚拟机具有字节对齐的特点,1字节的数据类型被对齐为4字节,故占用空间多了3MB


实验代码

Key

public class Key {
  byte b1;
  byte b2;
  byte b3;
  byte b4;
  byte b5;
  byte b6;
  byte b7;
  byte b8;
  byte b9;
  byte b10;
  byte b11;
  byte b12;
  byte b13;
  byte b14;
  byte b15;
  byte b16;
  byte b17;
  byte b18;
  byte b19;
  byte b20;
  byte b21;
  byte b22;
  byte b23;
  byte b24;
  byte b25;
  byte b26;
  byte b27;
  byte b28;
  byte b29;
  byte b30;
  byte b31;
  byte b32;
}


Value

public class Value {
  int pos;
  byte type;

  public Value(int pos, byte type) {
    this.pos = pos;
    this.type = type;
  }
}

Main

public class Main {
  private static final int size = 10_000_00;

  public static void main(String[] args) throws InterruptedException {
    HashMap<Key, Value> map = new HashMap<>();

    // System.out.println(Integer.toBinaryString(-1));
    for (int i = 1; i <= size; i++) {
      map.put(new Key(), new Value(1,(byte) 1));
    }

    System.out.println("finish " + map.size());
    Thread.sleep(1000000);
  }

}



SHA256算法吞吐量

吞吐量

408次SHA256每毫秒


带SHA256计算的IOTDB写入测试

实验场景

10条时间序列,每次tablet插入100个点,一共插入100000个tablet,每次插入对deviceID做一次SHA256计算


实验结果

写入时间 / 是否带SHA256计算
写入时间65649 ms64939 ms


实验代码

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

public class SpeedMain {
  private static MessageDigest md;
  private static final int size = 1_000_000;
  private static final int pathSize = 200;

  public static void main(String[] args) throws NoSuchAlgorithmException {
    md = MessageDigest.getInstance("SHA-256");
    StringBuilder path = new StringBuilder();
    Random random = new Random();

    for (int i = 0; i < pathSize; i++) {
      path.append(random.nextInt(9));
    }

    long curTime = System.nanoTime();

    for(int i = 0; i < size; i++){
      cal(path.toString());
      md.reset();
    }

    long finishTime = System.nanoTime();
    System.out.println("Throughput: " + size / ((finishTime - curTime) / 1_000_000) + " num / ms.");

  }

  private static byte[] cal(String s){
    return md.digest(s.getBytes());
  }
}


新实现下的内存占用

测试数据量

100万设备,每个设备下100个测点

数据结构

HashMap<DeviceID, HashMap<String, SchemaEntry>>


内存占用

内存占用
Hashmap Node3.2GB
Hashmap Node[]1.2GB

DeviceID

48MB
HashMap48MB
Schema Entry4.8GB

String

2.4G
char[]4.0G*
总计15.696GB

*java中char类型占用两个字节,长度为10的string占用20字节,4字节对齐,外加8字节引用,4字节数组长度,4字节对齐

  • No labels