點擊上方藍(lán)色字體,選擇“設(shè)為星標(biāo)”
點擊右側(cè)關(guān)注,大數(shù)據(jù)開發(fā)領(lǐng)域最強(qiáng)公眾號!點擊右側(cè)關(guān)注,大數(shù)據(jù)真好玩!
美團(tuán)各業(yè)務(wù)線存在大量的 OLAP 分析場景,需要基于 Hadoop 數(shù)十億級別的數(shù)據(jù)進(jìn)行分析,直接響應(yīng)分析師和城市 BD 等數(shù)千人的交互式訪問請求,對 OLAP 服務(wù)的擴(kuò)展性、穩(wěn)定性、數(shù)據(jù)精確性和性能均有很高要求。本文主要介紹美團(tuán)的具體 OLAP 需求,如何將 Kylin 應(yīng)用到實際場景中,以及目前的使用方式和現(xiàn)狀。同時也將 Kylin 和其它系統(tǒng)(如 Presto、Druid 等)進(jìn)行了對比,闡述了 Kylin 的獨(dú)特優(yōu)勢。
作為公司的平臺部門,需要給各個業(yè)務(wù)線提供平臺的服務(wù),那么如何建設(shè)一個滿足各種需求的公司平臺級 OLAP 分析服務(wù)呢。首先,一個開源項目在公司真正落地會遇到很多障礙,這主要是由各個業(yè)務(wù)線不同的數(shù)據(jù)特點和業(yè)務(wù)特點決定的,所以本文會介紹一下美團(tuán)的數(shù)據(jù)場景有什么特點;其次,針對這些數(shù)據(jù)特點,尤其是和 Kylin 設(shè)計初衷不太相符的部分,有什么樣的解決方案;第三,目前 OLAP 領(lǐng)域還沒有所謂事實上的標(biāo)準(zhǔn),很多引擎都可以做類似事情,比如普通的 MPP,Kylin,或者 ES 等。這些系統(tǒng)之間的對比情況如何,應(yīng)該如何選擇,我們也有部分測試數(shù)據(jù)可以分享;最后,簡單討論一下未來準(zhǔn)備在 Kylin 上做的工作。1 美團(tuán)的數(shù)據(jù)場景特點
第一個特點是數(shù)據(jù)規(guī)模和模型特點。一方面從數(shù)據(jù)規(guī)模上來講,事實表一般在 1 億到 10 億量級,同時還有千萬量級的維表,也就是超高基數(shù)的維表。另一方面,數(shù)據(jù)模型是一開始遇到的最大困難。因為 Kylin 最初的設(shè)計是基于一個星形模型的,但很不幸由于各種原因,很多數(shù)據(jù)都是雪花的模型,還有其它的模型,比如所謂“星座”模型,也就是中間是兩張或者三張事實表,周圍關(guān)聯(lián)了其它很多維表。業(yè)務(wù)邏輯決定了這些數(shù)據(jù)的關(guān)聯(lián)方式非常復(fù)雜,根本無法用經(jīng)典標(biāo)準(zhǔn)的理論來解釋。第二個是維度。維度最理想的情況是固定的,每天變化的只是事實表。但實際上維度經(jīng)常會變,這可能和行業(yè)特點有關(guān),比如組織架構(gòu),相關(guān)的維度數(shù)據(jù)可能每天都會變化。除此之外還可能要用今天的維度去關(guān)聯(lián)所有的歷史數(shù)據(jù),因此要重刷歷史數(shù)據(jù),相應(yīng)的開銷也比較大。第三個是數(shù)據(jù)回溯的問題。比如發(fā)現(xiàn)數(shù)據(jù)生成有問題,或者上游出錯了,此時就需要重跑數(shù)據(jù)。這也是和經(jīng)典理論模型有區(qū)別的。從維度的角度來看,一般維度的個數(shù)在 5-20 個之間,相對來說還是比較適合用 Kylin 的。另一個特點是一般都會有一個日期維度,有可能是當(dāng)天,也有可能是一個星期,一個月,或者任意一個時間段。另外也會有較多的層次維度,比如組織架構(gòu)從最上面的大區(qū)一直到下面的蜂窩,就是一個典型的層次維度。從指標(biāo)的角度來講,一般情況下指標(biāo)個數(shù)在 50 個以內(nèi),相對來說 Kylin 在指標(biāo)上的限制并沒有那么嚴(yán)格,都能滿足需求。其中有比較多的表達(dá)式指標(biāo),在 Kylin 里面聚合函數(shù)的參數(shù)只能是單獨(dú)的一列,像 sum(if…) 這種就不能支持,因此需要一些特別的解決方法。另外一個非常重要的問題是數(shù)據(jù)的精確性,目前在 OLAP 領(lǐng)域,各個系統(tǒng)都是用 hyperloglog 等近似算法做去重計數(shù),這主要是出于開銷上的考慮,但我們的業(yè)務(wù)場景要求數(shù)據(jù)必須是精確的。因此這也是要重點解決的問題。在查詢上也有比較高的要求。因為平臺的查詢服務(wù)可能直接向城市 BD 開放,每次會有幾十、上百萬次的訪問,所以穩(wěn)定性是首先要保證的。第二要求有很高的性能。因為用 Kylin 主要是為了實現(xiàn)交互式的分析,讓使用者能夠很快拿到結(jié)果,所以需要秒級響應(yīng)。另外經(jīng)常會有人問到,Kylin 有沒有可視化的前端,在我們內(nèi)部更多是由業(yè)務(wù)方來做,因為原來本身就有這樣的系統(tǒng),以前接的是 MySQL 等其它的數(shù)據(jù)源,現(xiàn)在可以直接使用 Kylin 的 JDBC driver 對接起來。以上是美團(tuán)在 OLAP 查詢方面的一些特點。在用 Kylin 之前,實際上有一些方案,但效果并不理想。比如用 Hive 直接去查,這種情況下,第一個是慢,第二會消耗計算集群的資源。尤其每個月第一天,大家都要出月報,跑的 SQL 非常多,全提到集群上去,并發(fā)度限制導(dǎo)致跑的比平時更慢。我們原來也做過預(yù)聚合的嘗試,這個思路跟 Kylin 很像,只不過是自己做這個事,用 Hive 先把所有的維度算出來,然后導(dǎo)入 MySQL 或者 HBase。但是這個方案并沒有像 Kylin 這么好的模型定義抽象,也沒有從配置到執(zhí)行,預(yù)計算,查詢這樣整體的框架?,F(xiàn)在通過使用 Kylin 實現(xiàn)了低成本的解決這些問題。2 接入 Apache Kylin 的解決方案
針對上述的問題,經(jīng)過大量的嘗試和驗證,目前主要的解決方案有以下幾點。最重要的第一點,就是采用寬表。所有非標(biāo)準(zhǔn)星型的數(shù)據(jù)模型,都可以通過預(yù)處理先拉平,做成一個寬表來解決。只要能根據(jù)業(yè)務(wù)邏輯把這些表關(guān)聯(lián)起來,生成一張寬表,然后再基于這張表在 Kylin 里做數(shù)據(jù)的聚合就可以了。寬表不只能解決數(shù)據(jù)模型的問題,還能解決維度變化、或者超高基數(shù)的維度等問題。第二點是表達(dá)式指標(biāo)的問題,也可以通過提前處理解決。把表達(dá)式單獨(dú)轉(zhuǎn)成一列,再基于這列做聚合就可以了。實際上寬表和表達(dá)式變換的處理可以用 hive 的 view,也可以生成物理表。第三個是精確去重的問題,目前的方案是基于 Bitmap。由于數(shù)據(jù)類型的限制,目前只支持 int 類型,其它包括 long、string 等類型還不支持。因為需要把每個值都能映射到 Bitmap 里, 如果是 long 的話開銷太大。如果用哈希的話就會沖突,造成結(jié)果不準(zhǔn)確。另外 Bitmap 本身開銷也是比較大的,尤其跑預(yù)計算的時候,如果算出來的基數(shù)很大,對應(yīng)的數(shù)據(jù)結(jié)構(gòu)就是幾十兆,內(nèi)存會有 OOM 的風(fēng)險。這些問題后面我們也會想一些辦法解決,也歡迎在社區(qū)里一起討論。(補(bǔ)充說明:目前已在 1.5.3 版本中實現(xiàn)了全類型精確去重計數(shù)的支持。)從整個系統(tǒng)的部署方式上來說,目前 Server 采用了分離部署的方式。Kylin Server 本質(zhì)上就是一個客戶端,并不需要太多資源,一般情況下使用虛擬機(jī)就能夠滿足需求。實際的部署情況可以看這張圖,左下角的是 hadoop 主集群,用于執(zhí)行每天所有 hadoop 作業(yè)。中間最重要的是 Kylin01 和 02 這兩個 server,是用于線上環(huán)境的 serve。其中 kylin01 是生產(chǎn)環(huán)境,這個環(huán)境一方面要負(fù)責(zé)從主機(jī)群上跑計算,把數(shù)據(jù)導(dǎo)到 HBase,另外也要響應(yīng)前端的請求,從 HBase 里讀數(shù)據(jù)。如果想新增一個 Cube 的話,需要在 kylin02 上操作,也就是預(yù)上線環(huán)境。所有業(yè)務(wù)方人員的 cube 數(shù)據(jù)模型定義都是在 kylin02 上做,沒有問題后由管理員切到 kylin01 上。這樣做的一個好處是 kylin01 作為一個線上服務(wù)能保證穩(wěn)定性,甚至權(quán)限控制能更嚴(yán)格一些;第二,預(yù)上線環(huán)境下開發(fā)完成后,管理員可以在投入生產(chǎn)前進(jìn)行一次 review,保證 cube 的效率。右上角是另外的調(diào)度系統(tǒng)。整個數(shù)據(jù)倉庫的數(shù)據(jù)生產(chǎn)都是通過這個調(diào)度系統(tǒng)來調(diào)度的,其中的任務(wù)類型很多,Kylin 的 cube build 任務(wù)也是作為其中的一種類型。在上游的數(shù)據(jù)就緒以后,根據(jù)配置的依賴關(guān)系,自動觸發(fā) Cube 建立的過程。左上角這邊還有一個完全獨(dú)立的線下測試集群,這個集群是完全開放的,主要是給用戶做一些最開始的可行性調(diào)研或者評估的工作,但同時也不保證穩(wěn)定性。一個開源的系統(tǒng)從社區(qū)拿回來,到真正的落地,再到上生產(chǎn),這個過程相對還是比較長的,這里并沒有太多的技術(shù)問題,更多的是一些流程上的經(jīng)驗。就是如何在各個階段給業(yè)務(wù)方提供更好的服務(wù),使得接入 Kylin 的過程更順暢,溝通成本更低。整個過程主要分為四個階段。第一個階段是方案選型,業(yè)務(wù)方根據(jù)業(yè)務(wù)需求,選擇一些方案進(jìn)行調(diào)研。我們在這個階段提供了需求的 Checklist,從數(shù)據(jù)模型,維度各個方面列出來比較詳細(xì)的點,可以讓業(yè)務(wù)方自己對照,確定需求是不是能夠被滿足。在確定 Kylin 能滿足需求的基礎(chǔ)上,接下來是第二步,線下探查,也就是線下評估或者測試。我們提供了非常詳細(xì)的接入文檔,以及線下測試的環(huán)境。第三步是線上開發(fā),我們也有一些文檔支持,基于抽象出來的場景,每個場景怎么配置 Cube,或者做哪些預(yù)處理,如何優(yōu)化等,能夠給業(yè)務(wù)方一個指導(dǎo)性的意見。最后是開發(fā)完成后的切表上線。這個過程目前還是由管理員來操作,一方面是為了避免誤操作或者濫操作,另一方面也會對 cube 進(jìn)行 review,幫助進(jìn)行優(yōu)化。3 主流 OLAP 系統(tǒng)對比分析
通過和其它同學(xué)交流,有一個感覺就是大家都覺得 Kylin 還不錯,但并不是特別有信心,或者不知道非要用它的理由是什么,或者它和其它系統(tǒng)的對比是什么樣的?這里也有部分測試結(jié)果可以和大家分享。整個測試基于 SSB 的數(shù)據(jù)集,也是完全開源的,實際上是專門用于星型模型 OLAP 場景下的測試。整個測試數(shù)據(jù)集是非常標(biāo)準(zhǔn)的五張表,可以配置一些參數(shù)決定生成的數(shù)據(jù)集規(guī)模,然后在不同的規(guī)模下做不同查詢場景的測試。現(xiàn)在已經(jīng)完成的測試的系統(tǒng)包括:Presto,Kylin1.3,Kylin1.5 和 Druid。數(shù)據(jù)規(guī)模包含千萬、億、十億三種規(guī)模;維度個數(shù)為 30 個;指標(biāo)個數(shù)為 50 個。典型的測試場景包括:上卷、下鉆,和常用的聚合函數(shù)。這里挑選了典型的五個查詢場景:一個事實表的過濾和聚合;五張表全關(guān)聯(lián)之后的查詢;兩個 Count Dstinct 指標(biāo)和兩個 Sum 指標(biāo);后面兩個查詢包含 8~10 個的維度過濾。這張圖是千萬規(guī)模下的一個測試結(jié)果,包括了四個系統(tǒng)。我們在用 Kylin 或者其它系統(tǒng)之前沒有專門用于 OLAP 分析的引擎,只能用通用的。Presto 是其中表現(xiàn)非常好的引擎,但是在 OLAP 這種特定的場景下,可以看到不管跟 Kylin 還是 Druid 相比差的都比較多,所以前兩個測試包含了 Presto 結(jié)果,后面就沒有包含了這里比較有趣的現(xiàn)象是在第三個查詢,Kylin1.5 反而比 Kylin1.3 要慢一些。這個地方我們還沒有搞清楚是什么原因,后面會詳細(xì)的看一下。當(dāng)然這個也可以證明數(shù)據(jù)沒有修改過,是真實的測試數(shù)據(jù)。從后面的兩個查詢上可以看到,在千萬規(guī)模的級別,和 Druid 還是有比較大的差距。這主要和它們的實現(xiàn)模式相關(guān),因為 Druid 會把所有的數(shù)據(jù)預(yù)處理完以后都加載到內(nèi)存里,在做一些小數(shù)據(jù)量聚合的時候,可以達(dá)到非??斓乃俣?;但是 Kylin 要到 HBase 上讀,相對來說它的性能要差一些,但也完全能滿足需求。
在億級的規(guī)模上情況又有了變化,還是看后面兩個查詢,Kylin1.3 基本上是一個線性的增長,這個數(shù)據(jù)已經(jīng)變得比較難看了,這是由于 Kylin1.3 在掃描 HBase 的時候是串行方式,但是 Kylin1.5 反而會有更好的表現(xiàn),這是因為 Kylin1.5 引入了 HBase 并行 Scan,大大降低了掃描的時間。Kylin1.5 的數(shù)據(jù)會 shard 到不同的 region 上,在千萬量級上數(shù)據(jù)量還比較小,沒有明顯的體現(xiàn),但是上億以后,隨著數(shù)據(jù)量上升,region 也變多了,反而能把并發(fā)度提上去。所以在這里可以看到 Kylin1.5 表現(xiàn)會更好。這里也可以看出,在數(shù)據(jù)量成數(shù)量級上升后,Kylin 表現(xiàn)的更加穩(wěn)定,在不同規(guī)模數(shù)據(jù)集上依然可以保持不錯的查詢性能。而 Druid 隨著數(shù)據(jù)量的增長性能損失也成倍增長。
剛才是在性能方面做的一些分析,其實對于一個系統(tǒng)來說,性能只是一個方面,除此之外,我們也會去考量其它方面的情況,主要有以下四點。第一,功能的完備性。剛才提到我們所有的數(shù)據(jù)必須是精確的,但是現(xiàn)在基本上沒有哪個系統(tǒng)能完全覆蓋我們這個需求。比如 Druid 性能表現(xiàn)確實更好,但是它去重計數(shù)沒有辦法做到精確。第二,系統(tǒng)的易用性。作為一個平臺服務(wù),不僅要把系統(tǒng)用起來,還要維護(hù)它,因此要考慮部署和監(jiān)控的成本。這方面 Kylin 相對來說也是比較好的。Druid 一個集群的角色是非常多的,如果要把這個系統(tǒng)用起來的話,可能光搭這個環(huán)境,起這些服務(wù)都要很長的時間。這個對于我們做平臺來講,實際上是一個比較痛的事。不管是在部署,還是加監(jiān)控的時候,成本都是相對比較高的。另外一個查詢接口方面,我們最熟悉或者最標(biāo)準(zhǔn),最好用的當(dāng)然是標(biāo)準(zhǔn) SQL 的接口。ES、Druid 這些系統(tǒng)原來都不支持 SQL,當(dāng)然現(xiàn)在也有一些插件,但是在功能的完備性和數(shù)據(jù)的效率上都不如原生的支持。第三,數(shù)據(jù)成本。剛才提到了有些數(shù)據(jù)需要做一些預(yù)處理,比如表的拉平或者表達(dá)式列的變換,除此之外還有一些格式的轉(zhuǎn)化,比如有的系統(tǒng)只能讀 TEXT 格式,這樣都會帶來數(shù)據(jù)準(zhǔn)備的成本。另一方面是數(shù)據(jù)導(dǎo)入的效率。從數(shù)據(jù)進(jìn)入數(shù)據(jù)倉庫到真正能夠被查詢,這個時間中間有多長。數(shù)據(jù)存儲和服務(wù)的時候需要多少機(jī)器資源,這個都可以歸為數(shù)據(jù)成本,就是使用這個數(shù)據(jù)需要付出的成本。第四,查詢靈活性。經(jīng)常有業(yè)務(wù)方問到,如果 Cube 沒定義的話怎么辦?現(xiàn)在當(dāng)然查詢只能失敗。這個說明有的查詢模式不是那么固定的,可能突然要查一個數(shù),但以后都不會再查了。實際上在需要預(yù)定義的 OLAP 引擎上,這種需求普遍來講支持都不是太好。
從查詢效率上看,這里表現(xiàn)最不好的就是 Presto,表現(xiàn)最好的應(yīng)該是 Druid 和 Kylin1.5,兩者不相上下。從功能完備性上來講,確實 Presto 語法和 UDF 等等是很完備的,Kylin 會稍微差一些,但比 Druid 好一點。系統(tǒng)易用性上區(qū)別不是太大,這里主要考慮有沒有標(biāo)準(zhǔn)的 SQL 接口或者部署成本高不高,用戶上手能不能更快,目前來看 Druid 接口上確實不夠友好,需要去翻它的文檔才知道怎么去寫查詢的語法。在查詢成本上,Presto 是最好的,因為幾乎不需要做什么特殊的處理,基本上 Hive 能讀的數(shù)據(jù) Presto 也都能讀,所以這個成本非常低。Druid 和 Kylin 的成本相對較高,因為都需要提前的預(yù)計算,尤其是 Kylin 如果維度數(shù)特別多,而且不做特別優(yōu)化的話,數(shù)據(jù)量還是很可觀的。最后從靈活性上來講, Presto 只要 SQL 寫出來怎么查都可以,Druid 和 Kylin 都要做一些預(yù)先模型定義的工作。這方面也可以作為大家選型時候的參考。剛才比較客觀的對比了幾個系統(tǒng),接下來再總結(jié)一下 Kylin 的優(yōu)勢。第一,性能非常穩(wěn)定。因為 Kylin 依賴的所有服務(wù),比如 Hive、HBase 都是非常成熟的,Kylin 本身的邏輯并不復(fù)雜,所以穩(wěn)定性有一個很好的保證。目前在我們的生產(chǎn)環(huán)境中,穩(wěn)定性可以保證在 99.99% 以上。同時查詢時延也比較理想。我們現(xiàn)在有一個業(yè)務(wù)線需求,每天查詢量在兩萬次以上,95% 的時延低于 1 秒,99% 在 3 秒以內(nèi)?;旧夏軡M足我們交互式分析的需求。第二,對我們特別重要的一點,就是數(shù)據(jù)的精確性要求。其實現(xiàn)在能做到的只有 Kylin,所以說我們也沒有什么太多其他的選擇。第三,從易用性上來講,Kylin 也有非常多的特點。首先是外圍的服務(wù),不管是 Hive 還是 HBase,只要大家用 Hadoop 系統(tǒng)的話基本都有了,不需要額外工作。在部署運(yùn)維和使用成本上來講,都是比較低的。其次,有一個公共的 Web 頁面來做模型的配置。相比之下 Druid 現(xiàn)在還是基于配置文件來做。這里就有一個問題,配置文件一般都是平臺方或者管理員來管理的,沒辦法把這個配置系統(tǒng)開放出去,這樣在溝通成本和響應(yīng)效率上都不夠理想。Kylin 有一個通用的 Web Server 開放出來,所有用戶都可以去測試和定義,只有上線的時候需要管理員再 review 一下,這樣體驗就會好很多。第四,最后一點就是活躍開放的社區(qū)和熱心的核心開發(fā)者團(tuán)隊,社區(qū)里討論非常開放,大家可以提自己的意見及 patch,修復(fù) bug 以及提交新的功能等,包括我們美團(tuán)團(tuán)隊也貢獻(xiàn)了很多特性,比如寫入不同的 HBase 集群等。這里特別要指出的是核心團(tuán)隊都是中國人,這是 Apache 所有項目里唯一中國人為主的頂級項目,社區(qū)非常活躍和熱心,有非常多的中國工程師。特別是當(dāng)你貢獻(xiàn)越來越多的時候,社區(qū)會邀請成為 committer 等,包括我自己及團(tuán)隊成員也已經(jīng)是 Apache Kylin 的 committer。同時也非常高興看到以韓卿為首的 Apache Kylin 核心團(tuán)隊在今年初成立的創(chuàng)業(yè)公司 Kyligence,相信可以為整個項目及社區(qū)的發(fā)展帶來更大的空間和未來。4 未來工作
在未來工作方面,我們認(rèn)為 Kylin 還有一些不理想的方面,我們也會著力去做優(yōu)化和改進(jìn)。第一,精確去重計數(shù)。剛才提到只支持 Int,接下來有一個方案會支持所有的數(shù)據(jù)類型,能夠擴(kuò)展大家使用精確去重的場景范圍(補(bǔ)充說明:目前該功能已在 1.5.3 版本中實現(xiàn))。第二,在查詢效率和 Build 效率上也看到了一些可以優(yōu)化的部分。比如隊列資源拆分,我們所有計算集群的資源都是按照業(yè)務(wù)線核算成本的,但是現(xiàn)在 Kylin 本身還不太支持,這個我們也會抓緊去做,相信在很多公司也有類似的需求。還有大結(jié)果集和分頁。當(dāng)結(jié)果到了上百萬的量級時,查詢時延會上升到幾十秒。同時在查詢的時候有可能需要排序并且分頁,就是把結(jié)果全讀出來之后,根據(jù)其中的一個指標(biāo)再 order by,這個開銷也是比較大的。我們也會想辦法進(jìn)行優(yōu)化。最后,Kylin1.5 之后有明細(xì)數(shù)據(jù)和 Streaming 特性出來,后面也會做這方面的嘗試。5 Q&A
Q1:之前在 Build 的時候一直提到成本的問題,能給出一個估計值嗎,如果一百億的數(shù)據(jù),需要多少時間?有一個簡單數(shù)據(jù),大概是兩億行數(shù)據(jù),維度的話有十四五個,Build 時間不超過兩個小時,Build 出來的數(shù)據(jù)是五六百 G。
把這個數(shù)據(jù)抽出來之后,就是只參與 Build 的數(shù)據(jù)壓縮后只有幾個 G。
Q3:Kerberos 認(rèn)證失效的問題你們遇到過沒有?Kerberos 認(rèn)證完之后,會在本地臨時目錄下有一個 ticket 問題,每天在外部定時刷新一下就可以了,服務(wù)是不用停的。
主持人:我補(bǔ)充一下我們?yōu)槭裁催x擇 SQL 接口?Kylin 解決的是真正的用戶面是誰,其實是業(yè)務(wù)人員和分析人員,他只會 SQL,幾乎那些人很少說再學(xué)個 JAVA,所以能給他一個標(biāo)準(zhǔn)的 SQL 這個是讓他上船最快的事情。其實這就是易用性很重要。剛才看到了 Kylin 在千萬級規(guī)模和億級規(guī)模的表現(xiàn),如果數(shù)據(jù)規(guī)模上到十億,百億,千億的時候,我相信 Kylin 應(yīng)該會秒殺所有一切。因為我們現(xiàn)在有另一個案例,生產(chǎn)環(huán)境上千億規(guī)模的一張表,可以做到 90% 查詢在 1.8 秒以內(nèi)。另外我覺得非常好的一點,像美團(tuán)、京東這邊貢獻(xiàn)了很多 patch,其實就是把需求提出來,大家可以一起來做。版權(quán)聲明:
本文為大數(shù)據(jù)技術(shù)與架構(gòu)整理,原作者獨(dú)家授權(quán)。未經(jīng)原作者允許轉(zhuǎn)載追究侵權(quán)責(zé)任。歡迎點贊+收藏+轉(zhuǎn)發(fā)朋友圈素質(zhì)三連文章不錯?點個【在看】吧!?