偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Apache Flink 漫談系列(02) - 概述

開發(fā) 開發(fā)工具
本篇文章我們用一句話聊聊什么是 Apache Flink 的命脈?我的答案是:Apache Flink 是以"批是流的特例"的認(rèn)知進行系統(tǒng)設(shè)計的。

一、Apache Flink 的命脈

"命脈" 即生命與血脈,常喻極為重要的事物。系列的首篇,首篇的首段不聊Apache Flink的歷史,不聊Apache Flink的架構(gòu),不聊Apache Flink的功能特性,我們用一句話聊聊什么是 Apache Flink 的命脈?我的答案是:Apache Flink 是以"批是流的特例"的認(rèn)知進行系統(tǒng)設(shè)計的。

二、唯快不破

我們經(jīng)常聽說 "天下武功,唯快不破",大概意思是說 "任何一種武功的招數(shù)都是有拆招的,唯有速度快,快到對手根本來不及反應(yīng),你就將對手KO了,對手沒有機會拆招,所以唯快不破"。 那么這與Apache Flink有什么關(guān)系呢?Apache Flink是Native Streaming(純流式)計算引擎,在實時計算場景最關(guān)心的就是"快",也就是 "低延時"。

就目前最熱的兩種流計算引擎Apache Spark和Apache Flink而言,誰最終會成為No1呢?單從 "低延時" 的角度看,Spark是Micro Batching(微批式)模式,***延遲Spark能達(dá)到0.5~2秒左右,F(xiàn)link是Native Streaming(純流式)模式,***延時能達(dá)到微秒。很顯然是相對較晚出道的 Apache Flink 后來者居上。 那么為什么Apache Flink能做到如此之 "快"呢?根本原因是Apache Flink 設(shè)計之初就認(rèn)為 "批是流的特例",整個系統(tǒng)是Native Streaming設(shè)計,每來一條數(shù)據(jù)都能夠觸發(fā)計算。相對于需要靠時間來積攢數(shù)據(jù)Micro Batching模式來說,在架構(gòu)上就已經(jīng)占據(jù)了絕對優(yōu)勢。

那么為什么關(guān)于流計算會有兩種計算模式呢?歸其根本是因為對流計算的認(rèn)知不同,是"流是批的特例" 和 "批是流的特例" 兩種不同認(rèn)知產(chǎn)物。

1. Micro Batching 模式

Micro-Batching 計算模式認(rèn)為 "流是批的特例", 流計算就是將連續(xù)不斷的批進行持續(xù)計算,如果批足夠小那么就有足夠小的延時,在一定程度上滿足了99%的實時計算場景。那么那1%為啥做不到呢?這就是架構(gòu)的魅力,在Micro-Batching模式的架構(gòu)實現(xiàn)上就有一個自然流數(shù)據(jù)流入系統(tǒng)進行攢批的過程,這在一定程度上就增加了延時。具體如下示意圖:

Micro Batching 模式

很顯然Micro-Batching模式有其天生的低延時瓶頸,但任何事物的存在都有兩面性,在大數(shù)據(jù)計算的發(fā)展歷史上,最初Hadoop上的MapReduce就是優(yōu)秀的批模式計算框架,Micro-Batching在設(shè)計和實現(xiàn)上可以借鑒很多成熟實踐。

2. Native Streaming 模式

Native Streaming 計算模式認(rèn)為 ""批是流的特例",這個認(rèn)知更貼切流的概念,比如一些監(jiān)控類的消息流,數(shù)據(jù)庫操作的binlog,實時的支付交易信息等等自然流數(shù)據(jù)都是一條,一條的流入。Native Streaming 計算模式每條數(shù)據(jù)的到來都進行計算,這種計算模式顯得更自然,并且延時性能達(dá)到更低。具體如下示意圖:

Native Streaming 模式

很明顯Native Streaming模式占據(jù)了流計算領(lǐng)域 "低延時" 的核心競爭力,當(dāng)然Native Streaming模式的實現(xiàn)框架是一個歷史先河,***個實現(xiàn)Native Streaming模式的流計算框架是***個吃螃蟹的人,需要面臨更多的挑戰(zhàn),后續(xù)章節(jié)我們會慢慢介紹。當(dāng)然Native Streaming模式的框架實現(xiàn)上面很容易實現(xiàn)Micro-Batching和Batching模式的計算,Apache Flink就是Native Streaming計算模式的流批統(tǒng)一的計算引擎。

三、豐富的部署模式

Apache Flink 按不同的需求支持Local,Cluster,Cloud三種部署模式,同時Apache Flink在部署上能夠與其他成熟的生態(tài)產(chǎn)品進行***集成,如 Cluster模式下可以利用YARN(Yet Another Resource Negotiator)/Mesos集成進行資源管理,在Cloud部署模式下可以與GCE(Google Compute Engine), EC2(Elastic Compute Cloud)進行集成。

1. Local 模式

該模式下Apache Flink 整體運行在Single JVM中,在開發(fā)學(xué)習(xí)中使用,同時也可以安裝到很多端類設(shè)備上。

2. Cluster模式

該模式是典型的投產(chǎn)的集群模式,Apache Flink 既可以Standalone的方式進行部署,也可以與其他資源管理系統(tǒng)進行集成部署,比如與YARN進行集成。

這種部署模式是典型的Master/Slave模式,我們以Standalone Cluster模式為例示意如下:

其中JM(JobManager)是Master,TM(TaskManager)是Slave,這種Master/Slave模式有一個典型的問題就是SPOF(single point of failure), SPOF如何解決呢?Apache Flink 又提供了HA(High Availability)方案,也就是提供多個Master,在任何時候總有一個JM服役,N(N>=1)個JM候選,進而解決SPOF問題,示意如下:

在實際的生產(chǎn)環(huán)境我們都會配置HA方案,目前Alibaba內(nèi)部使用的也是基于YARN Cluster的HA方案。

3. Cloud 模式

該模式主要是與成熟的云產(chǎn)品進行集成,Apache Flink官網(wǎng)介紹了Google的GCE 參考,Amazon的EC2 參考,在Alibaba我們也可以將Apache Flink部署到Alibaba的ECS(Elastic Compute Service)。

四、完善的容錯機制

1. 什么是容錯

容錯(Fault Tolerance) 是指容忍故障,在故障發(fā)生時能夠自動檢測出來并使系統(tǒng)能夠自動回復(fù)正常運行。當(dāng)出現(xiàn)某些指定的網(wǎng)絡(luò)故障、硬件故障、軟件錯誤時,系統(tǒng)仍能執(zhí)行規(guī)定的一組程序,或者說程序不會因系統(tǒng)中的故障而中止,并且執(zhí)行結(jié)果也不會因系統(tǒng)故障而引起計算差錯。

2. 容錯的處理模式

在一個分布式系統(tǒng)中由于單個進程或者節(jié)點宕機都有可能導(dǎo)致整個Job失敗,那么容錯機制除了要保證在遇到非預(yù)期情況系統(tǒng)能夠"運行"外,還要求能"正確運行",也就是數(shù)據(jù)能按預(yù)期的處理方式進行處理,保證計算結(jié)果的正確性。計算結(jié)果的正確性取決于系統(tǒng)對每一條計算數(shù)據(jù)處理機制,一般有如下三種處理機制:

  • At Most Once:最多消費一次,這種處理機制會存在數(shù)據(jù)丟失的可能。
  • At Least Once:最少消費一次,這種處理機制數(shù)據(jù)不會丟失,但是有可能重復(fù)消費。
  • Exactly Once:精確一次,無論何種情況下,數(shù)據(jù)都只會消費一次,這種機制是對數(shù)據(jù)準(zhǔn)確性的***要求,在金融支付,銀行賬務(wù)等領(lǐng)域必須采用這種模式。

3. Apache Flink的容錯機制

Apache Flink的Job會涉及到3個部分,外部數(shù)據(jù)源(External Input), Flink內(nèi)部數(shù)據(jù)處理(Flink Data Flow)和外部輸出(External Output)。如下示意圖:

目前Apache Flink 支持兩種數(shù)據(jù)容錯機制:

  • At Least Once
  • Exactly Once

其中 Exactly Once 是最嚴(yán)格的容錯機制,該模式要求每條數(shù)據(jù)必須處理且僅處理一次。那么對于這種嚴(yán)格容錯機制,一個完整的Flink Job容錯要做到 End-to-End 的 容錯必須結(jié)合三個部分進行聯(lián)合處理,根據(jù)上圖我們考慮三個場景:

  • 場景一:Flink的Source Operator 在讀取到Kafla中pos=2000的數(shù)據(jù)時候,由于某種原因宕機了,這個時候Flink框架會分配一個新的節(jié)點繼續(xù)讀取Kafla數(shù)據(jù),那么新的處理節(jié)點怎樣處理才能保證數(shù)據(jù)處理且只被處理一次呢?

 

  • 場景二:Flink Data Flow內(nèi)部某個節(jié)點,如果上圖的agg()節(jié)點發(fā)生問題,在恢復(fù)之后怎樣處理才能保持map()流出的數(shù)據(jù)處理且只被處理一次?

  • 場景三:Flink的Sink Operator 在寫入Kafka過程中自身節(jié)點出現(xiàn)問題,在恢復(fù)之后如何處理,計算結(jié)果才能保證寫入且只被寫入一次?

4. 系統(tǒng)內(nèi)部容錯

Apache Flink利用Checkpointing機制來處理容錯,Checkpointing的理論基礎(chǔ) Stephan 在 Lightweight Asynchronous Snapshots for Distributed Dataflows 進行了細(xì)節(jié)描述,該機制源于有K. MANI CHANDY和LESLIE LAMPORT 發(fā)表的 Determining-Global-States-of-a-Distributed-System Paper。Apache Flink 基于Checkpointing機制對Flink Data Flow實現(xiàn)了At Least Once 和 Exactly Once 兩種容錯處理模式。

Apache Flink Checkpointing的內(nèi)部實現(xiàn)會利用 Barriers,StateBackend等后續(xù)章節(jié)會詳細(xì)介紹的技術(shù)來將數(shù)據(jù)的處理進行Marker。Apache Flink會利用Barrier將整個流進行標(biāo)記切分,如下示意圖:

這樣Apache Flink的每個Operator都會記錄當(dāng)前成功處理的Checkpoint,如果發(fā)生錯誤,就會從上一個成功的Checkpoint開始繼續(xù)處理后續(xù)數(shù)據(jù)。比如 Soruce Operator會將讀取外部數(shù)據(jù)源的Position實時的記錄到Checkpoint中,失敗時候會從Checkpoint中讀取成功的position繼續(xù)精準(zhǔn)的消費數(shù)據(jù)。每個算子會在Checkpoint中記錄自己恢復(fù)時候必須的數(shù)據(jù),比如流的原始數(shù)據(jù)和中間計算結(jié)果等信息,在恢復(fù)的時候從Checkpoint中讀取并持續(xù)處理流數(shù)據(jù)。

5. 外部Source容錯

Apache Flink 要做到 End-to-End 的 Exactly Once 需要外部Source的支持,比如上面我們說過 Apache Flink的Checkpointing機制會在Source節(jié)點記錄讀取的Position,那就需要外部數(shù)據(jù)提供讀取的Position和支持根據(jù)Position進行數(shù)據(jù)讀取。

6. 外部Sink容錯

Apache Flink 要做到 End-to-End 的 Exactly Once 相對比較困難,如上場景三所述,當(dāng)Sink Operator節(jié)點宕機,重新恢復(fù)時候根據(jù)Apache Flink 內(nèi)部系統(tǒng)容錯 exactly once的保證,系統(tǒng)會回滾到上次成功的Checkpoin繼續(xù)寫入,但是上次成功Checkpoint之后當(dāng)前Checkpoint未完成之前已經(jīng)把一部分新數(shù)據(jù)寫入到kafka了. Apache Flink自上次成功的Checkpoint繼續(xù)寫入kafka,就造成了kafka再次接收到一份同樣的來自Sink Operator的數(shù)據(jù),進而破壞了End-to-End 的 Exactly Once 語義(重復(fù)寫入就變成了At Least Once了),如果要解決這一問題,Apache Flink 利用Two phase commit(兩階段提交)的方式來進行處理。本質(zhì)上是Sink Operator 需要感知整體Checkpoint的完成,并在整體Checkpoint完成時候?qū)⒂嬎憬Y(jié)果寫入Kafka。

五、流批統(tǒng)一的計算引擎

批與流是兩種不同的數(shù)據(jù)處理模式,如Apache Storm只支持流模式的數(shù)據(jù)處理,Apache Spark只支持批(Micro Batching)模式的數(shù)據(jù)處理。那么Apache Flink 是如何做到既支持流處理模式也支持批處理模式呢?

1. 統(tǒng)一的數(shù)據(jù)傳輸層

開篇我們就介紹Apache Flink 的 "命脈"是以"批是流的特例"為導(dǎo)向來進行引擎的設(shè)計的,系統(tǒng)設(shè)計成為 "Native Streaming"的模式進行數(shù)據(jù)處理。那么Apache FLink將批模式執(zhí)行的任務(wù)看做是流式處理任務(wù)的特殊情況,只是在數(shù)據(jù)上批是有界的(有限數(shù)量的元素)。

Apache Flink 在網(wǎng)絡(luò)傳輸層面有兩種數(shù)據(jù)傳輸模式:

  • PIPELINED模式 - 即一條數(shù)據(jù)被處理完成以后,立刻傳輸?shù)较乱粋€節(jié)點進行處理。
  • BATCH 模式 - 即一條數(shù)據(jù)被處理完成后,并不會立刻傳輸?shù)较乱粋€節(jié)點進行處理,而是寫入到緩存區(qū),如果緩存寫滿就持久化到本地硬盤上,***當(dāng)所有數(shù)據(jù)都被處理完成后,才將數(shù)據(jù)傳輸?shù)较乱粋€節(jié)點進行處理。

對于批任務(wù)而言同樣可以利用PIPELINED模式,比如我要做count統(tǒng)計,利用PIPELINED模式能拿到更好的執(zhí)行性能。只有在特殊情況,比如SortMergeJoin,這時候我們需要全局?jǐn)?shù)據(jù)排序,才需要BATCH模式。大部分情況流與批可用統(tǒng)一的傳輸策略,只有特殊情況,才將批看做是流的一個特例繼續(xù)特殊處理。

2. 統(tǒng)一任務(wù)調(diào)度層

Apache Flink 在任務(wù)調(diào)度上流與批共享統(tǒng)一的資源和任務(wù)調(diào)度機制(后續(xù)章節(jié)會詳細(xì)介紹)。

3. 統(tǒng)一的用戶API層

Apache Flink 在DataStremAPI和DataSetAPI基礎(chǔ)上,為用戶提供了流批統(tǒng)一的上層TableAPI和SQL,在語法和語義上流批進行高度統(tǒng)一。(其中DataStremAPI和DataSetAPI對流和批進行了分別抽象,這一點并不優(yōu)雅,在Alibaba內(nèi)部對其進行了統(tǒng)一抽象)。

4. 求同存異

Apache Flink 是流批統(tǒng)一的計算引擎,并不意味著流與批的任務(wù)都走統(tǒng)一的code path,在對底層的具體算子的實現(xiàn)也是有各自的處理的,在具體功能上面會根據(jù)不同的特性區(qū)別處理。比如 批沒有Checkpoint機制,流上不能做SortMergeJoin。

六、Apache Flink 架構(gòu)

1. 組件棧

我們上面內(nèi)容已經(jīng)介紹了很多Apache Flink的各種組件,下面我們整體概覽一下全貌,如下:

Apache Flink的各種組件

TableAPI和SQL都建立在DataSetAPI和DataStreamAPI的基礎(chǔ)之上,那么TableAPI和SQL是如何轉(zhuǎn)換為DataStream和DataSet的呢?

2. TableAPI&SQL到DataStrem&DataSet的架構(gòu)

TableAPI&SQL最終會經(jīng)過Calcite優(yōu)化之后轉(zhuǎn)換為DataStream和DataSet,具體轉(zhuǎn)換示意如下:

對于流任務(wù)最終會轉(zhuǎn)換成DataStream,對于批任務(wù)最終會轉(zhuǎn)換成DataSet。

3. ANSI-SQL的支持

Apache Flink 之所以利用ANSI-SQL作為用戶統(tǒng)一的開發(fā)語言,是因為SQL有著非常明顯的優(yōu)點,如下:

  • Declarative - 用戶只需要表達(dá)我想要什么,不用關(guān)心如何計算。
  • Optimized - 查詢優(yōu)化器可以為用戶的 SQL 生成***的執(zhí)行計劃,獲取***的查詢性能。
  • Understandable - SQL語言被不同領(lǐng)域的人所熟知,用SQL 作為跨團隊的開發(fā)語言可以很大地提高效率。
  • Stable - SQL 是一個擁有幾十年歷史的語言,是一個非常穩(wěn)定的語言,很少有變動。
  • Unify - Apache Flink在引擎上對流與批進行統(tǒng)一,同時又利用ANSI-SQL在語法和語義層面進行統(tǒng)一。

4. ***擴展的優(yōu)化機制

Apache Flink 利用Apache Calcite對SQL進行解析和優(yōu)化,Apache Calcite采用Calcite是開源的一套查詢引擎,實現(xiàn)了兩套Planner:

  • HepPlanner - 是RBO(Rule Base Optimize)模式,基于規(guī)則的優(yōu)化。
  • VolcanoPlanner - 是CBO(Cost Base Optimize)模式,基于成本的優(yōu)化。

Flink SQL會利用Calcite解析優(yōu)化之后,最終轉(zhuǎn)換為底層的DataStrem和Dataset。上圖中 Batch rules和Stream rules可以根據(jù)優(yōu)化需要***添加優(yōu)化規(guī)則。

七、豐富的類庫和算子

Apache Flink 優(yōu)秀的架構(gòu)就像一座摩天大廈的地基一樣為Apache Flink 持久的生命力打下了良好的基礎(chǔ),為打造Apache Flink豐富的功能生態(tài)留下***的空間。

1. 類庫

  • CEP - 復(fù)雜事件處理類庫,核心是一個狀態(tài)機,廣泛應(yīng)用于事件驅(qū)動的監(jiān)控預(yù)警類業(yè)務(wù)場景。
  • ML - 機器學(xué)習(xí)類庫,機器學(xué)習(xí)主要是識別數(shù)據(jù)中的關(guān)系、趨勢和模式,一般應(yīng)用在預(yù)測類業(yè)務(wù)場景。
  • GELLY - 圖計算類庫,圖計算更多的是考慮邊和點的概念,一般被用來解決網(wǎng)狀關(guān)系的業(yè)務(wù)場景。

2. 算子

Apache Flink 提供了豐富的功能算子,對于數(shù)據(jù)流的處理來講,可以分為單流處理(一個數(shù)據(jù)源)和多流處理(多個數(shù)據(jù)源)。

3. 多流操作

  • UNION - 將多個字段類型一致數(shù)據(jù)流合并為一個數(shù)據(jù)流,如下示意:
  • JOIN - 將多個數(shù)據(jù)流(數(shù)據(jù)類型可以不一致)聯(lián)接為一個數(shù)據(jù)流,如下示意:

如上通過UION和JOIN我們可以將多流最終變成單流,Apache Flink 在單流上提供了更多的操作算子。

4. 單流操作

將多流變成單流之后,我們按數(shù)據(jù)輸入輸出的不同歸類如下:

如上表格對單流上面操作做簡單歸類,除此之外還可以做 過濾,排序,窗口等操作,我們后續(xù)章節(jié)會逐一介紹。

4. 存在的問題

Apache Flink 目前的架構(gòu)還存在很大的優(yōu)化空間,比如前面提到的DataStreamAPI和DataSetAPI其實是流與批在API層面不統(tǒng)一的體現(xiàn),同時看具體實現(xiàn)會發(fā)現(xiàn)DataStreamAPI會生成Transformation tree然后生成StreamGraph,***生成JobGraph,底層對應(yīng)StreamTask,但DataSetAPI會形成Operator tree,flink-optimize模塊會對Batch Plan進行優(yōu)化,形成Optimized Plan 后形成JobGraph,***形成BatchTask。具體示意如下:

這種情況其實 DataStreamAPI到Runtime 和 DataSetAPI到Runtime的實現(xiàn)上并沒有得到***程度的統(tǒng)一和復(fù)用。在這一點上面Aalibab 對Apache Flink 的增強在架構(gòu)和實現(xiàn)上都進行了進一步優(yōu)化。

八、Alibaba對Apache Flink的增強架構(gòu)

1. 組件棧

Alibaba 對Apache Flink進行了大量的架構(gòu)優(yōu)化,如下架構(gòu)是一直努力的方向,大部分功能還在持續(xù)開發(fā)中,具體如下:

如上架構(gòu)我們發(fā)現(xiàn)較大的變化是:

  • Query Processing - 我們增加了Query Processing層,在這一層進行統(tǒng)一的流和批的查詢優(yōu)化和底層算子的轉(zhuǎn)換。
  • DAG API - 我們在Runtime層面統(tǒng)一抽象API接口,在API層對流與批進行統(tǒng)一。

2. TableAPI&SQL到Runtime的架構(gòu)

Apache Flink執(zhí)行層是流批統(tǒng)一的設(shè)計,在API和算子設(shè)計上面我們盡量達(dá)到流批的共享,在TableAPI和SQL層無論是流任務(wù)還是批任務(wù)最終都轉(zhuǎn)換為統(tǒng)一的底層實現(xiàn)。示意圖如下:

這個層面最核心的變化是批最終也會生成StreamGraph,執(zhí)行層運行Stream Task。

九、特別說明

后續(xù)章節(jié)會以Alibaba對Apache Flink的增強為主介紹功能算子,篇章中分享的功能可能開源暫時沒有,但這些的內(nèi)容后續(xù)Alibaba會共享給社區(qū),需要大家耐心等待。

十、小結(jié)

本篇概要的介紹了"批是流的特例"這一設(shè)計觀點是Apache Flink的"命脈",它決定了Apache Flink的運行模式是純流式的,這在實時計算場景的"低延遲"需求上,相對于Micro Batching模式占據(jù)了架構(gòu)的絕對優(yōu)勢,同時概要的向大家介紹了Apache Flink的部署模式,容錯處理,引擎的統(tǒng)一性和Apache Flink的架構(gòu),***和大家分享了Alibaba對Apache Flink的增強架構(gòu),以及對開源Apache Flink所作出的優(yōu)化。

本篇沒有對具體技術(shù)進行詳細(xì)展開,大家只要對Apache Flink有初步感知,頭腦中知道Alibaba對Apache Flink進行了架構(gòu)優(yōu)化,增加了眾多功能就可以了,至于Apache Flink的具體技術(shù)細(xì)節(jié)和實現(xiàn)原理,以及Alibaba對Apache Flink做了哪些架構(gòu)優(yōu)化和增加了哪些功能后續(xù)章節(jié)會展開介紹!

# 關(guān)于點贊和評論

本系列文章難免有很多缺陷和不足,真誠希望讀者對有收獲的篇章給予點贊鼓勵,對有不足的篇章給予反饋和建議,先行感謝大家!

作者孫金城,花名 金竹,目前就職于阿里巴巴,自2015年以來一直投入于基于Apache Flink的阿里巴巴計算平臺Blink的設(shè)計研發(fā)工作。

【本文為51CTO專欄作者“金竹”原創(chuàng)稿件,轉(zhuǎn)載請聯(lián)系原作者】

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2019-01-03 10:17:53

Apache FlinTable API代碼

2022-06-10 17:26:07

數(shù)據(jù)集計算

2018-10-09 10:55:52

Apache FlinWatermark流計算

2022-07-13 12:53:59

數(shù)據(jù)存儲

2018-09-26 07:50:52

Apache Flin流計算計算模式

2018-10-16 08:54:35

Apache Flin流計算State

2018-11-29 09:01:26

Apache FlinJOIN代碼

2018-11-20 07:59:43

Apache Flin JOIN算子代碼

2018-10-22 21:43:39

Apache Flin流計算Fault Toler

2018-11-14 09:01:23

Apache FlinSQL代碼

2022-07-13 13:03:29

流計算亂序

2018-12-11 17:28:22

Apache FlinJOIN代碼

2018-11-07 08:48:31

Apache Flin持續(xù)查詢流計算

2022-07-12 10:38:25

分布式框架

2019-01-15 08:50:12

Apache FlinKafka分布式

2018-10-30 14:08:45

Apache Flin流表對偶duality

2018-12-29 08:16:32

Apache FlinJOIN代碼

2021-06-11 07:49:01

Docker容器安全 應(yīng)用程序

2020-04-09 11:08:30

PyFlinkJAR依賴

2018-10-30 11:10:05

Flink數(shù)據(jù)集計算
點贊
收藏

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