本文主要介紹順豐在數(shù)據(jù)倉(cāng)庫(kù)的數(shù)據(jù)實(shí)時(shí)化、數(shù)據(jù)庫(kù) CDC、Hudi on Flink 上的實(shí)踐應(yīng)用及產(chǎn)品化經(jīng)驗(yàn)。文章主要分為以下幾部分:順豐業(yè)務(wù)介紹
Hudi on Flink
產(chǎn)品化支持
后續(xù)計(jì)劃
先來(lái)看一下順豐大數(shù)據(jù)業(yè)務(wù)的全景圖。
大數(shù)據(jù)平臺(tái),中間的基礎(chǔ)部分是大數(shù)據(jù)平臺(tái),這塊是順豐結(jié)合開(kāi)源組件自行搭建的。與之相關(guān)的是大數(shù)據(jù)分析與人工智能,順豐有一個(gè)非常強(qiáng)的地面部隊(duì),就是線下的快遞小哥以及運(yùn)輸車(chē)輛,需要使用 AI 以及大數(shù)據(jù)分析來(lái)輔助管理,提升整體效率。
區(qū)塊鏈,順豐對(duì)接了很多客戶與商家,對(duì)于商家來(lái)說(shuō),首先需要確??旒强尚诺哪軌蜃鲐浳锏慕灰着c交換。這塊涉及的基本上都是品牌商家,溯源與存證的業(yè)務(wù)順豐也有涉及。
IoT,就像之前提及到的,因?yàn)轫権S地面部隊(duì)較多,相應(yīng)需要采集的數(shù)據(jù)也會(huì)比較多。我們的部分包裹中是有傳感器的,車(chē)輛也有相關(guān)的傳感器,如車(chē)輛的攝像頭,以及快遞小哥的手環(huán)(包含地理位置、員工的健康狀態(tài),對(duì)應(yīng)做一些關(guān)懷的舉動(dòng))。同時(shí),還有一些工作場(chǎng)景既有叉車(chē),也有分揀設(shè)備,這些就需要大數(shù)據(jù)平臺(tái)來(lái)做一些聯(lián)動(dòng),因此 IoT 的應(yīng)用相對(duì)較多。
智慧供應(yīng)鏈和智慧物流,這兩塊更多的是指如何用大數(shù)據(jù)的手段輔助業(yè)務(wù)做一些經(jīng)營(yíng)上的決策。比如我們有很多 B 端客戶,對(duì)于他們來(lái)說(shuō)如何在每個(gè)倉(cāng)庫(kù)里備貨,如何協(xié)調(diào)以及互相調(diào)撥,這部分就由智慧物流來(lái)完成。
下面這塊就是 IOT 實(shí)踐中的一部分:
從上面可以看出物流本身的環(huán)節(jié)是非常多的,下單、小哥收件、分揀、陸運(yùn)中轉(zhuǎn)等整個(gè)過(guò)程,紅色解釋部分是指我們會(huì)做的一些 IoT 與大數(shù)據(jù)結(jié)合的應(yīng)用,這里其實(shí)大部分都是基于 Flink 來(lái)完成的。
下面這張圖是順豐目前大數(shù)據(jù)整體的架構(gòu)概覽:
數(shù)據(jù)集成層:最下面為數(shù)據(jù)集成層,因?yàn)轫権S的歷史原因,所以包含了很多數(shù)據(jù)存儲(chǔ)引擎,如 Oracle、MySQL、MongoDB 等,并且部分引擎仍會(huì)繼續(xù)支持。右下物聯(lián)網(wǎng)設(shè)備相對(duì)較新,主要是進(jìn)行包含普通文本、網(wǎng)絡(luò)數(shù)據(jù)庫(kù)、圖像、音頻、視頻等的數(shù)據(jù)采集。
數(shù)據(jù)存儲(chǔ)計(jì)算:實(shí)時(shí)這塊順豐目前用的最多的還是 Flink,Storm 沒(méi)有標(biāo)示出來(lái),目前我們?cè)谧鲞w移。消息中間件處理目前主要使用 Kafka。然后右邊存儲(chǔ)結(jié)構(gòu)的種類(lèi)就相對(duì)豐富,因?yàn)椴煌膱?chǎng)景有不同的處理方式,比如數(shù)據(jù)分析需要性能比較強(qiáng)的 Clickhouse;數(shù)倉(cāng)和離線計(jì)算這塊還是比較傳統(tǒng),以 Hive 為主結(jié)合 Spark,目前我們是結(jié)合 Flink 與 Hudi 去實(shí)現(xiàn)離線實(shí)時(shí)化。
數(shù)據(jù)產(chǎn)品,我們傾向的還是首先降門(mén)檻,讓內(nèi)部開(kāi)發(fā)與用戶更容易上手。內(nèi)部同學(xué)如果要掌握如此多的組件,成本是非常高的,再加上規(guī)范化會(huì)導(dǎo)致溝通、維護(hù)以及運(yùn)維的高額成本,所以我們一定要去做一些產(chǎn)品化、規(guī)范化的事情。
上圖就是我們大數(shù)據(jù)整體數(shù)據(jù)采集的概覽,數(shù)據(jù)采集當(dāng)前包括微服務(wù)的應(yīng)用,部分?jǐn)?shù)據(jù)直發(fā)到 Kafka,還有些會(huì)落成日志,然后我們自己做了一個(gè)日志采集工具,類(lèi)似于 Flume,更加的輕量化,達(dá)到不丟、不重、以及遠(yuǎn)程的更新、限速。另外我們也會(huì)將 Kafka 中的數(shù)據(jù)通過(guò) Flink 放到 HDFS,以 Hudi 的形式去做。下面會(huì)詳細(xì)介紹。
上圖是一個(gè)簡(jiǎn)單的應(yīng)用架構(gòu),剛才所說(shuō)的大數(shù)據(jù)平臺(tái)數(shù)據(jù)我們會(huì)按需推送到 OLAP 分析引擎、數(shù)據(jù)庫(kù),這部分?jǐn)?shù)據(jù)推送過(guò)去之后,到達(dá)數(shù)據(jù)服務(wù)平臺(tái)。該數(shù)據(jù)服務(wù)平臺(tái)主要是考慮到用戶或研發(fā)對(duì)接數(shù)據(jù)庫(kù)更便捷,以往在使用時(shí),內(nèi)部用戶首先需要了解大數(shù)據(jù)組件的使用,而現(xiàn)在通過(guò)我們的數(shù)據(jù)服務(wù)產(chǎn)品以配置化的方式配置查詢條件、聚合條件即可,最終把結(jié)果生成一個(gè) restful 接口,業(yè)務(wù)系統(tǒng)可直接調(diào)用。比如研發(fā)用戶需要做搜索,只需要關(guān)注入?yún)?、出參,中間的過(guò)程不需要了解,這樣的話就能夠最大化的把技術(shù)門(mén)檻降下來(lái),使用時(shí)也會(huì)更高效簡(jiǎn)便。
中間部分我們是基于 Kong 做的網(wǎng)關(guān),在 Kong 里面可以加很多種通用的能力,包括監(jiān)控、限流、緩存等都可以在里面完成。
右邊的 Graphql,是 Facebook 開(kāi)源的一個(gè)組件。前端用戶經(jīng)常會(huì)出現(xiàn)需求的變更,后臺(tái)接口需要相應(yīng)地進(jìn)行調(diào)整,這種情況就可以使用 Graphql 來(lái)支持。這里其實(shí)是有兩個(gè)東西:apollo、graphql_Java,兩條線,apollo 適用于前端的研發(fā)用戶,用 node_js 來(lái)完成控制層的內(nèi)容;graphql_Java 適用于后端的用戶,主要提供一些接口。
接下來(lái)我們主要介紹 Hudi on Flink 在順豐的應(yīng)用實(shí)踐。Hudi 的核心優(yōu)勢(shì)主要分為兩部分:
首先,Hudi 提供了一個(gè)在 Hadoop 中更新刪除的解決方案,所以它的核心在于能夠增量更新,同時(shí)增量刪除。增量更新的好處是國(guó)內(nèi)與國(guó)際現(xiàn)在對(duì)隱私數(shù)據(jù)的保護(hù)要求比較高,比如在 Hive 中清理刪除某一個(gè)用戶的數(shù)據(jù)是比較困難的,相當(dāng)于重新清洗一遍數(shù)據(jù)。使用 Hudi 可以根據(jù)主鍵快速抓取,并將其刪除掉。
另外,時(shí)間漫游。之前我們有很多應(yīng)用需要做準(zhǔn)實(shí)時(shí)計(jì)算。如果要找出半個(gè)小時(shí)內(nèi)的增量到底是什么,變化點(diǎn)在哪,必須要把一天的數(shù)據(jù)全撈出來(lái),過(guò)濾一遍才能找出來(lái)。Hudi 提供時(shí)間漫游能力,只需要類(lèi)似 SQL 的語(yǔ)法就能快速地把全部增量撈出來(lái),然后后臺(tái)應(yīng)用使用時(shí),就能夠直接根據(jù)里面的數(shù)據(jù)做業(yè)務(wù)的更新,這是 Hudi 時(shí)間漫游里最重要的能力。
Hudi 有兩種的寫(xiě)的方法:
copy on write。
copy on write 這種形式更多是在每次寫(xiě)的時(shí)候,能夠重寫(xiě)歷史中關(guān)于更新記錄所在的文件,把它重寫(xiě)并且把增量部分再重新記錄下來(lái),相當(dāng)于把歷史狀態(tài)也給記錄下來(lái)。唯一的不足之處在于,寫(xiě)的時(shí)候性能會(huì)稍微弱,但是讀的性能是很強(qiáng)的,和正常使用 Hive 沒(méi)有什么區(qū)別。這個(gè)也是 Hudi 本身的優(yōu)點(diǎn)。實(shí)時(shí)性略低,這部分取決于寫(xiě)的文件合并的頻率。不過(guò)批量的話,寫(xiě)也不會(huì)影響到多少性能,所以本身也是批量的去寫(xiě)。比如每隔幾分鐘寫(xiě)一次,這個(gè)其實(shí)也不會(huì)產(chǎn)生很高的性能損耗,這就是 copy on write。
merge on read
merge on read 就是寫(xiě)的時(shí)候?qū)崟r(shí)會(huì)把 log 以 append 方式寫(xiě)到 HDFS 中并寫(xiě)成文件,然后在讀的時(shí)候?qū)⒁呀?jīng)生成的文本,再加上增量的部分合并,做一個(gè) merge 操作。好處在于查詢的時(shí)候數(shù)據(jù)都是實(shí)時(shí)的,但是由于查詢?nèi)蝿?wù)確實(shí)較多,相當(dāng)于是說(shuō)每次查的時(shí)候,都要把兩部分?jǐn)?shù)據(jù)取出來(lái)并做一個(gè)合并,因此也會(huì)造成損耗。
以上是 Hudi 情況的簡(jiǎn)單介紹。
上圖是我們將數(shù)據(jù)實(shí)時(shí)化 CDC 的過(guò)程。數(shù)據(jù)庫(kù)的 CDC,基本上都是只能到庫(kù)級(jí)別、庫(kù)粒度。前面的 source 支撐肯定也還是庫(kù)粒度,中間會(huì)經(jīng)過(guò)兩個(gè)過(guò)程:
一部分是 DML,它會(huì)有過(guò)濾,當(dāng)庫(kù)里面有 100 張表時(shí),很多時(shí)候有些表是不需要的,這部分我們會(huì)直接過(guò)濾掉,過(guò)濾就主要是通過(guò)產(chǎn)品化來(lái)打通它。
另一部分是 DDl,能夠?qū)崟r(shí)更新 schema。比如庫(kù)表字段的增加或者變更,再或者可能加了個(gè)表或者改了一個(gè)表,這部分會(huì)在實(shí)時(shí)程序中打通數(shù)據(jù)直通車(chē),只要有任何變更,就會(huì)生成一個(gè)新的版本,然后將元數(shù)據(jù)信息記錄到直通車(chē)?yán)?,同時(shí)也會(huì)包裝到 binlog kafka sink 里記錄,每一行會(huì)打上相應(yīng)的版本號(hào)。這樣的話就對(duì)于后面的使用就能夠直接對(duì)應(yīng)該條記錄,使用非常方便,不會(huì)有出錯(cuò)的情況。
這部分主要分享我們數(shù)倉(cāng)實(shí)時(shí)化的過(guò)程,我們的目標(biāo)是實(shí)現(xiàn) Kafka 里的數(shù)據(jù)在當(dāng)前離線數(shù)倉(cāng)中也能真正用起來(lái),包括很多做準(zhǔn)實(shí)時(shí)計(jì)算的用戶也能夠真正用起來(lái)。Hudi on Flink 就是我們嘗試的方案。以前 Hudi 這塊也做了 Hudi on Spark 方案,是官方推薦使用的方案,其實(shí)相當(dāng)于多維護(hù)一個(gè)組件,但是我們大方向上還是希望所有實(shí)時(shí)的東西都能夠讓 Flink 去完成,另外也希望是 Flink 的應(yīng)用生態(tài)能夠做得更加全面,在這部分就真正去把它落地下來(lái),并且在生產(chǎn)中應(yīng)用起來(lái)。
其實(shí)整個(gè)過(guò)程,比如做表數(shù)據(jù)實(shí)時(shí)化的時(shí)候,它是分為兩部份,一部分?jǐn)?shù)據(jù)初始化,在啟動(dòng)的時(shí)候,會(huì)把數(shù)據(jù)重新做批量的拉取,這個(gè)是用 Flink batch 來(lái)做的,其實(shí)社區(qū)本身也有提供這種能力。另外 Hudi 本身也具備把存量的 Hive 表 Hudi 化的能力,這是 Hudi 最新才出來(lái)的功能。這部分我們會(huì)用 Flink batch 的方式重新抽一遍,當(dāng)然也有存量,對(duì)于存量的一些表,可以直接用存量表來(lái)轉(zhuǎn)化,然后用 Flink batch 做初始化。
另外一部分是增量更新,增量更新是指有個(gè) DB connect 對(duì)接 Kafka,從 Kafka 的 source 拿到數(shù)據(jù)庫(kù)增量 CDC 的 binlog,然后把 binlog 進(jìn)行加工,同時(shí)再利用 Flink 本身的 checkpoint 機(jī)制(Flink 本身的 checkpoint 整體頻率可以控制)進(jìn)行 snapshot 的過(guò)程。其中所做的內(nèi)容也我們自己可以控制的,所以采用 checkpoint 的形式可以把 Hudi 所需要做的 upsert 的操作全部在 checkpoint 中更新到線上,最終形成 Hudi 里面的實(shí)時(shí)數(shù)據(jù)。
直接將 Kafka 數(shù)據(jù)扔到 Hudi 里相對(duì)容易,真正困難的點(diǎn)在于寬表。對(duì)于整個(gè) Hudi 來(lái)說(shuō),寬表是涉及到很多維表,當(dāng)很多維表或者事實(shí)表更新的時(shí)候,會(huì)由多個(gè)事實(shí)表做一個(gè)關(guān)聯(lián)。但不是每個(gè)事實(shí)表都能抓到寬表的真正主鍵,因此 Hudi 沒(méi)法做這種更新。所以如何把寬表做數(shù)據(jù)實(shí)時(shí)化是一個(gè)難題。
上圖是順豐的寬表方案。
第一層,對(duì)于 ODS,可以直接連接 Kafka,用 Hudi on Flink 的框架就能夠完成。
第二層,DWD,這里也有兩種辦法:
一種是用 Flink SQL 先把實(shí)時(shí)的 Kafka 寬表做完,不過(guò)這種辦法成本會(huì)高一點(diǎn),相當(dāng)于再次引入了 Kafka,整個(gè)數(shù)據(jù)鏈路變長(zhǎng),如果真正需要去用實(shí)時(shí)寬表可以小部分去推,但如果不存在純實(shí)時(shí)數(shù)據(jù)的需求,就沒(méi)有必要去做 DWD 的實(shí)時(shí) Kafka 寬表。
另外,在沒(méi)有 DWD 的實(shí)時(shí) Kafka 寬表的情況下,如何完成上述離線層的 DWD 實(shí)時(shí)化?這里有幾個(gè)步驟,首先創(chuàng)建一個(gè)維表的 UDF 做表關(guān)聯(lián),也是最方便的方式。其次,可以考慮直接用 join 的方式,用兩個(gè)實(shí)時(shí)表來(lái)做關(guān)聯(lián),但可能存在關(guān)聯(lián)不到的情況。
當(dāng)然,做維表關(guān)聯(lián),就涉及到外鍵主鍵的映射。外鍵主鍵映射是為了讓我們能夠在另一個(gè)事實(shí)表更新時(shí),快速找到主鍵在哪,即外鍵主鍵的映射 。另外主鍵索引,主鍵索引其實(shí)也是跟外鍵主鍵的映射相關(guān)。至于外鍵主鍵的映射,相當(dāng)于把它建成一個(gè)新的表主鍵索引獲取,這樣增量更新 Hudi 跟原來(lái)的 ODS 層就基本上一致了,這就是寬表實(shí)時(shí)加工的過(guò)程。下圖為運(yùn)單的寬表舉例。
上述從技術(shù)層面分析了順豐當(dāng)下業(yè)務(wù)架構(gòu)的相關(guān)情況,以下將分享我們?cè)诋a(chǎn)品化上所做的一些支持工作。
上圖是我們的數(shù)據(jù)直通車(chē),能夠做到讓用戶自己在產(chǎn)品中操作,不需要寫(xiě)代碼即可完成,可以實(shí)現(xiàn)低門(mén)檻的快速簡(jiǎn)便的應(yīng)用。比如配置數(shù)據(jù)接入僅需 1 分鐘左右,整個(gè)過(guò)程就是在產(chǎn)品上以配置化的手段就能夠?qū)?shù)據(jù)最終落在數(shù)據(jù)庫(kù),我們的離線表、數(shù)倉(cāng)、做數(shù)據(jù)分析都能夠直接快速的運(yùn)用起來(lái)。
另外,數(shù)據(jù)接入進(jìn)來(lái)之后,需要有數(shù)據(jù)管理的能力。上圖是數(shù)據(jù)管理能力測(cè)試環(huán)境的簡(jiǎn)單情況,我們需要讓用戶能夠管理相關(guān)的數(shù)據(jù),首先誰(shuí)用它了,其次它涉及什么字段,有哪些具體的內(nèi)容,同時(shí)它里面的血緣關(guān)系又是怎么樣的,這個(gè)就是我們數(shù)據(jù)資產(chǎn)管理所具備的功能。
上圖是我們 binlog 的 SDK,其實(shí)像 binlog 這種 avro 的格式,對(duì)用戶來(lái)說(shuō)使用有一定門(mén)檻。但還是有一些編碼的用戶,對(duì)于這些用戶我們提供具體的 SDK,所以在 SDK 里真正使用時(shí)都做到簡(jiǎn)便。左邊看起來(lái)是 json,實(shí)際上是 avro 格式。右邊的內(nèi)容就是在 Java 上的使用情況,這個(gè)是在代碼層面輔助研發(fā)快速應(yīng)用的工具。
我們?cè)谄脚_(tái)上也做一些簡(jiǎn)化的內(nèi)容,首先有一部分是關(guān)于拖拽的,拖拽是指封裝一些組件,用戶可以通過(guò)拖拽來(lái)快速完成其需求。這個(gè)產(chǎn)品上線后,很多之前沒(méi)有任何實(shí)時(shí)計(jì)算的經(jīng)驗(yàn),甚至連離線開(kāi)發(fā)的經(jīng)驗(yàn)也沒(méi)有的用戶都能夠做實(shí)時(shí)的數(shù)據(jù)開(kāi)發(fā)。
上圖為實(shí)時(shí)指標(biāo)采集,產(chǎn)品上線之后有很多監(jiān)控的需求,F(xiàn)link 本身提供很多 Metric,用戶也有很多 Metric,我們希望為用戶提供一個(gè)高效的解決方案,把 Metric 全部采集出來(lái),讓用戶能夠快速應(yīng)用。
這里在監(jiān)控里面也做了幾個(gè)工作,一個(gè)是爬蟲(chóng)方案,實(shí)現(xiàn)一個(gè) akka 的客戶端,F(xiàn)link 本身是 akka 的框架,每個(gè) jobmannager 都有 akka 的服務(wù)、接口,這樣只要實(shí)現(xiàn)一個(gè) akka 的客戶端,就能夠以 akka 的 API 形式獲取具體的 Metric 情況。這部分采集完之后發(fā)到 Kafka,最終存到 TDengine 再到 Grafana,提供給用戶。Grafana 也會(huì)整合到我們的實(shí)時(shí)計(jì)算平臺(tái)產(chǎn)品里面來(lái),在面對(duì)存量的情況時(shí),不需要重啟用戶的任務(wù),就能夠直接做數(shù)據(jù)采集。
但在面對(duì)增量情況時(shí),就需要補(bǔ)充一些 Metric,比如 CPU 使用率、內(nèi)存的使用率等。這部分我們以 Reporter 方案來(lái)滿足,Reporter 方案也是社區(qū)當(dāng)前主推的方案。Reporte r 方案的原理其實(shí)是在 Flink 的 Metrics Reporter 里進(jìn)行插件開(kāi)發(fā),然后發(fā)到 gateway,這個(gè) gateway 其實(shí)就是為了避免 Kafka 客戶端過(guò)多的問(wèn)題,所以這里中間做一個(gè)網(wǎng)關(guān),后面還是和上面的一致,這個(gè)就是 Flink 的任務(wù)監(jiān)控情況。
上述已經(jīng)分享了我們?cè)趦?nèi)部已經(jīng)落地、實(shí)際應(yīng)用的過(guò)程,后續(xù)我們還會(huì)做什么?
首先,彈性計(jì)算。目前像監(jiān)控任務(wù),用戶申請(qǐng)的資源遠(yuǎn)遠(yuǎn)超過(guò)實(shí)際需要使用的資源,會(huì)造成嚴(yán)重的資源浪費(fèi),內(nèi)存也一樣。處理類(lèi)似情況時(shí),我們使用了 Flink 延伸的框架 Metrics monitor,結(jié)合采集的 Metrics,能夠做到當(dāng)整個(gè)使用率過(guò)低或過(guò)高的時(shí)候,及時(shí)調(diào)整達(dá)到資源擴(kuò)縮容或者并發(fā)擴(kuò)容。
上面提到我們存量是有非常多的 Hive 任務(wù),包括 Spark 任務(wù)需要進(jìn)行替換,但怎么去做呢?
首先我們用 Flink 來(lái)替換,由于強(qiáng)制或平臺(tái)自動(dòng)推薦都有難度,所以我們做了一些折中方案。比如埋點(diǎn),當(dāng)需要把數(shù)據(jù)寫(xiě)到 Hive 的某個(gè)表,它會(huì)經(jīng)過(guò) Hiveserver,SQL 解析之后,此時(shí)將表進(jìn)行替換,執(zhí)行兩個(gè)路線:一個(gè)是正常的 table 這樣執(zhí)行會(huì)寫(xiě)到 Hive 里面去。另外也會(huì)埋點(diǎn)把寫(xiě)的表替換成另一個(gè)表,然后同時(shí)再以 Flink 的形式去執(zhí)行一遍,不過(guò)會(huì)產(chǎn)生額外的資源消耗,執(zhí)行大概生成兩個(gè)表,需要自動(dòng)計(jì)算兩者是否一致。如一致測(cè)試穩(wěn)定后就能以計(jì)算框架來(lái)去替換它。
大部分任務(wù)是兼容的可替換的,但也有小部分不兼容的情況,這部分可以采取人工處理,以盡量實(shí)現(xiàn)整個(gè)技術(shù)上的統(tǒng)一,這部分是后續(xù)需要完成的。
上圖是我們做批流一體化的過(guò)程,批流一體化在元數(shù)據(jù)管理與權(quán)限管理部分都已經(jīng)有一些落地。
除此之外我們結(jié)合剛剛所說(shuō)替換的過(guò)程,上圖就是 SQL 的兼容測(cè)試。因?yàn)檫@幾者都做完之后,其實(shí)批流一體化可以同步去做,相當(dāng)于同一個(gè)接口,加一個(gè)參數(shù),即可實(shí)現(xiàn)流批處理底層引擎的快速切換,有助于整個(gè)數(shù)據(jù)開(kāi)發(fā)能夠保持一致,所以批流一體化也是后面需要嘗試的。
上圖實(shí)際上是我們一體化整個(gè)框架的最終形式。首先上面有一層 IDE 能夠讓所有的用戶使用。然后下面各種基礎(chǔ)功能支持,包括自動(dòng)補(bǔ)全的 SQL 語(yǔ)法解析功能的支持,再往下就是一些資源管理、調(diào)度管理和知識(shí)管理,這些也是為了輔助開(kāi)發(fā)而用的。再下面一層是計(jì)算引擎,要把這些計(jì)算引擎跟用戶做一個(gè)大的隔離,讓用戶不用再關(guān)注底層技術(shù)的實(shí)現(xiàn)和使用,這是我們后面的要持續(xù)去做的事情。
傳網(wǎng)絡(luò)貨運(yùn)“獎(jiǎng)補(bǔ)”全面暫停,誰(shuí)破防了?
1873 閱讀“兔子”啃“蓮藕”,快遞生鮮牌怎么打?
964 閱讀快遞大變革:“納稅新規(guī)”落地、社保加強(qiáng)征管,這次反內(nèi)卷誰(shuí)會(huì)被淘汰?
938 閱讀物流企業(yè)大客戶銷(xiāo)售預(yù)測(cè)總翻車(chē)?攻略來(lái)了
694 閱讀京東物流在江蘇成立供應(yīng)鏈科技公司
651 閱讀速賣(mài)通啟用首個(gè)全自動(dòng)物流園區(qū),國(guó)內(nèi)段提速6小時(shí)
692 閱讀快遞行業(yè)增值稅新政落地,按照“收派服務(wù)”繳納增值稅
642 閱讀極兔海口-特拉維夫全貨機(jī)首航成功,24小時(shí)直達(dá)中東門(mén)戶
640 閱讀廣東快遞底價(jià)上漲
666 閱讀戈壁征途,極兔護(hù)航!極兔成為戈20官方指定物流合作伙伴
639 閱讀