關(guān)于Filter
從solr到es,一路下來(lái)對(duì)搜索引擎的長(zhǎng)期使用涩嚣,工作內(nèi)容也包含大量的搜索優(yōu)化的問(wèn)題赃梧,無(wú)論是搜索質(zhì)量還是速度都是需要關(guān)心的問(wèn)題。有一個(gè)結(jié)論我一直記得促绵,就是能使用filter的情況盡量使用filter攒庵,filter速度快,而且自帶緩存败晴。但是之前是知其然不知其所以然浓冒,今天想到這個(gè),所以專(zhuān)門(mén)研究了一下到底filter的原理尖坤。
Filter查詢(xún)?yōu)槭裁纯?/h2>
關(guān)于bitset
首先介紹bitset是什么
可以簡(jiǎn)單的理解為bit數(shù)組稳懒,即數(shù)組中只包含0或1
關(guān)于Filter
以以下的數(shù)據(jù)舉例子
word | doc1 | doc2 | doc3 |
---|---|---|---|
how | no | yes | yes |
are | yes | yes | no |
you | no | yes | yes |
yes和no表示索引是否包含word的詞
現(xiàn)在我們給出filter的條件word:are
,根據(jù)表中所得為yes,yes,no
慢味,將yes做1场梆,no做0,于是我們獲得了這個(gè)filter條件在這個(gè)索引中的bitset[1, 1, 0]
然后我們?cè)偌右粋€(gè)條件word:you
纯路,獲得新的bitset[0,1,1]
條件和起來(lái)的意思是word:are && word:you
或油,所以我們就做位運(yùn)算就可以了,可得到新集合[0, 1, 0]
驰唬,到這里完成了一次過(guò)濾查詢(xún)顶岸。
關(guān)于緩存
filter的特點(diǎn)就在于緩存速度快,那它是怎么緩存的呢叫编?和我過(guò)去接觸到的kv緩存的方式不一樣辖佣,es會(huì)緩存一些bitset,當(dāng)下次還有filter查詢(xún)的時(shí)候直接訪(fǎng)問(wèn)的bitset搓逾,這樣有以下好處
- bitset的內(nèi)存占用非常小
- 位運(yùn)算速度飛快
- 不需要再次訪(fǎng)問(wèn)倒排索引表
以上表舉例的話(huà)卷谈,當(dāng)我們的查詢(xún)?cè)俅卧O(shè)計(jì)剛才的filter時(shí),直接訪(fǎng)問(wèn)[0, 1, 0]即可霞篡。
以下引用官方文檔中關(guān)于緩存規(guī)則的描述
為了解決問(wèn)題世蔗,Elasticsearch 會(huì)基于使用頻次自動(dòng)緩存查詢(xún)端逼。如果一個(gè)非評(píng)分查詢(xún)?cè)谧罱?256 次查詢(xún)中被使用過(guò)(次數(shù)取決于查詢(xún)類(lèi)型),那么這個(gè)查詢(xún)就會(huì)作為緩存的候選凸郑。但是裳食,并不是所有的片段都能保證緩存 bitset 。只有那些文檔數(shù)量超過(guò) 10,000 (或超過(guò)總文檔數(shù)量的 3% )才會(huì)緩存 bitset 芙沥。因?yàn)樾〉钠慰梢院芸斓倪M(jìn)行搜索和合并诲祸,這里緩存的意義不大。
一旦緩存了而昨,非評(píng)分計(jì)算的 bitset 會(huì)一直駐留在緩存中直到它被剔除救氯。剔除規(guī)則是基于 LRU 的:一旦緩存滿(mǎn)了,最近最少使用的過(guò)濾器會(huì)被剔除歌憨。