2016-10-27
几周前应该工作的需要,使用开源的bloomfilter(避免重复造轮子,自己也懒....),起初谢了简单测试,发现没有问题,
就开始正式使用了,几天前无意中发现久远数据新出现,于是就产生了各种怀疑......自己程序问题?多个程序同事跑的问题?
等等!
最后排除代码问题后,开始怀疑使用的bloomfilter有问题,于是开始简洁测试环境,阅读bloomfilter源码,添加调试,
各种测想各种搞,两天时间无果(自己智商太低).
最终找到了问题所在,
先直接上代码:
bloomfilter查询接口:
146 func (bf *bloomFilter) Exists(b []byte) bool { 147 148 for _, s := range bf.Salts { 149 bf.H.Reset() 150 bf.H.Write(s) 151 bf.H.Write(b) 152 153 if bf.Filter.get(uint32(uint64(bf.H.Sum32())%bf.Bits)) == 0 { 154 dlog.Info("==============%d %s", s, str(b)) 155 return false 156 } 157 } 158 159 return true 160 }
其实问题就在bf.H,我们继续追踪bf.H:
69 type bloomFilter struct { ...... 74 H hash.Hash32 `json:"h"` 75 Salts [][]byte `json:"salts"` 76 }
我使用的H是fnv.New32a():
53 bf := bloom.NewBloomFilter(bloomConf.BFCap, bloomConf.BFfpr, fnv.New32a(), salts) 38 func New32a() hash.Hash32 { 39 var s sum32a = offset32 40 return &s 41 }
其实就是定义了一个uint32的新数据类型,注意这里是&s.
现在大家应该知道Exists中的bf.H问题了吧,bf.H在这里是共享数据,不支持重入。
而我们的访问量很大,导致self.H重入了,这样出现了错误!
有疑问加站长微信联系(非本文作者)