58同城 Elasticsearch 應(yīng)用及平臺(tái)建設(shè)實(shí)踐
分享嘉賓:于伯偉 58同城 高級(jí)架構(gòu)師
編輯整理:陳樹昌
內(nèi)容來源:DataFunTalk
導(dǎo)讀:Elasticsearch是一個(gè)分布式的搜索和分析引擎,可以用于全文檢索、結(jié)構(gòu)化檢索和分析,并能將這三者結(jié)合起來。Elasticsearch基于Lucene開發(fā),現(xiàn)在是使用最廣的開源搜索引擎之一。Elasticsearch可以應(yīng)用于在/離線日志流水、用戶標(biāo)簽畫像、數(shù)據(jù)庫二級(jí)緩存、安全風(fēng)控行為數(shù)據(jù)、圖數(shù)據(jù)庫索引、監(jiān)控?cái)?shù)據(jù)、Wiki文檔檢索等應(yīng)用場(chǎng)景。58同城有自己的主搜,而一些內(nèi)部創(chuàng)新搜索業(yè)務(wù)和大規(guī)模的數(shù)據(jù)實(shí)時(shí)OLAP ( On-Line Analytical Processing,聯(lián)機(jī)分析處理 ) 則是使用Elasticsearch。
本次分享的主題為58同城Elasticsearch應(yīng)用及平臺(tái)建設(shè)實(shí)踐。主要內(nèi)容包括:
集群優(yōu)化治理
典型應(yīng)用實(shí)踐
自動(dòng)化平臺(tái)建設(shè)
后續(xù)規(guī)劃
01
集群優(yōu)化治理
1. 背景
早期Elasticsearch分布在58內(nèi)的各個(gè)業(yè)務(wù)部門自主維護(hù),但是隨著Elasticsearch自身的功能加強(qiáng),各業(yè)務(wù)團(tuán)隊(duì)使用Elasticsearch的數(shù)量越來越多、使用的業(yè)務(wù)場(chǎng)景越來越重要,于是由數(shù)據(jù)庫部門對(duì)整個(gè)公司的Elasticsearch使用進(jìn)行了收斂管理,在這個(gè)過程中數(shù)據(jù)庫部門同學(xué)遇到了很多問題和挑戰(zhàn),具體如下:業(yè)務(wù)使用場(chǎng)景復(fù)雜多樣;Elasticsearch版本不統(tǒng)一;應(yīng)用與Elasticsearch數(shù)據(jù)服務(wù)混合部署;缺乏有效監(jiān)控;服務(wù)器硬件型號(hào)多樣;索引接入無管控,找不到負(fù)責(zé)人;接入規(guī)范不統(tǒng)一,接入溝通成本高;無平臺(tái)管理,手動(dòng)excel維護(hù)集群信息。
除了上面這些問題,接管Elasticsearch后,還面臨著服務(wù)性能方面的挑戰(zhàn):索引變紅 ( 集群健康狀態(tài) )、索引寫不進(jìn)去、查詢超時(shí)、內(nèi)存OOM、Master不響應(yīng)等。
在做分享之前,DataFun的小伙伴給反饋了很多問題,這些問題很大一部分是與Elasticsearch集群的規(guī)劃相關(guān),這有很多和我們之前遇到的問題也是一樣的。下面針對(duì)兩個(gè)處理比較多的問題來分享。
2. 典型問題之一:Elasticsearch集群的磁盤被打爆
造成磁盤被打爆有以下幾種原因:
索引泛濫,索引接入無流程管控
索引無生命周期管理
索引分片數(shù)量不合理,單分片過大
日志類索引未按天等細(xì)粒度劃分,單索引過大
多集群復(fù)用同一服務(wù)器節(jié)點(diǎn)
磁盤容量大小不一
這些問題比較基礎(chǔ),其實(shí)也反映出早期在使用Elasticsearch時(shí)沒有很好的規(guī)劃。針對(duì)上面的各種問題,總結(jié)了如下幾點(diǎn)實(shí)踐經(jīng)驗(yàn):
集群管控收斂賬號(hào)權(quán)限,限制每個(gè)賬號(hào)操作索引的范圍。避免各個(gè)部門或業(yè)務(wù)隨意復(fù)用集群,比如不通過系統(tǒng)申請(qǐng)直接將其它各種日志或業(yè)務(wù)數(shù)據(jù)直接Load進(jìn)Elasticsearch,造成索引泛濫無法治理。
索引生命周期管理。不管線上數(shù)據(jù)還是離線數(shù)據(jù),應(yīng)該有個(gè)消亡的過程。比如梳理過程甚至發(fā)現(xiàn)3年前的數(shù)據(jù)還存在,這極大的浪費(fèi)了磁盤空間。
合理的分片數(shù)量規(guī)劃。分片數(shù)量的規(guī)劃其實(shí)和我們的數(shù)據(jù)量有很密切的關(guān)系的。比如節(jié)點(diǎn)的個(gè)數(shù)是多少、磁盤的空間是多少,我們建議盡量控制單個(gè)分片數(shù)量在100G以內(nèi),避免單分片過大在均衡時(shí)將磁盤打爆。
日志類的索引,避免單個(gè)過大,按照天劃分是比較好的解決方案。如果按照天劃分索引仍然很大,這個(gè)時(shí)候就需要按小時(shí)更小粒度的劃分規(guī)則。
不同集群復(fù)用相同的服務(wù)器分區(qū)。由于Elasticsearch有自己的警戒水位線,之間會(huì)互相影響,很容易導(dǎo)致磁盤空間觸發(fā)達(dá)到上限問題。
3. 典型問題之二:Elasticsearch集群寫入變慢
Elasticsearch集群寫入變慢需要考慮以下幾個(gè)問題:
索引梳理,是否所有信息都要寫入?
分片數(shù)量是否合理?
業(yè)務(wù)需求是否需要多副本?
Refresh時(shí)間是否可以更大?
Logstash處理吞吐是否達(dá)到瓶頸?
Translog刷新策略是否要優(yōu)化?
磁盤硬件IO是否太差?
針對(duì)上面這幾個(gè)問題我們的實(shí)踐經(jīng)驗(yàn)是:
減少不必要的寫入。例如減少?zèng)]有必要的大文本類的寫入,因?yàn)檫@些大文本會(huì)耗更多的IO。
合理設(shè)置分片數(shù)量。分片數(shù)量不是越多越好,分片越多會(huì)導(dǎo)致寫入變慢。
多副本會(huì)極大的影響寫入吞吐。在Elasticsearch的寫入機(jī)制里,Primary要等待所有Replica寫完之后才能返回給客戶端。
對(duì)于日志類的索引沒有必要秒級(jí)刷新。大家可能都使用了默認(rèn)配置刷新時(shí)間,其實(shí)調(diào)整為5秒、10秒也是可以接受的。目前很多日志類的我們?cè)O(shè)置為60秒。
Logstash有吞吐瓶頸。之前測(cè)評(píng)在某一場(chǎng)景下,它的吞吐量也就1-2萬左右。業(yè)內(nèi)還有一些開源的工具替代Logstash,包括一些自研的程序,可以極大的提高寫入的吞吐。
明確服務(wù)器用的是SSD還是普通的SATA機(jī)械盤。ssd的讀寫速度會(huì)比普通的SATA機(jī)械盤快。目前針對(duì)一些業(yè)務(wù)數(shù)據(jù)我們采用冷熱分離策略,新數(shù)據(jù)庫寫入SSD磁盤,早期的數(shù)據(jù)會(huì)自動(dòng)均衡到SATA機(jī)械盤。
4. 開發(fā)規(guī)范
針對(duì)這些影響業(yè)務(wù)穩(wěn)定性的問題,我們內(nèi)部制定了相應(yīng)的規(guī)范約束:
日志類應(yīng)用:
提供容量與吞吐量預(yù)估
注:在新業(yè)務(wù)接入時(shí),我們要求業(yè)務(wù)方提供當(dāng)前業(yè)務(wù)的容量和吞吐量的預(yù)估值 ( 例如:每天的增量數(shù)據(jù)有多少條、保留的時(shí)間是多少 )。
提供靜態(tài)mapping結(jié)構(gòu)
注:包括對(duì)日志類的業(yè)務(wù),我們也強(qiáng)烈建議使用靜態(tài)mapping。
統(tǒng)一接入大數(shù)據(jù)部門Kafka集群,并提供topic和ClientId
提供Logstash filter過濾規(guī)則配置
索引配置,默認(rèn)5分片1副本 ( 可調(diào)整 )
數(shù)據(jù)保留策略,建議不超過30天
索引按天劃分,命名規(guī)則建議為:前綴+日期時(shí)間戳,如xxx-2020-02-01
注:這里還是強(qiáng)烈建議日志類索引按照天劃分。
禁止私自接入新索引,接入賬號(hào)權(quán)限限制匹配特定索引前綴
非日志類應(yīng)用:
這類多是數(shù)據(jù)檢索類的服務(wù)。
提供容量與吞吐量預(yù)估
提供業(yè)務(wù)類型評(píng)估,線上一級(jí)核心業(yè)務(wù)優(yōu)先接入公司主搜服務(wù)
注:因?yàn)檫@會(huì)涉及公司的商業(yè)搜索策略。
重要業(yè)務(wù)獨(dú)享集群,非核心業(yè)務(wù)復(fù)用公共集群
注:重要的業(yè)務(wù)要保證業(yè)務(wù)的可靠性、穩(wěn)定性。
提供靜態(tài)mapping結(jié)構(gòu)
索引配置,默認(rèn)5分片2副本
注:根據(jù)實(shí)際業(yè)務(wù)進(jìn)行動(dòng)態(tài)調(diào)整。
禁止私自接入新索引,接入賬號(hào)權(quán)限限制匹配特定索引前綴
5. Elasticsearch服務(wù)架構(gòu)
在整合所有Elasticsearch之后,我們統(tǒng)一了Elasticsearch的服務(wù)架構(gòu):
該架構(gòu)有以下幾個(gè)特點(diǎn):
Elasticsearch的每一個(gè)節(jié)點(diǎn)角色都是獨(dú)立的。我們的Master節(jié)點(diǎn)和Data節(jié)點(diǎn)不會(huì)復(fù)用,對(duì)于大規(guī)模集群也會(huì)額外增加client節(jié)點(diǎn)。
Elasticsearch的版本統(tǒng)一升級(jí)到6.8以上。因?yàn)镋lasticsearch在6.8版本開始提供基于角色的安全認(rèn)證,這對(duì)我們的索引治理和管控來說是非常重要的,而之前我們有不少Elasticsearch是在裸奔,沒有任何的安全限制。
公共的IK插件?,F(xiàn)在的分詞插件目前還是使用的默認(rèn)的IK插件。
冷熱數(shù)據(jù)分離。我們根據(jù)索引的業(yè)務(wù)場(chǎng)景,配置不同類型的數(shù)據(jù)節(jié)點(diǎn),配合我們的索引管理策略,在低負(fù)載的時(shí)候 ( 晚上或某個(gè)時(shí)間點(diǎn) ),自動(dòng)調(diào)整索引的配置,讓它進(jìn)行自動(dòng)遷移。
02
典型應(yīng)用實(shí)踐
1. ELKB簡(jiǎn)介
在介紹我們典型的應(yīng)用實(shí)踐之前,我們先再介紹ELKB。
ELKB是一套日志管理方案,它是Elasticsearch、Logstash、Kibana、Beats服務(wù)的簡(jiǎn)稱。Elasticsearch用于存儲(chǔ)數(shù)據(jù),并提供搜索和分析;Logstash用于數(shù)據(jù)收集及轉(zhuǎn)換管道,可擴(kuò)展的插件;Kibana用于對(duì)存儲(chǔ)在Elasticsearch中的數(shù)據(jù)進(jìn)行可視化展示;Beats用于多類型數(shù)據(jù)采集器。
ELKB的架構(gòu)分為三層:數(shù)據(jù)提取層、數(shù)據(jù)的存儲(chǔ)層、數(shù)據(jù)展示層。ELKB將數(shù)據(jù)的提取、存儲(chǔ)、展示做成套件,這是它比較優(yōu)勢(shì)的地方。
2. 應(yīng)用實(shí)踐之一:58實(shí)時(shí)日志平臺(tái)
早期階段:
58內(nèi)部有好多套技術(shù)方案實(shí)踐,該架構(gòu)是5年前系統(tǒng)運(yùn)維部同學(xué)維護(hù)的一套日志收集平臺(tái),有兩條業(yè)務(wù)線在使用。這個(gè)版本當(dāng)時(shí)比較低,它通過Logstash抓取日志,但是Logstash這塊非常消耗資源,經(jīng)常出現(xiàn)一些穩(wěn)定性的問題。
現(xiàn)在階段:
目前我們?cè)诠局髁鞯娜罩酒脚_(tái)主要是這種:
工作流程:
收集:日志收集使用大數(shù)據(jù)部門的Flume進(jìn)行抓取
存儲(chǔ):數(shù)據(jù)收集完后會(huì)存儲(chǔ)到公司統(tǒng)一的Kafka集群;
展示:我們做了日志管理平臺(tái)-飛流。另外因?yàn)镵afka存儲(chǔ)的數(shù)據(jù)時(shí)間有限制,我們將Kafka的數(shù)據(jù)寫入到線下的KV存儲(chǔ)系統(tǒng)或者一些檢索系統(tǒng)中。監(jiān)控報(bào)警系統(tǒng)可以提供一定的監(jiān)控。
改進(jìn)階段:
接著也就演變到了下面這種新的日志平臺(tái):
收集:在數(shù)據(jù)抓取層除了使用Flume之外,我們?cè)黾恿薋ilebeat等套件。
緩存:抓取的數(shù)據(jù)仍通過公司的Kafka集群進(jìn)行緩存
過濾轉(zhuǎn)換訂閱消費(fèi):通過Kafka之后的下游消費(fèi)我們使用Logstash,因?yàn)長(zhǎng)ogstash的單節(jié)點(diǎn)的吞吐量有性能瓶頸,我們通過部署多套,并讓多個(gè)Logstash節(jié)點(diǎn)進(jìn)行消費(fèi)。另外一種就是hangout。hangout是攜程一個(gè)開源的類似Logstash的Kafka消費(fèi)組件,它在部分場(chǎng)景下的吞吐量不錯(cuò)
存儲(chǔ)檢索:使用Elasticsearch
展示:我們還自研了一些應(yīng)用程序,通過Kibana直接給數(shù)據(jù)分析師、用研員提供服務(wù)。另外部分業(yè)務(wù)也依靠Elasticsearch做趨勢(shì)或者預(yù)警方面的功能監(jiān)控報(bào)警平臺(tái),以及一些日志管理系統(tǒng),用于滿足自己的業(yè)務(wù)需求。
3. 應(yīng)用實(shí)踐之二:MySQL實(shí)時(shí)慢日志
早期業(yè)內(nèi)大家做MySQL的慢日志系統(tǒng)大都是獲取上一整天的慢日志,進(jìn)行統(tǒng)一分析,然后生成上一天的慢日志報(bào)表。這種方式有一定的滯后性,如果業(yè)務(wù)調(diào)整SQL或者新發(fā)布了一個(gè)功能想看實(shí)時(shí)的性能狀況,這種需求是滿足不了的。開發(fā)人員需要看到數(shù)據(jù)庫實(shí)時(shí)的慢日志,以方便更快的進(jìn)行性能診斷。我們使用ELKB技術(shù)棧來實(shí)現(xiàn):
收集:采集層使用公司的agent來管理每個(gè) MySQL 服務(wù)器節(jié)點(diǎn)上的Filebeat,比如實(shí)現(xiàn)對(duì)每個(gè)MySQL節(jié)點(diǎn)配置Filebeat,并進(jìn)行初始化、啟停等管控。
緩存:數(shù)據(jù)收集完成后,上報(bào)匯總到公司的Kafka集群。
過濾:配置Logstash過濾分析節(jié)點(diǎn),因?yàn)镸ySQL慢日志格式還是比較復(fù)雜,這里面要做一些分析過濾、切割轉(zhuǎn)換等相關(guān)操作。
存儲(chǔ):最終統(tǒng)一存入到Elasticsearch中
展示:目前我們支持在58云DB平臺(tái)【內(nèi)部的私有云數(shù)據(jù)庫平臺(tái)】上直接查看。我們也可以通過Kibana提供的統(tǒng)計(jì)工具進(jìn)行趨勢(shì)分析、運(yùn)維報(bào)警等。
目前給開發(fā)人員提供的用戶端,通過頁面可以實(shí)時(shí)看到自己的MySQL,從收集到MySQL到展示,目前可以做到5秒以內(nèi)展示。
4. 總結(jié)
上面介紹的是58同城內(nèi)部?jī)蓚€(gè)主要的應(yīng)用實(shí)踐,目前數(shù)據(jù)庫團(tuán)隊(duì)已經(jīng)收斂了整個(gè)公司30+套各種業(yè)務(wù)的Elasticsearch集群、300多個(gè)節(jié)點(diǎn),服務(wù)器接近200臺(tái),我們的管理維護(hù)還有不少的工作要做。
03
平臺(tái)化建設(shè)
從去年開始,我們啟動(dòng)了Elasticsearch平臺(tái)化建設(shè),一是面向用戶端提高開發(fā)接入Elasticsearch的效率,另外就是面向DBA管理端,可以對(duì)Elasticsearch集群進(jìn)行高效運(yùn)維及索引治理等。
58云DB平臺(tái)Elasticsearch功能架構(gòu)圖如下:
1. 用戶端
針對(duì)用戶端,我們把Elasticsearch開放給開發(fā)人員、數(shù)據(jù)運(yùn)營(yíng)、數(shù)據(jù)分析師等,使他們能夠?qū)lasticsearch的數(shù)據(jù)進(jìn)行基本的查詢,包括數(shù)據(jù)統(tǒng)計(jì)、分析報(bào)表、 查看Elasticsearch的狀態(tài)等。
集群負(fù)責(zé)人可以從管理界面上看到自己名下的集群列表、Kibana地址、集群容量、操作申請(qǐng)等。
這個(gè)界面是索引申請(qǐng)界面。所有接入者通過標(biāo)準(zhǔn)化的方式、規(guī)范化的流程來完成需求提交。每一個(gè)索引的接入必須包括數(shù)據(jù)的保留策略、mapping、數(shù)據(jù)寫入方式等。
2. 管理端
在管理端,我們實(shí)現(xiàn)了一鍵部署Elasticsearch集群。由于Elasticsearch是分布式的,部署的線路是比較長(zhǎng)的,它需要多節(jié)點(diǎn)、不同的角色,包括監(jiān)控、Logstash、Filebeat等相關(guān)的管理都是支持的。
從管理界面上可以看到哪個(gè)ip地址上運(yùn)行著哪個(gè)集群、它的角色是什么。
一鍵自動(dòng)化部署。
3. 索引治理
索引治理后續(xù)會(huì)做一些索引的生命周期管理,現(xiàn)在的管理我們最多的還是依賴腳本,后面索引的工作,我們希望都放到平臺(tái)上來,都要有相關(guān)的操作記錄。
索引的監(jiān)控
對(duì)于服務(wù)端目前使用的是 Zabbix+ Grafana的方式。我們開發(fā)了一套程序。將所有集群的監(jiān)控指標(biāo)打入到其中一套Elasticsearch集群中去,然后Grafana基于Elasticsearch做了圖表的展示,再通過Zabbix進(jìn)行一些系統(tǒng)的報(bào)警。
用戶端,可以通過Kibana可以看到索引index的速度、延遲等信息。
04
后續(xù)規(guī)劃
1. 版本升級(jí)
Elasticsearch 7.X,在Elasticsearch 7.X版本在性能優(yōu)化上做了很多東西,包括:查詢的相關(guān)性、對(duì)內(nèi)存的管控方面。但是它同樣存在一個(gè)問題,Elasticsearch版本不向下兼容,比如6.x版本升級(jí)到7.x版本,它的變化會(huì)比較大。
2. 集群智能診斷
集群功能越來越多,目前集群出了問題還是依賴運(yùn)維人員手動(dòng)發(fā)現(xiàn)。我們希望通過規(guī)則或者自動(dòng)分析等手段,實(shí)現(xiàn)故障的自動(dòng)化處理。
3. 私有云探索
接到Elasticsearch業(yè)務(wù)需求,我們首先要分析它的業(yè)務(wù)模型:是搜索的還是日志流水的?不同的用途對(duì)硬件的消耗差別是很大的,而服務(wù)器并不是高度的契合業(yè)務(wù)配置。在這個(gè)方面是有非常多的資源浪費(fèi),我們希望通過云模式,能夠減少資源浪費(fèi),提高資源的利用率。
05
1. Elasticsearch數(shù)據(jù)如何與hadoop大數(shù)據(jù)平臺(tái)數(shù)據(jù)倉庫同步?
答:Hadoop或hive數(shù)據(jù)可以通過官方的相關(guān)組件,也可以通過自己寫程序進(jìn)行同步。
2. Elasticsearch日志應(yīng)用中,怎么定義日志格式,有些后臺(tái)日志情況復(fù)雜,比如except崩潰的,怎么處理這種后臺(tái)日志問題?
答:關(guān)于日志格式可以看下Filebeat,F(xiàn)ilebeat在收集日志的時(shí)候有多行合并功能,從Kafka到Logstash可以定義自己的過濾規(guī)則,這樣可以很容易的把問題解決掉。
3. MySQL數(shù)據(jù)如何導(dǎo)入到Elasticsearch,并保持實(shí)時(shí)同步?
這是一個(gè)比價(jià)大的主題,從MySQL到Elasticsearch這里考慮的規(guī)則還是比較多的。如:?jiǎn)伪韺?dǎo)入到單索引、多表導(dǎo)入到一個(gè)Elasticsearch索引、單表導(dǎo)入多個(gè)索引,這些都是不一樣的。業(yè)內(nèi)做MySQL到Elasticsearch的同步的方案比較多,主流的有如下幾種:
簡(jiǎn)單粗暴的由業(yè)務(wù)層雙寫,即寫完MySQL之后直接寫Elasticsearch,當(dāng)然這樣雙寫可能無法保證數(shù)據(jù)的一致性,有些公司對(duì)異常有補(bǔ)償機(jī)制:如果寫入ES失敗,先把寫失敗的數(shù)據(jù)記錄下來,通過獨(dú)立后端程序進(jìn)行異常的數(shù)據(jù)修復(fù)。
一些開源的工具。比如阿里開源的多數(shù)據(jù)源dataX,它的設(shè)計(jì)原理是直接到MySQL中查詢數(shù)據(jù),它高度依賴一條記錄的過期時(shí)間,大于過期時(shí)間就將數(shù)據(jù)取出來寫到Elasticsearch中去,這個(gè)實(shí)時(shí)性依賴于程序多久刷新一次,但是如果數(shù)據(jù)刪除了,是無法感知到的。
直接解析MySQL的binlog。阿里也有這樣的開源工具canal。它的實(shí)現(xiàn)原理就是模擬一個(gè)MySQL的從庫,它訂閱所有主庫的變更,當(dāng)MySQL數(shù)據(jù)變化時(shí),它將解析的變更可以放到Kafka中去,Kafka下游可以消費(fèi)后寫入Elasticsearch,也可以不經(jīng)過Kafka直接解析出來寫入Elasticsearch。但canal也有個(gè)問題。它單節(jié)點(diǎn)處理能力受限。當(dāng)MySQL主庫寫入稍微多一些的情況下,這時(shí)候canal解析速度跟不上,導(dǎo)致大量延遲,如果主庫的持續(xù)的寫入量大,canal會(huì)一直延遲,而且延遲越來越大,同時(shí)會(huì)出現(xiàn)很多問題。
4. Elasticsearch如何實(shí)現(xiàn)高效的二級(jí)索引?
答:類似于MySQL的回表查詢模式,先將所有待查詢的數(shù)據(jù)同步到Elasticsearch中,同步時(shí)帶上相關(guān)的記錄id,在Elasticsearch完成查詢后,再用這些id去相關(guān)的MySQL或HBASE進(jìn)行查詢返回完整數(shù)據(jù)。
于伯偉
58同城 | 高級(jí)架構(gòu)師
58同城數(shù)據(jù)庫部門負(fù)責(zé)人,負(fù)責(zé)為公司各業(yè)務(wù)提供高可靠、高性能的一站式數(shù)據(jù)庫服務(wù),主要數(shù)據(jù)庫類型包括MySQL、Redis、MongoDB、TiDB和Elasticsearch等,助力與賦能業(yè)務(wù)發(fā)展,提高效率。
特別推薦一個(gè)分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒關(guān)注的小伙伴,可以長(zhǎng)按關(guān)注一下:
長(zhǎng)按訂閱更多精彩▼
如有收獲,點(diǎn)個(gè)在看,誠(chéng)摯感謝
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!