大數(shù)據(jù)入門(mén) | 三埂息、分布式文件系統(tǒng)HDFS

本文大部分內(nèi)容轉(zhuǎn)自初步掌握HDFS的架構(gòu)及原理皮璧,并參考了網(wǎng)易云課堂《大數(shù)據(jù)技術(shù)原理與應(yīng)用》課程Chapter 3的內(nèi)容舟扎。


01?

什么是分布式文件系統(tǒng)?

分布式文件系統(tǒng)(Distributed File System)悴务,簡(jiǎn)單來(lái)說(shuō)睹限,就是把文件分布存儲(chǔ)到多個(gè)計(jì)算機(jī)節(jié)點(diǎn)上,這些節(jié)點(diǎn)可分為以下兩類(lèi):

\bullet ?主節(jié)點(diǎn) (Master Node)讯檐,或名稱(chēng)結(jié)點(diǎn)(NameNode)

\bullet ?從節(jié)點(diǎn)(Slave Node)羡疗,或數(shù)據(jù)節(jié)點(diǎn) (DataNode)

節(jié)點(diǎn)之間通過(guò)計(jì)算機(jī)網(wǎng)絡(luò)進(jìn)行連接。

02

什么是HDFS别洪?

HDFS是被設(shè)計(jì)成適合運(yùn)行在通用硬件上的分布式文件系統(tǒng)叨恨,它是Hadoop項(xiàng)目的核心子項(xiàng)目,是分布式計(jì)算中數(shù)據(jù)存儲(chǔ)管理的基礎(chǔ)挖垛。

它和現(xiàn)有的分布式文件系統(tǒng)有很多共同點(diǎn)痒钝。但同時(shí),它和其他的分布式文件系統(tǒng)的區(qū)別也是很明顯的痢毒。它所具有的高容錯(cuò)送矩、高可靠性、高可擴(kuò)展性哪替、高獲得性栋荸、高吞吐率等特征為海量數(shù)據(jù)提供了不怕故障的存儲(chǔ),為超大數(shù)據(jù)集(Large Data Set)的應(yīng)用處理帶來(lái)了很多便利凭舶。

03

為什么使用HDFS晌块?

\bullet ?高容錯(cuò)性:數(shù)據(jù)自動(dòng)保存多個(gè)副本,提高容錯(cuò)性帅霜,某一個(gè)副本丟失以后匆背,它可以自動(dòng)恢復(fù)。

\bullet ?適合批處理:它是通過(guò)移動(dòng)計(jì)算而不是移動(dòng)數(shù)據(jù)身冀;它會(huì)把數(shù)據(jù)位置暴露給計(jì)算框架靠汁。

\bullet ?適合大數(shù)據(jù)處理:處理數(shù)據(jù)達(dá)到 GB蜂大、TB、甚至PB級(jí)別的數(shù)據(jù)蝶怔;能夠處理百萬(wàn)規(guī)模以上的文件數(shù)量奶浦,數(shù)量相當(dāng)之大;能夠處理10K節(jié)點(diǎn)的規(guī)模踢星。

\bullet ?流式文件訪問(wèn):一次寫(xiě)入澳叉,多次讀取。文件一旦寫(xiě)入不能修改沐悦,只能追加成洗。

\bullet ?可構(gòu)建在廉價(jià)機(jī)器上:它通過(guò)多副本機(jī)制,提高可靠性藏否。它提供了容錯(cuò)和恢復(fù)機(jī)制瓶殃。比如某一個(gè)副本丟失,可以通過(guò)其它副本來(lái)恢復(fù)副签。

04?

哪些場(chǎng)合不適合使用HDFS遥椿?

\bullet ?低延時(shí)數(shù)據(jù)訪問(wèn):比如毫秒級(jí)的來(lái)存儲(chǔ)數(shù)據(jù),這是不行的淆储,它做不到冠场。

它適合高吞吐率的場(chǎng)景,就是在某一時(shí)間內(nèi)寫(xiě)入大量的數(shù)據(jù)本砰。但是它在低延時(shí)的情況下是不行的碴裙,比如毫秒級(jí)以內(nèi)讀取數(shù)據(jù),這樣它是很難做到的点额。

\bullet ?小文件存儲(chǔ):存儲(chǔ)大量小文件(這里的小文件是指小于HDFS系統(tǒng)的Block大小的文件(默認(rèn)64M))的話舔株,它會(huì)占用 NameNode大量的內(nèi)存來(lái)存儲(chǔ)文件、目錄和塊信息还棱。這樣是不可取的载慈,因?yàn)镹ameNode的內(nèi)存總是有限的。

小文件存儲(chǔ)的尋道時(shí)間會(huì)超過(guò)讀取時(shí)間诱贿,它違反了HDFS的設(shè)計(jì)目標(biāo)娃肿。

\bullet ?并發(fā)寫(xiě)入咕缎、文件隨機(jī)修改:一個(gè)文件只能有一個(gè)寫(xiě)珠十,不允許多個(gè)線程同時(shí)寫(xiě)。僅支持?jǐn)?shù)據(jù) append(追加)凭豪,不支持文件的隨機(jī)修改焙蹭。

05

HDFS如何存儲(chǔ)數(shù)據(jù)?

(1)HDFS的存儲(chǔ)單位

HDFS以塊作為存儲(chǔ)單位嫂伞,默認(rèn)一個(gè)塊64MB孔厉。塊的大小遠(yuǎn)遠(yuǎn)大于普通文件系統(tǒng)拯钻,可以最小化尋址開(kāi)銷(xiāo)。

HDFS采用抽象的塊概念可以帶來(lái)以下幾個(gè)明顯的好處

\bullet 支持大規(guī)模文件存儲(chǔ):文件以塊為單位進(jìn)行存儲(chǔ)撰豺,一個(gè)大規(guī)模文件可以被分拆成若干個(gè)文件塊粪般,不同的文件塊可以被分發(fā)到不同的節(jié)點(diǎn)上,因此污桦,一個(gè)文件的大小不會(huì)受到單個(gè)節(jié)點(diǎn)的存儲(chǔ)容量的限制亩歹,可以遠(yuǎn)遠(yuǎn)大于網(wǎng)絡(luò)中任意節(jié)點(diǎn)的存儲(chǔ)容量。

\bullet 簡(jiǎn)化系統(tǒng)設(shè)計(jì):首先凡橱,大大簡(jiǎn)化了存儲(chǔ)管理小作,因?yàn)槲募K大小是固定的,這樣就可以很容易計(jì)算出一個(gè)節(jié)點(diǎn)可以存儲(chǔ)多少文件塊稼钩;其次顾稀,方便了元數(shù)據(jù)的管理,元數(shù)據(jù)不需要和文件塊一起存儲(chǔ)坝撑,可以由其他系統(tǒng)負(fù)責(zé)管理元數(shù)據(jù)静秆。

\bullet 適合數(shù)據(jù)備份:每個(gè)文件塊都可以冗余存儲(chǔ)到多個(gè)節(jié)點(diǎn)上,大大提高了系統(tǒng)的容錯(cuò)性和可用性绍载。

(2)HDFS的存儲(chǔ)架構(gòu)

HDFS 采用Master/Slave的架構(gòu)來(lái)存儲(chǔ)數(shù)據(jù)诡宗,這種架構(gòu)主要由四個(gè)部分組成,分別為HDFS Client击儡、NameNode塔沃、DataNode和Secondary NameNode。

HDFS的架構(gòu)圖

(1)Client:就是客戶端阳谍。

\bullet 文件切分蛀柴。文件上傳 HDFS 的時(shí)候,Client 將文件切分成 一個(gè)一個(gè)的Block矫夯,然后進(jìn)行存儲(chǔ)鸽疾。

\bullet 與 NameNode 交互,獲取文件的位置信息训貌。

\bullet 與 DataNode 交互制肮,讀取或者寫(xiě)入數(shù)據(jù)。

\bullet Client 提供一些命令來(lái)管理 HDFS递沪,比如啟動(dòng)或者關(guān)閉HDFS豺鼻。

\bullet Client 可以通過(guò)一些命令來(lái)訪問(wèn) HDFS。

(2)NameNode:就是 master款慨,它是一個(gè)主管儒飒、管理者。

\bullet 管理 HDFS 的名稱(chēng)空間檩奠。

\bullet 管理數(shù)據(jù)塊(Block)映射信息桩了。

\bullet 配置副本策略附帽。

\bullet 處理客戶端讀寫(xiě)請(qǐng)求。

(3)DataNode:就是Slave井誉。NameNode 下達(dá)命令蕉扮,DataNode 執(zhí)行實(shí)際的操作。

\bullet 存儲(chǔ)實(shí)際的數(shù)據(jù)塊颗圣。

\bullet 執(zhí)行數(shù)據(jù)塊的讀/寫(xiě)操作慢显。

(4)SecondaryNameNode:NameNode 的冷備。

\bullet 輔助 NameNode欠啤,分擔(dān)其工作量荚藻。

\bullet 定期合并 FsImage和EditLog,并推送給NameNode洁段。

\bullet 在緊急情況下应狱,可輔助恢復(fù) NameNode。

06

HDFS如何檢測(cè)和處理錯(cuò)誤數(shù)據(jù)祠丝?

HDFS具有較高的容錯(cuò)性疾呻,可以兼容廉價(jià)的硬件,它把硬件出錯(cuò)看作一種常態(tài)写半,而不是異常岸蜗,并設(shè)計(jì)了相應(yīng)的機(jī)制檢測(cè)數(shù)據(jù)錯(cuò)誤和進(jìn)行自動(dòng)恢復(fù),主要包括以下幾種情形:名稱(chēng)節(jié)點(diǎn)出錯(cuò)叠蝇、數(shù)據(jù)節(jié)點(diǎn)出錯(cuò)和數(shù)據(jù)出錯(cuò)璃岳。

(1)名稱(chēng)節(jié)點(diǎn)出錯(cuò)

名稱(chēng)節(jié)點(diǎn)保存了所有的元數(shù)據(jù)信息,其中悔捶,最核心的兩大數(shù)據(jù)結(jié)構(gòu)是FsImage和Editlog铃慷,如果這兩個(gè)文件發(fā)生損壞,那么整個(gè)HDFS實(shí)例將失效蜕该。

因此犁柜,HDFS設(shè)置了備份機(jī)制,把這些核心文件同步復(fù)制到備份服務(wù)器SecondaryNameNode上堂淡。當(dāng)名稱(chēng)節(jié)點(diǎn)出錯(cuò)時(shí)馋缅,就可以根據(jù)備份服務(wù)器SecondaryNameNode中的FsImage和Editlog數(shù)據(jù)進(jìn)行恢復(fù)。

(2)數(shù)據(jù)節(jié)點(diǎn)出錯(cuò)

每個(gè)數(shù)據(jù)節(jié)點(diǎn)會(huì)定期向名稱(chēng)節(jié)點(diǎn)發(fā)送“心跳”信息绢淀,向名稱(chēng)節(jié)點(diǎn)報(bào)告自己的狀態(tài)萤悴。

當(dāng)數(shù)據(jù)節(jié)點(diǎn)發(fā)生故障,或者網(wǎng)絡(luò)發(fā)生斷網(wǎng)時(shí)更啄,名稱(chēng)節(jié)點(diǎn)就無(wú)法收到來(lái)自一些數(shù)據(jù)節(jié)點(diǎn)的心跳信息稚疹,這時(shí)居灯,這些數(shù)據(jù)節(jié)點(diǎn)就會(huì)被標(biāo)記為“宕機(jī)”祭务,節(jié)點(diǎn)上面的所有數(shù)據(jù)都會(huì)被標(biāo)記為“不可讀”内狗,名稱(chēng)節(jié)點(diǎn)不會(huì)再給它們發(fā)送任何I/O請(qǐng)求。

這時(shí)义锥,有可能出現(xiàn)一種情形柳沙,即由于一些數(shù)據(jù)節(jié)點(diǎn)的不可用,會(huì)導(dǎo)致一些數(shù)據(jù)塊的副本數(shù)量小于冗余因子拌倍。

名稱(chēng)節(jié)點(diǎn)會(huì)定期檢查這種情況赂鲤,一旦發(fā)現(xiàn)某個(gè)數(shù)據(jù)塊的副本數(shù)量小于冗余因子,就會(huì)啟動(dòng)數(shù)據(jù)冗余復(fù)制柱恤,為它生成新的副本数初。

(3)數(shù)據(jù)出錯(cuò)

網(wǎng)絡(luò)傳輸和磁盤(pán)錯(cuò)誤等因素,都會(huì)造成數(shù)據(jù)錯(cuò)誤梗顺。

客戶端在讀取到數(shù)據(jù)后泡孩,會(huì)采用md5和sha1對(duì)數(shù)據(jù)塊進(jìn)行校驗(yàn),以確定讀取到正確的數(shù)據(jù)寺谤。

在文件被創(chuàng)建時(shí)仑鸥,客戶端就會(huì)對(duì)每一個(gè)文件塊進(jìn)行信息摘錄,并把這些信息寫(xiě)入到同一個(gè)路徑的隱藏文件里面变屁。

當(dāng)客戶端讀取文件的時(shí)候眼俊,會(huì)先讀取該信息文件,然后粟关,利用該信息文件對(duì)每個(gè)讀取的數(shù)據(jù)塊進(jìn)行校驗(yàn)疮胖,如果校驗(yàn)出錯(cuò),客戶端就會(huì)請(qǐng)求到另外一個(gè)數(shù)據(jù)節(jié)點(diǎn)讀取該文件塊闷板,并且向名稱(chēng)節(jié)點(diǎn)報(bào)告這個(gè)文件塊有錯(cuò)誤获列,名稱(chēng)節(jié)點(diǎn)會(huì)定期檢查并且重新復(fù)制這個(gè)塊。

07?

HDFS如何讀取文件蛔垢?

HDFS的文件讀取原理击孩,主要包括以下幾個(gè)步驟:

文件讀取過(guò)程

① 首先調(diào)用FileSystem對(duì)象的open方法,其實(shí)獲取的是一個(gè)DistributedFileSystem的實(shí)例鹏漆。

② DistributedFileSystem通過(guò)RPC(遠(yuǎn)程過(guò)程調(diào)用)獲得文件的第一批block的locations巩梢,同一block按照重復(fù)數(shù)會(huì)返回多個(gè)locations,這些locations按照hadoop拓?fù)浣Y(jié)構(gòu)排序艺玲,距離客戶端近的排在前面括蝠。

③ 前兩步會(huì)返回一個(gè)FSDataInputStream對(duì)象,該對(duì)象會(huì)被封裝成 DFSInputStream對(duì)象饭聚,DFSInputStream可以方便的管理datanode和namenode數(shù)據(jù)流忌警。客戶端調(diào)用read方法秒梳,DFSInputStream就會(huì)找出離客戶端最近的datanode并連接datanode法绵。

④ 數(shù)據(jù)從datanode源源不斷的流向客戶端箕速。

⑤ 如果第一個(gè)block塊的數(shù)據(jù)讀完了,就會(huì)關(guān)閉指向第一個(gè)block塊的datanode連接朋譬,接著讀取下一個(gè)block塊盐茎。這些操作對(duì)客戶端來(lái)說(shuō)是透明的,從客戶端的角度來(lái)看只是讀一個(gè)持續(xù)不斷的流徙赢。

⑥ 如果第一批block都讀完了字柠,DFSInputStream就會(huì)去namenode拿下一批blocks的location,然后繼續(xù)讀狡赐,如果所有的block塊都讀完窑业,這時(shí)就會(huì)關(guān)閉掉所有的流。

08

HDFS如何寫(xiě)文件枕屉?

HDFS的文件寫(xiě)入原理数冬,主要包括以下幾個(gè)步驟:

文件寫(xiě)入過(guò)程

① 客戶端通過(guò)調(diào)用 DistributedFileSystem 的create方法,創(chuàng)建一個(gè)新的文件搀庶。

② DistributedFileSystem 通過(guò) RPC(遠(yuǎn)程過(guò)程調(diào)用)調(diào)用 NameNode拐纱,去創(chuàng)建一個(gè)沒(méi)有blocks關(guān)聯(lián)的新文件。創(chuàng)建前哥倔,NameNode 會(huì)做各種校驗(yàn)秸架,比如文件是否存在,客戶端有無(wú)權(quán)限去創(chuàng)建等咆蒿。如果校驗(yàn)通過(guò)东抹,NameNode 就會(huì)記錄下新文件,否則就會(huì)拋出IO異常沃测。

③ 前兩步結(jié)束后會(huì)返回 FSDataOutputStream 的對(duì)象缭黔,和讀文件的時(shí)候相似,F(xiàn)SDataOutputStream 被封裝成 DFSOutputStream蒂破,DFSOutputStream 可以協(xié)調(diào) NameNode和 DataNode馏谨。客戶端開(kāi)始寫(xiě)數(shù)據(jù)到DFSOutputStream,DFSOutputStream會(huì)把數(shù)據(jù)切成一個(gè)個(gè)小packet附迷,然后排成隊(duì)列 data queue惧互。

④ DataStreamer 會(huì)去處理接受 data queue,它先問(wèn)詢 NameNode 這個(gè)新的 block 最適合存儲(chǔ)的在哪幾個(gè)DataNode里喇伯,比如重復(fù)數(shù)是3喊儡,那么就找到3個(gè)最適合的 DataNode,把它們排成一個(gè) pipeline稻据。DataStreamer 把 packet 按隊(duì)列輸出到管道的第一個(gè) DataNode 中艾猜,第一個(gè) DataNode又把 packet 輸出到第二個(gè) DataNode 中,以此類(lèi)推。

⑤ DFSOutputStream 還有一個(gè)隊(duì)列叫 ack queue匆赃,也是由 packet 組成淤毛,等待DataNode的收到響應(yīng),當(dāng)pipeline中的所有DataNode都表示已經(jīng)收到的時(shí)候炸庞,這時(shí)ack queue才會(huì)把對(duì)應(yīng)的packet包移除掉。

⑥ 客戶端完成寫(xiě)數(shù)據(jù)后荚斯,調(diào)用close方法關(guān)閉寫(xiě)入流埠居。

⑦ DataStreamer 把剩余的包都刷到 pipeline 里,然后等待 ack 信息事期,收到最后一個(gè) ack 后滥壕,通知 DataNode 把文件標(biāo)示為已完成。



Enjoy reading :)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末兽泣,一起剝皮案震驚了整個(gè)濱河市绎橘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌唠倦,老刑警劉巖称鳞,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異稠鼻,居然都是意外死亡冈止,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)候齿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)熙暴,“玉大人,你說(shuō)我怎么就攤上這事慌盯≈苊梗” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵亚皂,是天一觀的道長(zhǎng)俱箱。 經(jīng)常有香客問(wèn)我,道長(zhǎng)灭必,這世上最難降的妖魔是什么匠楚? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮厂财,結(jié)果婚禮上芋簿,老公的妹妹穿的比我還像新娘。我一直安慰自己璃饱,他們只是感情好与斤,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般撩穿。 火紅的嫁衣襯著肌膚如雪磷支。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,158評(píng)論 1 308
  • 那天食寡,我揣著相機(jī)與錄音雾狈,去河邊找鬼。 笑死抵皱,一個(gè)胖子當(dāng)著我的面吹牛善榛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播呻畸,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼移盆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了伤为?” 一聲冷哼從身側(cè)響起咒循,我...
    開(kāi)封第一講書(shū)人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绞愚,沒(méi)想到半個(gè)月后叙甸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡位衩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年蚁署,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚂四。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡光戈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出遂赠,到底是詐尸還是另有隱情久妆,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布跷睦,位于F島的核電站筷弦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏抑诸。R本人自食惡果不足惜烂琴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蜕乡。 院中可真熱鬧奸绷,春花似錦、人聲如沸层玲。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至畔派,卻和暖如春铅碍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背线椰。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工胞谈, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人憨愉。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓烦绳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親莱衩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子爵嗅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,947評(píng)論 2 89
  • 1.HDFS簡(jiǎn)介 正如其名娇澎,HDFS(Hadoop Distribution File System)是一個(gè)分布式...
    Michaelhbjian閱讀 2,516評(píng)論 0 2
  • HDFS的設(shè)計(jì) HDFS以流式數(shù)據(jù)訪問(wèn)模式來(lái)存儲(chǔ)超大文件笨蚁,運(yùn)行于商用硬件集群上。 超大文件:指的是幾百M(fèi)B趟庄、幾百G...
    Vechace閱讀 844評(píng)論 0 1
  • 追完《那年花開(kāi)月正圓》已經(jīng)有幾天了括细,閑來(lái)無(wú)事說(shuō)說(shuō)吧: 我這個(gè)人有個(gè)毛病,自己覺(jué)得好的東西非得安利一通戚啥,比如這部劇我...
    落日芳草香閱讀 501評(píng)論 0 1
  • Git 介紹 寫(xiě)作環(huán)境 MarkDown語(yǔ)法 文章排版 Building replayability into t...
    一路安順閱讀 240評(píng)論 0 0