天天看点

roaringbitmap 源码(4)序列化和反序化以及分布式应用

迭代器和序列化和反序列化

serialize:都很简单。

ArrayContainer

@Override
public void serialize(DataOutput out) throws IOException {
  out.writeShort(Short.reverseBytes((short) this.cardinality));
  // little endian
  for (int k = ; k < this.cardinality; ++k) {
    out.writeShort(Short.reverseBytes(this.content[k]));
  }
}
           

反序列,也很简单

@Override
public void deserialize(DataInput in) throws IOException {
  this.cardinality =  & Short.reverseBytes(in.readShort());
  if (this.content.length < this.cardinality) {
    this.content = new short[this.cardinality];
  }
  for (int k = ; k < this.cardinality; ++k) {
    this.content[k] = Short.reverseBytes(in.readShort());;
  }
}
           

迭代器:Array的迭代很简单,下一个就行

这里主要讨论bitmap迭代器:

peeknext:

@Override
  public short peekNext() {
    long t = w & -w;
    return (short) (x *  + Long.bitCount(t - ));
  }
}
           

next:获取系一个answer之后把数据移动到后面一个位置。

@Override

public short next() {
  long t = w & -w;
  short answer = (short) (x *  + Long.bitCount(t - ));
  w ^= t;
  while (w == ) {
    ++x;
    if (x == bitmap.length) {
      break;
    }
    w = bitmap[x];
  }
  return answer;
}
           

结束语:

最近的项目底层数据压缩就是采用roaringbitmap。如果数据量一般都很大的时候,比如tag信息。tag信息以人为单位,比如一个

省份的人口。基本都是上亿的数据。如果单独用一个roaringbitmap 表示这个标签。基本需要12M的数据。当然高位不可能是饱和的。所以可以减少到10%。所以一般都是1M的文件。但是如果tag个数达到10万,数据将会是100G。如果需要计算and等操作,数据数据需要加载到内存。

如果标签数达到100万。(很正常,枚举型太对就有可能)。单机的内存就太多。所以采用分布式存储。。

方案。*将tag先经过切割。分成很多段,每一段的数据量的数据量就不是忒别大了。因为某一段的人,比如id从100-400 只能发送到一台机器。而且这台机器不受其他影响。数据需要汇总的时候能全部查询,也能单独查询,而这样的天生产品HBASE。

hbase定义表的时候能分区数据。所以元数据能单独维护。

hbase能用协处理,而且开发协处理很简单,每个协处理其相当于私有的处理。

hbase能和mapreduce结合 指定reduce与region个数相同。而且数据分区相同。map时也能对应一个region数数据。这样使得数据分离。*

同时,数据在查询的时候。能够发布一个查询,自动在region里做各自的查询,然后汇总。

支持功能:

全量批量导入:

增量批量导入:采用mapreduce导入。一个reduce对应一个region分区。

查询。解析解析引擎。

获取感兴趣的小圈子。

增删改查。

roaringbitmap基本结束,下个任务。HBASE。

继续阅读