后端好書閱讀與推薦(續(xù)四)(后端推薦書籍)

后端好書閱讀與推薦(續(xù)四)(后端推薦書籍)

docker生產(chǎn)環(huán)境實(shí)踐指南

Docker生產(chǎn)環(huán)境實(shí)踐指南 (豆瓣) https://book.douban.com/subject/26825958/

前面docker的基本概念和一些核心原理都看的差不多了,那么現(xiàn)在該關(guān)注一下具體的生產(chǎn)環(huán)境的使用方法了。

亮點(diǎn):

  • 在生產(chǎn)環(huán)境中運(yùn)行docker與在其它環(huán)境中相比,最主要的差異是需要在其安全性與穩(wěn)定性上投入更多的注意力
  • 書中提到docker 容器與宿主機(jī)是通過(guò)IPtables實(shí)現(xiàn)的nat轉(zhuǎn)換來(lái)進(jìn)行通信,這點(diǎn)官網(wǎng)有說(shuō)明 Docker container networking,然后就說(shuō)了不適宜網(wǎng)絡(luò)吞吐量有很高要求的應(yīng)用(但是可以禁用Docker的NAT來(lái)提升網(wǎng)絡(luò)性能),但是docker已經(jīng)做出了一些努力,效果并不差,見(jiàn):1,2,3
  • 書中對(duì)于docker相關(guān)常見(jiàn)的概念解釋得非常清晰易懂,這一部分尤其適合初學(xué)者
  • docker生產(chǎn)環(huán)境最好的方式是將應(yīng)用程序及其依賴預(yù)先打包成一個(gè)鏡像,而包含數(shù)據(jù)庫(kù)憑證等銘感信息在運(yùn)行時(shí)動(dòng)態(tài)添加(安全起見(jiàn));常見(jiàn)流程是開發(fā)機(jī)上打包并推送到倉(cāng)庫(kù),然后服務(wù)器從倉(cāng)庫(kù)拉取鏡像,這種用例簡(jiǎn)單但是從工作流和安全角度看并不理想,更標(biāo)準(zhǔn)的做法是使用持續(xù)集成 / 持續(xù)交付系統(tǒng)在應(yīng)用程序代碼或者dockerfile發(fā)生變化時(shí)自動(dòng)從新構(gòu)建鏡像
  • 實(shí)現(xiàn)開發(fā)速度和生產(chǎn)環(huán)境穩(wěn)定的方法之一是擁抱簡(jiǎn)單,亦即系統(tǒng)的每一個(gè)部分——容器——有且只有一個(gè)目標(biāo)。系統(tǒng)的簡(jiǎn)單需要設(shè)計(jì)時(shí)遵照如下原則:傾向無(wú)狀態(tài)服務(wù),傾向靜態(tài)配置,傾向靜態(tài)的網(wǎng)絡(luò)布局,區(qū)別對(duì)待有狀態(tài)和無(wú)狀態(tài)的服務(wù)
  • 保持鏡像小巧:可以從空的文件系統(tǒng)開始構(gòu)建,從類似于busybox、aipine這種輕量級(jí)操作系統(tǒng)開始構(gòu)建,如果嫌包少就可以從主流Linux發(fā)行版的容器優(yōu)化版開始構(gòu)建,最明智的做法是標(biāo)準(zhǔn)化一個(gè)特定的鏡像版本,并盡可能的用于所有容器;盡可能減少層數(shù),也就是相關(guān)的命令盡量放到一行,而且下載的內(nèi)容用完后要在同一行刪除;可以使用docker-squash來(lái)減小鏡像體積
  • 存儲(chǔ)鏡像:開源、公共項(xiàng)目建議存共有倉(cāng)庫(kù);安全性和性能要求較高的存私有倉(cāng)庫(kù);需要定制的使用save / load。此外,很多人可能不知道,DockerHub其實(shí)是提供了自動(dòng)構(gòu)建功能的,只要通過(guò)WebHook連上Github就行(親測(cè))
  • 一致性是擴(kuò)展環(huán)境和傳播知識(shí)的關(guān)鍵,所以應(yīng)該在一個(gè)構(gòu)建系統(tǒng)中構(gòu)建所有鏡像,而且要實(shí)現(xiàn)鏡像標(biāo)準(zhǔn)化,讓所有鏡像(盡可能)繼承于一個(gè)標(biāo)準(zhǔn)基礎(chǔ)鏡像
  • AUFS引擎的掛載速度非???,能很快的創(chuàng)建新容器所以成為了Docker存儲(chǔ)引擎的默認(rèn)解決方案。其性能瓶頸主要在需要寫入大文件的場(chǎng)景,因此使用AUFS來(lái)存放數(shù)據(jù)庫(kù)文件可能不是一個(gè)好主意,同樣太多的鏡像層可能導(dǎo)致文件查找時(shí)間過(guò)長(zhǎng),所以不要讓自己的文件有太多分層。AUFS有一個(gè)最大的問(wèn)題是沒(méi)有被容納到Linux主流發(fā)行版。事實(shí)上,在生產(chǎn)環(huán)境選擇存儲(chǔ)引擎,一個(gè)要點(diǎn)是看業(yè)務(wù)與特性是否吻合,另一個(gè)要點(diǎn)就是選最有把握能穩(wěn)定運(yùn)維的工具
  • Docker網(wǎng)絡(luò)實(shí)現(xiàn)包含三方面內(nèi)容,IP分配、域名解析、容器或服務(wù)發(fā)現(xiàn),這也是零配置網(wǎng)絡(luò)的理論基礎(chǔ)。零配置網(wǎng)絡(luò)即是一組在沒(méi)有人工干預(yù)的情況下自動(dòng)創(chuàng)建和配置一個(gè)TCP/IP網(wǎng)絡(luò)的技術(shù)。
  • Docker集群之中的服務(wù)發(fā)現(xiàn),目前是consul做得最好,可以自定義健康檢查機(jī)制,不像ZooKeeper(和TCP會(huì)話周期綁定)和etcd(和TTL值掛鉤),提供了一個(gè)非常完備的服務(wù)發(fā)現(xiàn)解決方案

本書名副其實(shí),對(duì)于在生產(chǎn)環(huán)境中使用docker有不錯(cuò)的方向指導(dǎo)意義,當(dāng)然細(xì)節(jié)還得自己扣啊。

注意:由于時(shí)間原因,書中有些內(nèi)容有些過(guò)時(shí)但是譯者給出了注解(但是譯者的注解也可能過(guò)時(shí)呀,所以一定要自己注意跟蹤docker的最新變化)

The Go Programming Language

The Go Programming Language (豆瓣) https://book.douban.com/subject/26337545/

為什么要了解一下 golang 呢?最明顯的原因就是,這個(gè)語(yǔ)言有一款殺手級(jí)應(yīng)用,也就是前面說(shuō)過(guò)很多次的:Docker;而且前一段時(shí)間 nodejs 的創(chuàng)始人不是要擁抱 go 語(yǔ)言了嗎,作為一個(gè)編程語(yǔ)言的創(chuàng)始人轉(zhuǎn)投另一門語(yǔ)言,還是很值得了解一下的;最后,對(duì) go 的協(xié)程是早有耳聞,傳言可以用同步的方式寫出異步的代碼,輕松實(shí)現(xiàn)高并發(fā)……

亮點(diǎn):

  • 正如Rob Pike所說(shuō),“軟件的復(fù)雜性是乘法級(jí)相關(guān)的”,通過(guò)增加一個(gè)部分的復(fù)雜性來(lái)修復(fù)問(wèn)題通常將慢慢地增加其他部分的復(fù)雜性。通過(guò)增加功能和選項(xiàng)和配置是修復(fù)問(wèn)題的最快的途徑,但是這很容易讓人忘記簡(jiǎn)潔的內(nèi)涵,即使從長(zhǎng)遠(yuǎn)來(lái)看,簡(jiǎn)潔依然是好軟件的關(guān)鍵因素。秉承著簡(jiǎn)潔原則,golang沒(méi)有內(nèi)置大多數(shù)語(yǔ)言都有的隱式轉(zhuǎn)換、宏、異常、繼承等等
  • 依然是簡(jiǎn)潔原則的貫徹,golang 不允許 import 沒(méi)有使用的包,也不能定義沒(méi)有使用的變量,否則連編譯都不能通過(guò)。還有左大括號(hào)必須和代碼在同一行……感覺(jué)這些強(qiáng)制要求非常有用,多一些標(biāo)準(zhǔn),少一些歧義,這應(yīng)該是利于工程化的
  • break 和 continue 都可以加label來(lái)實(shí)現(xiàn)跳出任一循環(huán),這個(gè)有點(diǎn)像 goto 語(yǔ)句,這種語(yǔ)句我們要少用,一般是在編譯器生成代碼過(guò)程使用的
  • 并不是所有的詞法域都顯式地對(duì)應(yīng)到由花括弧包含的語(yǔ)句;還有一些隱含的規(guī)則。比如for語(yǔ)句創(chuàng)建了兩個(gè)詞法域:花括弧包含的是顯式的部分是for的循環(huán)體部分詞法域,另外一個(gè)隱式的部分則是循環(huán)的初始化部分,比如用于迭代變量i的初始化。隱式的詞法域部分的作用域還包含條件測(cè)試部分和循環(huán)后的迭代部分(i ),當(dāng)然也包含循環(huán)體詞法域
  • 結(jié)構(gòu)體中的匿名成員是一個(gè)比較有意思的特點(diǎn),可以用來(lái)無(wú)縫的實(shí)現(xiàn)“對(duì)象組合”這一需求,組合是 go 實(shí)現(xiàn)面向?qū)ο缶幊痰暮诵?/li>
  • 大部分語(yǔ)言使用固定大小的函數(shù)調(diào)用棧,常見(jiàn)的大小從64KB到2MB不等。固定大小棧會(huì)限制遞歸的深度,當(dāng)你用遞歸處理大量數(shù)據(jù)時(shí),需要避免棧溢出;除此之外,還會(huì)導(dǎo)致安全性問(wèn)題。與相反,Go語(yǔ)言使用可變棧,棧的大小按需增加(初始時(shí)很小)。這使得我們使用遞歸時(shí)不必考慮溢出和安全問(wèn)題
  • 在Go中,錯(cuò)誤處理有一套獨(dú)特的編碼風(fēng)格。檢查某個(gè)子函數(shù)是否失敗后,我們通常將處理失敗的邏輯代碼放在處理成功的代碼之前。如果某個(gè)錯(cuò)誤會(huì)導(dǎo)致函數(shù)返回,那么成功時(shí)的邏輯代碼不應(yīng)放在else語(yǔ)句塊中,而應(yīng)直接放在函數(shù)體中。Go中大部分函數(shù)的代碼結(jié)構(gòu)幾乎相同,首先是一系列的初始檢查,防止錯(cuò)誤發(fā)生,之后是函數(shù)的實(shí)際邏輯
  • 當(dāng)defer語(yǔ)句被執(zhí)行時(shí),跟在defer后面的函數(shù)會(huì)被延遲執(zhí)行。直到包含該defer語(yǔ)句的函數(shù)執(zhí)行完畢時(shí),defer后的函數(shù)才會(huì)被執(zhí)行,不論包含defer語(yǔ)句的函數(shù)是通過(guò)return正常結(jié)束,還是由于panic導(dǎo)致的異常結(jié)束。deferred類似于java的finally,可用于保證資源回收、鎖釋放等
  • 看到第八章終于知道傳言的大概意思了,只需要在原來(lái)同步的調(diào)用函數(shù)的代碼之前加一個(gè) go 關(guān)鍵字,就能新建一個(gè)goroutine(可以類比線程,但是有不同之處),然后主線程就能繼續(xù)干活而不必等待函數(shù)執(zhí)行結(jié)束了
  • 線程和goroutine的區(qū)別主要有幾方面:goroutine的棧不是固定大小的,一般從2KB開始動(dòng)態(tài)變化,所以可以打開幾百上千的goroutine,而線程是固定棧大小,不可能開很多;goroutine由Go調(diào)度器進(jìn)行調(diào)度,而不是操作系統(tǒng),采用m:n模型(最多n個(gè)線程執(zhí)行m個(gè)goroutine),所以goroutine的切換代價(jià)較小
  • 雖然及時(shí)修改了一個(gè)源文件也要重新編譯該文件對(duì)應(yīng)的包及其依賴包,但是go的編譯速度非常快,主要有三點(diǎn)原因:所有導(dǎo)入包開頭顯示聲明,快速找到;禁止環(huán)裝依賴,可以并發(fā)編譯;編譯后的包記錄了包的依賴關(guān)系,編譯器不需要遍歷所有依賴文件只需讀取直接導(dǎo)入包的目標(biāo)文件
  • 程序的復(fù)雜性是可以控制的,其中兩種技術(shù)在實(shí)踐中被證明很有效:軟件正式部署前的代碼評(píng)審;自動(dòng)化測(cè)試(寫一些小的程序用來(lái)檢測(cè)被測(cè)試代碼的行為和預(yù)期的一樣)。go test 命令是一個(gè)按照一定的約定和組織的測(cè)試代碼的驅(qū)動(dòng)程序,在*_test.go文件中:測(cè)試函數(shù)以Test為函數(shù)名前綴,用于測(cè)試程序的一些邏輯行為,go test命令會(huì)調(diào)用這些測(cè)試函數(shù)并報(bào)告PASS或FAIL;基準(zhǔn)測(cè)試函數(shù)以Benchmark為函數(shù)名前綴,用于衡量函數(shù)的性能,go test命令會(huì)多次運(yùn)行基準(zhǔn)函數(shù)以計(jì)算一個(gè)平均的執(zhí)行時(shí)間;示例函數(shù)以Example為函數(shù)名前綴,提供一個(gè)由編譯器保證正確性的示例文檔

本書名不虛傳,對(duì)go的基礎(chǔ)知識(shí)介紹的很詳盡,底層原理也稍微有一些涉及,同時(shí)還有一些高級(jí)的話題比如各種并發(fā)、測(cè)試等,是一本入門go的好書,看完后對(duì)golang就有一個(gè)幾乎完整的概念了。

PS:gitbook有對(duì)應(yīng)中文版。

從PAXOS到ZOOKEEPER分布式一致性原理與實(shí)踐

從Paxos到Zookeeper (豆瓣) https://book.douban.com/subject/26292004/

如今搞分布式的似乎都離不開Zookeeper了,Zookeeper一般是作為分布式的基礎(chǔ)設(shè)施,還是很有必要了解一下的。本書闡釋了從集中式到分布式的問(wèn)題,如何解決,層層遞進(jìn)引入了Zookeeper,然后介紹了應(yīng)用場(chǎng)景和技術(shù)內(nèi)幕,算是一個(gè)非常全面的介紹了,而且作者的思路非常清晰,我們讀起來(lái)很流暢,但是書中涉及的一些協(xié)議本身是比較復(fù)雜的,讀起來(lái)有些麻煩。

亮點(diǎn):

  • 集中式的系統(tǒng)保證事務(wù)的 ACID 相對(duì)而言是比較容易的,而且有很多成熟的解決方案。但是根據(jù) CAP 理論:“一個(gè)分布式系統(tǒng)系統(tǒng)不可能同時(shí)滿足一致性、可用性、和分區(qū)容錯(cuò)性,最多只能滿足兩樣”,所以分布式系統(tǒng)不大可能嚴(yán)格滿足 ACID 的強(qiáng)一致性,而分區(qū)容錯(cuò)性 P 是分布式系統(tǒng)本身存在的意義,所以一般設(shè)計(jì)者就在 A 和 C 之間尋求平衡了,根據(jù) BASE 理論,一般分布式系統(tǒng)都實(shí)現(xiàn)以實(shí)現(xiàn)最終一致性、保證高可用性為目標(biāo)。BASE理論不僅應(yīng)用于分布式系統(tǒng),也廣泛應(yīng)用于現(xiàn)代關(guān)系數(shù)據(jù)庫(kù)
  • 數(shù)據(jù)的一致性與可用性之間的反復(fù)權(quán)衡產(chǎn)生了 一系列的一致性協(xié)議,最經(jīng)典莫過(guò)于二階段、三階段提交協(xié)議和Paxos算法了。這三者層層遞進(jìn),分別解決了前者的一些問(wèn)題,并各自在不同的領(lǐng)域被使用
  • Zookeeper是一個(gè)典型的分布式數(shù)據(jù)一致性解決方案(工業(yè)級(jí)產(chǎn)品),致力于提供一個(gè)高性能(高吞吐量)、高可用(解決單點(diǎn)問(wèn)題)、具有嚴(yán)格順序訪問(wèn)(主要是寫)控制能力(實(shí)現(xiàn)復(fù)雜同步原語(yǔ))的分布式協(xié)調(diào)服務(wù)。其設(shè)計(jì)目標(biāo):簡(jiǎn)單的數(shù)據(jù)模型(樹型、共享、內(nèi)存)、可以構(gòu)建集群、順序訪問(wèn)(請(qǐng)求有唯一遞增編號(hào))、高性能,可以保證許多一致性特性:順序一致性、原子性、單一視圖、可靠性、實(shí)時(shí)性。分布式應(yīng)用程序可以基于它實(shí)現(xiàn)數(shù)據(jù)發(fā)布訂閱、負(fù)載均衡、命名服務(wù)、分布式協(xié)調(diào)通知、集群管理、Master選舉、分布式鎖和分布式隊(duì)列等功能
  • 作者對(duì)ZooKeeper的常見(jiàn)應(yīng)用場(chǎng)景進(jìn)行了詳盡的描述,非常有借鑒意義,比如:client利用節(jié)點(diǎn)創(chuàng)建的API可以創(chuàng)建一個(gè)順序節(jié)點(diǎn),再加上其type就形成了一個(gè)全局唯一的ID了,從而實(shí)現(xiàn)命名服務(wù);不同機(jī)器通過(guò)在同一節(jié)點(diǎn)創(chuàng)建臨時(shí)子節(jié)點(diǎn),并根據(jù)其他機(jī)器的臨時(shí)子節(jié)點(diǎn)來(lái)判斷對(duì)應(yīng)的機(jī)器是否存活,從而實(shí)現(xiàn)心跳檢測(cè);通過(guò)強(qiáng)一致性的唯一節(jié)點(diǎn)保證來(lái)實(shí)現(xiàn)master選舉(誰(shuí)能建立特定節(jié)點(diǎn)誰(shuí)就是master,其他機(jī)器注冊(cè)watcher,一旦當(dāng)前master掛了節(jié)點(diǎn)刪除,就又開始新的選舉);通過(guò)節(jié)點(diǎn)唯一性來(lái)實(shí)現(xiàn)排它鎖、子節(jié)點(diǎn)排序來(lái)實(shí)現(xiàn)共享鎖……總而言之,可以在ZooKeeper子節(jié)點(diǎn)唯一性上面做很多文章
  • 具體使用案例,Canal這款基于Mysql BinLog的增量訂閱消費(fèi)組件使用ZooKeeper來(lái)實(shí)現(xiàn)Canal Server的主備切換功能,主要原理就是臨時(shí)節(jié)點(diǎn)和節(jié)點(diǎn)唯一性;Canal Client利用ZooKeeper來(lái)時(shí)刻關(guān)注Canal Server的變化,進(jìn)行消費(fèi)并記錄消費(fèi)點(diǎn)
  • 數(shù)據(jù)模型:由ZNode(稱為節(jié)點(diǎn),類型有持久、臨時(shí)、順序節(jié)點(diǎn),可組合)層次化組織而構(gòu)成的樹,路徑類似于Unix文件系統(tǒng),每個(gè)ZNode可以存數(shù)據(jù)、創(chuàng)建子節(jié)點(diǎn)(臨時(shí)節(jié)點(diǎn)無(wú)子節(jié)點(diǎn));采用版本號(hào)以及CAS來(lái)實(shí)現(xiàn)樂(lè)觀鎖機(jī)制;采用ACL來(lái)實(shí)現(xiàn)細(xì)粒度的權(quán)限管理;采用一次性、客戶端回調(diào)串行執(zhí)行、推拉結(jié)合的輕量級(jí)watcher來(lái)實(shí)現(xiàn)時(shí)間發(fā)布訂閱
  • Leader選舉的原理簡(jiǎn)單說(shuō)來(lái)就是誰(shuí)的數(shù)據(jù)越新,那么其ZXID(事務(wù)ID)越大,就越能夠保證數(shù)據(jù)的恢復(fù),就越能成為L(zhǎng)eader,對(duì)于相同的ZXID,那么SID較大的成為L(zhǎng)eader,這個(gè)應(yīng)該沒(méi)啥特別的原因,只是作為一種確定機(jī)制。
  • Leader是集群中的核心,主要工作:事務(wù)請(qǐng)求的唯一調(diào)度者和處理者,保證集群事務(wù)處理的順序性;集群內(nèi)部各個(gè)服務(wù)的調(diào)度者。Follower是集群狀態(tài)跟隨者,主要工作:處理客戶端非事務(wù)請(qǐng)求,轉(zhuǎn)發(fā)事務(wù)請(qǐng)求給Leader;參與事務(wù)請(qǐng)求Proposal的投票;參與Leader選舉。Observer觀察集群最新變化狀態(tài)并同步過(guò)來(lái),工作類似于Follower,只是不參與任何投票,通常用于在不影響集群事務(wù)處理的情況下提升集群的非事務(wù)處理能力

看完全書再去看看應(yīng)用案例可能會(huì)產(chǎn)生更好的理解。

現(xiàn)代操作系統(tǒng)(原書第4版)

現(xiàn)代操作系統(tǒng)(原書第4版) (豆瓣) https://book.douban.com/subject/27096665/

操作系統(tǒng)是我們一切編程的根基,不了解操作系統(tǒng)就只是“粘貼復(fù)制員”而不是“程序員”更別提“工程師”了。這本書既講到了傳統(tǒng)的重點(diǎn)概念:內(nèi)存、進(jìn)程、文件、安全等,又講到了現(xiàn)在廣泛應(yīng)用的虛擬化、云、Linux、Windows等,無(wú)愧于“現(xiàn)代操作系統(tǒng)”的名稱。

亮點(diǎn):

  • 抽象是管理復(fù)雜性的一個(gè)關(guān)鍵,好的抽象可以把一個(gè)幾乎不可能管理的任務(wù)劃分為兩個(gè)可管理的部分,其一是抽象的定義與實(shí)現(xiàn),其二是用這些抽象解決問(wèn)題。操作系統(tǒng)就是把硬件丑陋的接口轉(zhuǎn)換為一個(gè)良好、清晰、優(yōu)雅、一致的抽象。最為人熟知的抽象就是“文件”,它統(tǒng)一了各種格式的數(shù)據(jù)、各種IO設(shè)備對(duì)于用戶的接口(操作系統(tǒng)3大抽象:文件,進(jìn)程與線程,地址空間,分別對(duì)應(yīng)磁盤,處理器,內(nèi)存)??梢园巡僮飨到y(tǒng)理解為一個(gè)資源管理者,管理硬件資源如何分配給應(yīng)用程序,讓應(yīng)用程序更好地使用這些資源
  • 技術(shù)的變化會(huì)導(dǎo)致某些思想迅速過(guò)時(shí),但是也可能使得另一種是思想復(fù)活,當(dāng)技術(shù)的變化影響了系統(tǒng)內(nèi)部不同組件的相對(duì)性能之時(shí)就更是如此。比如早期計(jì)算機(jī)指令由硬件直接執(zhí)行,微程序設(shè)計(jì)出現(xiàn)后采用解釋執(zhí)行,RISC又采用了直接執(zhí)行,java又采用了解釋執(zhí)行,這樣來(lái)回?cái)[動(dòng)主要是因?yàn)閳?zhí)行速度不總是關(guān)鍵因素,還有可能是網(wǎng)絡(luò)延遲。再比如計(jì)算服務(wù)過(guò)時(shí)了,但是又以云計(jì)算的形式重新流行,所以對(duì)待技術(shù)要保持客觀、辯證的態(tài)度,不要因?yàn)楝F(xiàn)在看起來(lái)過(guò)時(shí)就對(duì)它唾棄,說(shuō)不定將來(lái)它又能流行起來(lái)發(fā)揮大的作用
  • 有了進(jìn)程還要線程的原因:邏輯上,一個(gè)應(yīng)用中本身可以劃分為多個(gè)活動(dòng),一個(gè)活動(dòng)一個(gè)線程便于理解;線程更輕量級(jí),容易創(chuàng)建、撤銷;若存在大量IO處理,多線程彼此重疊進(jìn)行是可以提升吞吐量的(若每個(gè)線程都是CPU密集型則不能);多線程可以真正利用多核。
  • 都知道java有偏向鎖、輕量級(jí)鎖、重量級(jí)鎖的升級(jí),實(shí)際上操作系統(tǒng)也有類似鎖的概念,而且Linux還采取了“Futex”這個(gè)方案來(lái)結(jié)合自旋鎖和重量級(jí)鎖(阻塞)的優(yōu)點(diǎn)。一個(gè)Futex包含兩部分:一個(gè)內(nèi)核服務(wù)和一個(gè)用戶庫(kù),簡(jiǎn)單說(shuō)來(lái)就是在用戶態(tài)創(chuàng)建一個(gè)futex同步變量,當(dāng)有進(jìn)程要獲得鎖時(shí),對(duì)futex執(zhí)行\(zhòng)”down\”操作即原子性的給futex同步變量減1,如果成功即可繼續(xù)不需進(jìn)入內(nèi)核態(tài),否則進(jìn)入內(nèi)核態(tài)阻塞,這樣就大大減少了低競(jìng)爭(zhēng)時(shí)的吞吐量
  • 通過(guò)交換技術(shù),系統(tǒng)可以同時(shí)運(yùn)行超過(guò)實(shí)際內(nèi)存大小的多個(gè)進(jìn)程;現(xiàn)代計(jì)算機(jī)都使用某種虛擬內(nèi)存技術(shù),每個(gè)進(jìn)程地址被分為同樣大小的頁(yè)面(通常4、8KB),可以被放入空閑內(nèi)存的任何頁(yè)框內(nèi),有多種頁(yè)面置換算法,實(shí)際應(yīng)用中用的最多的是老化算法和工作集時(shí)鐘算法;如果在執(zhí)行過(guò)程中有大小變化的數(shù)據(jù)結(jié)構(gòu)可以采用分段的方法,但是幾乎沒(méi)有主流的操作系統(tǒng)考慮分段算法
  • 文件系統(tǒng)的存儲(chǔ)區(qū)分配方案有連續(xù)文件、鏈表、文件分配表和iNode。磁盤空間可以通過(guò)位圖的空閑表來(lái)管理。提升文件系統(tǒng)性能的做法有高速緩存、預(yù)讀取、以及盡可能將一個(gè)文件的塊放在一起等方法
  • 操作系統(tǒng)除了負(fù)責(zé)提供抽象還要負(fù)責(zé)管理所有IO,IO主要有三種方式實(shí)現(xiàn):程序控制IO、中斷驅(qū)動(dòng)IO、DMA
  • 死鎖發(fā)生有四個(gè)條件:互斥條件、占有和等待條件、不可搶占條件、環(huán)路等待;解決辦法有四個(gè):鴕鳥對(duì)策、死鎖檢測(cè)與恢復(fù)、合理資源分配動(dòng)態(tài)避免死鎖、通過(guò)破壞引起死鎖發(fā)生的四個(gè)必要條件之一來(lái)防止死鎖發(fā)生
  • 虛擬化的好處:可以在節(jié)省硬件與電力資源的情況下實(shí)現(xiàn)強(qiáng)隔離性、使得各個(gè)應(yīng)用程序很容易擁有自己的運(yùn)行環(huán)境、設(shè)置檢查點(diǎn)和虛擬機(jī)遷移比在普通操作系統(tǒng)中容易的多,目前虛擬化最重要的用途就是云
  • 編寫操作系統(tǒng)不容易,那么從何入手呢?從對(duì)外接口開始,三大原則:簡(jiǎn)單,不是當(dāng)沒(méi)什么東西可以添加而是當(dāng)沒(méi)什么東西可以減少時(shí)才能達(dá)到盡善盡美,或者說(shuō)KISS原則;完備,完事應(yīng)該簡(jiǎn)單,但是不能過(guò)于簡(jiǎn)單,必須要能完成用戶所需的一切事情;效率,如果功能不能有效實(shí)現(xiàn)那就不值得擁有這個(gè)功能。這些原則對(duì)于我們所有的系統(tǒng)設(shè)計(jì)都有借鑒意義

這本書的字真是太多了,也太小了,吐槽一下印刷,此外,內(nèi)容也很細(xì)很全,還是應(yīng)該采取先觀其大略、使用時(shí)細(xì)讀的策略。

大規(guī)模分布式存儲(chǔ)系統(tǒng)

大規(guī)模分布式存儲(chǔ)系統(tǒng) (豆瓣): https://book.douban.com/subject/25723658/

看了許多分布式概念性的書籍,也了解了java中間件、分布式一致性、ZooKeeper作為基礎(chǔ)設(shè)施等等概念,是時(shí)候找個(gè)具體的方向了解分布式了,那么這本書就是分布式在存儲(chǔ)這一塊的具體實(shí)戰(zhàn)了。本書從概念到實(shí)戰(zhàn),講了分布式文件、鍵值系統(tǒng)、表格系統(tǒng)、數(shù)據(jù)庫(kù)等等,幾乎覆蓋了所有涉及存儲(chǔ)的方向,看完就能對(duì)分布式存儲(chǔ)有一個(gè)較為完整的了解了。

亮點(diǎn):

  • 分布式存儲(chǔ)有幾個(gè)特性:可擴(kuò)展(容易擴(kuò)展到幾百幾千臺(tái)集群規(guī)模,且性能隨數(shù)量線性增長(zhǎng))、低成本(構(gòu)建于普通PC機(jī)之上)、高性能、易用(提供易用的對(duì)外接口);主要挑戰(zhàn)在于數(shù)據(jù)分布均勻、數(shù)據(jù)一致性、容錯(cuò)性、負(fù)載均衡、事務(wù)并發(fā)與控制、易用性、壓縮解壓縮;數(shù)據(jù)分為非結(jié)構(gòu)化數(shù)據(jù)(圖、文)、結(jié)構(gòu)化數(shù)據(jù)(關(guān)系數(shù)據(jù)庫(kù))、半結(jié)構(gòu)化數(shù)據(jù)(HTML);不同的存儲(chǔ)系統(tǒng)適合不同的數(shù)據(jù)類型,分布式文件系統(tǒng)主要存儲(chǔ)Blob對(duì)象(文檔、圖片、視頻)等非結(jié)構(gòu)化數(shù)據(jù)和作為其他分布式系統(tǒng)的基礎(chǔ),分布式鍵值系統(tǒng)存儲(chǔ)簡(jiǎn)單的半結(jié)構(gòu)化數(shù)據(jù),分布式表格存儲(chǔ)復(fù)雜的半結(jié)構(gòu)化數(shù)據(jù),分布式數(shù)據(jù)庫(kù)存儲(chǔ)結(jié)構(gòu)化數(shù)據(jù)
  • 設(shè)計(jì)網(wǎng)絡(luò)系統(tǒng)的基本原則是:網(wǎng)絡(luò)永遠(yuǎn)是不可靠的,任何一個(gè)消息只有收到對(duì)方回復(fù)后才可認(rèn)為發(fā)送成功,系統(tǒng)設(shè)計(jì)時(shí)總是假設(shè)網(wǎng)絡(luò)將會(huì)出現(xiàn)異常并采取相應(yīng)處理措施(但是我們必須假設(shè)信道是可靠的,不然任何工作于其之上的任何協(xié)議都不能是可靠的)
  • 分布式系統(tǒng)在CAP理論的C和A之間權(quán)衡時(shí)可以參照Oracle的DataGuard復(fù)制組件的三種模式:最大保護(hù)模式(亦即強(qiáng)同步模式,主庫(kù)先將操作日志同步到至少一個(gè)備庫(kù)才能返回給客戶端成功結(jié)果),應(yīng)用于余額等關(guān)鍵記錄;最大性能模式(亦即異步復(fù)制,主庫(kù)完成執(zhí)行就返回客戶端,將重做日志以異步的方式復(fù)制到備庫(kù)),應(yīng)用于用戶操作日志等非關(guān)鍵記錄;最大可用性模式(上述兩種模式的折中,正常情況相當(dāng)于最大保護(hù)模式,當(dāng)主備之間的網(wǎng)絡(luò)出現(xiàn)故障切換為最大性能模式),應(yīng)用于一般記錄
  • 故障檢測(cè)可以通過(guò)心跳檢測(cè)來(lái)做,這是最原始的想法,但是機(jī)器也可能因?yàn)樘?,或者與控制節(jié)點(diǎn)的網(wǎng)絡(luò)斷掉而無(wú)法進(jìn)行心跳,這種情況下使用時(shí)鐘同步(需要考慮一個(gè)時(shí)間提前量,因?yàn)闀r(shí)鐘并不能嚴(yán)格一致一般都會(huì)有小于1秒的微小誤差)加租約(Lease)的形式可以較好地避免這個(gè)問(wèn)題
  • 跨機(jī)房部署有三種方案:集群整體切換(實(shí)際最常見(jiàn)做法,兩個(gè)機(jī)房保持獨(dú)立,保持相同的副本數(shù),有主備之分(Primary,Secondary),可能強(qiáng)同步或者異步復(fù)制),單個(gè)集群跨機(jī)房(不同數(shù)據(jù)分片的主副本位于不同機(jī)房)、Paxos選主副本(每個(gè)數(shù)據(jù)分片的多個(gè)副本構(gòu)成一個(gè)Paxos復(fù)制組,自動(dòng)選舉主副本,降低了對(duì)總控節(jié)點(diǎn)的依賴但是工程復(fù)雜度很高)。
  • GFS成功的經(jīng)驗(yàn)表明:?jiǎn)蜯aster的設(shè)計(jì)是可行的,不僅簡(jiǎn)化了系統(tǒng),而且能較好地實(shí)現(xiàn)一致性。這是一種中心化的架構(gòu),是目前互聯(lián)網(wǎng)的主流架構(gòu),而去中心化的Gossip協(xié)議雖然借著Cassandra(Amazon的Dynamo的開源實(shí)現(xiàn))大火了一把,但是由于其復(fù)雜性與一致性問(wèn)題實(shí)際上分布式系統(tǒng)很少使用
  • OceanBase是一款可擴(kuò)展的關(guān)系型數(shù)據(jù)庫(kù)(支持強(qiáng)一致性和跨表事務(wù)),主要架構(gòu)分內(nèi)四部分:RootServer一主一備,主備強(qiáng)同步,負(fù)責(zé)集群管理,數(shù)據(jù)分布以及副本管理;UpdateServer一主一備,主備同步模式可配置,接受寫操作,并且定期把新數(shù)據(jù)同步給Chunkserver;ChunkServer存儲(chǔ)基線數(shù)據(jù),只提供讀取服務(wù),并定期接受UpdateServer的數(shù)據(jù)同步;MergeServer解析用戶Mysql兼容請(qǐng)求,將請(qǐng)求轉(zhuǎn)發(fā)給對(duì)應(yīng)的ChunkServer和UpdateServer,無(wú)狀態(tài),類似于網(wǎng)關(guān)的作用
  • OceanBase寫操作強(qiáng)一致性的原理是:UpdateServer將redo日志發(fā)送給備機(jī),redo日志寫到本地磁盤,redo日志應(yīng)用到主機(jī)內(nèi)存表,返回客戶端成功。這樣即使主備機(jī)切換也能保證新的主機(jī)有以前所有的操作記錄而不會(huì)丟失,可以通過(guò)增加備機(jī)數(shù)量來(lái)提高可用性保證。當(dāng)然UpdateServer主備同步也支持異步模式,支持最終一致性,一般用來(lái)實(shí)現(xiàn)異地容災(zāi)。此外主備集群也可以實(shí)現(xiàn)錯(cuò)峰合并
  • OceanBase借助UpdateServer邏輯單點(diǎn)來(lái)實(shí)現(xiàn)強(qiáng)一致性,那么這個(gè)單點(diǎn)會(huì)不會(huì)成為瓶頸呢?一般來(lái)說(shuō),互聯(lián)網(wǎng)業(yè)務(wù)讀寫比都比較高,所以不會(huì)成為瓶頸,即使是雙十一這種,也可以通過(guò)自動(dòng)凍結(jié)內(nèi)存表轉(zhuǎn)入SSD硬盤、定期合并與分發(fā)、旁路導(dǎo)入、多塊網(wǎng)卡配置、RAID卡緩存模塊、成組提交等優(yōu)化方式來(lái)避免內(nèi)存、網(wǎng)絡(luò)、磁盤的瓶頸;通過(guò)主備強(qiáng)一致備份策略與實(shí)時(shí)同步避免單點(diǎn)故障,這樣這個(gè)單點(diǎn)問(wèn)題就幾乎不存在了
  • 列式存儲(chǔ)的主要目的有兩個(gè):大部分OLAP只需要讀取部分列而不是全部列數(shù)據(jù),列式存儲(chǔ)可以避免讀取無(wú)用數(shù)據(jù);將同一列的數(shù)據(jù)在物理上存放在一起,能夠極大的提高數(shù)據(jù)壓縮率
  • 大表左連接是互聯(lián)網(wǎng)的一個(gè)常見(jiàn)問(wèn)題,一般采取引用(多表主鍵連接)、或者嵌套(主表冗余連表信息),但是這分別只能適應(yīng)讀取次數(shù)少、讀寫比較高的場(chǎng)景,如果讀取次數(shù)多且讀寫比不高那么這兩種做法就沒(méi)轍了。OceanBase采用基線數(shù)據(jù)冗余連表 修改增量合并的方式解決了這個(gè)問(wèn)題

看完這本書是真的很有收獲,對(duì)整個(gè)分布式架構(gòu)有了一個(gè)完整的了解,從大大的跨機(jī)房到一個(gè)小小的數(shù)據(jù)分片副本,從上到下非常清晰。此外最佳實(shí)踐那一部分也是很贊的,強(qiáng)烈推薦此書。

微服務(wù)設(shè)計(jì)

微服務(wù)設(shè)計(jì) (豆瓣): https://book.douban.com/subject/26772677/

微服務(wù)最近兩年越來(lái)越火,其實(shí)這并不是什么新鮮概念,計(jì)算機(jī)體系里面早就有單內(nèi)核與微內(nèi)核的架構(gòu)思想了,微服務(wù)也是一種類似的思想,但是是處于更高級(jí)別的應(yīng)用架構(gòu)層(所以計(jì)算機(jī)領(lǐng)域里面的許多思想是可以相互借鑒的比如抽象、緩存、LRU算法、并行處理等等)。微服務(wù)的好處是很多的,單個(gè)服務(wù)容易開發(fā)、理解和維護(hù);容納異構(gòu)技術(shù);部署簡(jiǎn)單、迭代速度快、變化小bug少;彈性、擴(kuò)展性好等等。本書就帶領(lǐng)我們從建模、集成、測(cè)試到部署和監(jiān)控,全面了解微服務(wù),為進(jìn)一步學(xué)習(xí)指引方向。

亮點(diǎn):

  • 微服務(wù)是一種分布式系統(tǒng)解決方案,推動(dòng)細(xì)粒度服務(wù)的使用,這些小而自治的服務(wù)協(xié)同工作,都有自己的生命周期,圍繞業(yè)務(wù)領(lǐng)域建模,根據(jù)業(yè)務(wù)的邊界來(lái)確定服務(wù)的邊界,因此也很容易確定某個(gè)功能代碼的位置,避免了傳統(tǒng)分層架構(gòu)的許多問(wèn)題。一個(gè)微服務(wù)就是一個(gè)實(shí)體,不同微服務(wù)通過(guò)網(wǎng)絡(luò)通信互相調(diào)用。我們知道,直接進(jìn)程內(nèi)方法調(diào)用是很快,但是也意味著兩個(gè)對(duì)象緊密耦合了,通過(guò)網(wǎng)絡(luò)通信調(diào)用雖然慢一些,但是兩個(gè)對(duì)象就松耦合了,可以隨時(shí)替換掉一個(gè)而另一個(gè)完全不用知道,我覺(jué)得隨著網(wǎng)速越來(lái)越快,網(wǎng)絡(luò)通信代價(jià)越來(lái)越小,微服務(wù)的優(yōu)勢(shì)將越來(lái)越明顯,直接耦合調(diào)用的方式的優(yōu)勢(shì)將越來(lái)越弱
  • 架構(gòu)師就類似于城市規(guī)劃師應(yīng)該專注于大方向,只能參與少量細(xì)節(jié),需要保證系統(tǒng)能滿足當(dāng)前的需求,還要能夠應(yīng)對(duì)將來(lái)的變化,以一種演化的方式來(lái)進(jìn)行規(guī)劃,這是一個(gè)很大的標(biāo)準(zhǔn),從何入手呢?答案是:分區(qū),定好服務(wù)邊界與交互方式,可以使用限界上下文。演化的方式就是我們要理解,隨著項(xiàng)目發(fā)展,服務(wù)一定會(huì)越來(lái)越大,我們要做的就是讓架構(gòu)增量變化,在拆分這件事變得過(guò)分昂貴之前進(jìn)行拆分
  • 重用代碼可能引入危險(xiǎn),因?yàn)槲覀兛赡芤敕?wù)之間的耦合。所以雖然我們要做到DRY原則,但是也要防止過(guò)度追求DRY原則帶來(lái)的系統(tǒng)過(guò)度耦合,這是一個(gè)比較微妙的話題,要記住,DRY不是意味著避免重復(fù)的代碼,而是意味著避免系統(tǒng)行為和知識(shí)的重復(fù),在微服務(wù)內(nèi)部不要違反DRY,跨服務(wù)時(shí)可以適當(dāng)違反來(lái)避免服務(wù)之間耦合
  • 處理跨服務(wù)的業(yè)務(wù)流程時(shí)可以選擇:編排,一個(gè)中心節(jié)點(diǎn)調(diào)度其他所有服務(wù)完成,這樣流程很清晰,但是會(huì)導(dǎo)致中心節(jié)點(diǎn)承擔(dān)過(guò)多,其它服務(wù)淪為貧血的基于CURD的服務(wù);協(xié)同,相關(guān)服務(wù)訂閱特定的事件,事件由客戶端觸發(fā)之后每個(gè)服務(wù)各自完成自己的處理,這樣能明顯消除耦合,但是就看不到明顯的流程圖了,而且可能需要跨服務(wù)監(jiān)控,但是總體而言傾向于協(xié)同,利大于弊
  • 真正的持續(xù)集成要理解3個(gè)問(wèn)題:是否每天簽入代碼到主線?是否有一組測(cè)試來(lái)驗(yàn)證修改?構(gòu)件失敗過(guò)后是否把修復(fù)CI當(dāng)做第一要?jiǎng)?wù)?最好是每一個(gè)微服務(wù)都有自己的代碼庫(kù)和CI,只有這樣才能真正實(shí)現(xiàn)獨(dú)立部署
  • 微服務(wù)部署最好采用單主機(jī)(可以是物理主機(jī)、虛擬機(jī)、容器)單服務(wù)的方式,這樣利于團(tuán)隊(duì)自治、服務(wù)部署、監(jiān)控、故障排查、擴(kuò)展性更好等,但是這個(gè)模式會(huì)引入大量主機(jī),這就意味著重復(fù)勞動(dòng)會(huì)多起來(lái),所以我們一定要實(shí)現(xiàn)自動(dòng)化(不管什么技術(shù)棧都要追求自動(dòng)化)
  • 自動(dòng)化測(cè)試類型分為單元測(cè)試、服務(wù)測(cè)試、用戶測(cè)試(端到端測(cè)試)。其中單元測(cè)試是針對(duì)一個(gè)函數(shù)的、面向技術(shù)、幫助開發(fā)人員快速發(fā)現(xiàn)錯(cuò)誤和增加重構(gòu)信心;服務(wù)測(cè)試針對(duì)一系列函數(shù)構(gòu)成的完整服務(wù),提高測(cè)試隔離性,幫助快速定位問(wèn)題;端到端測(cè)試包含整個(gè)系統(tǒng),增強(qiáng)我們發(fā)布服務(wù)的信心。這三者的比例最好是前者比后者多一個(gè)數(shù)量級(jí)
  • 監(jiān)控固然要看低層指標(biāo)比如CPU利用率、空閑內(nèi)存、帶寬使用等等,但是這些指標(biāo)往往太多而帶來(lái)噪聲不利于監(jiān)控我們真正關(guān)心的行為,所以需要語(yǔ)義監(jiān)控,亦即準(zhǔn)備一些合成數(shù)據(jù)和事件來(lái)觀察系統(tǒng)是否按照我們的期望完成任務(wù),當(dāng)然這些數(shù)據(jù)要注意不能和真實(shí)生產(chǎn)數(shù)據(jù)混淆
  • 任何組織在設(shè)計(jì)一套系統(tǒng)時(shí),所交付的方案在結(jié)構(gòu)上都與該組織的溝通結(jié)構(gòu)一致。這被稱為康威定律
  • 構(gòu)建分布式系統(tǒng)需要思維的轉(zhuǎn)變,那就是故障總會(huì)出現(xiàn),不是所有人都需要像Google或者Netflix一樣使用ChaosMonkey來(lái)模擬故障測(cè)試系統(tǒng)的健壯性,但是我們都需要為各種故障做好準(zhǔn)備比如:超時(shí)(設(shè)置默認(rèn)超時(shí)并記錄日志)、斷路器(請(qǐng)求失敗一定次數(shù)后斷路器打開,下次快速失敗就不用再等待了)、艙壁(服務(wù)內(nèi)外都可以使用,關(guān)注點(diǎn)分離,為每個(gè)下游單獨(dú)準(zhǔn)備連接池)、隔離

PS:書中提到了不少參考書,都是可以看看的。

算法(第4版)

算法(第4版) (豆瓣) https://book.douban.com/subject/19952400/

本書講解的算法和數(shù)據(jù)結(jié)構(gòu)都是我們必須掌握的,屬于入門級(jí)知識(shí),但是作者講的很仔細(xì),很有趣,沒(méi)有那么多的數(shù)學(xué)證明,比《算法導(dǎo)論》讀起來(lái)跟容易一些,但是作者的觀點(diǎn)也都是立得住的,有理有據(jù),值得通看,形成自己對(duì)于算法的初步體系。

亮點(diǎn):

  • 本書提供了所有代碼還有教學(xué)視頻,可以輔助學(xué)習(xí),網(wǎng)址。我把代碼fork了一份,在這
  • 本書對(duì)算法性能的分析是科學(xué)式的,亦即先對(duì)性能提出假設(shè),建立數(shù)學(xué)模型,然后用多種實(shí)驗(yàn)驗(yàn)證它們,必要時(shí)重復(fù)這個(gè)過(guò)程
  • API的目的是將調(diào)用和實(shí)現(xiàn)分離(模塊化編程),可以將API看做調(diào)用和實(shí)現(xiàn)之間的一份契約,他詳細(xì)說(shuō)明了每個(gè)方法的作用,實(shí)現(xiàn)的目標(biāo)就是遵守這份契約。讀到這里就有一個(gè)感想,我們程序的進(jìn)步都是在努力地把人為的契約固化到代碼中,減少出錯(cuò)概率。比如程序員之間直接約定不夠可靠,那么就通過(guò)接口來(lái)強(qiáng)制約定;再比如生產(chǎn)與開發(fā)環(huán)境不容易保持一致,就通過(guò)DockerFile來(lái)強(qiáng)制約定
  • 作者循循善誘,為了給我們分析算法性能提供動(dòng)力,講了一個(gè)3-sum問(wèn)題的逐步優(yōu)化過(guò)程:暴力的3-sum是一個(gè)立方級(jí)別的算法,先從簡(jiǎn)單的情況考慮2-sum,通過(guò)線性對(duì)數(shù)級(jí)別的排序,然后用對(duì)數(shù)級(jí)別的二分查找一個(gè)元素的相反數(shù)來(lái)進(jìn)行統(tǒng)計(jì),這個(gè)算法就是線性對(duì)數(shù)級(jí)別的,然后自然擴(kuò)展到3-sum,得到平方對(duì)數(shù)級(jí)別的快速的3-sum,并查集也是類似循序漸進(jìn)的教法
  • 初級(jí)算法雖然簡(jiǎn)單,但是它幫我們建立了一些基本規(guī)則,展示了一些性能基準(zhǔn),在某些特殊情況下也是很好的選擇,也是開發(fā)更強(qiáng)大的算法的基礎(chǔ),所以仍有必要系統(tǒng)的學(xué)習(xí)它們
  • 把排序算法講了一遍之后,講到了規(guī)約(為了解決某個(gè)問(wèn)題而發(fā)明的算法可以解決另一個(gè)問(wèn)題),比如排序就可以用了解決很多其他問(wèn)題,一般能將暴力的平方級(jí)別解法下降到非暴力的線性對(duì)數(shù)級(jí)別,比如:找出重復(fù)元素、排名、優(yōu)先隊(duì)列、中位數(shù)、第K個(gè)最小/大的值(模仿快速排序的partition操作就能達(dá)到線性級(jí)別)等
  • 散列表的意義是在時(shí)間與空間之間取得一個(gè)平衡,選擇適當(dāng)大小的數(shù)組M,既不會(huì)因?yàn)榭真湵碓斐蓛?nèi)存浪費(fèi)也不會(huì)因?yàn)殒湵硖L(zhǎng)而導(dǎo)致查找效率低
  • 書中對(duì)于圖的表述中,深度優(yōu)先等遍歷方式都給出了詳細(xì)的算法與示例的軌跡圖,你想看不懂都難
  • 就解決圖的連通性問(wèn)題,理論上來(lái)說(shuō),深度優(yōu)先比union-find(聯(lián)合查找或者說(shuō)并查集)更快,但是實(shí)際上union-find更快,因?yàn)樗恍枰獙?duì)圖進(jìn)行預(yù)處理,是一種動(dòng)態(tài)的算法(能用接近常數(shù)的時(shí)間檢查兩點(diǎn)是否相通,甚至是添加邊),而對(duì)于已經(jīng)是圖的數(shù)據(jù)類型使用深度優(yōu)先更快,因?yàn)樗芾靡阎畔?/li>
  • 用于子串查找的KMP算法的基本思想是,當(dāng)文本出現(xiàn)不匹配時(shí)就能知曉一部分文本內(nèi)容,可以利用這些信息避免將指針會(huì)退到所有這些已知字符之前,亦即充分利用已知信息,這也是插入排序優(yōu)于選擇排序的原因。KMP主要亮點(diǎn)是提前判斷如何重新開始查找,這種判斷不需要文本指針i完全回退,只需根據(jù)模式本身信息重新進(jìn)行比較位置的選擇
  • 許多問(wèn)題都可以規(guī)約為排序問(wèn)題(中位數(shù)、不同值統(tǒng)計(jì))、最短路徑問(wèn)題(任務(wù)調(diào)度、套匯)、最大流量問(wèn)題(就業(yè)安置、網(wǎng)絡(luò)可靠性)、線性規(guī)劃(最大流量)
  • NP是所有搜索問(wèn)題(有解且驗(yàn)證解的正確性的時(shí)間不會(huì)超過(guò)輸入規(guī)模的多項(xiàng)式的問(wèn)題)的集合;P是能夠在多項(xiàng)式時(shí)間內(nèi)解決的所有搜索問(wèn)題的集合

本書的java基礎(chǔ)部分是相當(dāng)?shù)呢S富,學(xué)完算法也可以順帶復(fù)習(xí)一遍java了,很劃算 (* ̄︶ ̄)。

還有,本書雖厚,但是一定要看完,這樣才有一個(gè)完整的體系,并且算法的細(xì)節(jié)也能掌握了,之所以不采取往常對(duì)待大部頭的觀其大略的方法是因?yàn)檫@是算法,是經(jīng)常需要我們實(shí)施的領(lǐng)域,和代碼編寫直接相關(guān)(不像操作系統(tǒng)的知識(shí)),所以必須掌握細(xì)節(jié)??梢詤⒁?jiàn)我的另外幾篇專門講算法的博客

Hadoop權(quán)威指南

Hadoop權(quán)威指南(第3版) (豆瓣): https://book.douban.com/subject/26206050/

Hadoop的出現(xiàn)開啟了大數(shù)據(jù)的序幕,到了現(xiàn)在已經(jīng)成為一個(gè)比較完善的生態(tài),服務(wù)于云計(jì)算與大數(shù)據(jù)。記得大三的時(shí)候?qū)W校有免費(fèi)的云服務(wù)器,我申請(qǐng)了5臺(tái)自己搭建了一個(gè)Hadoop集群跑了一下 Hello World 級(jí)別的 Word Count,然后就開始期末考試了,沒(méi)有再繼續(xù)深入了解,現(xiàn)在是時(shí)候全面的了解一下了,這本書號(hào)稱權(quán)威指南,看它沒(méi)錯(cuò)。

亮點(diǎn):

  • MapReduce相對(duì)于其他系統(tǒng)的優(yōu)勢(shì):比RDBMS更適合一次寫入多次讀取的任務(wù),適合批處理任務(wù),是一種線性可伸縮的編程模型;因?yàn)楸M量做到數(shù)據(jù)本地存儲(chǔ),所以比網(wǎng)格計(jì)算(帶寬限制,只適宜CPU密集型任務(wù))更能處理巨量數(shù)據(jù)的任務(wù),同時(shí)處理CPU密集型任務(wù)也不弱;比志愿計(jì)算(貢獻(xiàn)CPU而非帶寬)更可靠,更易實(shí)施,更好控制
  • HDFS是Hadoop的旗艦級(jí)文件系統(tǒng),但是Hadoop也能集成其它文件系統(tǒng)如S3,HDFS設(shè)計(jì)要點(diǎn):超大文件、流式數(shù)據(jù)訪問(wèn)、商用硬件(零售店可買)、低延遲訪問(wèn)不太適用(HBASE更佳)、大量的小文件、僅支持單用戶寫入且不能隨機(jī)寫
  • 分布式文件系統(tǒng)的塊(chunk)抽象有許多好處:一個(gè)文件可以大于任意磁盤的容量(因?yàn)闊o(wú)需把一個(gè)文件存在一個(gè)磁盤上);抽象塊簡(jiǎn)化了存儲(chǔ)設(shè)計(jì)(塊大小固定,默認(rèn)64MB磁盤性能越好越大,故每塊盤能存多少塊是固定的,而且元數(shù)據(jù)也可以單獨(dú)管理);適合數(shù)據(jù)備份,從而提高容錯(cuò)能力和可用性(每一塊可以復(fù)制到多個(gè)機(jī)器上,默認(rèn)是3個(gè),如果塊、磁盤或機(jī)器發(fā)生故障系統(tǒng)會(huì)從其他機(jī)器讀取副本,此過(guò)程對(duì)用戶透明。而且多個(gè)副本可以提高讀取性能)
  • HDFS 有兩種節(jié)點(diǎn),一個(gè)namenode作為管理者,管理整個(gè)文件系統(tǒng)的命名空間,維護(hù)整個(gè)文件系統(tǒng)樹及其文件與目錄,同時(shí)也記錄著每個(gè)文件中各個(gè)塊所在的數(shù)據(jù)節(jié)點(diǎn)信息,namenode至關(guān)重要必須正常運(yùn)行,所以提供了兩種容錯(cuò)機(jī)制,實(shí)時(shí)同步元數(shù)據(jù)至其它地方和運(yùn)行輔助namenode;多個(gè)datanode作為實(shí)際工作者,存儲(chǔ)數(shù)據(jù)塊供讀寫并定期向namenode發(fā)送存儲(chǔ)的塊的列表
  • YARN將JobTracker劃分為多個(gè)職能的實(shí)體(資源管理器和應(yīng)用管理器),改善了經(jīng)典的MapReduce面臨的擴(kuò)展性問(wèn)題,實(shí)際上比MapReduce更具一般性,MapReduce只是YARN應(yīng)用的一種形式,有很多其他的YARN應(yīng)用如分布式shell
  • MapReduce提供了計(jì)數(shù)器(統(tǒng)計(jì)無(wú)效數(shù)據(jù))、排序、連接(join操作,將兩個(gè)數(shù)據(jù)集合二為一)、邊數(shù)據(jù)分布(配置額外的只讀數(shù)據(jù)來(lái)完成作業(yè))、MapReduce庫(kù)類等常見(jiàn)功能
  • 部署hadoop時(shí)典型配置是同一個(gè)機(jī)架有一些節(jié)點(diǎn),不同機(jī)架通過(guò)交換機(jī)連接起來(lái)的二級(jí)網(wǎng)絡(luò)架構(gòu)。因?yàn)闄C(jī)架內(nèi)部通信更快所以一定要把這些配置告訴Hadoop系統(tǒng),這樣分配MapReduce任務(wù)時(shí)會(huì)傾向于機(jī)架內(nèi)節(jié)點(diǎn),節(jié)省傳輸成本,同時(shí)HDFS的文件塊的3個(gè)副本也會(huì)盡量分布在兩個(gè)機(jī)架上
  • Pig是一種探索大規(guī)模數(shù)據(jù)集的腳本語(yǔ)言,省去MapReduce繁瑣耗時(shí)的步驟(寫mapper、reducer,代碼編譯,打包,提交作業(yè)),僅需控制臺(tái)的幾行pig Latin代碼就能處理TB級(jí)別的數(shù)據(jù),而且支持更豐富的數(shù)據(jù)結(jié)構(gòu)
  • Hive能把SQL查詢轉(zhuǎn)換為一些列運(yùn)行在Hadoop上運(yùn)行的MapReduce作業(yè),它把數(shù)據(jù)組織為表,通過(guò)這種方式為HDFS中的數(shù)據(jù)賦予結(jié)構(gòu)。Hive與傳統(tǒng)數(shù)據(jù)庫(kù)有很多類似之處(如SQL語(yǔ)言的支持,尤其類似于Mysql),但是其底層依賴于HDFS和MapReduce而非傳統(tǒng)的文件系統(tǒng),Hive采用讀時(shí)模式(查詢時(shí)進(jìn)行模式檢查)而非寫時(shí)模式(寫入時(shí)檢查模式)可以使得數(shù)據(jù)加載非常迅速,因?yàn)樗皇且苿?dòng)數(shù)據(jù)而不需要讀取、解析、序列化等。寫時(shí)模式有利于提升查詢性能,因?yàn)榭梢越⑺饕?、?shù)據(jù)壓縮等,Hive沒(méi)有考慮過(guò)這些特性(以及事務(wù)、更新、刪除等),因?yàn)镸apReduce下,全表掃描是常態(tài)
  • HBASE是在HDFS上開發(fā)的面向列[族]的分布式數(shù)據(jù)庫(kù),如果需要實(shí)時(shí)的訪問(wèn)超大規(guī)模的數(shù)據(jù)集,就可以使用HBASE。與RDBMS相比,HBASE能解決很多伸縮性問(wèn)題(表可以高達(dá)幾十億行,幾百萬(wàn)列)、能水平分區(qū)并在上千個(gè)普通節(jié)點(diǎn)上自動(dòng)復(fù)制、線性擴(kuò)展與新節(jié)點(diǎn)自動(dòng)處理。RDBMS對(duì)于中小規(guī)模應(yīng)用提供的易用性、靈活性和完整的功能性是幾乎無(wú)可取代的,但是要在數(shù)據(jù)規(guī)模和并發(fā)讀中任意方面向上擴(kuò)展就會(huì)損失很多性能,因?yàn)镽DBMS是面向行的具有ACID和事務(wù)的強(qiáng)一致性等特性,向上擴(kuò)展意味著要打破這些特性,使得管理變得復(fù)雜
  • ZooKeeper一般用來(lái)構(gòu)建分布式服務(wù)具有許多特性:簡(jiǎn)單(核心是一個(gè)精簡(jiǎn)的文件系統(tǒng))、豐富(提供分布式隊(duì)列、鎖、領(lǐng)導(dǎo)選舉等功能)、高可用(運(yùn)行于一組機(jī)器,避免單點(diǎn)故障)、松耦合交互(參與者不必互相了解)、資源庫(kù)(提供通用協(xié)調(diào)模式的開源共享庫(kù))

本書作為了解Hadoop的設(shè)計(jì)思想以及關(guān)鍵點(diǎn)的手段,我尚未進(jìn)入真正的使用,很多代碼以及API部分就省略沒(méi)看了,所以雖然是個(gè)大部頭,但是看起來(lái)并不會(huì)特別慢。當(dāng)然如果真的要使用,書中的接口和代碼可能就已經(jīng)過(guò)時(shí)了,要搭配最新官方文檔來(lái)看

HTTP權(quán)威指南

HTTP權(quán)威指南 (豆瓣): https://book.douban.com/subject/10746113/

Http協(xié)議構(gòu)成了當(dāng)今互聯(lián)網(wǎng)的基石,無(wú)論是瀏覽網(wǎng)頁(yè)還是使用APP都離不開這個(gè)協(xié)議,非常有必要進(jìn)行全面的了解。這本書也是一個(gè)權(quán)威指南,看完就能有一個(gè)完整的概念了,而且本書還講到了許多架構(gòu)方面的經(jīng)驗(yàn),只賺不賠哈哈。

亮點(diǎn):

  • URI 統(tǒng)一資源標(biāo)識(shí)符,在世界范圍唯一標(biāo)志并定位一個(gè)信息資源,包含URL和URN;URL 統(tǒng)一資源定位符,描述一臺(tái)特定服務(wù)器上的某特定資源的位置;URN 統(tǒng)一資源名稱,作為特定內(nèi)容的唯一名稱而與資源所在地?zé)o關(guān)(所以資源可以遷移到另一處而不影響其訪問(wèn),URL就不行)?,F(xiàn)在幾乎所有URI都是URL,URN由于架構(gòu)的缺乏(雖然引入了PURL)和巨大的工程變動(dòng)仍處于試驗(yàn)階段并未廣泛使用
  • HTTP延時(shí)一般都是由TCP延時(shí)造成的(除非是客戶端、服務(wù)端超載或者處理復(fù)雜的動(dòng)態(tài)資源),如果要編寫高性能HTTP程序就要考慮許多的TCP層面的問(wèn)題與解決方案:TCP握手產(chǎn)生的延時(shí)對(duì)于傳輸少量的http報(bào)文而言是巨大的開銷(復(fù)用已有TCP連接);延遲確認(rèn)算法不太適用于HTTP這種雙峰特征的請(qǐng)求響應(yīng)式行為(調(diào)整或禁用這個(gè)算法);慢啟動(dòng)影響新的Http連接的傳輸速度(復(fù)用連接,持久連接);Nagle算法影響小的Http報(bào)文傳輸(可以禁用該算法,TCP_NODELAY);TIME_WAIT累計(jì)與端口耗盡,TIME_WAIT狀態(tài)會(huì)持續(xù)2MSL(如120s)的時(shí)間才會(huì)轉(zhuǎn)換到CLOSE狀態(tài),然后才能創(chuàng)建相同IP和端口的連接(服務(wù)器端口有限,如60000個(gè)),限制了服務(wù)器的連接速率(60000/120=500次每秒),可以增加客戶端負(fù)載生成器的數(shù)量或者虛擬IP
  • 減少Http連接延時(shí)的方法:并行連接(并行執(zhí)行多個(gè)Http事務(wù)),管道化連接(通過(guò)共享的TCP連接發(fā)起請(qǐng)求),復(fù)用連接(交替?zhèn)魉驼?qǐng)求與響應(yīng)報(bào)文),持久連接(由于站點(diǎn)本地性,http事務(wù)結(jié)束后不必馬上釋放TCP連接,因?yàn)楹苡锌赡荞R上又要向該站點(diǎn)發(fā)起請(qǐng)求)。其中持久連接與并行連接搭配可能是最高效的方式
  • web代理連接的是兩個(gè)使用相同協(xié)議的應(yīng)用,而網(wǎng)關(guān)連接的是兩個(gè)或多個(gè)使用不同協(xié)議的端點(diǎn)。所以web代理扮演的是中間人傳輸者的角色(改善安全性、提高性能,比如完成訪問(wèn)控制、防火墻、匿名者、緩存、反向代理負(fù)載均衡、內(nèi)容路由器、轉(zhuǎn)碼器等等),網(wǎng)關(guān)扮演的是協(xié)議轉(zhuǎn)換器的角色(比如PHP-FPM能把Nginx轉(zhuǎn)發(fā)的http請(qǐng)求解析出來(lái)然后調(diào)用php-cgi來(lái)注入?yún)?shù)并執(zhí)行PHP代碼得到結(jié)果然后封裝為http協(xié)議回復(fù)給nginx)
  • 大規(guī)模web爬蟲對(duì)其訪問(wèn)管理(避免重復(fù))用到了一些技術(shù):樹和散列表(加速查找)、有損的位圖(url映射成數(shù)字,url無(wú)限數(shù)字有線所以可能有沖突)、檢查點(diǎn)(已訪問(wèn)URL存入本地)、分類(集群爬蟲通過(guò)通訊來(lái)分配URL,各自爬取部分)、規(guī)范化URL、廣度優(yōu)先爬取、節(jié)流、限制url大小、黑名單、內(nèi)容指紋、人工監(jiān)視等等
  • 內(nèi)容協(xié)商技術(shù)可以使得服務(wù)器把內(nèi)容的不同版本發(fā)送給對(duì)應(yīng)的用戶,主要有3種機(jī)制:客戶端驅(qū)動(dòng)、服務(wù)器驅(qū)動(dòng)、透明。
  • 重定向普遍存在,原因無(wú)非:可靠的執(zhí)行Http事務(wù)(備用節(jié)點(diǎn))、最小化時(shí)延(就近訪問(wèn))、節(jié)約網(wǎng)絡(luò)帶寬(服務(wù)器分散,減少擁塞)。用到的主要技術(shù)有:Http重定向、DNS重定向、任播尋址、IP MAC轉(zhuǎn)發(fā)、IP地址轉(zhuǎn)發(fā)、顯示瀏覽器配置、代理自動(dòng)配置、web Proxy代理自動(dòng)發(fā)現(xiàn)等等

這本書詳細(xì)描述了HTTP協(xié)議的方方面面,而且給出了許多參考,如果我們真的要做一個(gè)完美的Http應(yīng)用,還是值得我們細(xì)細(xì)翻閱的。

相關(guān)新聞

聯(lián)系我們
聯(lián)系我們
公眾號(hào)
公眾號(hào)
在線咨詢
分享本頁(yè)
返回頂部