全部产品
云市场

注意事项

更新时间:2020-04-08 15:38:56

1. HBase自定义时间戳的支持

当用户在给表中的列加上Solr索引之后,带时间戳的写入将会被禁止掉(非索引列不会禁止带时间戳写入),当用户写入的数据带时间戳时,会抛出User defined timestamp is not allowed when external index is enabled...的Exception。由于Solr不支持列时间戳,不带时间戳可以简化HBase同步Solr的逻辑。如果:

  1. 使用的场景一定要带入时间戳
  2. 写入HBase的数据是通过BDS同步过来(如主备同步,RDS的增量导入等),BDS有可能会加上写入时间戳。

用户可以通过修改表属性的方式,打开对自定义时间戳的支持。用户可以通过Shelll修改表的Mutability属性为MUTABLE_ALL来打开对自定义时间戳的支持。打开时间戳支持会有一些性能损耗,但通常不会非常明显。

  1. # 打开时间戳支持
  2. hbase(main):002:0> alter 'testTable', MUTABILITY=> 'MUTABLE_ALL'
  3. # 关闭时间戳支持
  4. hbase(main):002:0> alter 'testTable', MUTABILITY=> 'MUTABLE_LATEST'

2. HBase中删除的支持

HBase中可以删除整行,删除某个family下的所有列,或者删除某个固定的列,HBase还支持删除指定某个版本的列。由于Solr并不支持多版本,如果在HBase删除指定的某个版本,会导致HBase和Solr中的数据不一致。因此当用户给HBase中的列加上Solr索引之后,删除这个列的指定版本的行为将会被禁止。举例来说

  1. //如果构造的Delete对象不加任何Family和Qualifier,则代表删除整行 --支持
  2. Delete delete = new Delete(Bytes.toBytes("row"));
  3. //删除f:q1这一列 --支持
  4. delete.addColumns(Bytes.toBytes("f"), Bytes.toBytes("q1"));
  5. //删除时间戳在ts1和ts1之前的所有数据 -- 开自定义时间戳(MUTABLE_ALL)后支持
  6. delete.addColumns(Bytes.toBytes("f"), Bytes.toBytes("q1"), ts1);
  7. //删除f这个famliy里所有的列 --支持
  8. delete.addFamily(Bytes.toBytes("f"));
  9. //删除f这个famliy里时间戳在ts1和ts1之前的所有列数据 -- 开自定义时间戳(MUTABLE_ALL)后支持
  10. delete.addFamily(Bytes.toBytes("f"), ts1);
  11. //删除f:q1这一列的最新版本 --不支持
  12. delete.addColumn(Bytes.toBytes("f"), Bytes.toBytes("q1"));
  13. //删除f:q1这一列中时间戳(版本)为ts1的数据 --不支持
  14. delete.addColumn(Bytes.toBytes("f"), Bytes.toBytes("q1"), ts1);

注意: 为了防止数据不一致,在HBase中执行删除某一行后,Solr中对应的Document不会删除,而是会删除这个Document中除了id这个field(Rowkey映射)以外的其他所有field。一般情况下,用户都是带一定条件去查询Solr,不会命中这种只有id的行。但如果查询到只有id这个field的行,代表此行已经删除,用户需要自行过滤。我们后续将考虑使用Solr的TTL功能在一定时间后自动删除这些行。

TTL的支持

HBase和Solr都支持数据TTL过期,但是HBase的TTL机制与Solr的TTL机制不一样,HBase是单个KV过期,而Solr中只能按照Document(对应HBase的一行)过期,而且过期的时间不会完全一致,同时Solr中数据过期后,如果删除事件还没有完成,过期数据仍然可能读到,而HBase不会有这样的问题。因此在开启TTL后,会导致Solr和HBase中数据短暂的不一致。比如在Solr中查到对应的rowkey再反查HBase时,由于数据在HBase中已经过期,数据可能查不到,在开启TTL后,用户需要处理此类case。