使用Aerospike中遇到的那些坑

Aerospike 数据库是一个键-值存储的高性能实时 NoSQL(灵活模式)数据库,以低延迟和高吞吐量而闻名。以下记录我在使用过程中的遇到的一些“坑”:

1)Set无法drop

这个之所以出现在第一位,并不是因为其重要性,只是因为由于Set无法drop,导致要重建表只能delete all record,从而有可能会导致幽灵数据的问题。

解决方法:

  1. Insert records (through Java Client) into a set with expiration set for each record
  2. after all the records are expired, use asinfo to set ‘set-delete’ flag to TRUE
  3. restart aerospike
  4. The set will be dropped

2)delete record 后出现幽灵数据。

场景:将以前存储在LevelDB中的数据迁移到Aerospike中,对象采用的直接存储的方式。导入一部分数据后发现某些对象会报无法序列化的异常,就把所有使用到的bean都加了serialVersionUID。

结果使用一段时间后发现报serialVersionUID不一致的异常,以为是Aerospike的序列化BUg,就想不直接存储,改成存储JSON string。通过scanAll的方式遍历set,delete了所有的record,删除成功后,在aql中查询记录数为0。

测试没问题,一切正常,然而高兴没多久,发现后台又有异常,是在取出数据然后转成对象时候,说不能讲对象转成String。通过aql查询后发现,set中有几条非json形式的数据,看入库日期竟然是清空表前的时期。

经google后发现在Aerospike的社区中有过相关的讨论。原来delete record时只是删除了索引,并没有真正的删除数据(就像是只是在内存中删除,并未实时的刷到硬盘中,造成数据的一致性不能保证),在Aerospike重启后会重新load数据,这样被删除了数据就会重新出现。

解决办法:

a)合理设置TTL时间

b)尽量不使用硬删除,使用软删除打标记的方式

c)在网上看到如下方法,但是并没有尝试,不保证效果:在配置文件当中添加cold-start-        empty true,重启节点,此时节点会认为本地硬盘是空的,重新从集群中恢复数据,这          个时候我们删除的set就不会出现了

d)合理利用namespace

3)关于数据类型

a)最好不用直接使用boolean,到了数据库中会变成0/1

b)不要使用int/float数据类型,如果使用double类型,请保证小数点后一定有数字。之所以这么说,原因是int/float会变成long/double,而没有小位数的double会变成long

c)不要直接保存LinkedHashMap/TreeMap之类的map,因为保存时AS会强制转父类。

4)尽量不用使用单节点的部署方式,有很大可能性出现timeout。

具体表现为aql中可以正常show sets,但未set timeout时直接返回timeout,设置过后再次查询会导致查询hang住,无法取消、中断

 

此条目发表在技术, 未分类分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。