golang bloomfilter踩过的坑(https://github.com/mmczoo/dgobloom)

2016-10-27


golang bloomfilter踩过的坑(https://github.com/mmczoo/dgobloom)




几周前应该工作的需要,使用开源的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重入了,这样出现了错误!

你可能感兴趣的:(golang bloomfilter踩过的坑(https://github.com/mmczoo/dgobloom))