自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

大規(guī)模塊存儲(chǔ) EC 系統(tǒng)構(gòu)建

存儲(chǔ) 存儲(chǔ)架構(gòu)
糾刪碼則是將用戶的原始數(shù)據(jù)進(jìn)行切分,形成 K 個(gè)大小相等的分片,然后對(duì)這些分片進(jìn)行編碼,形成 M 個(gè)校驗(yàn)分片。校驗(yàn)分片的大小和數(shù)據(jù)分片相同。K+M 個(gè)分片會(huì)被分布在不同的機(jī)器上。

本文整理自 2023 年 7 月 DataFunSummit 2023 數(shù)據(jù)基礎(chǔ)架構(gòu)峰會(huì)——大規(guī)模存儲(chǔ)架構(gòu)分論壇的同名主題分享。

非常歡迎大家的到來,今天由我來分享百度智能云塊存儲(chǔ) EC 系統(tǒng)的構(gòu)建。塊存儲(chǔ)系統(tǒng)在百度智能云的產(chǎn)品名叫 CDS,底層 EC 系統(tǒng)由 Aries 承擔(dān)。

關(guān)于 Aries 的詳細(xì)介紹,可以參考文末「傳送門」的第一篇文章。

今天主要介紹的內(nèi)容如下,首先會(huì)比較一下各種容錯(cuò)方式,介紹一下我們選擇 EC 容錯(cuò)方式的必然性;然后給大家介紹一下在塊存儲(chǔ)產(chǎn)品下構(gòu)建 EC 引擎的挑戰(zhàn),并逐步展開對(duì)這些挑戰(zhàn)進(jìn)行分析和解決的方法;最后,我們介紹一下基于這個(gè)解決方案的一些優(yōu)化。

1. 數(shù)據(jù)容錯(cuò)方式比較

首先介紹一下常見的數(shù)據(jù)容錯(cuò)方式。

數(shù)據(jù)容錯(cuò)在單機(jī)和分布式系統(tǒng)下,有著不同的選擇。

單機(jī)情況下,比較直接的方式是選用 RAID 卡。在 BIOS 中配置,一般支持 RAID5 就夠了。如果沒有 RAID 卡,也可以用軟 RAID,創(chuàng)建帶有 RAID 功能的邏輯卷。

分布式的情況,比較直接的方式是采用多副本的形式,將數(shù)據(jù)復(fù)制成多份,存在不同的機(jī)器。實(shí)際上,最好將每份數(shù)據(jù)保存到不同的交換機(jī)下。另外一種方式是采用分布式糾刪碼的方式。這種方式其實(shí)就是分布式的 RAID。只不過,單機(jī)用奇偶校驗(yàn)的 RAID5 基本可以保證數(shù)據(jù)安全,而分布式系統(tǒng)中,由于磁盤規(guī)模龐大,糾刪碼的復(fù)雜度要高一些。

圖片圖片

這里介紹一下分布式容錯(cuò)方式的實(shí)現(xiàn)。多副本方式容錯(cuò),每個(gè)副本的數(shù)據(jù)相同,所以,一般采用分布式的一致性協(xié)議對(duì)數(shù)據(jù)進(jìn)行同步,主流的協(xié)議為 Paxos 和 Raft。有的系統(tǒng)也會(huì)自研一些分發(fā)寫的協(xié)議。最終目的是保證多份數(shù)據(jù)相同。多副本情況下,假設(shè)是 N 副本,則最多允許 N-1 份數(shù)據(jù)損壞。

糾刪碼則是將用戶的原始數(shù)據(jù)進(jìn)行切分,形成 K 個(gè)大小相等的分片,然后對(duì)這些分片進(jìn)行編碼,形成 M 個(gè)校驗(yàn)分片。校驗(yàn)分片的大小和數(shù)據(jù)分片相同。K+M 個(gè)分片會(huì)被分布在不同的機(jī)器上。一般情況下,糾刪碼允許最多 M 個(gè)分片數(shù)據(jù)損壞。最常用的糾刪碼是 Reed-Solomon 編碼(RS 碼);

圖片圖片

從成本考慮,3 副本將數(shù)據(jù)存儲(chǔ) 3 份,因此是 3 倍的存儲(chǔ)成本。而糾刪碼,是 K+M 的形式,K 份的數(shù)據(jù),編碼形成 M 份校驗(yàn)。通常情況下,M 比 K 要小。因此存儲(chǔ)成本一般為 1.x 倍。

但是,糾刪碼也有自己缺點(diǎn)。多副本將數(shù)據(jù)無修改地復(fù)制到另外節(jié)點(diǎn),不需要計(jì)算參與,數(shù)據(jù)恢復(fù)則是將數(shù)據(jù)重新復(fù)制一遍,方法比較簡單。而糾刪碼則涉及到編碼和解碼,除了計(jì)算以外,編碼和解碼同樣會(huì)帶來額外的 I/O 開銷。

現(xiàn)代 CPU 已經(jīng)支持 RS 編碼的硬件加速,能夠提升編碼/解碼速度,極大減少計(jì)算壓力。而 I/O 放大,則是我們重點(diǎn)要解決的問題。

磁盤通常具有 1%~2% 的年化故障率。由于分布式系統(tǒng)規(guī)模都比較大,大的集群都會(huì)有千臺(tái)機(jī)器,萬塊磁盤的規(guī)模,一定會(huì)同時(shí)出現(xiàn)多塊磁盤同時(shí)故障。因此,一般分布式系統(tǒng)都采用 2 個(gè)以上的備份或者校驗(yàn)。一般采用 3 副本或者 RS 編碼才能保證數(shù)據(jù)的可靠性?;谀壳暗募阂?guī)模和成本,糾刪碼是必然的選擇。

圖片圖片

2. 大規(guī)模塊存儲(chǔ) EC 的技術(shù)挑戰(zhàn)

既然選擇了糾刪碼,下面那必須解決 EC 系統(tǒng)中面臨的各種問題。

系統(tǒng)面臨的挑戰(zhàn)主要來自幾個(gè)方面。一個(gè)是產(chǎn)品訪問特性,塊存儲(chǔ)存儲(chǔ)的是動(dòng)態(tài)數(shù)據(jù),用戶會(huì)隨時(shí)對(duì)數(shù)據(jù)進(jìn)行修改。而 EC 修改代價(jià)高,原地修改需要引入額外計(jì)算和 I/O 放大。

另外就是用戶下發(fā)給磁盤的數(shù)據(jù)大小不一,而小寫不適合 EC。如何解決小 I/O 的 EC,是另外一個(gè)問題。

應(yīng)用場景上,用戶對(duì)大小寫的要求是不一樣的。因此,我們的設(shè)計(jì)需要一個(gè)合理的系統(tǒng)開銷,減少資源占用,使得用戶有比較好的 I/O 表現(xiàn)。

圖片圖片

對(duì)比一下對(duì)象存儲(chǔ)。它對(duì)外的接口是 put、get、delete。寫入時(shí),將一個(gè)對(duì)象的整體數(shù)據(jù)整體寫入和整體刪除,不涉及到重新編碼的問題。因此,除了寫入時(shí)產(chǎn)生的校驗(yàn)數(shù)據(jù)需要保存,沒有其他寫放大問題。

圖片圖片

塊存儲(chǔ),主要接口是讀寫和刪除。與對(duì)象存儲(chǔ)不同,這里的寫絕大部分是對(duì)原有數(shù)據(jù)的修改。

對(duì)于部分?jǐn)?shù)據(jù)修改,如果重新計(jì)算校驗(yàn),需要將剩余數(shù)據(jù)從其余節(jié)點(diǎn)讀到內(nèi)存中,重新計(jì)算校驗(yàn)值,然后將校驗(yàn)再次寫回。這里涉及到了「讀-修改-寫」,I/O 放大比較嚴(yán)重。

圖片圖片

這里是線上 I/O 次數(shù)統(tǒng)計(jì),小 I/O 的次數(shù)遠(yuǎn)遠(yuǎn)多于大 I/O。塊存儲(chǔ) CDS 中,4K 大小的 I/O 占據(jù)了半數(shù)以上的寫次數(shù)。但是小 I/O 不太適合 EC。

舉個(gè)例子:我們?nèi)绻捎?K 為 4,M 為 2 的編碼,需要將分片切成 1K 大小,而一般情況下,文件系統(tǒng)對(duì)于 4K 倍數(shù)的 I/O 支持比較友好,1K 的 I/O size,相對(duì)來說,不是很合理的 I/O size。如果 K 值更大,會(huì)產(chǎn)生更細(xì)碎的分片。我們需要解決這些小 I/O 的 EC。

圖片圖片

現(xiàn)代軟件已經(jīng)對(duì)磁盤訪問有比較多的優(yōu)化。當(dāng)程序追求吞吐時(shí)會(huì)下發(fā)大 I/O,減少磁盤尋道時(shí)間。當(dāng)程序?qū)ρ訒r(shí)有需求時(shí),通常會(huì)下發(fā)盡量小的 I/O,減少不必要的數(shù)據(jù)對(duì) I/O 帶寬的占用。

因此,總體看來,對(duì)于小 I/O用戶需要的是小的延時(shí),對(duì)于用戶大的 I/O 用戶需要的是高的吞吐。

硬件的物理帶寬是有限的,提供高性能的存儲(chǔ)引擎,系統(tǒng)本身占用的資源應(yīng)該盡量小。對(duì)于存儲(chǔ)引擎來說,主要就是寫放大問題。

圖片圖片

3. 百度滄海的實(shí)現(xiàn)方案

針對(duì)以上問題,我們看一下百度滄海的解決方案。

這里我們重新看一下修改,I/O 放大的主要原因是需要對(duì)原有存量數(shù)據(jù)進(jìn)行修改操作,如果不做特殊優(yōu)化,這些操作需要將原有數(shù)據(jù)讀出來,用于計(jì)算新的校驗(yàn)。

CDS 的選擇是構(gòu)建一個(gè)索引層,索引指向 EC 后的數(shù)據(jù),數(shù)據(jù)的修改不在原地進(jìn)行。

這里給了個(gè)例子,用戶第一次寫的數(shù)據(jù),EC 并且存儲(chǔ)后,建立了一個(gè)索引指向這塊數(shù)據(jù)。后續(xù)在中間的修改將作為一個(gè)新數(shù)據(jù)進(jìn)行 EC 并且存儲(chǔ)。然后構(gòu)建新的索引指向新的數(shù)據(jù),之前的索引分裂成 2 部分。

圖片圖片

這樣做后,我們實(shí)際上建立了一個(gè)基于 EC 數(shù)據(jù)的 Append 引擎。EC 后的數(shù)據(jù),對(duì)應(yīng)的就是 Append 引擎中的 segment。所有的修改采用追加寫的形式,等同于 append 引擎的單路追加寫。

實(shí)際上,CDS 并未從頭開始設(shè)計(jì)一個(gè) EC 系統(tǒng),而是采用了公司內(nèi)成熟的 EC 系統(tǒng) Aries 作為底層儲(chǔ)存介質(zhì),Aries 是百度滄海提供的特別優(yōu)秀的 EC 系統(tǒng)和數(shù)據(jù)底座。寫入 Aries 的數(shù)據(jù)將作為一個(gè) slice 存儲(chǔ),而一個(gè) slice 可以對(duì)應(yīng)到邏輯層的一個(gè) segment。

圖片圖片

我們前面提到了需要處理用戶小寫 EC 的問題。可以采用的一個(gè)方案是建立一個(gè)三副本的存儲(chǔ)層,用來緩存用戶 I/O。當(dāng)用戶寫滿一定規(guī)模的數(shù)據(jù)時(shí)(比如:1GB),將這些數(shù)據(jù) EC 后進(jìn)行存儲(chǔ)。

這樣的好處是所有寫數(shù)據(jù)混在一起進(jìn)行存儲(chǔ),分片的切分可以根據(jù) EC 規(guī)模進(jìn)行選擇,可以做到分片對(duì) I/O 友好。其中,EC 層基本可以假設(shè)分片是固定大小的。

圖片圖片

但是,這么做的缺點(diǎn)也很明顯。數(shù)據(jù)會(huì)被先寫到 3 副本層,再寫到 EC 層。一定會(huì)有多于 4 倍的 I/O 放大。我們也統(tǒng)計(jì)了線上數(shù)據(jù)的寫入量,數(shù)據(jù)量占據(jù)比較多的是大 I/O。這些大 I/O 對(duì) EC 相對(duì)比較友好,可以采用直接 EC 的方式進(jìn)行。

圖片圖片

百度滄海的方案是將大寫和小寫進(jìn)行分別處理。大寫直接進(jìn)行 EC,小寫采用 3 副本形式存儲(chǔ)。

這樣做的好處是,大寫的數(shù)據(jù)不經(jīng)過 3 副本層,規(guī)避了緩存帶來的絕大多數(shù) I/O 放大。3 副本主要存儲(chǔ)小 I/O,因?yàn)檎急刃。詫?duì)成本的壓力增長不是很大,I/O 放大也不是很嚴(yán)重。

圖片圖片

系統(tǒng)實(shí)現(xiàn)時(shí),預(yù)留了 10% 作為 3 副本存儲(chǔ)空間。3 副本也采用 append 引擎進(jìn)行存儲(chǔ)。數(shù)據(jù) compaction 時(shí),直接將數(shù)據(jù)存儲(chǔ)到 EC 層。

這種設(shè)計(jì),當(dāng) 3 副本層空間緊張時(shí),數(shù)據(jù)仍然會(huì)被進(jìn)行 EC 存儲(chǔ),能夠在用戶都是小 I/O 的極端情況下,仍然有不錯(cuò)的成本表現(xiàn)。

圖片圖片

內(nèi)部交流時(shí),經(jīng)常會(huì)被問到數(shù)據(jù)是否會(huì)從 EC 層轉(zhuǎn)移到 3 副本層。如果是同種介質(zhì),我們假設(shè)訪問延時(shí)沒有變化。因此,不將 3 副本層作為緩存層。

圖片圖片

大 I/O 并不是固定大小,系統(tǒng)選擇將大 I/O 直接 EC 的情況下,對(duì)于底層 EC 的存儲(chǔ)引擎有新的要求。它必須能夠處理不同大小的分片。

設(shè)計(jì)難點(diǎn)是,釋放的空間如何被回收利用。圖中給了個(gè)例子,當(dāng)數(shù)據(jù)比空洞大時(shí),無法將數(shù)據(jù)放入;當(dāng)數(shù)據(jù)比空洞小時(shí),造成空間浪費(fèi)。因此,下層存儲(chǔ)應(yīng)該采用能夠很好適應(yīng)變長分片的引擎。

圖片圖片

EC 存儲(chǔ)引擎層仍然采用 append 寫的方式。新數(shù)據(jù) append 寫,緊密排列在存儲(chǔ)系統(tǒng)的后端。這樣,新數(shù)據(jù)的空間分配變的簡單。

相對(duì)于原地寫,append 寫無論是對(duì)于 ssd 還是 hdd,性能都更好,這也為高性能存儲(chǔ)打下了基礎(chǔ)。

圖片圖片

因此,總體架構(gòu)是一個(gè)雙層 append 架構(gòu)。第一層有一個(gè)邏輯的 append 引擎,每個(gè) EC 數(shù)據(jù)對(duì)應(yīng)一個(gè)邏輯 segment。下層物理層存儲(chǔ) EC 的分片,也采用 append 的方式,數(shù)據(jù)只進(jìn)行追加寫。

我們通過兩層架構(gòu)解決了修改放大,大小寫如何 EC 的問題。但是,仍然需要進(jìn)一步提高系統(tǒng)性能,提升用戶體驗(yàn)。

圖片圖片

目前采用 2 層 append 引擎的方式構(gòu)建系統(tǒng)。Append 的性能必然會(huì)對(duì)系統(tǒng)產(chǎn)生比較大的影響。存儲(chǔ)系統(tǒng),一般的瓶頸都是 I/O。Append 引擎天然存在寫放大,主要來源為 compaction。

由于系統(tǒng)總帶寬固定,如果 compaction 占用的帶寬過大,留給用戶使用的帶寬就會(huì)降低,影響用戶體驗(yàn)。

Append 引擎的一個(gè)重要評(píng)價(jià)指標(biāo),就是 I/O 放大,即系統(tǒng)總的物理 I/O 除以用戶的 I/O。

圖片圖片

要實(shí)現(xiàn)比較低的 I/O 放大,我們需要了解用戶數(shù)據(jù)的訪問特征。根據(jù)用戶數(shù)據(jù)的訪問特征,進(jìn)行有效優(yōu)化。

一般來說,用戶的數(shù)據(jù)訪問都存在熱點(diǎn)情況。即最近寫過的數(shù)據(jù),被再次寫的概率更大,也符合齊夫分布的特征。

齊夫分布,如公式所示,r 為訪問頻率的排名。C 和 ? 為常數(shù)。即排名越往后,訪問頻率越低。對(duì)這個(gè)公式同時(shí)取對(duì)數(shù)的情況下,是一個(gè)下降的直線。我們也對(duì)線上數(shù)據(jù)的寫頻率進(jìn)行了統(tǒng)計(jì)。除了長尾外,前半部分排名的數(shù)據(jù),基本符合齊夫分布。

如果按照訪問時(shí)間進(jìn)行統(tǒng)計(jì),那么 1 天內(nèi)有寫的熱數(shù)據(jù),只占總數(shù)據(jù)的 5% 左右。

圖片圖片

既然數(shù)據(jù)有冷熱,那么當(dāng)我們選擇 segment 進(jìn)行 compaction,就可以利用數(shù)據(jù)的這種訪問特點(diǎn)進(jìn)行。

一般的選擇方法是貪心算法,即選擇最空的 segment 進(jìn)行 compaction。如圖中的例子,在貪心算法的情況下,由于 segment B 的空洞率更高,會(huì)選擇 segment B 進(jìn)行 compaction。但是,由于 B 中的數(shù)據(jù)比較新,很有可能是熱數(shù)據(jù),則這些數(shù)據(jù)過很小的一段時(shí)間就可能被覆蓋寫。這次數(shù)據(jù)搬遷就顯得多余。

考慮到 segment A 中數(shù)據(jù)比較老。按照用戶訪問特點(diǎn),更老的數(shù)據(jù)被更新的可能性更小。Segment A 會(huì)被長期占用,空洞空間無法釋放。實(shí)際上,這些空洞更有價(jià)值,因?yàn)橐坏┽尫?,能夠被利用很長時(shí)間。所以,cost-benefit 算法兼顧了空洞率和數(shù)據(jù)年齡。它的 pick 算法如公式所示,其中 u 代表有效數(shù)據(jù)率,age 表示 segment 中最新數(shù)據(jù)的年齡。這樣,空洞率比較高的的 segment 會(huì)被選中,老的 segment 也有大概率被選中,釋放出更有價(jià)值的空洞。

圖片圖片

另外,compaction 的數(shù)據(jù)和用戶的寫入數(shù)據(jù)同樣有不同的冷熱。通常 compaction 的數(shù)據(jù)為長時(shí)間沒有寫到的數(shù)據(jù)。將這些數(shù)據(jù)單獨(dú)分流,能夠形成較為穩(wěn)定的 segment。而用戶的寫入的數(shù)據(jù)短時(shí)間內(nèi)被寫的可能性比較大,也單獨(dú)放置。這樣進(jìn)行分類后,能夠形成一些致密的 segment,存放老數(shù)據(jù)。頻繁的寫入形成一些稀疏的 segment,這些 segment 可以被反復(fù)利用。

如果想要更好的效果,可以將數(shù)據(jù)流劃分更細(xì),更多地減少寫放大。

圖片圖片

我們統(tǒng)計(jì)了線上統(tǒng)計(jì)訪問,進(jìn)行回放,控制不同物理空間使用情況下,驗(yàn)證了寫放大的優(yōu)化效果。

從圖中可以看出,cost-benefit 與貪心算法相比,能夠有效減少寫放大。在高空間占用率的情況下(如 95%),cost-benefit 方式,能夠達(dá)到 1.5 以下的寫放大。而貪心算法則要達(dá)到 4 倍以上。

另外,更多的分流能夠減少寫放大。在貪心算法的情況下,能夠節(jié)省較多的 I/O。cost-benefit 情況下,4 路到 6 路收益不太明顯。

另外可以看出,空間使用率對(duì)寫放大也有影響,即較低的空間使用率的情況下,寫放大更好。這也符合直覺,compaction 越晚發(fā)生,segment 形成的空洞越多。

圖片圖片

對(duì)于多層 append 系統(tǒng),每一層都期望把本層能用的空間盡量用滿,然后再做 compaction。但是這么做會(huì)導(dǎo)致下一層的空間持續(xù)緊張,導(dǎo)致下層寫放大比較嚴(yán)重。例如,如果邏輯層寫的比較滿,遲遲不做 compaction,那么物理層則需要頻繁做 compaction 為邏輯層提供充足寫空間。

系統(tǒng)的整體寫放大,應(yīng)該是每一層的寫放大的乘積。那么,總體寫放大并不是追求單獨(dú)一層低寫放大,而是一個(gè)均衡的寫放大,使得整體寫放大較低。

圖片圖片

因此,我們結(jié)合自己的系統(tǒng)特征,設(shè)計(jì)了一個(gè)均衡 compaction 的點(diǎn)。最上層是用戶數(shù)據(jù)空間,下層是 EC 系統(tǒng)能夠提供的物理空間,中間是寫入 EC 層的數(shù)據(jù)。

我們選擇一個(gè)中間點(diǎn)進(jìn)行 compaction 的選擇,如果這個(gè)點(diǎn)偏左,說明上層數(shù)據(jù)比較致密,空洞較少,則下層進(jìn)行 compaction。如果這個(gè)點(diǎn)偏右,則說明下層致密,上層空洞率較多,觸發(fā)上層的 compaction。

這樣,我們就形成了一個(gè)動(dòng)態(tài)可調(diào)節(jié)的 compaction 點(diǎn),使得上下層的 compaction 都不太大,動(dòng)態(tài)維護(hù)一個(gè)較低的整體 compaction。

圖片圖片

總結(jié)下來,系統(tǒng)有低成本的需求,大規(guī)模場景下多副本由于成本問題,不能滿足需求。因此,我們必要采用糾刪碼的形式組織數(shù)據(jù)。

而糾刪碼本身修改代價(jià)比較大,系統(tǒng)設(shè)計(jì)當(dāng)中,利用追加寫的方式進(jìn)行修改。并且采用大小寫分離的方式存儲(chǔ)數(shù)據(jù)。分離后,大寫部分產(chǎn)生的 EC 數(shù)據(jù)為變長,采用 append 的引擎,為這種變長分片提供更好的空間分配機(jī)制,同時(shí)能夠充分利用硬件追加寫的性能優(yōu)勢。

綜上,百度滄海的塊存儲(chǔ)采用了 2 層 append 方案,規(guī)避了 EC 的修改代價(jià)。通過大小寫分離情況,解決了小寫不適合 EC 的情況。同時(shí)選擇了合適 pick 算法、數(shù)據(jù)分流、合適的 compaction 點(diǎn)的方式,優(yōu)化了系統(tǒng)的寫放大,能夠達(dá)到低成本下較高的系統(tǒng)性能。

圖片圖片

以上是今天分享的全部內(nèi)容。

責(zé)任編輯:武曉燕 來源: 百度智能云技術(shù)站
相關(guān)推薦

2021-04-22 13:38:21

前端開發(fā)技術(shù)

2017-10-27 08:40:44

分布式存儲(chǔ)剪枝系統(tǒng)

2017-09-04 08:49:17

存儲(chǔ)原理架構(gòu)

2023-12-01 10:25:34

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

2017-10-17 08:33:31

存儲(chǔ)系統(tǒng)分布式

2018-08-24 09:42:05

云存儲(chǔ)存儲(chǔ)大數(shù)據(jù)

2011-08-03 09:15:47

存儲(chǔ)內(nèi)存云云計(jì)算

2016-01-12 14:59:40

分布式存儲(chǔ)分布式存儲(chǔ)架構(gòu)

2018-02-27 08:39:47

圖譜數(shù)據(jù)存儲(chǔ)

2023-09-06 10:33:44

2014-04-27 10:16:31

QCon北京2014Andrew Bett

2012-07-05 09:39:27

虛擬化

2022-08-10 09:02:03

風(fēng)控Flink阿里云

2013-03-22 14:44:52

大規(guī)模分布式系統(tǒng)飛天開放平臺(tái)

2021-09-06 14:52:17

MySQL存儲(chǔ)架構(gòu)

2023-09-08 07:45:32

2017-10-09 16:51:34

機(jī)器學(xué)習(xí)No Free Lun

2018-04-12 17:23:41

金融Linux紅旗軟件

2016-01-29 20:23:23

華為

2009-04-09 09:32:00

VoWLANWLAN
點(diǎn)贊
收藏

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