mapkeeper连接的数据库,修改ycsb insert和get的key长度

通过测试可以发现ycsb进行评测数据库工作负载的时候insert生成的key值是通过Fowler_Noll_Vo_hash之后得到18或者是19长度的字符串然后在前面加上"user"和填充位之后得到22或者23固定长度。这里主要是coreworkload中的buildKeyName(keynum) 方法实现的(这里的keynum是按照顺序递增的,value是keynum进行hash编码之后得到的值,加上“user”之后就会变成22位或者23位)
 

pre keynum:994 value:633995401461691778    value length:18
pre keynum:995 value:6858042526771971499   value length:19
pre keynum:996 value:4152828024211893584   value length:19

如果我想变成16位固定长度的key就需要更改hash算法,hash算法主要是调用core目录下Utils文件中hash,因此我在util文件中添加有关md5 hash算法,可以通过调用直接生成以下三种形式字符串:16位纯数字、数字和字母组合还有32位数字和字母组合。

import java.security.MessageDigest;
//生成16位纯数字的字符串
public static String getMD5(byte[] source) {
    String s = null;
    char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
    try {
      MessageDigest md = MessageDigest.getInstance("MD5");
      md.update(source);
      byte[] tmp = md.digest();
      char[] str = new char[16];
      int k = 0;
      for (int i = 0; i < 16; i++) {
        byte byte0 = tmp[i];
        //只取高位
        str[k++] = hexDigits[(byte0 >>> 4 & 0xf)%10];
        // str[k++] = hexDigits[byte0 & 0xf];
      }
      s = new String(str);  // 换后的结果转换为字符串
    }catch(Exception e) {
      e.printStackTrace();
    }
    return s;
  }
//md5生成32位带数字和字母的字符串
  public static String encrypt32(String encryptStr) {
    MessageDigest md5;
    try {
      md5 = MessageDigest.getInstance("MD5");
      byte[] md5Bytes = md5.digest(encryptStr.getBytes());
      StringBuffer hexValue = new StringBuffer();
      for (int i = 0; i < md5Bytes.length; i++) {
        int val = ((int) md5Bytes[i]) & 0xff;
        if (val < 16) {
          hexValue.append("0");
        }
        hexValue.append(Integer.toHexString(val));
      }
      encryptStr = hexValue.toString();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    return encryptStr;
  }

  /**
   * @Description:加密-16位小写,md5生成16位带数字和字母的字符串
   * @author:wangrui
   * @time:2019年7月1日 上午11:15:33
   */
  public static String encrypt16(String encryptStr) {
    return encrypt32(encryptStr).substring(8, 24);
  }

由于主要是想生成16位纯数字的字符串,因此hash方法改为调用getMD5()方法:

public static String hash(long val) {
    //return fnvhash64(val);s
    String value = Long.toString(val);
    String result = getMD5(value.getBytes());
    System.out.println("md5 16:" + result);
   // System.out.println("type" + Long.parseLong(encrypt16(value)).getClass().getName());
    return result;
  }

同时coreworkloads文件中buildKeyName方法也要进行修改:

protected String buildKeyName(long keynum) {
    long key1 = keynum;
    String value;
    if (!orderedinserts) {
      value = Utils.hash(keynum);
    }else{
      value = Long.toString(keynum);
    }
    System.out.print("pre keynum:" + key1 + "value:" + value + "\tvalue length:" + value.length());
    int fill = zeropadding - value.length();
    String prekey = "user";
    for (int i = 0; i < fill; i++) {
      prekey += '0';
    }
    return value;
  }

然后就可以啦,直接mvn clean package之后如果成功直接

bin/ycsb load mapkeeper -s -P workloads/workloada -p "mapkeeper.host=127.0.0.1" -p "mapkeeper.port=9090"
bin/ycsb run mapkeeper -s -P workloads/workloada -p "mapkeeper.host=127.0.0.1" -p "mapkeeper.port=9090"

会在server端显示如下结果:(前面字符串就是key,后面1080是value的长度)

3331381741354218 1080
5063212704481401 1080
5745152715228050 1080
3623115442630601 1080
9029155151691022 1080
0103052120949582 1080
4090110252202017 1080
6291874550027021 1080
8021102527374213 1080
7112324837217912 1080
9410524758250505 1080

 

你可能感兴趣的:(ycsb)