一种基于抽样的分布式搜索结果合并翻页方法及系统的制作方法

文档序号:6546575阅读:278来源:国知局
一种基于抽样的分布式搜索结果合并翻页方法及系统的制作方法
【专利摘要】本发明公开了一种基于抽样的分布式搜索结果合并翻页方法及系统,旨在显著降低分布式搜索结果合并翻页过程中,存在的网络带宽和计算消耗较大的问题,同时本发明亦可改良后应用于其它分布式查询系统的结果合并翻页中。其技术方案为:对索引数据切片,形成索引文件切片,然后分到各个切片搜索服务器(shard-search?server)上,完成了索引文件的初始化工作;搜索结果合并节点(gather)接收外部系统的合并翻页请求,进入基于抽样的分布式搜索结果合并翻页具体步骤。
【专利说明】一种基于抽样的分布式搜索结果合并翻页方法及系统
【技术领域】
[0001]本发明属于海量数据处理【技术领域】,具体涉及一种针对分布式搜索结果合并翻页问题的方法及系统。
【背景技术】
[0002]电子商务平台(B2B、B2C等)的出现极大地方便了人们的生活,当人们越来越多地依赖这些平台时,也对平台本身提出了更高的要求:比如,在淘宝、京东等交易平台上,人们希望能够更多、更快、更精准地发现自己需要的商品;而对于电商企业而言,要满足人们的这些要求,在技术层面上通常需要一款高效、精准的海量搜索系统。由于检索数据庞大且快速增长,传统的集中式的搜索系统已经越来越不能胜任大型电商平台的检索任务。
[0003]随着分布式及数据切片技术的发展,市面上出现了基于数据切片的分布式搜索系统,其中以apache开源的solr及Elasticsearch公司的elasticsearch较具代表性。这些分布式的搜索系统都具备较好的可扩展性,能够将数据分片索引于庞大的机器集群上,这为解决海量数据的检索问题提供了方案。然而由于切片技术本身的局限性,这些搜索系统也存在着一些问题,搜索结果的合并翻页就是其中较为突出的一个问题。试想这样一个需求:用户需要获取某次搜索结果中,排序位次是第951名到第1000名的50条记录。
[0004]对于这样一个问题,现有的分布式搜索系统的解决办法通常有两个:其一,向每个搜索切片发送检索请求,并获取各自检索结果的前1000名,然后在一个合并节点上,对来自于各个切片的搜索进行合并,最后取出其中位于第951名到第1000名间的50条记录;其二,忽略排名的严格要求,近似地认为各个切片上对等位次的记录在合并结果中的排名基本相当,如此即可简单地从各个切片上对等地获取少量记录“凑”成目标翻页。然而,这两个方案都存在着各自严重的问题。对于方案一,目标翻页的记录数只有50,而搜索系统却需要从各个切片上各自获取1000条记录,如果切片数量为n,那么一次搜索请求需要传输和重排序的记录数就是nX 1000 ;如此拓展开来,当用户所需的翻页很深时,就会带来巨大的网络带宽和计算开销;而对于方案二,很明显它牺牲了排名的准确性,这对于类似于B2B的电商平台来说,由于排名涉及到其会员的重要利益,显然是不能容忍的。那么,一个高效且精确的、针对分布式搜索结果的合并、排序、翻页方案就成了当前迫切需要解决的问题。
[0005]在这个问题上,专利“合并排序分布式数据的方法”(申请号:CN03152258.0)做了相关研究,其提出的方法主要为:切片节点分别完成查询及排序工作,然后由合并节点逐次向切片节点顺序地预取一个小批量的结果集(如:每批次40条记录);每获取一个批次的记录后,合并节点对现有记录集进行一次排序,并根据排序结果决定向哪些切片请求下一批次的记录;如此往复,直到合并节点获取到用户所需的全部记录为止。该专利提出的方法在一定程度上解决了数据过度传输和合并的问题。然而该专利在使用场景上却存在着明显的局限性,首先该专利是针对主从式可堆栈网络装置的排序性能问题提出的,因此它所解决的是如何高效地获取前若干个记录的问题;而本发明所提出的问题是:如何高效地获取指定翻页,即获取排序结果中一个特定片段的问题,此问题实际上具有更强的“随机性”。
【发明内容】

[0006]为解决上述问题,本发明设计了一种基于抽样的分布式搜索结果合并翻页方法及系统,旨在显著降低分布式搜索结果合并翻页过程中,存在的网络带宽和计算消耗较大的问题,同时本发明亦可改良后应用于其它分布式查询系统的结果合并翻页中。
[0007]本专利提供的具体技术方案如下:
[0008]一种基于抽样的分布式搜索结果排序翻页方法,包括:
[0009]对索引数据切片(通常基于一致性hash值),形成索引文件切片,然后分到各个切片搜索服务器(下文称shard-search server)上,完成了索引文件的初始化工作。
[0010]搜索结果合并节点(下文称gather)接收外部系统的合并翻页请求,进入步骤I。
[0011]步骤1:gather分别向shard-search server发送查询及针对搜索结果的抽样请求,并等待响应结果。
[0012]步骤2:shard-search server依照查询条件检索,并对命中结果排序,最后从排序结果中获取能够涵盖当前翻页的前若干条记录,若这些记录数量并不巨大,可将这些记录数据存放于临时缓存中(以备步骤6的记录召回);针对这些记录,shard-search server以固定步长(如:50)做整数倍抽样,并将抽样记录返回。
[0013]步骤3:gather在获取到各shard-search server的抽样结果后,将它们按照排序域值做统一排序。
[0014]步骤4:基于步骤3的排序结果,gather进一步计算出所需目标翻页的记录在各个切片上的大致开始位置(以下称startpoint),同时将肯定不属于目标翻页的记录排除在外。
[0015]步骤5:基于步骤4的结果,gather向各个切片发起召回记录的请求,这些请求只召回从startpoint向下的少量记录,其数量是抽样步长与翻页尺寸的和,其中翻页尺寸指的是一页包含搜索记录的数量。
[0016]步骤6:各shard-search server接收到记录召回请求后,优先从步骤2中所述的记录缓存中获取所需记录,并将其所对应的缓存清空;如缓存中不存在相应记录,则可进行二次查找,最后返回目标记录。
[0017]步骤7:gather在获取到各shard-search server的召回结果后,将其再次按照排序域值排序,再结合各个切片对应的startpoint从排序结果中截取出目标翻页记录,至此整个过程完毕。
[0018]一种基于抽样的分布式搜索结果合并翻页系统,包括:
[0019]gather (搜索结果合并节点)和shard-search server (搜索切片服务器)两个大部分,其中gather进一步细化为TopSamplesFetcher (记录抽样抓取器)、TopSamplesMerger (记录抽样合并器)>ApproximateStartPointsCalculator (翻页近似起点计算器)、PageFetcher (指定翻页抓取器)、PageMerger (指定翻页合并截取器)几个主要部件;而shard-search server则主要包括TopSampler (记录抽样器)、TopSearcher (记录查询器)、TopResultTmpCache (记录结果临时缓存器)、PageGetter (翻页获取器)几个主要部件。
[0020]整体上,gather与shard-search server通过网络进行通信(本发明省略说明),它们按照不同的请求各自调用内部部件进行处理,并交换计算结果,最终由gather完成最后翻页结果的计算并返回。
[0021]gather,是整个系统的枢纽,用于接收外部系统的排序翻页请求,并按请求信息向shard-search server分两次发送抽样、召回请求,其中召回请求需基于gather对于抽样
集合的计算结果-startpoint ;最后,gather从召回的结果中准确计算出当前的目标翻
页记录并返回给外部系统。
[0022]TopSamplesFetcher,用于抓取shard-search server查询请求结果的抽样,包括并发地向shard-search server发送抽样请求,并接收抽样结果。
[0023]TopSamplesMerger,用于按查询域排序合并TopSamplesFetcher的抓取结果。
[0024]ApproximateStartPointsCalculator,根据 TopSamplesMerger 的合并结果,计算出各个 shard-search server 对应的 startpoint。
[0025]PageFetcher,根据 ApproximateStartPointsCalculator 的计算结果,向各个shard-search server发起记录召回请求,并接收召回结果。
[0026]PageMerger,对PageFetcher的结果做最后的合并,并按照startpoint准确地从排序结果中截取出目标翻页记录,将结果返回gather。
[0027]shard-search server,负责接收并协调内部部件处理来自于gather的抽样和召回请求,最后将处理结果返回gather。
[0028]TopSearcher,用于执行具体的记录查询任务,它将命中结果进行初始排序,并截取出能够覆盖当前翻页的前若干条记录。
[0029]TopResultTmpCache,用于缓存TopSearcher的最终截取结果,该缓存与具体的
排序翻页请求--对应,即一次完整的排序翻页请求完成后,其对应缓存将被一并清除;
此外,为防止内存的无限制开销,本发明对缓存中存放实体的数目做了上限控制,一旦达到了缓存上限将按照LRU算法自动将部分实体数据驱逐出缓存。其中,LRU算法是LeastRecently Used的缩写,即最少使用页面置换算法,是为虚拟页式存储管理服务的。
[0030]TopSampler,接受 shard-search server 的调用,并分别调用 TopSearcher 和TopResultTmpCache获取并缓存能够覆盖当前翻页的前若干条记录,最后对这些记录按固定步长进行抽样并返回抽样结果。
[0031]PageGetter,接受shard-search server的调用,负责取出需要召回的记录,它将根据实际情况决定从TopResultTmpCache直接获取目标记录,或是发起二次查询获取目标记录。
[0032]本发明与现有技术相比,其显著优点:
[0033]I)能够支持分布式搜索领域的大结果集的合并及高深度翻页,同时本发明并不局限于搜索领域,具有较高的通用性。
[0034]2)通过将合并翻页的过程所需的数据,分解为抽样和召回两次请求来获取,一方面避免了大量的记录数据从shard-search server向gather传输,同时也避免了 gather对它们的完全再排序,极大地降低网络带宽和计算消耗。
[0035]3)在保证效率的同时,本发明仍不失排序的严格性,这满足了那些对排序有着严格要求的应用场景。
[0036]4)本发明中,shard-search server在抽样阶段对命中的记录结果做了选择性缓存,这很好地避免了记录召回阶段二次查询操作的发生,极大提升了整个合并翻页过程的效率。
【专利附图】

【附图说明】
[0037]图1为本发明实施例的系统结构图。
[0038]图2为本发明实施例的合并翻页方法整体时序图。
[0039]图3为本发明实施例的抽样合并及startpoint计算过程图。
[0040]图4为本发明实施例的召回记录合并及翻页截取过程图。
【具体实施方式】
[0041]为了使本发明的目的、技术方案和优点更加清楚,下面结合附图和具体实施例对本发明进行详细描述。
[0042]如图1所示,为本发明实施例的系统结构,为了描述方便,假设本实施例中把索引文件数据拆分成两个切片,分别部署于2个shard-search server,包括:
[0043]一 个 gather serverlOl,其中内置 TopSamplesFetcherl02、TopSamplesMerger 103、ApproximateStartPointsCalculator 104、PageFetcher 105、PageMergerl06 几个部件;两个切片搜索服务器 shardl-search serverl07、shardl_searchserverll2,其中 shardl-search serverl07 内置 TopSamplerl08、TopSearcher 109>TopResultTmpCachel 10、PageGetterlll 几个部件;而另一个切片服务器 shard2_searchserver 112 贝内 置 TopSampler 113> TopSearcherl 14> TopResultTmpCachell5>PageGetterl 16 几个部件;shardl_search serverl07 与 shard2_search server 112 分别被部署了不同的数据切片。
[0044]如图2所示,为本发明实施例的合并翻页方法整体时序图,为方便下面的图例制作及阐述方便,这里首先假设外部系统请求的几个要素:1、搜索结果以记录评分的降序排列,2、本例一页包含5条记录,且目标翻页为排序结果的第56名至第60名间的5条记录,
3、抽样步长为10。需要声明的是:以上条件并非本发明的局限场景,纯粹为图例制作及阐述方便而设;另外,由于切片评分的公平性并非本发明要解决的问题,这里假设各切片的评分是公平的,即可在同一环境下进行比较。其详细过程如下:
[0045]步骤201:gather serverlOl接收到外部系统合并翻页请求,调用TopSamplesFetcher 102 分别向 shardl-search server 107 和 shard2_search server 112 发送查询及抽样请求。
[0046]步骤2O2:shardl-search ServerlO7 和 shard2_search serverll2 接收到请求后,分别调用TopSearcher 109和TopSearcher 114执行查询操作,并各自将命中结果按评分排序,然后各自截取其中的前60条记录作为结果,并将结果分别返回给TopSamplelOS和TopSamplell3。
[0047]步骤203:TopSamplel08和TopSamplell3分别对前60条记录做步长为10的等距抽样,如此各自抽样出6条记录作为抽样集合;同时TopSamplel08和TopSamplel 13分别将各自获取的前60条记录缓存于临时缓存TopResultTmpCachelll和TopResultTmpCachel 16中,以备记录召回时取回。[0048]步骤204:shardl_search serverl07 和 shard2_search serverll2 分别将TopSamplel08 和 TopSamplell3 的抽样结果通过网络返回给 gather serverlOl。
[0049]步骤205:gather serverlOl 收到 shardl-search ServerlO7 和 shard2_searchserverll2返回的抽样结果后,调用TopSamplesMergerl03对抽样结果按评分做再次排序。
[0050]步骤206:ApproximateStartPointsCalculator 104 基于步骤 205 对记录抽样的排序结果,分别计算出针对 shardl-search serverl07 和 shard2_search serverll2 的startpoint。步骤205与本步骤具体的计算实施例如图3所示。
[0051]主要内容包括:
[0052]1:来自于shardl-search serverl07的抽样结果301,其中包含标识为A?F的记录及其评分。
[0053]2:来自于shard2_search serverll2的抽样结果302,其中包含标识为G?L的记录及其评分。
[0054]3:ApproximateStartPointsCalculatorl04 对抽样集合的排序结果 303,其中除了记录标识及评分,还加入了每个记录前置记录的数量,以辅助startpoint计算。
[0055]4:shardl-search server 107 与 shard2_search serverl12 各自的startpoint-304 和 305。
[0056]主要计算过程包括:
[0057]1:对抽样结果301与抽样结果302按记录评分重新排序,得到排序结果303。
[0058]2:根据目标翻页排除无需召回的记录,本例中目标翻页是第56名到第60名间的记录,借助于303可以确定排名位于记录B之前的记录无需召回;*B向上找到最近的分属shardl-search serverl07与shard2_search serverl 12的两个抽样记录,以它们做为召回记录的startpoint,很显然在本例中它们是记录304和记录305。
[0059]步骤2O7:gather serverlOl 分别向 shardl-search serverl07 与 shard2_searchserverl 12发送记录召回请求,召回请求以各自的startpoint为起点,即startpoint之前的文档不再召回之列。此外,为保证召回记录的完整性,召回记录的数量为抽样步长与每个页面包含搜索记录数量的和,本例中应为10+5 = 15。
[0060]步骤208:shardl-search serverl07 与 shard2_search serverll2 分别调用PageGetterllO和PageGetterl 15获取召回记录。PageGetter首先尝试从TopResultTmpCache中获取抽样阶段记录缓存,如能成功获取则从中截取出需召回记录,最后将记录缓存从TopResultTmpCache中清除;否则将发起二次查询,然后从查询结果中截取出需召回记录。
[0061]步骤2O9:shardl-search ServerlO7 与 shard2_search serverll2 分别将步骤208的召回结果通过网络返回给gather serverlOl。
[0062]步骤210:gather serverlOl接收到所有的召回记录后,首先调用PageMergerl06对它们做再次排序,然后根据startpoint从排序结果中准确计算出本次翻页请求所需的实际记录集合,并返回到外部系统。本步骤具体的计算实施例如图4所示。
[0063]主要内容包括:
[0064]1:来自于shardl-search serverl07的记录召回结果401,其中包含标识为B+n、C及C+n的记录及其评分,B+n表示排名介于于B记录与C记录之间的记录,而C+n则表示排名位于C记录之后的记录。
[0065]2:来自于shard2_search serverll2的记录召回结果402,其中包含标识为I+n、J及J+n的记录及其评分,I+n表示排名介于于I记录与J记录之间的记录,而J+n则表示排名位于J记录之后的记录。
[0066]3:PageMergerl06对召回记录集合按评分所作的重排序结果403。
[0067]4:PageMergerl06在重排序结果403基础上,根据startpoint截取的目标翻页结果,其中阴影部分为本例最终所需的5条记录。
[0068]主要计算过程及原理包括:
[0069]1:对召回结果401与召回结果402按记录评分重新排序,得到排序结果403。
[0070]2:上一步结果包含30条记录,需要从中进一步截取出第56名到第60名间的记录。本例中,向 shardl-search serverl07 和 shard2_search serverll2 发起召回的startpoint分别为B和I记录;那么从全局排序上看,位于本次召回记录集合之前的记录应包括:位于shardl-search serverl07上的B记录及其之前的记录、位于shard2_searchserverll2上的I记录及其之前的记录,共50条记录;因此,本次所需翻页的第56名应对应到结果403的第6名,以此而下截取5条记录即为本次的翻页记录结果,如图4中的阴影部分所示。
[0071]本发明还可有其他多种实施方式,在不背离本发明精神及其实质的情况下,熟悉本领域的技术人员可根据本发明做出各种相应的改变和变形,这些相应的改变和变形都应属于本发明所附的权利要求的保护范围。
【权利要求】
1.一种基于抽样的分布式搜索结果排序翻页方法,其特征在于,包括: 对索引数据切片,形成索引文件切片,然后分到各个切片搜索服务器(shard-searchserver)上,完成了索引文件的初始化工作; 搜索结果合并节点(gather)接收外部系统的合并翻页请求,进入步骤I ; 步骤1:搜索结果合并节点(gather)分别向各个切片搜索服务器发送查询及针对搜索结果的抽样请求,并等待响应结果; 步骤2:切片搜索服务器(shard-search server)依照查询条件检索,并对命中结果排序,最后从排序结果中获取能够涵盖当前翻页的前若干条记录,针对这些记录,切片搜索服务器以固定步长做整数倍抽样,并将抽样记录返回; 步骤3:搜索结果合并节点(gather)在获取到各个切片搜索服务器(shard-searchserver)的抽样结果后,将它们按照排序域值做统一排序; 步骤4:基于步骤3的排序结果,搜索结果合并节点(gather)进一步计算出所需目标翻页的记录在各个切片上的大致开始位置(startpoint),同时将肯定不属于目标翻页的记录排除在外; 步骤5:基于步骤4的结果,搜索结果合并节点(gather)向各个切片发起召回记录的请求,这些请求只召回从目标翻页记录在各个切片上大致开始位置(startpoint)向下的少量记录; 步骤6:各个切片搜索服务器(shard-search server)接收到记录召回请求,查找后返回目标记录; 步骤7:搜索结果合并节点(gather)在获取到各个切片搜索服务器(shard-searchserver)的召回结果后,将其再次按照排序域值排序,再结合各个切片对应的目标翻页记录在各个切片上大致开始位置(startpoint)从排序结果中截取出目标翻页记录,至此整个过程完毕。
2.根据权利要求1所述的基于抽样的分布式搜索结果排序翻页方法,其特征在于: 步骤I中,索引数据切片是基于一致性hash值。
3.根据权利要求1所述的基于抽样的分布式搜索结果排序翻页方法,其特征在于: 步骤2中,若这些记录数量并不巨大,则将这些记录数据存放于临时缓存中,以备步骤6的记录召回。
4.根据权利要求1所述的基于抽样的分布式搜索结果排序翻页方法,其特征在于: 步骤5中,请求召回少量记录的数量是抽样步长与翻页尺寸的和。
5.根据权利要求1所述的基于抽样的分布式搜索结果排序翻页方法,其特征在于: 步骤6中,各个切片搜索服务器(shard-search server)接收到记录召回请求后,优先从步骤2中所述的记录缓存中获取所需记录,并将其所对应的缓存清空;如缓存中不存在相应记录,则可进行二次查找,最后返回目标记录。
6.一种基于抽样的分布式搜索结果合并翻页系统,其特征在于,包括: 搜索结果合并节点(gather) 和搜索切片服务器(shard-search server)两个大部分,其中所述搜索结果合并节点(gather)由记录抽样抓取器(TopSamplesFetcher)、记录抽样合并器(TopSamplesMerger)、翻页近似起点计算器(ApproximateStartPointsCalculator)、指定翻页抓取器(PageFetcher)、指定翻页合并截取器(PageMerger)构成;所述搜索切片服务器(shard-search server)包括记录抽样器(TopSampler)、记录查询器(TopSearcher)、记录结果临时缓存器(TopResultTmpCache)、翻页获取器(PageGetter)。
7.根据权利要求6所述的基于抽样的分布式搜索结果合并翻页系统,其特征在于: 所述搜索结果合并节点(gather)和搜索切片服务器(shard-search server)通过网络进行通信,它们按照不同的请求各自调用内部部件进行处理,并交换计算结果,最终由所述搜索结果合并节点(gather)完成最后翻页结果的计算并返回; 所述搜索结果合并节点(gather),是整个系统的枢纽,用于接收外部系统的排序翻页请求,并按请求信息向所述搜索切片服务器(shard-search server)分两次发送抽样、召回请求,其中召回请求需基于所述搜索结果合并节点(gather)对于抽样集合的计算结果——目标翻页记录在各个切片上大致开始位置(startpoint);最后,所述搜索结果合并节点(gather)从召回的结果中准确计算出当前的目标翻页记录并返回给外部系统。
8.根据权利要求7所述的基于抽样的分布式搜索结果合并翻页系统,其特征在于: 所述记录抽样抓取器(TopSamplesFetcher),用于抓取所述搜索切片服务器(shard-search server) 查询请求结果的抽样,包括并发地向所述搜索切片服务器(shard-search server)发送抽样请求,并接收抽样结果; 所述记录抽样合并器(TopSamplesMerger),用于按查询域排序合并所述记录抽样抓取器(TopSamplesFetcher)的抓取结果; 所述翻页近似起点计算器(ApproximateStartPointsCalculator),根据所述记录抽样合并器(TopSamplesMerger)的合并结果,计算出各个所述搜索切片服务器(shard-searchserver)对应的目标翻页记录在各个切片上大致位置开始(startpoint); 所述指定翻页抓取器(PageFetcher),根据所述翻页近似起点计算器(ApproximateStartPointsCalculator)的计算结果,向各个所述搜索切片服务器(shard-search server)发起记录召回请求,并接收召回结果; 所述指定翻页合并截取器(PageMerger),对所述指定翻页抓取器(PageFetcher)的结果做最后的合并,并按照目标翻页记录在各个切片上大致开始位置(startpoint)准确地从排序结果中截取出目标翻页记录,将结果返回所述搜索结果合并节点(gather)。
9.根据权利要求6所述的基于抽样的分布式搜索结果合并翻页系统,其特征在于: 所述搜索结果合并节点(gather)和搜索切片服务器(shard-search server)通过网络进行通信,它们按照不同的请求各自调用内部部件进行处理,并交换计算结果,最终由所述搜索结果合并节点(gather)完成最后翻页结果的计算并返回; 所述搜索切片服务器(shard-search server),负责接收并协调内部部件处理来自于所述搜索结果合并节点(gather)的抽样和召回请求,最后将处理结果返回所述搜索结果合并节点(gather)。
10.根据权利要求9所述的基于抽样的分布式搜索结果合并翻页系统,其特征在于: 所述记录查询器(TopSearcher),用于执行具体的记录查询任务,它将命中结果进行初始排序,并截取出能够覆盖当前翻页的前若干条记录; 所述记录结果临时缓存器(TopResultTmpCache),用于所述缓存记录查询器(TopSearcher)的最终截取结果,该缓存与具体的排序翻页请求一一对应,即一次完整的排序翻页请求完成后,其对应缓存将被一并清除;同时,缓存中存放实体的数目一旦达到了缓存上限将按照最少使用页面置换算法(LRU)自动将部分实体数据驱逐出缓存; 所述记录抽样器(TopSampler),接受所述搜索切片服务器(shard-search server)的调用,并分别调用所述记录查询器(TopSearcher)和所述记录结果临时缓存器(TopResultTmpCache)获取并缓存能够覆盖当前翻页的前若干条记录,最后对这些记录按固定步长进行抽样并返回抽样结果; 所述翻页获取器 (PageGetter),接受所述搜索切片服务器(shard-search server)的调用,负责取出需要召回的记录,它将根据实际情况决定从所述记录结果临时缓存器(TopResultTmpCache)直接获取目标记录,或是发起二次查询获取目标记录。
【文档编号】G06F17/30GK103942346SQ201410204444
【公开日】2014年7月23日 申请日期:2014年5月14日 优先权日:2014年5月14日
【发明者】梁峰 申请人:焦点科技股份有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1