精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

一口氣看完 43 個(gè)關(guān)于 ElasticSearch 的使用建議

開源
最近十年,Elasticsearch 已經(jīng)成為了最受歡迎的開源檢索引擎,并沉淀了大量的實(shí)踐案例及優(yōu)化總結(jié)。在本文中,我們盡可能全面地總結(jié)了 Elasticsearch 日常開發(fā)中的一些重要實(shí)踐&避坑指南,希望能為大家提供 Elasticsearch 使用上的一些借鑒點(diǎn),歡迎討論!

一、前言

本文分享了在工作中關(guān)于 ElasticSearch 的一些使用建議。和其他更偏向手冊化更注重結(jié)論的文章不同,本文將一定程度上闡述部分建議背后的原理及使用姿勢參考,避免流于表面,只知其然而不知其所以然。如有不當(dāng)?shù)牡胤剑瑲g迎指正!

二、查詢相關(guān)

充分利用緩存

  • 分片查詢緩存(Shard Request Cache)

ES 層面的緩存實(shí)現(xiàn),封裝在 IndicesRequestCache 類中。緩存的 Key 是整個(gè)客戶端請求,緩存內(nèi)容為單個(gè)分片的查詢結(jié)果。主要作用是對聚合的緩存,查詢結(jié)果中被緩存的內(nèi)容主要包括:Aggregations(聚合結(jié)果)、Hits.total、以及 Suggestions等。

并非所有的分片級查詢都會(huì)被緩存。只有客戶端查詢請求中 size=0 的情況下才會(huì)被緩存。其他不被緩存的條件還包括 Scroll、設(shè)置了 Profile 屬性,查詢類型不是 QUERY_THEN_FETCH,以及設(shè)置了 requestCache=false 等。另外一些存在不確定性的查詢例如:范圍查詢帶有 Now,由于它是毫秒級別的,緩存下來沒有意義,類似的還有在腳本查詢中使用了 Math.random() 等函數(shù)的查詢也不會(huì)進(jìn)行緩存。

當(dāng)有新的 Segment 寫入到分片后,緩存會(huì)失效,因?yàn)橹暗木彺娼Y(jié)果已經(jīng)無法代表整個(gè)分片的查詢結(jié)果。所以分片每次 Refresh 之后,緩存會(huì)被清除。

  • 節(jié)點(diǎn)查詢緩存/過濾器緩存(Node Query Cache /Filter Cache)

Lucene 層面的緩存實(shí)現(xiàn),封裝在 LRUQueryCache 類中,默認(rèn)開啟。緩存的是某個(gè) Filter 子查詢語句在一個(gè) Segment 上的查詢結(jié)果。

并非所有的 Filter 查詢都會(huì)被緩存。對于體積較小的 Segment 不會(huì)建立 Query Cache,因?yàn)樗麄兒芸鞎?huì)被合并。Segment 的 Doc 數(shù)量需要大于 10000,并且占整個(gè)分片的 3% 以上才會(huì)走 Cache 策略(參考:緩存)。

當(dāng) Segment 合并的時(shí)候,被刪除的 Segment 其關(guān)聯(lián) Cache 會(huì)失效。

01. 使用過濾器上下文(Filter)替代查詢上下文(Query)。

  • Filter不會(huì)進(jìn)行打分操作,而 Must 會(huì)。
  • Filter 查詢可以被緩存,從而提高查詢性能。

正例:

// 創(chuàng)建BoolQueryBuilder
    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();


    // 構(gòu)建過濾器上下文
    boolQuery.filter(QueryBuilders.termQuery("field", "value"));

反例:

// 創(chuàng)建BoolQueryBuilder
    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();


    // 構(gòu)建查詢上下文
    boolQuery.must(QueryBuilders.termQuery("field1", "value1"));

02. 只關(guān)注聚合結(jié)果而不關(guān)注文檔細(xì)節(jié)時(shí),Size 設(shè)置為 0 利用分片查詢緩存。

參考示例:

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();


    // 添加聚合查詢
    sourceBuilder.aggregation(
        AggregationBuilders.terms("term_agg").field("field")
            .subAggregation(AggregationBuilders.sum("sum_agg").field("field"))
        );


    // 設(shè)置size為0,只返回聚合結(jié)果而不返回文檔
    sourceBuilder.size(0);

03. 日期范圍查詢使用絕對時(shí)間值。

日期字段上使用 Now,一般來說不會(huì)被緩存,因?yàn)槠ヅ涞降臅r(shí)間一直在變化。因此, 可以從業(yè)務(wù)的角度來考慮是否一定要用 Now,盡量使用絕對時(shí)間值,不需要解析相對時(shí)間表達(dá)式且利用 Query Cache 能夠提高查詢效率。例如時(shí)間范圍查詢中使用 Now/h,使用小時(shí)級別的單位,可以讓緩存在 1 小時(shí)內(nèi)都可能被訪問到。

正例:

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();


        // 獲取當(dāng)前日期并格式化為絕對時(shí)間值
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE;
        String currentDate = now.format(formatter);


        // 創(chuàng)建日期范圍查詢
        sourceBuilder.query(QueryBuilders.rangeQuery("date_field")
                .gte("2022-01-01")
                .lte(currentDate));
反例:
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();


        // 創(chuàng)建日期范圍查詢,使用相對時(shí)間值
        sourceBuilder.query(QueryBuilders.rangeQuery("date_field")
                .gte("now-7d")
                .lte("now"));

聚合查詢

04.避免多層聚合嵌套查詢。

聚合查詢的中間結(jié)果和最終結(jié)果都會(huì)在內(nèi)存中進(jìn)行,嵌套過多,會(huì)導(dǎo)致內(nèi)存耗盡。

如:

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();


        // 創(chuàng)建主要查詢
        sourceBuilder.query(QueryBuilders.matchAllQuery());


        // 創(chuàng)建第一層聚合
        TermsAggregationBuilder termAggBuilder1 = AggregationBuilders.terms("term_agg1").field("field_name1");


        // 創(chuàng)建第二層聚合
        TermsAggregationBuilder termAggBuilder2 = AggregationBuilders.terms("term_agg2").field("field_name2");
        termAggBuilder1.subAggregation(termAggBuilder2);


        // 創(chuàng)建第三層聚合
        TermsAggregationBuilder termAggBuilder3 = AggregationBuilders.terms("term_agg3").field("field_name3");
        termAggBuilder2.subAggregation(termAggBuilder3);


        sourceBuilder.aggregation(termAggBuilder1);

05. 嵌套查詢建議使用 Composite 聚合查詢方式。

對于常見的 Group by A,B,C 這種多維度 Groupby 查詢,嵌套聚合的性能很差,嵌套聚合被設(shè)計(jì)為在每個(gè)桶內(nèi)進(jìn)行指標(biāo)計(jì)算,對于平鋪的 Group by 來說有存在很多冗余計(jì)算,另外在 Meta 字段上的序列化反序列化代價(jià)也非常大,這類 Group by 替換為 Composite 可以將查詢速度提升 2 倍左右。

正例:

// 創(chuàng)建Composite Aggregation構(gòu)建器
        CompositeAggregationBuilder compositeAggregationBuilder = AggregationBuilders
                .composite("group_by_A_B_C")
                .sources(
                        AggregationBuilders.terms("group_by_A").field("fieldA.keyword"),
                        AggregationBuilders.terms("group_by_B").field("fieldB.keyword"),
                        AggregationBuilders.terms("group_by_C").field("fieldC.keyword")
                );


        // 創(chuàng)建查詢條件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
                .query(QueryBuilders.matchAllQuery())
                .aggregation(compositeAggregationBuilder)
                .size(0);

反例:

// 創(chuàng)建Terms Aggregation構(gòu)建器,按照字段A分組
        TermsAggregationBuilder termsAggregationA = AggregationBuilders.terms("group_by_A").field("fieldA.keyword");


        // 在字段A的基礎(chǔ)上創(chuàng)建Terms Aggregation構(gòu)建器,按照字段B分組
        TermsAggregationBuilder termsAggregationB = AggregationBuilders.terms("group_by_B").field("fieldB.keyword");


        // 在字段B的基礎(chǔ)上創(chuàng)建Terms Aggregation構(gòu)建器,按照字段C分組
        TermsAggregationBuilder termsAggregationC = AggregationBuilders.terms("group_by_C").field("fieldC.keyword");


        // 將字段C的聚合添加到字段B的聚合中
        termsAggregationB.subAggregation(termsAggregationC);


        // 將字段B的聚合添加到字段A的聚合中
        termsAggregationA.subAggregation(termsAggregationB);


        // 創(chuàng)建查詢條件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
                .query(QueryBuilders.matchAllQuery())
                .aggregation(termsAggregationA)
                .size(0);

06. 避免大聚合查詢。

聚合查詢的中間結(jié)果和最終結(jié)果都會(huì)在內(nèi)存中進(jìn)行,數(shù)據(jù)量太大會(huì)導(dǎo)致內(nèi)存耗盡。

07. 高基數(shù)場景嵌套聚合查詢建議使用 BFS 搜索。

聚合是在 ES 內(nèi)存完成的。當(dāng)一個(gè)聚合操作包含了嵌套的聚合操作時(shí),每個(gè)嵌套的聚合操作都會(huì)使用上一級聚合操作中構(gòu)建出的桶作為輸入,然后根據(jù)自己的聚合條件再進(jìn)行桶的進(jìn)一步分組。這樣對于每一層嵌套,都會(huì)再次動(dòng)態(tài)構(gòu)建一組新的聚合桶。在高基數(shù)場景,嵌套聚合操作會(huì)導(dǎo)致聚合桶數(shù)量隨著嵌套層數(shù)的增加指數(shù)級增長,最終結(jié)果就是占用 ES 大量內(nèi)存,從而導(dǎo)致 OOM 的情況發(fā)生。

默認(rèn)情況下,ES 使用 DFS(深度優(yōu)先)搜索。深度優(yōu)先先構(gòu)建完整的樹,然后修剪無用節(jié)點(diǎn)。BFS(廣度優(yōu)先)先執(zhí)行第一層聚合,再繼續(xù)下一層聚合之前會(huì)先做修剪。

在聚合查詢中,使用廣度優(yōu)先算法需要在每個(gè)桶級別上緩存文檔數(shù)據(jù),然后在剪枝階段后向子聚合重放這些文檔。因此,廣度優(yōu)先算法的內(nèi)存消耗取決于每個(gè)桶中的文檔數(shù)量。對于許多聚合查詢,每個(gè)桶中的文檔數(shù)量都非常大,聚合可能會(huì)有數(shù)千或數(shù)十萬個(gè)文檔。

但是,有大量桶但每個(gè)桶中文檔數(shù)量相對較少的情況下,使用廣度優(yōu)先算法能更加高效地利用內(nèi)存資源,而且可以讓我們構(gòu)建更加復(fù)雜的聚合查詢。雖然可能會(huì)產(chǎn)生大量的桶,但每個(gè)桶中只有相對較少的文檔,因此使用廣度優(yōu)先搜索算法可以更加節(jié)約內(nèi)存。

參考示例:

searchSourceBuilder.aggregation(
        AggregationBuilders.terms("brandIds")
                .collectMode(Aggregator.SubAggCollectionMode.BREADTH_FIRST)
                .field("brandId")
                .size(2000)
                .order(BucketOrder.key(true))
);

08.避免對 text 字段類型使用聚合查詢。

  • text 的 Fielddata 會(huì)加大對內(nèi)存的占用,如有需求使用,建議使用 Keyword。

09. 不建議使用 bucket_sort 進(jìn)行聚合深分頁查詢。

ES 的高 Cardinality 聚合查詢非常消耗內(nèi)存,超過百萬基數(shù)的聚合很容易導(dǎo)致節(jié)點(diǎn)內(nèi)存不夠用以至 OOM。

bucket_sort 使用桶排序算法,性能問題主要是由于它需要在內(nèi)存中緩存所有的文檔和聚合桶,然后才能進(jìn)行排序和分頁,隨著文檔數(shù)量增多和分頁深度增加,性能會(huì)逐漸變差,有深分頁問題。因?yàn)橥芭判蛐枰獙λ形臋n進(jìn)行整體排序,所以它的時(shí)間復(fù)雜度是 O(NlogN),其中 N 是文檔總數(shù)。

目前Elasticsearch支持聚合分頁(滾動(dòng)聚合)的目前只有復(fù)合聚合(Composite Aggregation)一種。滾動(dòng)的方式類似于SearchAfter。聚合時(shí)指定一個(gè)復(fù)合鍵,然后每個(gè)分片都按照這個(gè)復(fù)合鍵進(jìn)行排序和聚合,不需要在內(nèi)存中緩存所有文檔和桶,而是可以每次返回一頁的數(shù)據(jù)。

反例:使用 bucket_sort 深分頁 RT 達(dá)到 5000ms+

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
  boolQuery.filter(QueryBuilders.termQuery(EsNewApplyDocumentFields.IS_DEL, 0));
  TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("spuIdAgg").field("spuId").order(BucketOrder.key(false)).size(pageNum*pageSize);
  termsAggregationBuilder.subAggregation(new BucketSortPipelineAggregationBuilder("spuBucket",null).from((pageNum-1)*pageSize).size(pageSize));  searchSourceBuilder.query(boolQuery).aggregation(termsAggregationBuilder).size(0);

正例:使用 Composite Aggregation 優(yōu)化后深分頁查詢:423ms

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.filter(QueryBuilders.termQuery(EsNewApplyDocumentFields.IS_DEL, 0));
        CompositeAggregationBuilder compositeBuilder = new CompositeAggregationBuilder(
                "spuIdAgg",
                Collections.singletonList(new TermsValuesSourceBuilder("spuId").field("spuId").order("desc"))
        ).aggregateAfter(ImmutableMap.of("spuId", "603030")).size(20);
        searchSourceBuilder.query(boolQuery).aggregation(compositeBuilder).aggregation(totalAgg).size(0);

分頁

10. 避免使用 from+size 方式。

ES 中深度翻頁排序的花費(fèi)會(huì)隨著分頁的深度而成倍增長,分頁搜索不會(huì)單獨(dú)“Cache”。每次分頁的請求都是一次重新搜索的過程,而不是從第一次搜索的結(jié)果中獲取。如果數(shù)據(jù)特別大對 CPU 和內(nèi)存的消耗會(huì)非常巨大甚至?xí)?dǎo)致 OOM。

11. 避免高實(shí)時(shí)性&大結(jié)果集場景使用 Scroll 方式。

基于快照的上下文。實(shí)時(shí)性高的業(yè)務(wù)場景不建議使用。大結(jié)果集場景將生成大量Scroll 上下文,可能導(dǎo)致內(nèi)存消耗過大,建議使用 SearcheAfter 方式。

思考:對于 Scroll 和 SearchAfter 的選用怎么看?兩者分別適用于哪種場景?SearchAfter 可以完全替代 Scroll 嗎?

Scroll 維護(hù)一份當(dāng)前索引段的快照,適用于非實(shí)時(shí)滾動(dòng)遍歷全量數(shù)據(jù)查詢,但大量Contexts 占用堆內(nèi)存的代價(jià)較高;7.10 引入的新特性 Search After + PIT,查詢本質(zhì)是利用前向頁面的一組排序之檢索匹配下一頁,從而保證數(shù)據(jù)一致性;8.10 官方文檔明確指出不再建議使用 Scroll API 進(jìn)行深分頁。如果分頁檢索超過 Top10000+ 推薦使用 PIT + Search After。

12. SearchAfter 分頁/Scroll ID/ 遍歷索引中的數(shù)據(jù)指定 Sort 字段要保證唯一性,否則會(huì)造成分頁/遍歷數(shù)據(jù)不完整或重復(fù)。

13. 建議指定業(yè)務(wù)字段排序,不要采用默認(rèn)打分排序。

ES 默認(rèn)使用“_score”字段按評分排序。如在使用 Scroll API 獲取數(shù)據(jù)時(shí),如果沒有特殊的排序需求,推薦使用"sort":"_doc"讓 ES 按索引順序返回命中文檔,可以節(jié)省排序開銷。原因如下:

  • 使用非文檔 ID 排序,會(huì)導(dǎo)致每次查詢 ES 需要在每個(gè)分片記住上次返回的最后一個(gè)文檔,然后下次查詢中會(huì)對之前已經(jīng)返回的文檔進(jìn)行忽略過濾,同時(shí)在協(xié)調(diào)節(jié)點(diǎn)進(jìn)行排序操作。文檔 ID 排序則不需要上述操作。
  • 對于文檔 ID 排序,ES 內(nèi)部進(jìn)行了特殊優(yōu)化,性能表現(xiàn)更優(yōu)。

14. Scroll 查詢確保顯式調(diào)用 clearScroll() 方法清除 Scroll ID。

否則會(huì)導(dǎo)致 ES 在過期時(shí)間前無法釋放 Scroll 結(jié)果集占用的內(nèi)存資源,同時(shí)也會(huì)占用默認(rèn) 3000 個(gè) Scroll 查詢的容量,導(dǎo)致 too many scroll ID 的查詢拒絕報(bào)錯(cuò),影響業(yè)務(wù)。

其他

15. 注意 Must 和 Should 同時(shí)出現(xiàn)在語句里的時(shí)候,Should 會(huì)失效;注意 Must 和 Should 同時(shí)出現(xiàn)在同一層級的 bool 查詢時(shí),Should 查詢會(huì)失效。

正例:

{"query":{ "bool":{
            "must":[
                {"bool":{
                        "must":[
                            {
                                "term":{
                                    "status.keyword":"1"
                           } }]}},
                {"bool":{
                        "should":[
                            {"term":{
                                    "tag.keyword":"1"
  } } ] }}]}}}

反例:

{"query":{
        "bool":{
            "must":[
                {
                    "term":{
                        "status.keyword":"1"
                    }}],
            "should":[
                {
                    "term":{
                        "tag.keyword":"1"
                    }
   }]}}}
16. 避免查詢 indexName-*。

因?yàn)?Elasticsearch 中的索引名稱是全局可見的,可以通過查詢所有索引的方式來枚舉某個(gè)集群中的所有索引名稱。可以通過在 Elasticsearch 配置文件中設(shè)置 action.destructive_requires_name 參數(shù)來禁止查詢 indexName-*。

17. 腳本使用 Stored 方式,避免使用 Inline 方式。

對于固定結(jié)構(gòu)的 Script,使用 Stored 方式,把腳本通過 Kibana 存入 ES 集群,降低重復(fù)編譯腳本帶來的性能損耗。

正例:

第1步:通過stored方式,建script模版:
POST _script/activity_discount_price
{
  "script":{
        "lang":"painless",
        "source":"doc.xxx.value * params.discount"
  }
}


第2步:調(diào)用script腳本模版:cal_activity_discount
GET index/_search
{
  "script_fields": {
    "discount_price": {
      "script": {
           "id": "activity_discount_price",
           "params":{
               "discount": 0.8
           }
}}}}

反例:

//直接inline方式,請求中傳入腳本:
GET index/_search
{
  "script_fields": {
    "activity_discount_price": {
      "script": {
           "source":"doc.xxx.value * 0.8"
      }
    }
  }
}

18. 避免使用 _all 字段。

_all 字段包含了所有的索引字段,如果沒有獲取原始文檔數(shù)據(jù)的需求,可通過設(shè)置Includes、Excludes 屬性來定義放入 _source 的字段。_all 默認(rèn)將寫入的字段拼接成一個(gè)大的字符串,并對該字段進(jìn)行分詞,用于支持整個(gè) Doc 的全文檢索,“_all”字段在查詢時(shí)占用更多的 CPU,同時(shí)占用更多的磁盤存儲(chǔ)空間,默認(rèn)為“false”,不建議開啟該字段和使用。

19. 建議用 Get 查詢替換 Search 查詢。

GET/MGET 直接根據(jù)文檔 ID 從正排索引中獲取內(nèi)容。Search 不指定_id,根據(jù)關(guān)鍵詞從倒排索引中獲取內(nèi)容。

20. 避免進(jìn)行多索引查詢。

反例:

GET /index1,index2,index3/_search
{
  "query": {
    "match_all": {}
  }
}

21. 避免單次召回大量數(shù)據(jù),建議使用 _source_includes 和 _source_excludes 參數(shù)來包含或排除字段。

大型文檔尤其有用,部分字段檢索可以節(jié)省網(wǎng)絡(luò)開銷。

參考示例:

// 創(chuàng)建SearchSourceBuilder,并設(shè)置查詢條件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery());


        // 設(shè)置要包含的字段
        String[] includes = {"field1", "field2"};
        sourceBuilder.fetchSource(includes, Strings.EMPTY_ARRAY);


        // 設(shè)置要排除的字段
        String[] excludes = {"field3"};
        sourceBuilder.fetchSource(Strings.EMPTY_ARRAY, excludes);

22. 避免使用 Wildcard 進(jìn)行中綴模糊查詢。

ES 官方文檔并不推薦使用 Wildcard 來進(jìn)行中綴模糊的查詢,原因在于 ES 內(nèi)部為了加速這種帶有通配符查詢,會(huì)將輸入的字符串 Pattern 構(gòu)建成一個(gè) DFA (Deterministic Finite Automaton),而帶有通配符的 Pattern 構(gòu)造出來的 DFA 可能會(huì)很復(fù)雜,開銷很大。

建議使用 ES 官方在 7.9 推出的一種專門用來解決模糊查詢慢的 Wildcard 字段類型。與 Text 字段相比,它不會(huì)將文本看作是標(biāo)點(diǎn)符號分割的單詞集合;與 Keyword 字段比,它在中綴搜索場景下具有無與倫比的查詢速度,且對輸入沒有大小限制,這是 Keyword 類型無法相比的。

23. 避免使用 Scripting。

Painless 腳本語言語法相對簡單,靈活度高,安全性高,性能高(相對于其他腳本,但是其性能比 DSL 要低)。不適用于非復(fù)雜業(yè)務(wù),一般 DSL 能解決大部分的問題,解決不了的用類似 Painless 等腳本語言。主要性能影響如下:單次查詢或更新耗時(shí)增加,腳本的執(zhí)行時(shí)間相比于其他查詢和更新操作可能會(huì)更長,因?yàn)樵趫?zhí)行腳本之前需要對其進(jìn)行詞法分析、語法分析和代碼編譯等預(yù)處理工作。

24. 避免使用腳本查詢(Script Query)計(jì)算動(dòng)態(tài)字段,建議在索引時(shí)計(jì)算并在文檔中添加該字段。

例如,我們有一個(gè)包含大量用戶信息的索引,我們需要查詢以"1234"開頭的所有用戶。運(yùn)行一個(gè)腳本查詢?nèi)?source":“doc[‘num’].value.startsWith(‘1234’)”。這個(gè)查詢非常耗費(fèi)資源,索引時(shí)考慮添加“num_prefix”的keyword字段,然后查詢"name_prefix":“1234”。

三、寫入相關(guān)

25. 避免代碼中或手工直接 Refresh 操作。

合理設(shè)置索引 Settings/Refresh_Interval 時(shí)間,通過系統(tǒng)完成 Refresh 動(dòng)作。

26. 避免單個(gè)文檔過大。

鑒于默認(rèn) http.max_content_length 設(shè)置為 100MB,Elasticsearch 將拒絕索引任何大于該值的文檔。

27. 寫入數(shù)據(jù)不指定 Doc_ID,讓 ES 自動(dòng)生成。

索引具有顯式 ID 的文檔時(shí) ES 在寫入過程中會(huì)多一步判斷的過程,即檢查具有相同ID 的文檔是否已經(jīng)存在于相同的分片中,隨著索引增長而變得更加昂貴。

28. 合理使用 Bulk API 批量寫。

大數(shù)據(jù)量寫入時(shí)可以使用 Bulk,但是請求響應(yīng)的耗時(shí)會(huì)增加,即使連接斷開,ES 集群內(nèi)部也仍然在執(zhí)行。高速大批量數(shù)據(jù)寫入時(shí),可能造成集群短時(shí)間內(nèi)響應(yīng)緩慢甚至假死的的情況。

  • 可以通過性能測試確定最佳數(shù)量,官方建議大約 5-15mb。
  • 超時(shí)時(shí)間需要足夠長,建議 60s 以上。
  • 寫入端盡量將數(shù)據(jù)輪詢打到不同節(jié)點(diǎn)上。

29. 腳本刷大量數(shù)據(jù),寫入前調(diào)大 Refresh Interval,不建議將副本分片為 0,待寫入完成后再調(diào)回來。

副本分片重新加入節(jié)點(diǎn)會(huì)觸發(fā)副分片恢復(fù) Recovery 流程,如果是大分片會(huì)影響集群性能。

四、索引創(chuàng)建

分片

30. 副本分片數(shù)大于等于 1。

高可用性保證。增加副本數(shù)可以一定程度上提高搜索性能;但會(huì)降低寫入性能,建議每個(gè)主分片對應(yīng) 1-2 個(gè)副本分片即可。

31. 官方建議單分片限制最大數(shù)據(jù)條數(shù)不超過 2^32 - 1。

32. 索引主分片數(shù)量不要設(shè)置過大。

ES 創(chuàng)建好索引后,一般情況下不再動(dòng)態(tài)調(diào)整主分片數(shù)量。

每個(gè)分片本質(zhì)上就是一個(gè) Lucene 索引,因此會(huì)消耗相應(yīng)的文件句柄、內(nèi)存和 CPU 資源。

ES 使用詞頻統(tǒng)計(jì)來計(jì)算相關(guān)性,當(dāng)然這些統(tǒng)計(jì)也會(huì)分配到各個(gè)分片上,如果在大量分片上只維護(hù)了很少的數(shù)據(jù),則將導(dǎo)致最終的文檔相關(guān)性較差。

一般來說,我們遵循一些原則:

  • 讀場景較多則可以設(shè)置少一點(diǎn),寫場景則可以設(shè)置多一些。
  • 控制每個(gè)分片占用的硬盤容量不超過ES的最大 JVM 的堆空間設(shè)置(32G),因此,如果索引的總?cè)萘吭?200G 左右,那分片大小在 7-8 個(gè)左右即可。
  • 考慮一下 Node 數(shù)量,一般一個(gè)節(jié)點(diǎn)對應(yīng)一臺物理機(jī),如果分片數(shù)遠(yuǎn)大于節(jié)點(diǎn)數(shù),則一個(gè)節(jié)點(diǎn)上存在多個(gè)分片,一旦該節(jié)點(diǎn)故障,即使保持了1個(gè)以上的副本,同樣有可能會(huì)導(dǎo)致數(shù)據(jù)丟失,集群無法恢復(fù)。所以, 一般都設(shè)置分片數(shù)不超過節(jié)點(diǎn)數(shù)的 3 倍。

33. 單個(gè)分片數(shù)據(jù)量不要超過 50GB。

單個(gè)索引的規(guī)模控制在 1TB 以內(nèi),單個(gè)分片大小控制在 30 ~ 50GB ,Docs 數(shù)控制在 10 億內(nèi),如果超過建議滾動(dòng)。

Mapping設(shè)計(jì)

34. 避免使用字段動(dòng)態(tài)映射功能,指定具體字段類型,子類型(若需要),分詞器(特別有場景需要)。

35. 對于不需要分詞的字符串字段,使用 Keyword 類型而不是 Text 類型。

36. ES 默認(rèn)字段個(gè)數(shù)最大 1000,建議不要超過 100。

單個(gè) Doc 在建立索引時(shí)的運(yùn)算復(fù)雜度,最大的因素不在于 Doc 的字節(jié)數(shù)或者說某個(gè)字段 Value 的長度,而是字段的數(shù)量。例如在滿負(fù)載的寫入壓力測試中,Mapping 相同的情況下,一個(gè)有 10 個(gè)字段,200 字節(jié)的 Doc, 通過增加某些字段 Value 的長度到 500 字節(jié),寫入 ES 時(shí)速度下降很少,而如果字段數(shù)增加到 20,即使整個(gè) Doc 字節(jié)數(shù)沒增加多少,寫入速度也會(huì)降低一倍。

37. 對于不索引字段,Index 屬性設(shè)置為 False。

在下面的例子中,Title 字段的 Index 屬性被設(shè)置為 False,表示該字段不會(huì)被包含在索引中。而 Content 字段的 Index 屬性默認(rèn)為 True,表示該字段會(huì)被包含在索引中。需要注意的是,即使 Index 屬性被設(shè)置為 False,該字段仍然會(huì)被保存在文檔中,可以被查詢和聚合。

參考示例:

{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "index": false
      },
      "content": {
        "type": "text"
      }
    }
  }
}

38. 避免使用 Nested 或 Parent/Child。

Nested Query慢,Parent/Child Query 更慢,針對 1 個(gè) Document,每一個(gè) Nested Field 都會(huì)生成一個(gè)獨(dú)立的 Document,這將使 Doc 數(shù)量劇增,影響查詢效率尤其是 JOIN 的效率。因此能在 Mapping 設(shè)計(jì)階段搞定的(大寬表設(shè)計(jì)或采用比較 Smart 的數(shù)據(jù)結(jié)構(gòu)),就不要用父子關(guān)系的 Mapping。如果一定要使用 Nested Fields,保證 Nested Fields字段不能過多,目前ES默認(rèn)限制是Index.mapping.nested_fields.limit=50。不建議使用 Nested,那有什么方式來解決 ES 無法 JOIN 的問題?主要有幾種實(shí)現(xiàn)方式:

  • 在文檔建模上盡可能在設(shè)計(jì)時(shí)將業(yè)務(wù)轉(zhuǎn)化有關(guān)聯(lián)關(guān)系的文檔形式,使用扁平的文檔模型。
  • 獨(dú)立索引存儲(chǔ),實(shí)際業(yè)務(wù)層分多次請求實(shí)現(xiàn)。
  • 通過寬表冗余存儲(chǔ)避免關(guān)聯(lián)。
  • 否則 Nested 和 Parent/Child 存儲(chǔ)對性能均有一定影響,由于 Nested 更新子文檔時(shí)需要 Reindex 整個(gè)文檔,所以對寫入性能影響較大,適用于 1 對 n(n 較小)場景;Parent/Child 存儲(chǔ)在相同 Type中,寫入相比 Nested性能高,用于 1 對 n(n 較大)場景,但比 Nested 查詢更慢,官網(wǎng)說是 5-10 倍左右。

39. 避免使用 Norms。

Norm 是索引評分因子,如果不用按評分對文檔進(jìn)行排序,設(shè)置為“False”。

參考示例:

"title": {"type": "string","norms": {"enabled": false}}

對于 Text 類型的字段而言,默認(rèn)開啟了 Norms,而 Keyword 類型的字段則默認(rèn)關(guān)閉了 Norms。

開啟 Norms 之后,每篇文檔的每個(gè)字段需要一個(gè)字節(jié)存儲(chǔ) Norms。對于 Text 類型的字段而言是默認(rèn)開啟 Norms 的,因此對于不需要評分的 Text 類型的字段,可以禁用 Norms。

40. 對不需要進(jìn)行聚合/排序的字段禁用列存 Doc_Values。

面向列的方式存儲(chǔ),主要用戶排序、聚合和訪問腳本中字段值等數(shù)據(jù)訪問場景。幾乎所有字段類型都支持 Doc_Values,值得注意的是,需要分析的字符串字段除外。默認(rèn)情況下,所有支持 Doc_Values 的字段都啟用了這個(gè)功能。如果確定不需要對字段進(jìn)行排序或聚合,或從腳本訪問字段值,則可以禁用此功能以減少冗余存儲(chǔ)成本。

Keyword和Numeric的選擇

Keyword 類型的主要缺點(diǎn)是在聚合的時(shí)候需要構(gòu)建全局序數(shù),而數(shù)值類型則不用。但低基數(shù)字段通常會(huì)命中大量結(jié)果集,例如性別,使用 Numeric 則會(huì)在構(gòu)建 Bitset 上產(chǎn)生很高的代價(jià)。

綜上所述,在類型選擇上可以參考下面的原則:

  • 在僅查詢的情況下,如果有 Range 查詢需求,使用 Numeric,否則使用 KeyWord。
  • 在僅聚合的情況下,如果明確字段是低基數(shù)的,使用 Keyword 配合 Execution_hint:map,其他情況使用 Numeric。
  • 剩下 Term 查詢+聚合的場景,需要綜合考慮 Numeric 類型 Term 查詢構(gòu)建 BitSet 和 Keyword 類型構(gòu)建全局序數(shù)哪個(gè)代價(jià)更大,需要看實(shí)際場景,但是目前所知的最壞情況下,構(gòu)建 Bitset 會(huì)導(dǎo)致 CPU 跑滿,構(gòu)建全局序數(shù)的主要問題是帶來的查詢延遲,也會(huì)給 JVM 帶來一些壓力。

41. 對于極少使用 Range 查詢的數(shù)字值,使用 Keyword 類型。

并非所有數(shù)值數(shù)據(jù)都應(yīng)映射為數(shù)值字段數(shù)據(jù)類型。Elasticsearch 為查詢優(yōu)化數(shù)字字段,例如 Integer or long。如果不需要范圍查找,對于 Term 查詢而言,Keyword 比 Integer 性能更好。

42. 對于有頻繁且較為固定的 Range 查詢字段,增加 Keyword 類型 Pre-Indexing字段。

如果對字段的大多數(shù)查詢在一個(gè)固定的范圍上運(yùn)行 Range 聚合,那么可以增加一個(gè) Keyword 類型的字段,通過將范圍“Pre-Indexing”到索引中并使用 Terms 聚合來加快聚合速度。

43. 對需要聚合查詢的高基數(shù) Keyword 字段啟用 Eager_Global_Ordinals。

參考:eager_global_ordinals

序號(Ordinals)用于在 Keyword 字段上運(yùn)行 Terms 聚合。序號用一個(gè)自增數(shù)值表示,ES 維護(hù)這個(gè)自增數(shù)字與實(shí)際值的映射關(guān)系,并為每一數(shù)值分配一個(gè) Bucket,映射關(guān)系是 Segment 級別的。

但是做聚合操作時(shí)往往需要結(jié)合多個(gè) Segment 的結(jié)果,而每個(gè) Segment 的 Ordinals 映射關(guān)系是不一致的,所以 ES 會(huì)在每個(gè)分片上創(chuàng)建全局序號(Global Ordinals)結(jié)構(gòu) ,一個(gè)全局統(tǒng)一的映射,維護(hù)全局的 Ordinal 與每個(gè) Segment 的 Ordinal 的映射關(guān)系。

默認(rèn)情況下,Global Ordinals 默認(rèn)是延時(shí)構(gòu)建,在第一次查詢?nèi)?Term Aggregation 使用到時(shí)才會(huì)構(gòu)建。因?yàn)?ES 不知道哪些字段將用于 Terms 聚合,哪些字段不會(huì)。對于基數(shù)大的字段,構(gòu)建成本較大。

啟用 eager_global_ordinals 后,Elasticsearch 會(huì)在分片構(gòu)建時(shí)預(yù)先計(jì)算出全局詞項(xiàng)表,以便在查詢時(shí)能夠更快地加載和使用。但啟用 eager_global_ordinals 后,每次執(zhí)行 Refresh 操作都會(huì)構(gòu)建 Global Ordinals,相當(dāng)于把搜索時(shí)候花費(fèi)的構(gòu)建成本轉(zhuǎn)移到寫入時(shí),所以會(huì)對寫入效率有一定的影響,可以配合增大索引的 Refresh Interval 來使用。

參考示例:

PUT index
{
    "mappings": {
        "type": { 
            "properties": {
                "foo": {
                    "type": "keyword",
                    "eager_global_ordinals" : true
                }
            }
        }
    }
}

五、總結(jié)

最近十年,Elasticsearch 已經(jīng)成為了最受歡迎的開源檢索引擎,并沉淀了大量的實(shí)踐案例及優(yōu)化總結(jié)。在本文中,我們盡可能全面地總結(jié)了 Elasticsearch 日常開發(fā)中的一些重要實(shí)踐&避坑指南,希望能為大家提供 Elasticsearch 使用上的一些借鑒點(diǎn),歡迎討論!

參考文章:

1.《Elasticsearch 源碼解析與優(yōu)化實(shí)戰(zhàn)》

2.《Elasticsearch權(quán)威指南》

3.https://www.easyice.cn/archives/367

4.https://www.elastic.co/guide/en/elasticsearch/guide/current/filter-caching.html#_independent_query_caching

5.https://www.elastic.co/guide/cn/elasticsearch/guide/current/_preventing_combinatorial_explosions.html

6.https://www.elastic.co/guide/en/elasticsearch/reference/current/eager-global-ordinals.html

責(zé)任編輯:武曉燕 來源: 得物技術(shù)
相關(guān)推薦

2021-06-08 22:43:07

IPC方式Qt

2021-03-29 12:22:25

微信iOS蘋果

2020-03-31 08:12:25

Kafka架構(gòu)數(shù)據(jù)庫

2020-10-21 06:39:21

CPU寄存器架構(gòu)

2024-01-29 00:29:49

通信技術(shù)行業(yè)

2021-12-06 08:30:49

SpringSpring Bean面試題

2025-05-14 01:55:00

FCMCPAI

2020-10-22 12:30:33

MySQL

2020-09-24 09:08:04

分布式系統(tǒng)架構(gòu)

2020-04-14 13:32:56

@Transacti失效場景

2021-03-01 18:52:39

工具在線瀏覽器

2024-04-26 09:40:10

項(xiàng)目精度丟失javascrip

2022-05-24 11:50:46

延時(shí)消息分布式

2021-05-18 09:03:16

Gomapslice

2020-07-08 07:45:44

OAuth2.0授權(quán)

2022-08-14 15:40:55

表情DIY

2024-03-26 09:42:27

分片算法應(yīng)用

2021-01-04 11:23:21

手機(jī)無線電通訊

2024-03-28 12:52:00

AI模型

2010-03-20 21:51:27

pwn2OwnMac OS X漏洞
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

久久噜噜噜精品国产亚洲综合| 欧美日韩在线不卡| 精品久久久久久乱码天堂| 免费在线观看黄网站| 美日韩中文字幕| 欧美精品乱码久久久久久| 国产日本在线播放| eeuss影院在线观看| 国产高清精品网站| 日韩美女在线观看| 一区二区国产精品精华液| 九色丨蝌蚪丨成人| 欧美精品日韩精品| 日本日本19xxxⅹhd乱影响| av电影在线播放高清免费观看| 成人亚洲精品久久久久软件| 国产精品福利小视频| 久久精品性爱视频| 99久久www免费| 国产视频精品自拍| 伦伦影院午夜理论片| 性欧美超级视频| 亚洲线精品一区二区三区八戒| 日本视频精品一区| 粉嫩av一区二区夜夜嗨| 久久精品国产色蜜蜜麻豆| 69av成年福利视频| 精品处破女学生| 91视频一区| 亚洲偷欧美偷国内偷| aaa黄色大片| 91嫩草国产线观看亚洲一区二区| 91久久精品一区二区三区| 精品国产一区二区三区无码| 免费黄网站在线| 亚洲国产精品av| 久久99九九| 成人免费视频国产免费麻豆| 狠狠色丁香久久婷婷综| 国产精品久久久久aaaa九色| 中文字幕精品无码一区二区| 亚洲国产精品第一区二区| 久久综合色88| 国产午夜精品理论片| 欧美在线色图| 亚洲人成人99网站| 给我看免费高清在线观看| 荡女精品导航| 5566中文字幕一区二区电影| 亚洲综合婷婷久久| 未满十八勿进黄网站一区不卡| 在线看日本不卡| www国产黄色| 樱花草涩涩www在线播放| 午夜精品123| 亚洲午夜精品久久久久久人妖| 91超碰在线免费| 亚洲免费观看高清在线观看| 蜜臀av.com| 性欧美videoshd高清| 《视频一区视频二区| 最新av在线免费观看| 欧美r级在线| 一区二区三区国产精品| av一区二区三区免费观看| 日本大片在线播放| 午夜精品福利一区二区蜜股av| 久久精品国产sm调教网站演员| 男男gaygays亚洲| 丰满岳妇乱一区二区三区| 日韩中文字幕三区| 国产成人精品一区二三区在线观看| 在线观看成人免费视频| 成 人 黄 色 小说网站 s色| 9999精品视频| 精品久久久久久最新网址| 免费看毛片的网站| 色综合综合网| 日韩中文有码在线视频| 欧产日产国产v| 日韩五码在线| 国产成人久久精品| 国产麻豆精品一区| zzijzzij亚洲日本少妇熟睡| 欧美日韩国产精品一卡| 日本三级视频在线播放| 亚洲黄网站在线观看| 精品这里只有精品| 久久91视频| 精品99999| 国产又黄又粗视频| 欧美日韩影院| 欧美在线观看一区二区三区| 亚洲熟妇av乱码在线观看| 国产成人欧美日韩在线电影| 久久综合伊人77777麻豆| 日本最新在线视频| 午夜久久福利影院| 日韩在线不卡一区| 精品少妇3p| 色诱女教师一区二区三区| 久久黄色小视频| 日韩成人一级片| 国产精品一区二区欧美黑人喷潮水| 免费黄色片在线观看| 亚洲免费av观看| 欧美,日韩,国产在线| 狂野欧美性猛交xxxx| 亚洲国产精品专区久久| 日韩一卡二卡在线观看| 国产欧美一级| 91在线在线观看| av在线首页| 精品福利樱桃av导航| 欧美一级特黄aaa| 香蕉视频一区二区三区| 欧美高清无遮挡| 国产精品国产av| 国产人妖乱国产精品人妖| 国产在线播放观看| 久久国产精品美女| 日韩亚洲欧美成人| 无码人妻黑人中文字幕| 北条麻妃国产九九精品视频| 国产卡一卡二在线| 成人网ww555视频免费看| 日韩经典一区二区三区| 久久久国产精品黄毛片| 久久99精品国产.久久久久久| 欧美国产综合视频| 欧美一级鲁丝片| 精品日韩一区二区三区| 久久精品黄色片| 精品亚洲porn| 亚洲电影免费| 巨胸喷奶水www久久久免费动漫| 精品视频久久久久久| 国产福利久久久| 成人性生交大片免费看中文 | 99re只有精品| 中文字幕中文字幕一区二区| 91香蕉视频导航| 欧美系列电影免费观看| 国产精品99久久久久久久久久久久 | 日韩欧美亚洲日产国| 中文字幕在线看片| 日韩毛片在线看| 免费黄色网址在线| 久久久久久**毛片大全| 国产精品丝袜久久久久久消防器材| 美日韩黄色大片| 91a在线视频| 日本一级在线观看| 91精品福利在线| 老司机福利在线观看| 奇米888四色在线精品| 日韩国产美国| 日本午夜免费一区二区| 久久久国产视频91| 国产精品欧美亚洲| 亚洲精品水蜜桃| 国产乱淫av麻豆国产免费| 亚洲一级影院| 蜜桃精品久久久久久久免费影院| 成人免费无遮挡| 色先锋资源久久综合5566| 中文字幕在线观看欧美| 综合久久给合久久狠狠狠97色| 亚洲欧美一区二区三区不卡| 亚洲视频免费| 久热这里只精品99re8久 | 毛片免费不卡| 日韩精品专区在线影院观看 | 精品视频1区2区| 日韩三级在线观看视频| 国产aⅴ精品一区二区三区色成熟| 久久手机在线视频| 天天操综合520| 国产精品丝袜高跟| 亚洲综合影视| 精品视频在线播放免| 一区二区自拍偷拍| 亚洲青青青在线视频| 日韩少妇一区二区| 免费一级片91| 91黄色在线看| 精品色999| 99热在线国产| 欧美黑人巨大xxxxx| 久久精品视频亚洲| 偷拍精品一区二区三区| 欧美日韩精品欧美日韩精品 | 日韩视频免费| 一区二区三区久久网| 成功精品影院| 国产精自产拍久久久久久| 国产网红女主播精品视频| 亚洲欧美中文字幕在线一区| 国产精品区在线观看| 欧美视频在线观看免费| 日本中文字幕免费在线观看| 2021国产精品久久精品| 国产又粗又猛大又黄又爽| 先锋亚洲精品| 黄色成人在线免费观看| 国产中文精品久高清在线不| 国产精品国色综合久久| www.一区| 欧美在线亚洲一区| 黄页网站在线观看免费| 一夜七次郎国产精品亚洲| 欧美熟妇乱码在线一区| 欧美精品 日韩| 亚洲熟女综合色一区二区三区| 一区二区三区**美女毛片| 国产亚洲精品精品精品| 99亚偷拍自图区亚洲| 人妻换人妻仑乱| 老色鬼精品视频在线观看播放| 日韩欧美一区二| 欧美日本三区| 欧美三级午夜理伦三级老人| 精品国产91乱码一区二区三区四区| 国产精品果冻传媒潘| 玖玖玖视频精品| 国产有码一区二区| 成人午夜一级| 国产精品99蜜臀久久不卡二区| 性xxxxfreexxxxx欧美丶| 久久久影视精品| 日韩免费影院| 欧美成人在线免费| 嫩草在线视频| 久久国产一区二区三区| 91官网在线| 亚洲性线免费观看视频成熟| 日本中文字幕一区二区有码在线| 亚洲国产成人av在线| www男人的天堂| 日韩亚洲欧美成人一区| 97超碰中文字幕| 在线播放/欧美激情| 在线视频1卡二卡三卡| 欧美亚洲国产一区在线观看网站| 欧美黄色一级大片| 在线免费观看日本欧美| 无码一区二区三区| 欧美性淫爽ww久久久久无| 日本熟妇一区二区三区| 欧洲一区在线电影| 艳妇乳肉豪妇荡乳av无码福利| 91精品福利视频| 亚洲影视一区二区| 欧美高清精品3d| 国产日本精品视频| 日韩精品中午字幕| 日本高清视频免费观看| 亚洲精品久久久一区二区三区 | 伊人网av在线| 欧美欧美欧美欧美首页| 国产av一区二区三区| 日韩精品一区二区三区在线播放 | 久久亚洲私人国产精品va| 久草免费在线观看| 欧美老少配视频| 成人国产电影在线观看| 日本欧美一级片| 国产成人久久精品麻豆二区| 国产女同一区二区| 亚洲三级av| 裸体丰满少妇做受久久99精品| 国产麻豆精品久久| 中文字幕在线亚洲三区| 在线日韩电影| 又色又爽又高潮免费视频国产| 久久99精品久久久久| 在线观看你懂的视频| 91在线视频免费观看| 精品亚洲aⅴ无码一区二区三区| 亚洲欧洲精品一区二区三区不卡| 欧美精品色哟哟| 欧美丝袜一区二区| 在线观看黄色网| 亚洲成av人乱码色午夜| 国产三级视频在线| 欧美日韩电影在线观看| 国产一区一一区高清不卡| 91亚洲精品久久久| 亚洲另类av| 波多野结衣激情| 欧美亚洲一区二区三区| 一区二区久久精品| 久久久久久久久久看片| 欧产日产国产v| 欧美视频中文字幕| 四虎精品一区二区三区| 日韩视频在线观看免费| 深夜福利视频一区二区| 亚洲自拍欧美色图| 国产影视精品一区二区三区| 国内精品在线观看视频| 麻豆国产欧美日韩综合精品二区| 丰满岳乱妇一区二区| 亚洲色图.com| 国语对白做受69按摩| 亚洲第一精品自拍| 97超碰资源站在线观看| 国产精品人成电影| 欧美尿孔扩张虐视频| 九一免费在线观看| 美女视频第一区二区三区免费观看网站 | 99精品视频99| 欧美成人伊人久久综合网| yw193.com尤物在线| 欧美亚洲午夜视频在线观看| 在线播放一区二区精品视频| 国产精品99久久久久久大便| 日韩精品成人一区二区三区| 人妻av一区二区| 亚洲一区二区三区激情| 国产伦子伦对白视频| 丝袜亚洲欧美日韩综合| 3d性欧美动漫精品xxxx软件| 精品国产一区二区三区四区vr| 欧美日韩国产在线一区| 激情久久综合网| 一区在线观看免费| 在线观看免费黄色小视频| 一区二区欧美激情| 色偷偷色偷偷色偷偷在线视频| 国产欧美日韩在线播放| 亚洲网站在线| www.四虎精品| 亚洲福中文字幕伊人影院| 亚洲黄色在线免费观看| 欧美日本国产在线| 国产精品18hdxxxⅹ在线| 欧美高清中文字幕| 国产成人av电影在线播放| 久久久久99精品成人片试看| 欧美一二三区在线| 欧美男男video| 鬼打鬼之黄金道士1992林正英| 综合天堂av久久久久久久| 九九九久久久久久久| 亚洲伊人伊色伊影伊综合网| 亚洲精品免费在线观看视频| 欧美大片免费观看在线观看网站推荐| 国产一区二区三区免费在线 | 91资源在线观看| 国产欧美日韩在线播放| 亚洲激情在线| 97伦伦午夜电影理伦片| 在线视频观看一区| 视频免费一区| 91在线高清视频| 狠狠干成人综合网| 免费无码一区二区三区| 色综合欧美在线视频区| 国产大片在线免费观看| 国产欧美va欧美va香蕉在线| 亚洲五月综合| 在线观看免费视频黄| 色婷婷久久综合| 日本暖暖在线视频| 51国偷自产一区二区三区的来源 | 五月婷婷六月丁香| 国产91精品最新在线播放| 欧美gay男男猛男无套| 久久艹这里只有精品| 午夜精品一区二区三区电影天堂| 欧美婷婷久久五月精品三区| 国产精品入口免费视| 欧美国产综合| 波多野结衣一本| 6080yy午夜一二三区久久| 不卡一本毛片| 亚洲春色综合另类校园电影| 国产精品影音先锋| 波多野结衣视频网站| 日韩视频亚洲视频| 精品日产乱码久久久久久仙踪林| 日本激情视频在线| 亚洲男人都懂的| 邻居大乳一区二区三区| 亚洲精品日韩av| 免播放器亚洲| 欧美丰满熟妇bbbbbb| 国产视频综合在线| 精品一区二区三区免费看| www国产黄色| 亚洲男同1069视频| 国产日韩精品在线看| 懂色一区二区三区av片| 秋霞影院一区二区| 日本少妇在线观看| 日韩中文字幕在线播放| 日本天堂一区| 亚洲三级在线视频| 欧美唯美清纯偷拍|