摘要:后端好書閱讀與推薦系列文章后端好書閱讀與推薦后端好書閱讀與推薦續后端好書閱讀與推薦續二后端好書閱讀與推薦續三后端好書閱讀與推薦續四這里依然記錄一下每本書的亮點與自己讀書心得和體會,分享并求拍磚。
后端好書閱讀與推薦系列文章:
后端好書閱讀與推薦
后端好書閱讀與推薦(續)
后端好書閱讀與推薦(續二)
后端好書閱讀與推薦(續三)
后端好書閱讀與推薦(續四)
這里依然記錄一下每本書的亮點與自己讀書心得和體會,分享并求拍磚。
Docker生產環境實踐指南Docker生產環境實踐指南 (豆瓣) https://book.douban.com/subje...
前面docker的基本概念和一些核心原理都看的差不多了,那么現在該關注一下具體的生產環境的使用方法了。
亮點:
在生產環境中運行docker與在其它環境中相比,最主要的差異是需要在其安全性與穩定性上投入更多的注意力
書中提到docker 容器與宿主機是通過IPtables實現的nat轉換來進行通信,這點官網有說明 Docker container networking,然后就說了不適宜網絡吞吐量有很高要求的應用(但是可以禁用Docker的NAT來提升網絡性能),但是docker已經做出了一些努力,效果并不差,見:1,2,3
書中對于docker相關常見的概念解釋得非常清晰易懂,這一部分尤其適合初學者
docker生產環境最好的方式是將應用程序及其依賴預先打包成一個鏡像,而包含數據庫憑證等銘感信息在運行時動態添加(安全起見);常見流程是開發機上打包并推送到倉庫,然后服務器從倉庫拉取鏡像,這種用例簡單但是從工作流和安全角度看并不理想,更標準的做法是使用持續集成 / 持續交付系統在應用程序代碼或者dockerfile發生變化時自動從新構建鏡像
實現開發速度和生產環境穩定的方法之一是擁抱簡單,亦即系統的每一個部分——容器——有且只有一個目標。系統的簡單需要設計時遵照如下原則:傾向無狀態服務,傾向靜態配置,傾向靜態的網絡布局,區別對待有狀態和無狀態的服務
保持鏡像小巧:可以從空的文件系統開始構建,從類似于busybox、aipine這種輕量級操作系統開始構建,如果嫌包少就可以從主流Linux發行版的容器優化版開始構建,最明智的做法是標準化一個特定的鏡像版本,并盡可能的用于所有容器;盡可能減少層數,也就是相關的命令盡量放到一行,而且下載的內容用完后要在同一行刪除;可以使用docker-squash來減小鏡像體積
存儲鏡像:開源、公共項目建議存共有倉庫;安全性和性能要求較高的存私有倉庫;需要定制的使用save / load。此外,很多人可能不知道,DockerHub其實是提供了自動構建功能的,只要通過WebHook連上Github就行(親測)
一致性是擴展環境和傳播知識的關鍵,所以應該在一個構建系統中構建所有鏡像,而且要實現鏡像標準化,讓所有鏡像(盡可能)繼承于一個標準基礎鏡像
AUFS引擎的掛載速度非常快,能很快的創建新容器所以成為了Docker存儲引擎的默認解決方案。其性能瓶頸主要在需要寫入大文件的場景,因此使用AUFS來存放數據庫文件可能不是一個好主意,同樣太多的鏡像層可能導致文件查找時間過長,所以不要讓自己的文件有太多分層。AUFS有一個最大的問題是沒有被容納到Linux主流發行版。事實上,在生產環境選擇存儲引擎,一個要點是看業務與特性是否吻合,另一個要點就是選最有把握能穩定運維的工具
Docker網絡實現包含三方面內容,IP分配、域名解析、容器或服務發現,這也是零配置網絡的理論基礎。零配置網絡即是一組在沒有人工干預的情況下自動創建和配置一個TCP/IP網絡的技術。
Docker集群之中的服務發現,目前是consul做得最好,可以自定義健康檢查機制,不像zookeeper(和TCP會話周期綁定)和etcd(和TTL值掛鉤),提供了一個非常完備的服務發現解決方案
本書名副其實,對于在生產環境中使用docker有不錯的方向指導意義,當然細節還得自己扣啊。
注意:由于時間原因,書中有些內容有些過時但是譯者給出了注解(但是譯者的注解也可能過時呀,所以一定要自己注意跟蹤docker的最新變化)
The Go Programming Language (豆瓣) https://book.douban.com/subje...
為什么要了解一下 golang 呢?最明顯的原因就是,這個語言有一款殺手級應用,也就是前面說過很多次的:Docker;而且前一段時間 nodejs 的創始人不是要擁抱 go 語言了嗎,作為一個編程語言的創始人轉投另一門語言,還是很值得了解一下的;最后,對 go 的協程是早有耳聞,傳言可以用同步的方式寫出異步的代碼,輕松實現高并發......
亮點:
正如Rob Pike所說,“軟件的復雜性是乘法級相關的”,通過增加一個部分的復雜性來修復問題通常將慢慢地增加其他部分的復雜性。通過增加功能和選項和配置是修復問題的最快的途徑,但是這很容易讓人忘記簡潔的內涵,即使從長遠來看,簡潔依然是好軟件的關鍵因素。秉承著簡潔原則,golang沒有內置大多數語言都有的隱式轉換、宏、異常、繼承等等
依然是簡潔原則的貫徹,golang 不允許 import 沒有使用的包,也不能定義沒有使用的變量,否則連編譯都不能通過。還有左大括號必須和代碼在同一行......感覺這些強制要求非常有用,多一些標準,少一些歧義,這應該是利于工程化的
break 和 continue 都可以加label來實現跳出任一循環,這個有點像 goto 語句,這種語句我們要少用,一般是在編譯器生成代碼過程使用的
并不是所有的詞法域都顯式地對應到由花括弧包含的語句;還有一些隱含的規則。比如for語句創建了兩個詞法域:花括弧包含的是顯式的部分是for的循環體部分詞法域,另外一個隱式的部分則是循環的初始化部分,比如用于迭代變量i的初始化。隱式的詞法域部分的作用域還包含條件測試部分和循環后的迭代部分(i++),當然也包含循環體詞法域
結構體中的匿名成員是一個比較有意思的特點,可以用來無縫的實現“對象組合”這一需求,組合是 go 實現面向對象編程的核心
大部分語言使用固定大小的函數調用棧,常見的大小從64KB到2MB不等。固定大小棧會限制遞歸的深度,當你用遞歸處理大量數據時,需要避免棧溢出;除此之外,還會導致安全性問題。與相反,Go語言使用可變棧,棧的大小按需增加(初始時很小)。這使得我們使用遞歸時不必考慮溢出和安全問題
在Go中,錯誤處理有一套獨特的編碼風格。檢查某個子函數是否失敗后,我們通常將處理失敗的邏輯代碼放在處理成功的代碼之前。如果某個錯誤會導致函數返回,那么成功時的邏輯代碼不應放在else語句塊中,而應直接放在函數體中。Go中大部分函數的代碼結構幾乎相同,首先是一系列的初始檢查,防止錯誤發生,之后是函數的實際邏輯
當defer語句被執行時,跟在defer后面的函數會被延遲執行。直到包含該defer語句的函數執行完畢時,defer后的函數才會被執行,不論包含defer語句的函數是通過return正常結束,還是由于panic導致的異常結束。deferred類似于java的finally,可用于保證資源回收、鎖釋放等
看到第八章終于知道傳言的大概意思了,只需要在原來同步的調用函數的代碼之前加一個 go 關鍵字,就能新建一個goroutine(可以類比線程,但是有不同之處),然后主線程就能繼續干活而不必等待函數執行結束了
線程和goroutine的區別主要有幾方面:goroutine的棧不是固定大小的,一般從2KB開始動態變化,所以可以打開幾百上千的goroutine,而線程是固定棧大小,不可能開很多;goroutine由Go調度器進行調度,而不是操作系統,采用m:n模型(最多n個線程執行m個goroutine),所以goroutine的切換代價較小
雖然及時修改了一個源文件也要重新編譯該文件對應的包及其依賴包,但是go的編譯速度非常快,主要有三點原因:所有導入包開頭顯示聲明,快速找到;禁止環裝依賴,可以并發編譯;編譯后的包記錄了包的依賴關系,編譯器不需要遍歷所有依賴文件只需讀取直接導入包的目標文件
程序的復雜性是可以控制的,其中兩種技術在實踐中被證明很有效:軟件正式部署前的代碼評審;自動化測試(寫一些小的程序用來檢測被測試代碼的行為和預期的一樣)。go test 命令是一個按照一定的約定和組織的測試代碼的驅動程序,在*_test.go文件中:測試函數以Test為函數名前綴,用于測試程序的一些邏輯行為,go test命令會調用這些測試函數并報告PASS或FAIL;基準測試函數以Benchmark為函數名前綴,用于衡量函數的性能,go test命令會多次運行基準函數以計算一個平均的執行時間;示例函數以Example為函數名前綴,提供一個由編譯器保證正確性的示例文檔
本書名不虛傳,對go的基礎知識介紹的很詳盡,底層原理也稍微有一些涉及,同時還有一些高級的話題比如各種并發、測試等,是一本入門go的好書,看完后對golang就有一個幾乎完整的概念了。
PS:gitbook有對應中文版。
從PAXOS到ZOOKEEPER分布式一致性原理與實踐從Paxos到Zookeeper (豆瓣) https://book.douban.com/subje...
如今搞分布式的似乎都離不開Zookeeper了,Zookeeper一般是作為分布式的基礎設施,還是很有必要了解一下的。本書闡釋了從集中式到分布式的問題,如何解決,層層遞進引入了Zookeeper,然后介紹了應用場景和技術內幕,算是一個非常全面的介紹了,而且作者的思路非常清晰,我們讀起來很流暢,但是書中涉及的一些協議本身是比較復雜的,讀起來有些麻煩。
亮點:
集中式的系統保證事務的 ACID 相對而言是比較容易的,而且有很多成熟的解決方案。但是根據 CAP 理論:“一個分布式系統系統不可能同時滿足一致性、可用性、和分區容錯性,最多只能滿足兩樣”,所以分布式系統不大可能嚴格滿足 ACID 的強一致性,而分區容錯性 P 是分布式系統本身存在的意義,所以一般設計者就在 A 和 C 之間尋求平衡了,根據 BASE 理論,一般分布式系統都實現以實現最終一致性、保證高可用性為目標。BASE理論不僅應用于分布式系統,也廣泛應用于現代關系數據庫
數據的一致性與可用性之間的反復權衡產生了 一系列的一致性協議,最經典莫過于二階段、三階段提交協議和Paxos算法了。這三者層層遞進,分別解決了前者的一些問題,并各自在不同的領域被使用
Zookeeper是一個典型的分布式數據一致性解決方案(工業級產品),致力于提供一個高性能(高吞吐量)、高可用(解決單點問題)、具有嚴格順序訪問(主要是寫)控制能力(實現復雜同步原語)的分布式協調服務。其設計目標:簡單的數據模型(樹型、共享、內存)、可以構建集群、順序訪問(請求有唯一遞增編號)、高性能,可以保證許多一致性特性:順序一致性、原子性、單一視圖、可靠性、實時性。分布式應用程序可以基于它實現數據發布訂閱、負載均衡、命名服務、分布式協調通知、集群管理、Master選舉、分布式鎖和分布式隊列等功能
作者對ZooKeeper的常見應用場景進行了詳盡的描述,非常有借鑒意義,比如:client利用節點創建的API可以創建一個順序節點,再加上其type就形成了一個全局唯一的ID了,從而實現命名服務;不同機器通過在同一節點創建臨時子節點,并根據其他機器的臨時子節點來判斷對應的機器是否存活,從而實現心跳檢測;通過強一致性的唯一節點保證來實現master選舉(誰能建立特定節點誰就是master,其他機器注冊watcher,一旦當前master掛了節點刪除,就又開始新的選舉);通過節點唯一性來實現排它鎖、子節點排序來實現共享鎖......總而言之,可以在ZooKeeper子節點唯一性上面做很多文章
具體使用案例,Canal這款基于Mysql BinLog的增量訂閱消費組件使用ZooKeeper來實現Canal Server的主備切換功能,主要原理就是臨時節點和節點唯一性;Canal Client利用ZooKeeper來時刻關注Canal Server的變化,進行消費并記錄消費點
數據模型:由ZNode(稱為節點,類型有持久、臨時、順序節點,可組合)層次化組織而構成的樹,路徑類似于Unix文件系統,每個ZNode可以存數據、創建子節點(臨時節點無子節點);采用版本號以及CAS來實現樂觀鎖機制;采用ACL來實現細粒度的權限管理;采用一次性、客戶端回調串行執行、推拉結合的輕量級watcher來實現時間發布訂閱
Leader選舉的原理簡單說來就是誰的數據越新,那么其ZXID(事務ID)越大,就越能夠保證數據的恢復,就越能成為Leader,對于相同的ZXID,那么SID較大的成為Leader,這個應該沒啥特別的原因,只是作為一種確定機制。
Leader是集群中的核心,主要工作:事務請求的唯一調度者和處理者,保證集群事務處理的順序性;集群內部各個服務的調度者。Follower是集群狀態跟隨者,主要工作:處理客戶端非事務請求,轉發事務請求給Leader;參與事務請求Proposal的投票;參與Leader選舉。Observer觀察集群最新變化狀態并同步過來,工作類似于Follower,只是不參與任何投票,通常用于在不影響集群事務處理的情況下提升集群的非事務處理能力
看完全書再去看看應用案例可能會產生更好的理解。
現代操作系統(原書第4版)現代操作系統(原書第4版) (豆瓣) https://book.douban.com/subje...
操作系統是我們一切編程的根基,不了解操作系統就只是“粘貼復制員”而不是“程序員”更別提“工程師”了。這本書既講到了傳統的重點概念:內存、進程、文件、安全等,又講到了現在廣泛應用的虛擬化、云、Linux、Windows等,無愧于“現代操作系統”的名稱。
亮點:
抽象是管理復雜性的一個關鍵,好的抽象可以把一個幾乎不可能管理的任務劃分為兩個可管理的部分,其一是抽象的定義與實現,其二是用這些抽象解決問題。操作系統就是把硬件丑陋的接口轉換為一個良好、清晰、優雅、一致的抽象。最為人熟知的抽象就是“文件”,它統一了各種格式的數據、各種IO設備對于用戶的接口(操作系統3大抽象:文件,進程與線程,地址空間,分別對應磁盤,處理器,內存)。可以把操作系統理解為一個資源管理者,管理硬件資源如何分配給應用程序,讓應用程序更好地使用這些資源
技術的變化會導致某些思想迅速過時,但是也可能使得另一種是思想復活,當技術的變化影響了系統內部不同組件的相對性能之時就更是如此。比如早期計算機指令由硬件直接執行,微程序設計出現后采用解釋執行,RISC又采用了直接執行,java又采用了解釋執行,這樣來回擺動主要是因為執行速度不總是關鍵因素,還有可能是網絡延遲。再比如計算服務過時了,但是又以云計算的形式重新流行,所以對待技術要保持客觀、辯證的態度,不要因為現在看起來過時就對它唾棄,說不定將來它又能流行起來發揮大的作用
有了進程還要線程的原因:邏輯上,一個應用中本身可以劃分為多個活動,一個活動一個線程便于理解;線程更輕量級,容易創建、撤銷;若存在大量IO處理,多線程彼此重疊進行是可以提升吞吐量的(若每個線程都是CPU密集型則不能);多線程可以真正利用多核。
都知道java有偏向鎖、輕量級鎖、重量級鎖的升級,實際上操作系統也有類似鎖的概念,而且Linux還采取了“Futex”這個方案來結合自旋鎖和重量級鎖(阻塞)的優點。一個Futex包含兩部分:一個內核服務和一個用戶庫,簡單說來就是在用戶態創建一個futex同步變量,當有進程要獲得鎖時,對futex執行"down"操作即原子性的給futex同步變量減1,如果成功即可繼續不需進入內核態,否則進入內核態阻塞,這樣就大大減少了低競爭時的吞吐量
通過交換技術,系統可以同時運行超過實際內存大小的多個進程;現代計算機都使用某種虛擬內存技術,每個進程地址被分為同樣大小的頁面(通常4、8KB),可以被放入空閑內存的任何頁框內,有多種頁面置換算法,實際應用中用的最多的是老化算法和工作集時鐘算法;如果在執行過程中有大小變化的數據結構可以采用分段的方法,但是幾乎沒有主流的操作系統考慮分段算法
文件系統的存儲區分配方案有連續文件、鏈表、文件分配表和iNode。磁盤空間可以通過位圖的空閑表來管理。提升文件系統性能的做法有高速緩存、預讀取、以及盡可能將一個文件的塊放在一起等方法
操作系統除了負責提供抽象還要負責管理所有IO,IO主要有三種方式實現:程序控制IO、中斷驅動IO、DMA
死鎖發生有四個條件:互斥條件、占有和等待條件、不可搶占條件、環路等待;解決辦法有四個:鴕鳥對策、死鎖檢測與恢復、合理資源分配動態避免死鎖、通過破壞引起死鎖發生的四個必要條件之一來防止死鎖發生
虛擬化的好處:可以在節省硬件與電力資源的情況下實現強隔離性、使得各個應用程序很容易擁有自己的運行環境、設置檢查點和虛擬機遷移比在普通操作系統中容易的多,目前虛擬化最重要的用途就是云
編寫操作系統不容易,那么從何入手呢?從對外接口開始,三大原則:簡單,不是當沒什么東西可以添加而是當沒什么東西可以減少時才能達到盡善盡美,或者說KISS原則;完備,完事應該簡單,但是不能過于簡單,必須要能完成用戶所需的一切事情;效率,如果功能不能有效實現那就不值得擁有這個功能。這些原則對于我們所有的系統設計都有借鑒意義
這本書的字真是太多了,也太小了,吐槽一下印刷,此外,內容也很細很全,還是應該采取先觀其大略、使用時細讀的策略。
大規模分布式存儲系統大規模分布式存儲系統 (豆瓣): https://book.douban.com/subje...
看了許多分布式概念性的書籍,也了解了java中間件、分布式一致性、ZooKeeper作為基礎設施等等概念,是時候找個具體的方向了解分布式了,那么這本書就是分布式在存儲這一塊的具體實戰了。本書從概念到實戰,講了分布式文件、鍵值系統、表格系統、數據庫等等,幾乎覆蓋了所有涉及存儲的方向,看完就能對分布式存儲有一個較為完整的了解了。
亮點:
分布式存儲有幾個特性:可擴展(容易擴展到幾百幾千臺集群規模,且性能隨數量線性增長)、低成本(構建于普通PC機之上)、高性能、易用(提供易用的對外接口);主要挑戰在于數據分布均勻、數據一致性、容錯性、負載均衡、事務并發與控制、易用性、壓縮解壓縮;數據分為非結構化數據(圖、文)、結構化數據(關系數據庫)、半結構化數據(HTML);不同的存儲系統適合不同的數據類型,分布式文件系統主要存儲Blob對象(文檔、圖片、視頻)等非結構化數據和作為其他分布式系統的基礎,分布式鍵值系統存儲簡單的半結構化數據,分布式表格存儲復雜的半結構化數據,分布式數據庫存儲結構化數據
設計網絡系統的基本原則是:網絡永遠是不可靠的,任何一個消息只有收到對方回復后才可認為發送成功,系統設計時總是假設網絡將會出現異常并采取相應處理措施(但是我們必須假設信道是可靠的,不然任何工作于其之上的任何協議都不能是可靠的)
分布式系統在CAP理論的C和A之間權衡時可以參照Oracle的DataGuard復制組件的三種模式:最大保護模式(亦即強同步模式,主庫先將操作日志同步到至少一個備庫才能返回給客戶端成功結果),應用于余額等關鍵記錄;最大性能模式(亦即異步復制,主庫完成執行就返回客戶端,將重做日志以異步的方式復制到備庫),應用于用戶操作日志等非關鍵記錄;最大可用性模式(上述兩種模式的折中,正常情況相當于最大保護模式,當主備之間的網絡出現故障切換為最大性能模式),應用于一般記錄
故障檢測可以通過心跳檢測來做,這是最原始的想法,但是機器也可能因為太忙,或者與控制節點的網絡斷掉而無法進行心跳,這種情況下使用時鐘同步(需要考慮一個時間提前量,因為時鐘并不能嚴格一致一般都會有小于1秒的微小誤差)加租約(Lease)的形式可以較好地避免這個問題
跨機房部署有三種方案:集群整體切換(實際最常見做法,兩個機房保持獨立,保持相同的副本數,有主備之分(Primary,Secondary),可能強同步或者異步復制),單個集群跨機房(不同數據分片的主副本位于不同機房)、Paxos選主副本(每個數據分片的多個副本構成一個Paxos復制組,自動選舉主副本,降低了對總控節點的依賴但是工程復雜度很高)。
GFS成功的經驗表明:單Master的設計是可行的,不僅簡化了系統,而且能較好地實現一致性。這是一種中心化的架構,是目前互聯網的主流架構,而去中心化的Gossip協議雖然借著Cassandra(Amazon的Dynamo的開源實現)大火了一把,但是由于其復雜性與一致性問題實際上分布式系統很少使用
OceanBase是一款可擴展的關系型數據庫(支持強一致性和跨表事務),主要架構分內四部分:RootServer一主一備,主備強同步,負責集群管理,數據分布以及副本管理;UpdateServer一主一備,主備同步模式可配置,接受寫操作,并且定期把新數據同步給Chunkserver;ChunkServer存儲基線數據,只提供讀取服務,并定期接受UpdateServer的數據同步;MergeServer解析用戶Mysql兼容請求,將請求轉發給對應的ChunkServer和UpdateServer,無狀態,類似于網關的作用
OceanBase寫操作強一致性的原理是:UpdateServer將redo日志發送給備機,redo日志寫到本地磁盤,redo日志應用到主機內存表,返回客戶端成功。這樣即使主備機切換也能保證新的主機有以前所有的操作記錄而不會丟失,可以通過增加備機數量來提高可用性保證。當然UpdateServer主備同步也支持異步模式,支持最終一致性,一般用來實現異地容災。此外主備集群也可以實現錯峰合并
OceanBase借助UpdateServer邏輯單點來實現強一致性,那么這個單點會不會成為瓶頸呢?一般來說,互聯網業務讀寫比都比較高,所以不會成為瓶頸,即使是雙十一這種,也可以通過自動凍結內存表轉入SSD硬盤、定期合并與分發、旁路導入、多塊網卡配置、RAID卡緩存模塊、成組提交等優化方式來避免內存、網絡、磁盤的瓶頸;通過主備強一致備份策略與實時同步避免單點故障,這樣這個單點問題就幾乎不存在了
列式存儲的主要目的有兩個:大部分OLAP只需要讀取部分列而不是全部列數據,列式存儲可以避免讀取無用數據;將同一列的數據在物理上存放在一起,能夠極大的提高數據壓縮率
大表左連接是互聯網的一個常見問題,一般采取引用(多表主鍵連接)、或者嵌套(主表冗余連表信息),但是這分別只能適應讀取次數少、讀寫比較高的場景,如果讀取次數多且讀寫比不高那么這兩種做法就沒轍了。OceanBase采用基線數據冗余連表+修改增量合并的方式解決了這個問題
看完這本書是真的很有收獲,對整個分布式架構有了一個完整的了解,從大大的跨機房到一個小小的數據分片副本,從上到下非常清晰。此外最佳實踐那一部分也是很贊的,強烈推薦此書。
微服務設計微服務設計 (豆瓣): https://book.douban.com/subje...
微服務最近兩年越來越火,其實這并不是什么新鮮概念,計算機體系里面早就有單內核與微內核的架構思想了,微服務也是一種類似的思想,但是是處于更高級別的應用架構層(所以計算機領域里面的許多思想是可以相互借鑒的比如抽象、緩存、LRU算法、并行處理等等)。微服務的好處是很多的,單個服務容易開發、理解和維護;容納異構技術;部署簡單、迭代速度快、變化小bug少;彈性、擴展性好等等。本書就帶領我們從建模、集成、測試到部署和監控,全面了解微服務,為進一步學習指引方向。
亮點:
微服務是一種分布式系統解決方案,推動細粒度服務的使用,這些小而自治的服務協同工作,都有自己的生命周期,圍繞業務領域建模,根據業務的邊界來確定服務的邊界,因此也很容易確定某個功能代碼的位置,避免了傳統分層架構的許多問題。一個微服務就是一個實體,不同微服務通過網絡通信互相調用。我們知道,直接進程內方法調用是很快,但是也意味著兩個對象緊密耦合了,通過網絡通信調用雖然慢一些,但是兩個對象就松耦合了,可以隨時替換掉一個而另一個完全不用知道,我覺得隨著網速越來越快,網絡通信代價越來越小,微服務的優勢將越來越明顯,直接耦合調用的方式的優勢將越來越弱
架構師就類似于城市規劃師應該專注于大方向,只能參與少量細節,需要保證系統能滿足當前的需求,還要能夠應對將來的變化,以一種演化的方式來進行規劃,這是一個很大的標準,從何入手呢?答案是:分區,定好服務邊界與交互方式,可以使用限界上下文。演化的方式就是我們要理解,隨著項目發展,服務一定會越來越大,我們要做的就是讓架構增量變化,在拆分這件事變得過分昂貴之前進行拆分
重用代碼可能引入危險,因為我們可能引入服務之間的耦合。所以雖然我們要做到DRY原則,但是也要防止過度追求DRY原則帶來的系統過度耦合,這是一個比較微妙的話題,要記住,DRY不是意味著避免重復的代碼,而是意味著避免系統行為和知識的重復,在微服務內部不要違反DRY,跨服務時可以適當違反來避免服務之間耦合
處理跨服務的業務流程時可以選擇:編排,一個中心節點調度其他所有服務完成,這樣流程很清晰,但是會導致中心節點承擔過多,其它服務淪為貧血的基于CURD的服務;協同,相關服務訂閱特定的事件,事件由客戶端觸發之后每個服務各自完成自己的處理,這樣能明顯消除耦合,但是就看不到明顯的流程圖了,而且可能需要跨服務監控,但是總體而言傾向于協同,利大于弊
真正的持續集成要理解3個問題:是否每天簽入代碼到主線?是否有一組測試來驗證修改?構件失敗過后是否把修復CI當做第一要務?最好是每一個微服務都有自己的代碼庫和CI,只有這樣才能真正實現獨立部署
微服務部署最好采用單主機(可以是物理主機、虛擬機、容器)單服務的方式,這樣利于團隊自治、服務部署、監控、故障排查、擴展性更好等,但是這個模式會引入大量主機,這就意味著重復勞動會多起來,所以我們一定要實現自動化(不管什么技術棧都要追求自動化)
自動化測試類型分為單元測試、服務測試、用戶測試(端到端測試)。其中單元測試是針對一個函數的、面向技術、幫助開發人員快速發現錯誤和增加重構信心;服務測試針對一系列函數構成的完整服務,提高測試隔離性,幫助快速定位問題;端到端測試包含整個系統,增強我們發布服務的信心。這三者的比例最好是前者比后者多一個數量級
監控固然要看低層指標比如CPU利用率、空閑內存、帶寬使用等等,但是這些指標往往太多而帶來噪聲不利于監控我們真正關心的行為,所以需要語義監控,亦即準備一些合成數據和事件來觀察系統是否按照我們的期望完成任務,當然這些數據要注意不能和真實生產數據混淆
任何組織在設計一套系統時,所交付的方案在結構上都與該組織的溝通結構一致。這被稱為康威定律
構建分布式系統需要思維的轉變,那就是故障總會出現,不是所有人都需要像Google或者Netflix一樣使用ChaosMonkey來模擬故障測試系統的健壯性,但是我們都需要為各種故障做好準備比如:超時(設置默認超時并記錄日志)、斷路器(請求失敗一定次數后斷路器打開,下次快速失敗就不用再等待了)、艙壁(服務內外都可以使用,關注點分離,為每個下游多帶帶準備連接池)、隔離
PS:書中提到了不少參考書,都是可以看看的。
算法(第4版)算法(第4版) (豆瓣) https://book.douban.com/subje...
本書講解的算法和數據結構都是我們必須掌握的,屬于入門級知識,但是作者講的很仔細,很有趣,沒有那么多的數學證明,比《算法導論》讀起來跟容易一些,但是作者的觀點也都是立得住的,有理有據,值得通看,形成自己對于算法的初步體系。
亮點:
本書提供了所有代碼還有教學視頻,可以輔助學習,網址。我把代碼fork了一份,在這
本書對算法性能的分析是科學式的,亦即先對性能提出假設,建立數學模型,然后用多種實驗驗證它們,必要時重復這個過程
API的目的是將調用和實現分離(模塊化編程),可以將API看做調用和實現之間的一份契約,他詳細說明了每個方法的作用,實現的目標就是遵守這份契約。讀到這里就有一個感想,我們程序的進步都是在努力地把人為的契約固化到代碼中,減少出錯概率。比如程序員之間直接約定不夠可靠,那么就通過接口來強制約定;再比如生產與開發環境不容易保持一致,就通過DockerFile來強制約定
作者循循善誘,為了給我們分析算法性能提供動力,講了一個3-sum問題的逐步優化過程:暴力的3-sum是一個立方級別的算法,先從簡單的情況考慮2-sum,通過線性對數級別的排序,然后用對數級別的二分查找一個元素的相反數來進行統計,這個算法就是線性對數級別的,然后自然擴展到3-sum,得到平方對數級別的快速的3-sum,并查集也是類似循序漸進的教法
初級算法雖然簡單,但是它幫我們建立了一些基本規則,展示了一些性能基準,在某些特殊情況下也是很好的選擇,也是開發更強大的算法的基礎,所以仍有必要系統的學習它們
把排序算法講了一遍之后,講到了規約(為了解決某個問題而發明的算法可以解決另一個問題),比如排序就可以用了解決很多其他問題,一般能將暴力的平方級別解法下降到非暴力的線性對數級別,比如:找出重復元素、排名、優先隊列、中位數、第K個最小/大的值(模仿快速排序的partition操作就能達到線性級別)等
散列表的意義是在時間與空間之間取得一個平衡,選擇適當大小的數組M,既不會因為空鏈表造成內存浪費也不會因為鏈表太長而導致查找效率低
書中對于圖的表述中,深度優先等遍歷方式都給出了詳細的算法與示例的軌跡圖,你想看不懂都難
就解決圖的連通性問題,理論上來說,深度優先比union-find(聯合查找或者說并查集)更快,但是實際上union-find更快,因為它不需要對圖進行預處理,是一種動態的算法(能用接近常數的時間檢查兩點是否相通,甚至是添加邊),而對于已經是圖的數據類型使用深度優先更快,因為它能利用已知信息
用于子串查找的KMP算法的基本思想是,當文本出現不匹配時就能知曉一部分文本內容,可以利用這些信息避免將指針會退到所有這些已知字符之前,亦即充分利用已知信息,這也是插入排序優于選擇排序的原因。KMP主要亮點是提前判斷如何重新開始查找,這種判斷不需要文本指針i完全回退,只需根據模式本身信息重新進行比較位置的選擇
許多問題都可以規約為排序問題(中位數、不同值統計)、最短路徑問題(任務調度、套匯)、最大流量問題(就業安置、網絡可靠性)、線性規劃(最大流量)
NP是所有搜索問題(有解且驗證解的正確性的時間不會超過輸入規模的多項式的問題)的集合;P是能夠在多項式時間內解決的所有搜索問題的集合
本書的java基礎部分是相當的豐富,學完算法也可以順帶復習一遍java了,很劃算 (* ̄︶ ̄)。
還有,本書雖厚,但是一定要看完,這樣才有一個完整的體系,并且算法的細節也能掌握了,之所以不采取往常對待大部頭的觀其大略的方法是因為這是算法,是經常需要我們實施的領域,和代碼編寫直接相關(不像操作系統的知識),所以必須掌握細節。可以參見我的另外幾篇專門講算法的博客
Hadoop權威指南(第3版) (豆瓣): https://book.douban.com/subje...
Hadoop的出現開啟了大數據的序幕,到了現在已經成為一個比較完善的生態,服務于云計算與大數據。記得大三的時候學校有免費的云服務器,我申請了5臺自己搭建了一個Hadoop集群跑了一下 Hello World 級別的 Word Count,然后就開始期末考試了,沒有再繼續深入了解,現在是時候全面的了解一下了,這本書號稱權威指南,看它沒錯。
亮點:
MapReduce相對于其他系統的優勢:比RDBMS更適合一次寫入多次讀取的任務,適合批處理任務,是一種線性可伸縮的編程模型;因為盡量做到數據本地存儲,所以比網格計算(帶寬限制,只適宜CPU密集型任務)更能處理巨量數據的任務,同時處理CPU密集型任務也不弱;比志愿計算(貢獻CPU而非帶寬)更可靠,更易實施,更好控制
HDFS是Hadoop的旗艦級文件系統,但是Hadoop也能集成其它文件系統如S3,HDFS設計要點:超大文件、流式數據訪問、商用硬件(零售店可買)、低延遲訪問不太適用(HBASE更佳)、大量的小文件、僅支持單用戶寫入且不能隨機寫
分布式文件系統的塊(chunk)抽象有許多好處:一個文件可以大于任意磁盤的容量(因為無需把一個文件存在一個磁盤上);抽象塊簡化了存儲設計(塊大小固定,默認64MB磁盤性能越好越大,故每塊盤能存多少塊是固定的,而且元數據也可以多帶帶管理);適合數據備份,從而提高容錯能力和可用性(每一塊可以復制到多個機器上,默認是3個,如果塊、磁盤或機器發生故障系統會從其他機器讀取副本,此過程對用戶透明。而且多個副本可以提高讀取性能)
HDFS 有兩種節點,一個namenode作為管理者,管理整個文件系統的命名空間,維護整個文件系統樹及其文件與目錄,同時也記錄著每個文件中各個塊所在的數據節點信息,namenode至關重要必須正常運行,所以提供了兩種容錯機制,實時同步元數據至其它地方和運行輔助namenode;多個datanode作為實際工作者,存儲數據塊供讀寫并定期向namenode發送存儲的塊的列表
YARN將JobTracker劃分為多個職能的實體(資源管理器和應用管理器),改善了經典的MapReduce面臨的擴展性問題,實際上比MapReduce更具一般性,MapReduce只是YARN應用的一種形式,有很多其他的YARN應用如分布式shell
MapReduce提供了計數器(統計無效數據)、排序、連接(join操作,將兩個數據集合二為一)、邊數據分布(配置額外的只讀數據來完成作業)、MapReduce庫類等常見功能
部署hadoop時典型配置是同一個機架有一些節點,不同機架通過交換機連接起來的二級網絡架構。因為機架內部通信更快所以一定要把這些配置告訴Hadoop系統,這樣分配MapReduce任務時會傾向于機架內節點,節省傳輸成本,同時HDFS的文件塊的3個副本也會盡量分布在兩個機架上
Pig是一種探索大規模數據集的腳本語言,省去MapReduce繁瑣耗時的步驟(寫mapper、reducer,代碼編譯,打包,提交作業),僅需控制臺的幾行pig Latin代碼就能處理TB級別的數據,而且支持更豐富的數據結構
Hive能把SQL查詢轉換為一些列運行在Hadoop上運行的MapReduce作業,它把數據組織為表,通過這種方式為HDFS中的數據賦予結構。Hive與傳統數據庫有很多類似之處(如SQL語言的支持,尤其類似于Mysql),但是其底層依賴于HDFS和MapReduce而非傳統的文件系統,Hive采用讀時模式(查詢時進行模式檢查)而非寫時模式(寫入時檢查模式)可以使得數據加載非常迅速,因為他只是移動數據而不需要讀取、解析、序列化等。寫時模式有利于提升查詢性能,因為可以建立索引、數據壓縮等,Hive沒有考慮過這些特性(以及事務、更新、刪除等),因為MapReduce下,全表掃描是常態
HBASE是在HDFS上開發的面向列[族]的分布式數據庫,如果需要實時的訪問超大規模的數據集,就可以使用HBASE。與RDBMS相比,HBASE能解決很多伸縮性問題(表可以高達幾十億行,幾百萬列)、能水平分區并在上千個普通節點上自動復制、線性擴展與新節點自動處理。RDBMS對于中小規模應用提供的易用性、靈活性和完整的功能性是幾乎無可取代的,但是要在數據規模和并發讀中任意方面向上擴展就會損失很多性能,因為RDBMS是面向行的具有ACID和事務的強一致性等特性,向上擴展意味著要打破這些特性,使得管理變得復雜
ZooKeeper一般用來構建分布式服務具有許多特性:簡單(核心是一個精簡的文件系統)、豐富(提供分布式隊列、鎖、領導選舉等功能)、高可用(運行于一組機器,避免單點故障)、松耦合交互(參與者不必互相了解)、資源庫(提供通用協調模式的開源共享庫)
本書作為了解Hadoop的設計思想以及關鍵點的手段,我尚未進入真正的使用,很多代碼以及API部分就省略沒看了,所以雖然是個大部頭,但是看起來并不會特別慢。當然如果真的要使用,書中的接口和代碼可能就已經過時了,要搭配最新官方文檔來看
HTTP權威指南HTTP權威指南 (豆瓣): https://book.douban.com/subje...
Http協議構成了當今互聯網的基石,無論是瀏覽網頁還是使用APP都離不開這個協議,非常有必要進行全面的了解。這本書也是一個權威指南,看完就能有一個完整的概念了,而且本書還講到了許多架構方面的經驗,只賺不賠哈哈。
亮點:
URI 統一資源標識符,在世界范圍唯一標志并定位一個信息資源,包含URL和URN;URL 統一資源定位符,描述一臺特定服務器上的某特定資源的位置;URN 統一資源名稱,作為特定內容的唯一名稱而與資源所在地無關(所以資源可以遷移到另一處而不影響其訪問,URL就不行)。現在幾乎所有URI都是URL,URN由于架構的缺乏(雖然引入了PURL)和巨大的工程變動仍處于試驗階段并未廣泛使用
HTTP延時一般都是由TCP延時造成的(除非是客戶端、服務端超載或者處理復雜的動態資源),如果要編寫高性能HTTP程序就要考慮許多的TCP層面的問題與解決方案:TCP握手產生的延時對于傳輸少量的http報文而言是巨大的開銷(復用已有TCP連接);延遲確認算法不太適用于HTTP這種雙峰特征的請求響應式行為(調整或禁用這個算法);慢啟動影響新的Http連接的傳輸速度(復用連接,持久連接);Nagle算法影響小的Http報文傳輸(可以禁用該算法,TCP_NODELAY);TIME_WAIT累計與端口耗盡,TIME_WAIT狀態會持續2MSL(如120s)的時間才會轉換到CLOSE狀態,然后才能創建相同IP和端口的連接(服務器端口有限,如60000個),限制了服務器的連接速率(60000/120=500次每秒),可以增加客戶端負載生成器的數量或者虛擬IP
減少Http連接延時的方法:并行連接(并行執行多個Http事務),管道化連接(通過共享的TCP連接發起請求),復用連接(交替傳送請求與響應報文),持久連接(由于站點本地性,http事務結束后不必馬上釋放TCP連接,因為很有可能馬上又要向該站點發起請求)。其中持久連接與并行連接搭配可能是最高效的方式
web代理連接的是兩個使用相同協議的應用,而網關連接的是兩個或多個使用不同協議的端點。所以web代理扮演的是中間人傳輸者的角色(改善安全性、提高性能,比如完成訪問控制、防火墻、匿名者、緩存、反向代理負載均衡、內容路由器、轉碼器等等),網關扮演的是協議轉換器的角色(比如PHP-FPM能把Nginx轉發的http請求解析出來然后調用php-cgi來注入參數并執行PHP代碼得到結果然后封裝為http協議回復給nginx)
大規模web爬蟲對其訪問管理(避免重復)用到了一些技術:樹和散列表(加速查找)、有損的位圖(url映射成數字,url無限數字有線所以可能有沖突)、檢查點(已訪問URL存入本地)、分類(集群爬蟲通過通訊來分配URL,各自爬取部分)、規范化URL、廣度優先爬取、節流、限制url大小、黑名單、內容指紋、人工監視等等
內容協商技術可以使得服務器把內容的不同版本發送給對應的用戶,主要有3種機制:客戶端驅動、服務器驅動、透明。
重定向普遍存在,原因無非:可靠的執行Http事務(備用節點)、最小化時延(就近訪問)、節約網絡帶寬(服務器分散,減少擁塞)。用到的主要技術有:Http重定向、DNS重定向、任播尋址、IP MAC轉發、IP地址轉發、顯示瀏覽器配置、代理自動配置、web Proxy代理自動發現等等
這本書詳細描述了HTTP協議的方方面面,而且給出了許多參考,如果我們真的要做一個完美的Http應用,還是值得我們細細翻閱的。
閱讀原文
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/28038.html
摘要:可以通過大數據生態的一系列工具生態來解決大數據問題數據分片主要有兩種方式哈希和范圍。哈希的問題是范圍查詢支持不佳,范圍的問題是可能冷熱數據不均。 后端好書閱讀與推薦系列文章:后端好書閱讀與推薦后端好書閱讀與推薦(續)后端好書閱讀與推薦(續二)后端好書閱讀與推薦(續三)后端好書閱讀與推薦(續四)后端好書閱讀與推薦(續五)后端好書閱讀與推薦(續六) Elasticsearch權威指南 El...
摘要:可以通過大數據生態的一系列工具生態來解決大數據問題數據分片主要有兩種方式哈希和范圍。哈希的問題是范圍查詢支持不佳,范圍的問題是可能冷熱數據不均。 后端好書閱讀與推薦系列文章:后端好書閱讀與推薦后端好書閱讀與推薦(續)后端好書閱讀與推薦(續二)后端好書閱讀與推薦(續三)后端好書閱讀與推薦(續四)后端好書閱讀與推薦(續五)后端好書閱讀與推薦(續六) Elasticsearch權威指南 El...
摘要:持續交付持續交付豆瓣微服務離不開,而核心就是幾點自動化連續小范圍快速可靠。敏捷革命敏捷革命提升個人創造力與企業效率的全新協作模式豆瓣實際上正是敏捷開發的最佳實踐,有了前面的鋪墊,我們可以通過這本書我們來真正了解敏捷開發的全貌。 后端好書閱讀與推薦系列文章: 后端好書閱讀與推薦后端好書閱讀與推薦(續)后端好書閱讀與推薦(續二)后端好書閱讀與推薦(續三)后端好書閱讀與推薦(續四)后端好書...
閱讀 3602·2021-11-24 10:25
閱讀 2508·2021-11-24 09:38
閱讀 1217·2021-09-08 10:41
閱讀 2902·2021-09-01 10:42
閱讀 2569·2021-07-25 21:37
閱讀 1980·2019-08-30 15:56
閱讀 914·2019-08-30 15:55
閱讀 2748·2019-08-30 15:54