golang bloomfilterが踏んだ穴(https://github.com/mmczoo/dgobloom)
1513 ワード
2016-10-27
golang bloomfilterが踏んだ穴(https://github.com/mmczoo/dgobloom)
数週間前に仕事をすべきだったので、オープンソースのbloomfilter(車輪を繰り返すのを避けて、自分も怠け者...)を使って、最初は簡単なテストをしましたが、問題はありませんでした.
本格的に使われるようになり、数日前に何気なく久遠のデータが新たに出てきたことに気づき、様々な疑問を抱いたのですが...自分のプログラムの問題?複数のプログラムが同時に走る問題?
待って!
最後にコードの問題を排除した後、使用するbloomfilterに問題があるのではないかと疑い始め、環境を簡潔にテストし、bloomfilterのソースコードを読み、デバッグを追加し始めました.
いろいろなことを考えて、2日間は結果が出なかった(自分のIQが低すぎる).
最終的に問題点を見つけました
まず直接コードを入力:
bloomfilterクエリーインタフェース:
実は問題はbfです.H、私たちはbfを追跡し続けます.H:
私が使っているHはfnvです.New32a():
実はuint 32の新しいデータ型を定義しています.ここでは&sです.
今皆さんはExistsのbfを知っているはずです.H問題か?Hはここでは共有データであり,再入力はサポートされていない.
私たちのアクセス量が多く、self.Hが再入して、これでエラーが発生しました!
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が再入して、これでエラーが発生しました!