<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    CONAN ZONE

    你越掙扎我就越興奮

    BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
      0 Posts :: 282 Stories :: 0 Comments :: 0 Trackbacks
    本文將介紹Solr查詢中涉及到的Cache使用及相關(guān)的實(shí)現(xiàn)。Solr查詢的核心類就是SolrIndexSearcher,

    每個(gè)core通常在 同一時(shí)刻只由當(dāng)前的SolrIndexSearcher供上層的handler使用

    (當(dāng)切換SolrIndexSearcher時(shí)可能會(huì)有兩個(gè)同時(shí)提供服務(wù)),而Solr的各種Cache是依附于SolrIndexSearcher的,SolrIndexSearcher在則Cache 生,SolrIndexSearcher亡則Cache被清空close掉。

    Solr中的應(yīng)用Cache有filterCache、 queryResultCache、documentCache等,這些Cache都是SolrCache的實(shí)現(xiàn)類,

    并且是 SolrIndexSearcher的成員變量,各自有著不同的邏輯和使命,下面分別予以介紹和分析。

    1、SolrCache接口實(shí)現(xiàn)類

    Solr提供了兩種SolrCache接口實(shí)現(xiàn)類:solr.search.LRUCache和solr.search.FastLRUCache。

    FastLRUCache是1.4版本中引入的,其速度在普遍意義上要比LRUCache更fast些。
    下面是對(duì)SolrCache接口主要方法的注釋:

    public interface SolrCache{publicObjectinit(Mapargs,Objectpersistence, CacheRegenerator regenerator);
    publicintsize();
    publicObjectput(Objectkey,Objectvalue);
    publicObjectget(Objectkey);publicvoidclear();voidwarm(SolrIndexSearcher searcher, SolrCache old)throwsIOException;
    publicvoidclose();}

    1.1、solr.search.LRUCache

    LRUCache可配置參數(shù)如下:

    1)size:cache中可保存的最大的項(xiàng)數(shù),默認(rèn)是1024
    2)initialSize:cache初始化時(shí)的大小,默認(rèn)是1024。
    3)autowarmCount:
    當(dāng)切換SolrIndexSearcher時(shí),可以對(duì)新生成的SolrIndexSearcher做autowarm(預(yù)熱)處理。
    autowarmCount表示從舊的SolrIndexSearcher中取多少項(xiàng)來(lái)在新的SolrIndexSearcher中被重新生成,

    如何重新生成由CacheRegenerator實(shí)現(xiàn)。在當(dāng)前的1.4版本的Solr中,這個(gè)autowarmCount只能取預(yù)熱的項(xiàng)數(shù),

    將來(lái)的4.0版本可以指定為已有cache項(xiàng)數(shù)的百分比,以便能更好的平衡autowarm的開銷及效果。

    如果不指定該參數(shù),則表示不做autowarm處理。實(shí)現(xiàn)上,LRUCache直接使用LinkedHashMap來(lái)緩存數(shù)據(jù),

    由initialSize來(lái)限定cache的大小,淘汰策略也是使用LinkedHashMap的內(nèi)置的LRU方式,

    讀寫操作都是對(duì)map的全局鎖,所以并發(fā)性效果方面稍差。

    1.2、solr.search.FastLRUCache

    在配置方面,F(xiàn)astLRUCache除了需要LRUCache的參數(shù),還可有選擇性的指定下面的參數(shù):

    1)minSize:當(dāng)cache達(dá)到它的最大數(shù),淘汰策略使其降到minSize大小,默認(rèn)是0.9*size。
    2)acceptableSize:當(dāng)淘汰數(shù)據(jù)時(shí),期望能降到minSize,但可能會(huì)做不到,則可勉為其難的降到acceptableSize,

    默認(rèn)是0.95*size。

    3)cleanupThread:相比LRUCache是在put操作中同步進(jìn)行淘汰工作,F(xiàn)astLRUCache可選擇由獨(dú)立的線程來(lái)做,

    也就是配置cleanupThread的時(shí)候。當(dāng)cache大小很大時(shí),每一次的淘汰數(shù)據(jù)就可能會(huì)花費(fèi)較長(zhǎng)時(shí)間,

    這對(duì)于提供查詢請(qǐng)求的線程來(lái)說(shuō)就不太合適,由獨(dú)立的后臺(tái)線程來(lái)做就很有必要。實(shí)現(xiàn)上,

    FastLRUCache內(nèi)部使用了ConcurrentLRUCache來(lái)緩存數(shù)據(jù),它是個(gè)加了LRU淘汰策略的ConcurrentHashMap,

    所以其并發(fā)性要好很多,這也是多數(shù)Java版Cache的極典型實(shí)現(xiàn)。

    2、filterCache

    filterCache存儲(chǔ)了無(wú)序的lucene document id集合,該cache有3種用途:

    1)filterCache
    存儲(chǔ)了filter queries(“fq”參數(shù))得到的document id集合結(jié)果。Solr中的query參數(shù)有兩種,即q和fq。如果fq存在,

    Solr是先查詢fq(因?yàn)閒q可以多個(gè),所以多個(gè)fq查詢是個(gè)取結(jié)果交集 的過(guò)程),之后將fq結(jié)果和q結(jié)果取并。

    在這一過(guò)程中,filterCache就是key為單個(gè)fq(類型為Query),value為documentid集合(類型為DocSet)的cache。

    對(duì)于fq為range query來(lái)說(shuō),filterCache表現(xiàn)出其有價(jià)值的一面。
    2)filterCache
    還可用于facet查詢(http://wiki.apache.org/solr/SolrFacetingOverview),facet查詢中各
    facet的計(jì)數(shù)是通過(guò)對(duì)滿足query條件的document
    id集合(可涉及到filterCache)的處理得到的。因?yàn)榻y(tǒng)計(jì)各facet計(jì)數(shù)可能會(huì)涉及到所有的doc
    id,所以filterCache的大小需要能容下索引的文檔數(shù)。
    3)如果solfconfig.xml中配置了<useFilterForSortedQuery/>,

    那么如果查詢有filter(此filter是一需要過(guò)濾的DocSet,而不是fq,我未見(jiàn)得它有什么用),

    則使用filterCache。

    下面是filterCache的配置示例:

    <!-- Internal cache used by SolrIndexSearcher for filters (DocSets),unordered sets of *all* documents
    that match a query.When a new searcher is opened, its caches may be prepopulatedor "autowarmed"
     using data from caches in the old searcher.autowarmCount is the number of items to prepopulate.
    For LRUCache,the prepopulated items will be the most recently accessed items.-->
    <filterCacheclass="solr.LRUCache"size="16384"initialSize="4096"/>

    對(duì)于是否使用filterCache及如何配置filterCache大小,需要根據(jù)應(yīng)用特點(diǎn)、統(tǒng)計(jì)、效果、經(jīng)驗(yàn)等各方面來(lái)評(píng)估。

    對(duì)于使用fq、facet的應(yīng)用,對(duì)filterCache的調(diào)優(yōu)是很有必要的。

    3、queryResultCache

    顧名思義,queryResultCache是對(duì)查詢結(jié)果的緩存(SolrIndexSearcher中的cache緩存的都是document id set),
    這個(gè)結(jié)果就是針對(duì)查詢條件的完全有序的結(jié)果。 下面是它的配置示例:
    <!-- queryResultCache caches results of searches - ordered lists ofdocument ids (DocList) based on a query, a sort, and the rangeof documents requested.-->
    <queryResultCacheclass="solr.LRUCache"size="16384"initialSize="4096"/>
    
    緩存的key是個(gè)什么結(jié)構(gòu)呢?就是下面的類(key的hashcode就是QueryResultKey的成員變量hc):
    publicQueryResultKey(Query query, List<Query>filters, Sort sort,intnc_flags)
    {
    this.query=query;
    this.sort=sort;
    this.filters=filters;
    this.nc_flags=nc_flags;
    inth=query.hashCode();
    if(filters!=null)h^=filters.hashCode();
    sfields=(this.sort!=null)?this.sort.getSort():defaultSort;
    for(SortField sf:sfields)
    { // mix the bits so that sortFields are position dependent
    // so that a,b won't hash to the same value as b,ah^=(h<<8)|(h>>>25);
    // reversible hashif(sf.getField()!=null)h+=sf.getField().hashCode();h+=sf.getType();
    if(sf.getReverse())h=~h;if(sf.getLocale()!=null)h+=sf.getLocale().hashCode();
    if(sf.getFactory()!=null)h+=sf.getFactory().hashCode();}hc=h;
    }
    因?yàn)椴樵儏?shù)是有start和rows的,所以某個(gè)QueryResultKey可能命中了cache,但start和rows卻不在cache的
    document id set范圍內(nèi)。當(dāng)然,document id
    set是越大命中的概率越大,但這也會(huì)很浪費(fèi)內(nèi)存,這就需要個(gè)參數(shù):queryResultWindowSize來(lái)指定document id
    set的大小。Solr中默認(rèn)取值為50,可配置,WIKI上的解釋很深簡(jiǎn)單明了:
    <!-- An optimization for use with the queryResultCache. When a searchis requested, a superset of the requested number
    of document idsare collected.  For example, of a search for a particular queryrequests matching documents 10 
    through 19, and queryWindowSize is 50,then documents 0 through 50 will be collected and cached.
    Any furtherrequests in that range can be satisfied via the cache.-->
    <queryResultWindowSize>50</queryResultWindowSize>
    相比f(wàn)ilterCache來(lái)說(shuō),queryResultCache內(nèi)存使用上要更少一些,但它的效果如何就很難說(shuō)。
    就索引數(shù)據(jù)來(lái)說(shuō),通常我們只是在索引上存儲(chǔ)應(yīng)用主鍵id,再?gòu)臄?shù)據(jù)庫(kù)等數(shù)據(jù)源獲取其他需要的字段。
    這使得查詢過(guò)程變成,首先通過(guò)solr得到document id set,再由Solr得到應(yīng)用id集合,
    最后從外部數(shù)據(jù)源得到完成的查詢結(jié)果。如果對(duì)查詢結(jié)果正確性沒(méi)有苛刻的要求,可以在Solr之外獨(dú)立的緩存完整的

    查詢結(jié)果(定時(shí)作廢),這時(shí)queryResultCache就不是很有必要,否則可以考慮使用queryResultCache。當(dāng)然,如果發(fā)現(xiàn)在
    queryResultCache生命周期內(nèi),query重合度很低,也不是很有必要開著它。

    4、documentCache

    又顧名思義,documentCache用來(lái)保存<doc_id,document>對(duì)的。如果使用documentCache,就盡可能開大

    些,至少要大過(guò)<max_results> *<max_concurrent_queries>,否則因?yàn)閏ache的淘汰,
    一次請(qǐng)求期間還需要重新獲取document一次。也要注意document中存儲(chǔ)的字段的多少,避免大量的內(nèi)存消耗。
    下面是documentCache的配置示例:<!-- documentCache caches Lucene Document objects (the stored fields for each document).-->
    <documentCacheclass="solr.LRUCache"size="16384"initialSize="16384"/>
    
    5、User/Generic Caches 
    Solr支持自定義Cache,只需要實(shí)現(xiàn)自定義的regenerator即可,下面是配置示例:<!-- Example of a generic cache. These caches may be accessed by namethrough SolrIndexSearcher.getCache(),
    cacheLookup(), and cacheInsert().The purpose is to enable easy caching of user/application level data.
    The regenerator argument should be specified as an implementationof solr.search.CacheRegenerator if
     autowarming is desired.--><!--<cache name="yourCacheNameHere"class="solr.LRUCache"size="4096"
    initialSize="2048"regenerator="org.foo.bar.YourRegenerator"/>-->
    6、The Lucene FieldCache 
    lucene中有相對(duì)低級(jí)別的FieldCache,Solr并不對(duì)它做管理,所以,lucene的FieldCache還是由lucene的IndexSearcher來(lái)搞。

    7、autowarm

    上面有提到autowarm,autowarm觸發(fā)的時(shí)機(jī)有兩個(gè),一個(gè)是創(chuàng)建第一個(gè)Searcher時(shí)(firstSearcher),一個(gè)是創(chuàng)建個(gè)新

    Searcher(newSearcher)來(lái)代替當(dāng)前的Searcher。在Searcher提供請(qǐng)求服務(wù)前,Searcher中的各個(gè)Cache可以
    做warm處理,處理的地方通常是SolrCache的init方法,而不同cache的warm策略也不一樣。
    1)filterCache:filterCache注冊(cè)了下面的CacheRegenerator,就是由舊的key查詢索引得到新值put到新cache中。solrConfig.filterCacheConfig.setRegenerator(newCacheRegenerator(){publicbooleanregenerateItem
    (SolrIndexSearcher newSearcher, SolrCache newCache, SolrCache oldCache,ObjectoldKey,ObjectoldVal)
    throwsIOException{newSearcher.cacheDocSet((Query)oldKey,null,false);returntrue;}});
    2)queryResultCache:queryResultCache的autowarm不在SolrCache的init(也就是說(shuō),不是去遍歷已
    有的queryResultCache中的query key執(zhí)行查詢),而是通過(guò)SolrEventListener接口的void
    newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher
    currentSearcher)方法,來(lái)執(zhí)行配置中特定的query查詢,達(dá)到顯示的預(yù)熱lucene FieldCache的效果。
    queryResultCache的配置示例如下:
    <listenerevent="newSearcher"class="solr.QuerySenderListener"><arrname="queries"><!-- seed common sort fields --><lst>
    <strname="q">anything</str><strname="sort">name desc price desc populartiy desc</str></lst></arr>
    </listener><listenerevent="firstSearcher"class="solr.QuerySenderListener"><arrname="queries">
    <!-- seed common sort fields --><lst><strname="q">anything</str><strname="sort">
    name desc, price desc, populartiy desc</str></lst><!-- seed common facets and filter queries -->
    <lst><strname="q">anything</str><strname="facet.field">category</str>
    <strname="fq">inStock:true</str><strname="fq">price:[0 TO 100]</str></lst></arr></listener>
    3)documentCache:因?yàn)樾滤饕膁ocument id和索引文檔的對(duì)應(yīng)關(guān)系發(fā)生變化,所以documentCache沒(méi)有warm的過(guò)程,
    落得白茫茫一片真干凈。盡管autowarm很好,也要注意autowarm帶來(lái)的開銷,這需要在實(shí)際中檢驗(yàn)其warm的開銷,
    也要注意Searcher的切換頻率,避免因?yàn)閣arm和切換影響Searcher提供正常的查詢服務(wù)。

    8、參考文章
    http://wiki.apache.org/solr/SolrCaching
    posted on 2012-06-13 14:12 CONAN 閱讀(1863) 評(píng)論(0)  編輯  收藏 所屬分類: Solr
    主站蜘蛛池模板: 亚洲视频在线观看免费视频| 久久亚洲精品中文字幕三区| 亚洲中文无码线在线观看| 青青青国产手机频在线免费观看 | 一本久久免费视频| 国产一区视频在线免费观看| 亚洲精品无码久久久久APP| 成人免费一区二区三区在线观看| 亚洲ts人妖网站| 全免费a级毛片免费看无码| 国产精品手机在线亚洲| 免费真实播放国产乱子伦| 五级黄18以上免费看| 亚洲乱码无码永久不卡在线| 国产成人精品一区二区三区免费| 亚洲国产综合专区在线电影| 亚洲高清视频免费| 亚洲综合av一区二区三区| 国产精品免费视频网站| 又硬又粗又长又爽免费看| 中文字幕亚洲不卡在线亚瑟| 任你躁在线精品免费| 久久久久久亚洲AV无码专区| 成人毛片视频免费网站观看| 国产精品亚洲综合网站| 国产亚洲精品无码专区| 182tv免费观看在线视频 | 欧洲乱码伦视频免费国产| 亚洲国产精品无码av| 国产大片91精品免费观看不卡| 狠狠色伊人亚洲综合网站色| 亚洲AV成人潮喷综合网| 69视频免费在线观看| 亚洲色欲色欲www在线播放| 亚洲男人的天堂在线va拉文| 高清一区二区三区免费视频| 亚洲最大无码中文字幕| 中文字幕在亚洲第一在线| 91在线视频免费看| 你好老叔电影观看免费| 亚洲人精品亚洲人成在线|