別再說你不會 ElasticSearch 調優(yōu)了汽纠,都給你整理好了

第一部分:調優(yōu)索引速度

第二部分-調優(yōu)搜索速度

第三部分:通用的一些建議

英文原文:https://www.elastic.co/guide/en/elasticsearch/reference/current/how-to.html

ES發(fā)布時帶有的默認值呀洲,可為es的開箱即用帶來很好的體驗藻糖。全文搜索遭赂、高亮、聚合渣淳、索引文檔 等功能無需用戶修改即可使用,當你更清楚的知道你想如何使用es后梢睛,你可以作很多的優(yōu)化以提高你的用例的性能,下面的內容告訴你 你應該/不應該 修改哪些配置

第一部分:調優(yōu)索引速度

(https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html)

使用批量請求批量請求將產生比單文檔索引請求好得多的性能肥印。

為了知道批量請求的最佳大小,您應該在具有單個分片的單個節(jié)點上運行基準測試绝葡。 首先嘗試索引100個文件深碱,然后是200,然后是400挤牛,等等莹痢。 當索引速度開始穩(wěn)定時,您知道您達到了數據批量請求的最佳大小。 在配合的情況下竞膳,最好在太少而不是太多文件的方向上犯錯航瞭。 請注意,如果群集請求太大坦辟,可能會使群集受到內存壓力刊侯,因此建議避免超出每個請求幾十兆字節(jié),即使較大的請求看起來效果更好锉走。

發(fā)送端使用多worker/多線程向es發(fā)送數據 發(fā)送批量請求的單個線程不太可能將Elasticsearch群集的索引容量最大化滨彻。 為了使用集群的所有資源,您應該從多個線程或進程發(fā)送數據挪蹭。 除了更好地利用集群的資源亭饵,這應該有助于降低每個fsync的成本。

請確保注意TOO_MANY_REQUESTS(429)響應代碼(Java客戶端的EsRejectedExecutionException)梁厉,這是Elasticsearch告訴您無法跟上當前索引速率的方式辜羊。 發(fā)生這種情況時,應該再次嘗試暫停索引词顾,理想情況下使用隨機指數回退八秃。

與批量調整大小請求類似,只有測試才能確定最佳的worker數量肉盹。 這可以通過逐漸增加工作者數量來測試昔驱,直到集群上的I / O或CPU飽和。

調大 refresh interval 默認的index.refresh_interval是1s上忍,這迫使Elasticsearch每秒創(chuàng)建一個新的分段骤肛。 增加這個價值(比如說30s)將允許更大的部分flush并減少未來的合并壓力。

加載大量數據時禁用refresh和replicas 如果您需要一次加載大量數據睡雇,則應該將index.refresh_interval設置為-1并將index.number_of_replicas設置為0來禁用刷新萌衬。這會暫時使您的索引處于危險之中饮醇,因為任何分片的丟失都將導致數據 丟失它抱,但是同時索引將會更快,因為文檔只被索引一次朴艰。 初始加載完成后观蓄,您可以將index.refresh_interval和index.number_of_replicas設置回其原始值。

設置參數祠墅,禁止OS將es進程swap出去 您應該確保操作系統(tǒng)不會swapping out the java進程侮穿,通過禁止swap (https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration-memory.html)

為filesystem cache分配一半的物理內存 文件系統(tǒng)緩存將用于緩沖I / O操作。 您應該確保將運行Elasticsearch的計算機的內存至少減少到文件系統(tǒng)緩存的一半毁嗦。

使用自動生成的id(auto-generated ids) 索引具有顯式id的文檔時亲茅,Elasticsearch需要檢查具有相同id的文檔是否已經存在于相同的分片中,這是昂貴的操作,并且隨著索引增長而變得更加昂貴克锣。 通過使用自動生成的ID茵肃,Elasticsearch可以跳過這個檢查,這使索引更快袭祟。

買更好的硬件 搜索一般是I/O 密集的验残,此時,你需要 a.為filesystem cache分配更多的內存 b.使用SSD硬盤 c.使用local storage(不要使用NFS巾乳、SMB 等remote filesystem) d.亞馬遜的 彈性塊存儲(Elastic Block Storage)也是極好的您没,當然,和local storage比起來胆绊,它還是要慢點 如果你的搜索是 CPU-密集的氨鹏,買好的CPU吧

加大 indexing buffer size 如果你的節(jié)點只做大量的索引,確保index.memory.index_buffer_size足夠大压状,每個分區(qū)最多可以提供512 MB的索引緩沖區(qū)喻犁,而且索引的性能通常不會提高。 Elasticsearch采用該設置(java堆的一個百分比或絕對字節(jié)大泻位骸)肢础,并將其用作所有活動分片的共享緩沖區(qū)。 非陈道活躍的碎片自然會使用這個緩沖區(qū)传轰,而不是執(zhí)行輕量級索引的碎片。

默認值是10%谷婆,通常很多:例如慨蛙,如果你給JVM 10GB的內存,它會給索引緩沖區(qū)1GB纪挎,這足以承載兩個索引很重的分片期贫。

禁用_field_names字段 _field_names字段引入了一些索引時間開銷,所以如果您不需要運行存在查詢异袄,您可能需要禁用它通砍。 (_field_names:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-field-names-field.html)

剩下的,再去看看 “調優(yōu) 磁盤使用”吧 (https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-disk-usage.html)中有許多磁盤使用策略也提高了索引速度烤蜕。

第二部分-調優(yōu)搜索速度

filesystem cache越大越好 為了使得搜索速度更快封孙, es嚴重依賴filesystem cache 一般來說,需要至少一半的 可用內存 作為filesystem cache讽营,這樣es可以在物理內存中 保有 索引的熱點區(qū)域(hot regions of the index)

用更好的硬件 搜索一般是I/O bound的虎忌,此時,你需要 a.為filesystem cache分配更多的內存 b.使用SSD硬盤 c.使用local storage(不要使用NFS橱鹏、SMB 等remote filesystem) d.亞馬遜的 彈性塊存儲(Elastic Block Storage)也是極好的膜蠢,當然堪藐,和local storage比起來,它還是要慢點 如果你的搜索是 CPU-bound挑围,買好的CPU吧

文檔模型(document modeling) 文檔需要使用合適的類型庶橱,從而使得 search-time operations 消耗更少的資源。咋作呢贪惹? 答:避免 join操作苏章。具體是指 a.nested 會使得查詢慢 好幾倍 b.parent-child關系 更是使得查詢慢幾百倍 如果 無需join 能解決問題,則查詢速度會快很多

預索引 數據 根據“搜索數據最常用的方式”來最優(yōu)化索引數據的方式 舉個例子: 所有文檔都有price字段奏瞬,大部分query 在 fixed ranges 上運行 range aggregation枫绅。你可以把給定范圍的數據 預先索引下。然后硼端,使用 terms aggregation

Mappings(能用 keyword 最好了) 數字類型的數據并淋,并不意味著一定非得使用numeric類型的字段。 一般來說珍昨,存儲標識符的 字段(書號ISBN县耽、或來自數據庫的 標識一條記錄的 數字),使用keyword更好(integer镣典,long 不好哦兔毙,親) 6.避免運行腳本 一般來說,腳本應該避免兄春。 如果他們是絕對需要的澎剥,你應該使用painless和expressions引擎。

搜索rounded 日期 日期字段上使用now赶舆,一般來說不會被緩存哑姚。但,rounded date則可以利用上query cache rounded到分鐘等

強制merge只讀的index 只讀的index可以從“merge成 一個單獨的 大segment”中收益

預熱 全局序數(global ordinals) 全局序數 用于 在 keyword字段上 運行 terms aggregations es不知道 哪些fields 將 用于/不用于 term aggregation芜茵,因此 全局序數 在需要時才加載進內存 但叙量,可以在mapping type上,定義 eager_global_ordinals==true九串,這樣绞佩,refresh時就會加載 全局序數

預熱 filesystem cache 機器重啟時,filesystem cache就被清空蒸辆。OS將index的熱點區(qū)域(hot regions of the index)加載進filesystem cache是需要花費一段時間的征炼。 設置 index.store.preload 可以告知OS 這些文件需要提早加載進入內存

11使用索引排序來加速連接 索引排序對于以較慢的索引為代價來加快連接速度非常有用析既。在索引分類文檔中閱讀更多關于它的信息躬贡。

12.使用preference來優(yōu)化高速緩存利用率 有多個緩存可以幫助提高搜索性能,例如文件系統(tǒng)緩存眼坏,請求緩存或查詢緩存拂玻。然而酸些,所有這些緩存都維護在節(jié)點級別,這意味著如果連續(xù)運行兩次相同的請求檐蚜,則有一個或多個副本魄懂,并使用循環(huán)(默認路由算法),那么這兩個請求將轉到不同的分片副本闯第,阻止節(jié)點級別的緩存幫助市栗。

由于搜索應用程序的用戶一個接一個地運行類似的請求是常見的,例如為了分析索引的較窄的子集咳短,使用標識當前用戶或會話的優(yōu)選值可以幫助優(yōu)化高速緩存的使用填帽。

13.副本可能有助于吞吐量,但不會一直存在 除了提高彈性外咙好,副本可以幫助提高吞吐量篡腌。例如,如果您有單個分片索引和三個節(jié)點勾效,則需要將副本數設置為2嘹悼,以便共有3個分片副本,以便使用所有節(jié)點层宫。

現在假設你有一個2-shards索引和兩個節(jié)點杨伙。在一種情況下,副本的數量是0萌腿,這意味著每個節(jié)點擁有一個分片缀台。在第二種情況下,副本的數量是1哮奇,這意味著每個節(jié)點都有兩個碎片膛腐。哪個設置在搜索性能方面表現最好?通常情況下鼎俘,每個節(jié)點的碎片數少的設置將會更好哲身。原因在于它將可用文件系統(tǒng)緩存的份額提高到了每個碎片,而文件系統(tǒng)緩存可能是Elasticsearch的1號性能因子贸伐。同時勘天,要注意,沒有副本的設置在發(fā)生單個節(jié)點故障的情況下會出現故障捉邢,因此在吞吐量和可用性之間進行權衡脯丝。

那么復制品的數量是多少?如果您有一個具有num_nodes節(jié)點的群集伏伐,那么num_primaries總共是主分片宠进,如果您希望能夠一次處理max_failures節(jié)點故障,那么正確的副本數是max(max_failures藐翎,ceil(num_nodes / num_primaries) - 1)材蹬。

14.打開自適應副本選擇 當存在多個數據副本時实幕,elasticsearch可以使用一組稱為自適應副本選擇的標準,根據包含分片的每個副本的節(jié)點的響應時間堤器,服務時間和隊列大小來選擇數據的最佳副本昆庇。這可以提高查詢吞吐量并減少搜索量大的應用程序的延遲。

第三部分:通用的一些建議

1闸溃、不要 返回大的結果集 es設計來作為搜索引擎整吆,它非常擅長返回匹配query的top n文檔。但辉川,如“返回滿足某個query的 所有文檔”等數據庫領域的工作掂为,并不是es最擅長的領域。如果你確實需要返回所有文檔员串,你可以使用Scroll API

2勇哗、避免 大的doc。即寸齐,單個doc 小了 會更好 given that(考慮到) http.max_context_length默認==100MB欲诺,es拒絕索引操作100MB的文檔。當然你可以提高這個限制渺鹦,但扰法,Lucene本身也有限制的,其為2GB 即使不考慮上面的限制毅厚,大的doc 會給 network/memory/disk帶來更大的壓力塞颁; a.任何搜索請求,都需要獲取 _id 字段吸耿,由于filesystem cache工作方式祠锣。即使它不請求 _source字段,獲取大doc _id 字段消耗更大 b.索引大doc時消耗內存會是 doc本身大小 的好幾倍 c.大doc的 proximity search, highlighting 也更加昂貴咽安。它們的消耗直接取決于doc本身的大小

3伴网、避免 稀疏 a.不相關數據 不要 放入同一個索引 b.一般化文檔結構(Normalize document structures) c.避免類型 d.在 稀疏 字段上,禁用 norms & doc_values 屬性

稀疏為什么不好妆棒? Lucene背后的數據結構 更擅長處理 緊湊的數據 text類型的字段澡腾,norms默認開啟;numerics, date, ip, keyword糕珊,doc_values默認開啟 Lucene內部使用 integer的doc_id來標識文檔 和 內部API交互动分。 舉個例子: 使用match查詢時生成doc_id的迭代器,這些doc_id被用于獲取它們的norm红选,以便計算score澜公。當前的實現是每個doc中保留一個byte用于存儲norm值。獲取norm值其實就是讀取doc_id位置處的一個字節(jié) 這非常高效纠脾,Lucene通過此值可以快速訪問任何一個doc的norm值玛瘸;但蜕青,給定一個doc苟蹈,即使某個field沒有值糊渊,仍需要為此doc的此field保留一個字節(jié) doc_values也有同樣的問題。2.0之前的fielddata被現在的doc_values所替代了慧脱。 稀疏性 最明顯的影響是 對存儲的需求(任何doc的每個field渺绒,都需要一個byte);但是呢菱鸥,稀疏性 對 索引速度和查詢速度 也是有影響的宗兼,因為:即使doc并沒有某些字段值,但氮采,索引時殷绍,依然需要寫這些字段,查詢時鹊漠,需要skip這些字段的值 某個索引中擁有少量稀疏字段主到,這完全沒有問題。但躯概,這不應該成為常態(tài) 稀疏性影響最大的是 norms&doc_values 登钥,但,倒排索引(用于索引 text以及keyword字段)娶靡,二維點(用于索引geo_point字段)也會受到較小的影響

如何避免稀疏呢牧牢? 1、不相關數據 不要 放入同一個索引 給個tip:索引凶硕А(即:doc的個數較少)塔鳍,則,primary shard也要少 2呻此、一般化文檔結構(Normalize document structures) 3献幔、避免類型(Avoid mapping type) 同一個index,最好就一個mapping type 在同一個index下面趾诗,使用不同的mapping type來存儲數據蜡感,聽起來不錯,但恃泪,其實不好郑兴。given that(考慮到)每一個mapping type會把數據存入 同一個index,因此贝乎,多個不同mapping type情连,各個的field又互不相同,這同樣帶來了稀疏性 問題 4览效、在 稀疏 字段上却舀,禁用 norms & doc_values 屬性 a.norms用于計算score虫几,無需score,則可以禁用它(所有filtering字段挽拔,都可以禁用norms) b.doc_vlaues用于sort&aggregations辆脸,無需這兩個,則可以禁用它 但是螃诅,不要輕率的做出決定啡氢,因為 norms&doc_values無法修改。只能reindex

秘訣1:混合 精確查詢和提取詞干(mixing exact search with stemming) 對于搜索應用术裸,提取詞干(stemming)都是必須的倘是。例如:查詢 skiing時,ski和skis都是期望的結果 但袭艺,如果用戶就是要查詢skiing呢搀崭? 解決方法是:使用multi-field。同一份內容猾编,以兩種不同的方式來索引存儲 query.simple_query_string.quote_field_suffix瘤睹,竟然是 查詢完全匹配的

秘訣2:獲取一致性的打分 score不能重現 同一個請求,連續(xù)運行2次袍镀,但默蚌,兩次返回的文檔順序不一致。這是相當壞的用戶體驗

如果存在 replica苇羡,則就可能發(fā)生這種事绸吸,這是因為: search時,replication group中的shard是按round-robin方式來選擇的设江,因此兩次運行同樣的請求锦茁,請求如果打到 replication group中的不同shard,則兩次得分就可能不一致

那問題來了叉存,“你不是整天說 primary和replica是in-sync的码俩,是完全一致的”嘛,為啥打到“in-sync的歼捏,完全一致的shard”卻算出不同的得分稿存?

原因就是標注為“已刪除”的文檔。如你所知瞳秽,doc更新或刪除時瓣履,舊doc并不刪除,而是標注為“已刪除”练俐,只有等到 舊doc所在的segment被merge時袖迎,“已刪除”的doc才會從磁盤刪除掉

索引統(tǒng)計(index statistic)是打分時非常重要的一部分,但,由于 deleted doc 的存在燕锥,在同一個shard的不同copy(即:各個replica)上 計算出的 索引統(tǒng)計 并不一致

個人理解: a. 所謂 索引統(tǒng)計 應該就是df辜贵,即 doc_freq b. 索引統(tǒng)計 是基于shard來計算的

搜索時,“已刪除”的doc 當然是 永遠不會 出現在 結果集中的

索引統(tǒng)計時归形,for practical reasons托慨,“已刪除”doc 依然是統(tǒng)計在內的

假設,shard A0 剛剛完成了一次較大的segment merge连霉,然后移除了很多“已刪除”doc榴芳,shard A1 尚未執(zhí)行 segment merge嗡靡,因此 A1 依然存在那些“已刪除”doc

于是:兩次請求打到 A0 和 A1 時跺撼,兩者的 索引統(tǒng)計 是顯著不同的

如何規(guī)避 score不能重現 的問題?使用 preference 查詢參數 發(fā)出搜索請求時候讨彼,用 標識字符串 來標識用戶歉井,將 標識字符串 作為查詢請求的preference參數。這確保多次執(zhí)行同一個請求時候哈误,給定用戶的請求總是達到同一個shard哩至,因此得分會更為一致(當然,即使同一個shard蜜自,兩次請求 跨了 segment merge菩貌,則依然會得分不一致) 這個方式還有另外一個優(yōu)點,當兩個doc得分一致時重荠,則默認按著doc的 內部Lucene doc id 來排序(注意:這并不是es中的 _id 或 _uid)箭阶。但是呢,shard的不同copy間戈鲁,同一個doc的 內部Lucene doc id 可能并不相同仇参。因此,如果總是達到同一個shard婆殿,則诈乒,具有相同得分的兩個doc,其順序是一致的

score錯了 score錯了(Relevancy looks wrong) 如果你發(fā)現

具有相同內容的文檔婆芦,其得分不同

完全匹配 的查詢 并沒有排在第一位 這可能都是由 sharding 引起的

默認情況下怕磨,搜索文檔時,每個shard自己計算出自己的得分消约。

索引統(tǒng)計 又是打分時一個非常重要的因素肠鲫。

如果每個shard的 索引統(tǒng)計相似,則 搜索工作的很好 文檔是平分到每個primary shard的荆陆,因此 索引統(tǒng)計 會非常相似滩届,打分也會按著預期工作。但,萬事都有個但是:

索引時使用了 routing(文檔不能平分到每個primary shard 啦)

查詢多個索引

索引中文檔的個數 非常少 這會導致:參與查詢的各個shard帜消,各自的 索引統(tǒng)計 并不相似(而棠枉,索引統(tǒng)計對 最終的得分 又影響巨大),于是 打分出錯了(relevancy looks wrong)

那泡挺,如何繞過 score錯了(Relevancy looks wrong)辈讶?

如果數據集較小,則娄猫,只使用一個primary shard(es默認是5個)贱除,這樣兩次查詢 索引統(tǒng)計 不會變化,因而得分也就一致啦 另一種方式是媳溺,將search_type設置為:dfs_query_then_fetech(默認是query_then_fetch) dfs_query_then_fetch的作用是

向 所有相關shard 發(fā)出請求月幌,要求 所有相關shard 返回針對當前查詢的 索引統(tǒng)計

然后,coordinating node 將 merge這些 索引統(tǒng)計悬蔽,從而得到 merged statistics

coordinating node 要求 所有相關shard 執(zhí)行 query phase扯躺,于是 發(fā)出請求,這時蝎困,也帶上 merged statistics录语。這樣,執(zhí)行query的shard 將使用 全局的索引統(tǒng)計 大部分情況下禾乘,要求 所有相關shard 返回針對當前查詢的 索引統(tǒng)計澎埠,這是非常cheap的。但始藕,如果查詢中 包含 非常大量的 字段/term查詢蒲稳,或者有 fuzzy查詢,此時鳄虱,獲取 索引統(tǒng)計 可能并不cheap弟塞,因為 為了得到 索引統(tǒng)計 可能 term dictionary 中 所有的term都需要被查詢一遍

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市拙已,隨后出現的幾起案子决记,更是在濱河造成了極大的恐慌,老刑警劉巖倍踪,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件系宫,死亡現場離奇詭異,居然都是意外死亡建车,警方通過查閱死者的電腦和手機扩借,發(fā)現死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缤至,“玉大人潮罪,你說我怎么就攤上這事。” “怎么了嫉到?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵沃暗,是天一觀的道長。 經常有香客問我何恶,道長孽锥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任细层,我火速辦了婚禮惜辑,結果婚禮上,老公的妹妹穿的比我還像新娘疫赎。我一直安慰自己盛撑,他們只是感情好,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布虚缎。 她就那樣靜靜地躺著撵彻,像睡著了一般钓株。 火紅的嫁衣襯著肌膚如雪实牡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天轴合,我揣著相機與錄音创坞,去河邊找鬼。 笑死受葛,一個胖子當著我的面吹牛题涨,可吹牛的內容都是我干的。 我是一名探鬼主播总滩,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼纲堵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了闰渔?” 一聲冷哼從身側響起席函,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎冈涧,沒想到半個月后茂附,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡督弓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年营曼,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愚隧。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡蒂阱,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情录煤,我是刑警寧澤虱痕,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站辐赞,受9級特大地震影響部翘,放射性物質發(fā)生泄漏。R本人自食惡果不足惜响委,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一新思、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赘风,春花似錦夹囚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瞬捕,卻和暖如春鞍历,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肪虎。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工劣砍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扇救。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓刑枝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親迅腔。 傳聞我的和親對象是個殘疾皇子装畅,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內容