golang bloomfilterが踏んだ穴(https://github.com/mmczoo/dgobloom)

1513 ワード

2016-10-27
golang bloomfilterが踏んだ穴(https://github.com/mmczoo/dgobloom)
数週間前に仕事をすべきだったので、オープンソースのbloomfilter(車輪を繰り返すのを避けて、自分も怠け者...)を使って、最初は簡単なテストをしましたが、問題はありませんでした.
本格的に使われるようになり、数日前に何気なく久遠のデータが新たに出てきたことに気づき、様々な疑問を抱いたのですが...自分のプログラムの問題?複数のプログラムが同時に走る問題?
待って!
最後にコードの問題を排除した後、使用するbloomfilterに問題があるのではないかと疑い始め、環境を簡潔にテストし、bloomfilterのソースコードを読み、デバッグを追加し始めました.
いろいろなことを考えて、2日間は結果が出なかった(自分のIQが低すぎる).
最終的に問題点を見つけました
まず直接コードを入力:
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 }

 
実はuint 32の新しいデータ型を定義しています.ここでは&sです.
今皆さんはExistsのbfを知っているはずです.H問題か?Hはここでは共有データであり,再入力はサポートされていない.
私たちのアクセス量が多く、self.Hが再入して、これでエラーが発生しました!