中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
學(xué)習(xí)筆記:The Log(我所讀過的最好的一篇分布式技術(shù)文章)


前言

這是一篇學(xué)習(xí)筆記。學(xué)習(xí)的材料來自Jay Kreps的一篇講Log的博文。原文很長,但是我堅(jiān)持看完了,收獲頗多,也深深為Jay哥的技術(shù)能力、架構(gòu)能力和對于分布式系統(tǒng)的理解之深刻所折服。同時(shí)也因?yàn)槟承├斫夂蚃ay哥觀點(diǎn)吻合而略沾沾自喜。


Jay Kreps是前Linkedin的Principal Staff Engineer,現(xiàn)任Confluent公司的聯(lián)合創(chuàng)始人和CEO,Kafka和Samza的主要作者。


所謂筆記,就是看了文章,提筆就記,因?yàn)镴ay哥本身本章組織的太好,而其本身的科學(xué)素養(yǎng)及哲學(xué)素養(yǎng)也很高,所以私以為出彩的東西就不省略了。


一、資料來源


The Log: What every software engineer should know about real-time data’s unifying abstraction


二、筆記

2.1 Log的價(jià)值


1) Log是如下系統(tǒng)的核心:


  • 分布式圖數(shù)據(jù)庫

  • 分布式搜索引擎

  • Hadoop

  • 第一代和第二代K-V數(shù)據(jù)庫


2) Log可能跟計(jì)算機(jī)的歷史一樣長,并且是分布式數(shù)據(jù)系統(tǒng)和實(shí)時(shí)計(jì)算系統(tǒng)的核心。


3) Log的名字很多:


  • Commit log

  • Transaction log

  • Write-ahead log


4) 不理解Log,你就不可能充分理解


  • 數(shù)據(jù)庫

  • NoSQL存儲

  • K-V存儲

  • 復(fù)制

  • Paxos算法

  • Hadoop

  • Version Control

  • 或者,任何軟件系統(tǒng)


2.2 什么是Log?

2.2.1 概述


  • 記錄會附加到log的尾部。

  • 從左到右讀取記錄。

  • 每個(gè)entry都有唯一且有序的log entry 序號。


記錄的順序定義了這樣的一個(gè)概念:時(shí)間。


因?yàn)樵娇孔蟮挠涗浽皆纭?/p>


Entry的序號可以當(dāng)作一種時(shí)間戳,將記錄的順序當(dāng)作時(shí)間這一概念看起來很奇怪,但是很快你就會發(fā)現(xiàn),這樣做:可以方便地將“時(shí)間”與任一特定的物理時(shí)鐘解耦。


Log和常見的文件、表(table)沒有那么大的差別。


  • 文件是一組字節(jié)

  • 表是一組記錄

  • Log可以說是某種將記錄按時(shí)間排序的文件或者表


這樣說,可能你會覺得log如此簡單,還有討論的必要嗎?
其實(shí),log的核心意義在于:


Log記錄了何時(shí)發(fā)生了什么(they record what happened and when.)。


而這一條,通常是分布式系統(tǒng)最最最核心的東西。


注意,這里有必要澄清幾個(gè)概念:


  • 本篇所討論的Log和程序員通常接觸的應(yīng)用日志(application logs)不同


  • 應(yīng)用日志通常是一種非結(jié)構(gòu)化的,記錄錯(cuò)誤信息、調(diào)試信息,用于追蹤應(yīng)用的運(yùn)行的,給人看的日志,比如通過log4j或者 syslog來寫入本地文件的日志。


  • 而本篇所討論的log是通過編程方式訪問的,不是給人看的,比如“journal”、“data logs”。


  • 應(yīng)用日志是本篇所討論的log的一種特化。


2.2.2 數(shù)據(jù)庫中的Logs

Log的起源不得而知,就像發(fā)明二分查找的人,難以意識到這種發(fā)明是一種發(fā)明。


Log的出現(xiàn)和IBM的System R 一樣早。


在數(shù)據(jù)庫中,需要在數(shù)據(jù)庫崩潰時(shí),保持多種多樣的數(shù)據(jù)結(jié)構(gòu)和索引保持同步。


為保證原子性和持久性,數(shù)據(jù)庫需要在對數(shù)據(jù)結(jié)構(gòu)和索引進(jìn)行修改提交之前,記錄其要修改的內(nèi)容。


所以log記錄了何時(shí)發(fā)生了什么,而每一張表和索引本身,都是這種歷史信息的映射。


因?yàn)閘og是立即持久化的,所以當(dāng)crash發(fā)生時(shí),其成為恢復(fù)其它持久化結(jié)構(gòu)的可靠來源。


Log從保證ACID特性的一種實(shí)現(xiàn),發(fā)展成了一種數(shù)據(jù)庫之間數(shù)據(jù)復(fù)制的手段。


很顯然,數(shù)據(jù)庫中發(fā)生的一系列的數(shù)據(jù)變更,成為數(shù)據(jù)庫之間 保持同步最需要的信息。


Oracle、MySQL、PostgreSQL,都包含了log傳輸協(xié)議,將log的一部分發(fā)送到用于保持復(fù)制的從數(shù)據(jù)庫(Slave)。


Oracle的XStreams和GoldenState,將log當(dāng)作一種通用的數(shù)據(jù)訂閱機(jī)制,以提供給非Oracle的數(shù)據(jù)庫訂閱數(shù)據(jù)。


MySQL和PostgreSQL也提供了類似的組件,這些組件是數(shù)據(jù)系統(tǒng)架構(gòu)的核心。


面向機(jī)器的Log,不僅僅可被用在數(shù)據(jù)庫中,也可以用在:


  • 消息系統(tǒng)

  • 數(shù)據(jù)流(data flow)

  • 實(shí)時(shí)計(jì)算


2.2.3 分布式系統(tǒng)中的logs

Log解決了兩個(gè)很重要的分布式數(shù)據(jù)系統(tǒng)中的問題:


1) 有序的數(shù)據(jù)變化


2) 數(shù)據(jù)分布式化


所謂的狀態(tài)機(jī)復(fù)制原理(State Machine Replication Principle):

如果兩個(gè)確定的處理過程,從相同的狀態(tài)開始,按照相同的順序,接收相同的輸入,那么它們將會產(chǎn)生相同的輸出,并以 相同的狀態(tài)結(jié)束。


所謂確定的(deterministic),是指處理過程是時(shí)間無關(guān)的,其處理結(jié)果亦不受額外輸入的影響。


可以通過非確定的例子來理解:


  • 多線程的執(zhí)行順序不同導(dǎo)致不同的結(jié)果

  • 執(zhí)行g(shù)etTimeOfDay()方法

  • 其它的不能重復(fù)的處理過程


所謂狀態(tài),可以是機(jī)器上的任意數(shù)據(jù),無論在處理結(jié)束后,是在機(jī)器的內(nèi)存中還是磁盤上。


相同的輸入按照相同的順序,產(chǎn)生相同的結(jié)果,這一點(diǎn)值得引起你的注意,這也是為什么log會如此重要,這是一個(gè)直覺性的概念:如果你將同一個(gè)log輸入兩個(gè)確定性的程序,它們將產(chǎn)生相同的輸出。


在分布式系統(tǒng)的構(gòu)建中,意識到這一點(diǎn),可以使得:


讓所有的機(jī)器做同樣的事,規(guī)約為:


構(gòu)建分布式的、滿足一致性的log系統(tǒng),以為所有處理系統(tǒng)提供輸入。


Log系統(tǒng)的作用,就是將所有的輸入流之上的不確定性驅(qū)散,確保所有的處理相同輸入的復(fù)制節(jié)點(diǎn)保持同步。


這種方法的最妙之處在于,你可以將索引日志的時(shí)間戳,作為所有復(fù)制節(jié)點(diǎn)的時(shí)鐘來對待:


通過將復(fù)制節(jié)點(diǎn)所處理過的log中最大的時(shí)間戳,作為復(fù)制節(jié)點(diǎn)的唯一ID,這樣,時(shí)間戳結(jié)合log,就可以唯一地表達(dá)此節(jié)點(diǎn)的整個(gè)狀態(tài)。


應(yīng)用這種方法的方式也很多:


  • 在log中記錄對一個(gè)服務(wù)的請求

  • 在回復(fù)請求的前后,記錄服務(wù)狀態(tài)的變化

  • 或者,服務(wù)所執(zhí)行的一系列轉(zhuǎn)換命令,等等。


理論上來講,我們可以記錄一系列的機(jī)器指令,或者所調(diào)用方法的名稱及參數(shù),只要數(shù)據(jù)處理進(jìn)程的行為相同,這些進(jìn)程就可以保證跨節(jié)點(diǎn)的一致性。


常玩兒數(shù)據(jù)庫的人,會將邏輯日志和物理日志區(qū)分對待:


  • 物理日志:記錄了所有的行內(nèi)容的變化。

  • 邏輯日志:不是記錄內(nèi)容的變化,而是Insert , update , delete等導(dǎo)致行內(nèi)容變化的SQL語句。


對分布式系統(tǒng),通常有兩種方式來處理復(fù)制和數(shù)據(jù)處理:


1) State machine model(active – active)


2) Primary-back model (active – passive)


如下圖所示:



為了理解上述兩種方式的不同,來看個(gè)簡單的例子:


現(xiàn)在,集群需要提供一個(gè)簡單的服務(wù),來做加法、乘法等算術(shù)運(yùn)算。初始,維護(hù)一個(gè)數(shù)字,比如0。


  • Active – active :在日志記錄這樣的一些操作,如“+1”、“*2”等,這樣,每個(gè)復(fù)制節(jié)點(diǎn)需要執(zhí)行這些操作,以保證最后的數(shù)據(jù)狀態(tài)是一致的。


  • Active – passive:一個(gè)單獨(dú)的master節(jié)點(diǎn),執(zhí)行“+1”、“*2”等操作,并且在日志中記錄操作的結(jié)果,如“1”、“3”、“6”等。


上面的例子也揭示了,為什么順序是復(fù)制節(jié)點(diǎn)之間保持一致性的關(guān)鍵因素,如果打亂了這些操作的順序,就會得到不同的運(yùn)算結(jié)果。


分布式log,可以當(dāng)做某些一致性算法的數(shù)據(jù)結(jié)構(gòu):


  • Paxos

  • ZAB

  • RAFT

  • Viewstamped Replication


一條log,表征了一系列的關(guān)于下一個(gè)值是什么的決定。


2.2.4 Changelog

從數(shù)據(jù)庫的角度來看,一組記錄數(shù)據(jù)變化的changelog和表,是對偶和互通的。


1) 依據(jù)記錄了數(shù)據(jù)變化的log,可以重構(gòu)某一狀態(tài)的表(也可以是非關(guān)系型存儲系統(tǒng)中有key的記錄)


2) 相反,表如果發(fā)生了變化,可以將變化計(jì)入log。


這正是你想要的準(zhǔn)實(shí)時(shí)復(fù)制的秘籍所在!


這一點(diǎn)和版本控制所做的事情極為類似:管理分布式的、并發(fā)的、對狀態(tài)進(jìn)行的修改。


版本控制工具,維護(hù)了反映修改的補(bǔ)丁,這其實(shí)就是log,你和一個(gè)被簽出(checked out)的分支快照進(jìn)行交互,這份快照就相當(dāng)于數(shù)據(jù)庫中的表。你會發(fā)現(xiàn),版本控制與分布式系統(tǒng)中,復(fù)制都是基于log的:當(dāng)你更新版本時(shí),你只是拉取了反映了版本變化的補(bǔ)丁,并應(yīng)用于當(dāng)前的分支快照。


2.3 數(shù)據(jù)集成(Data integration)

2.3.1 數(shù)據(jù)集成的含義

所謂數(shù)據(jù)集成,就是將一個(gè)組織中的所有服務(wù)和系統(tǒng)的數(shù)據(jù),變得可用。


實(shí)際上,對數(shù)據(jù)進(jìn)行有效利用,很符合馬斯洛的層次需求理論。


金字塔的最底層,是收集數(shù)據(jù),將其整合進(jìn)應(yīng)用系統(tǒng)中(無論是實(shí)時(shí)計(jì)算引擎,還是文本文件,還是python腳本)。


而這些數(shù)據(jù),需要經(jīng)過轉(zhuǎn)換,保持一個(gè)統(tǒng)一、規(guī)范、整潔的格式,以易于被讀取和處理。


當(dāng)上面的要求被滿足后,就可以開始考慮多種多樣的數(shù)據(jù)處理方式,比如map – reduce 或者實(shí)時(shí)查詢系統(tǒng)。


很顯然,如果沒有一個(gè)可靠的、完備的數(shù)據(jù)流,Hadoop就僅僅是一個(gè)昂貴的、難以整合的加熱器(集群很費(fèi)電么?)。


相反,如果能保證數(shù)據(jù)流可靠、可用且完備,就可以考慮更高級的玩法、更好的數(shù)據(jù)模型和一致的、更易被理解的語義。


接著,注意力就可以轉(zhuǎn)移到可視化、報(bào)表、算法和預(yù)測上來(挖啊機(jī)啊深度?。?。


2.3.2 數(shù)據(jù)集成的兩個(gè)復(fù)雜性


事件


事件數(shù)據(jù),記錄了事件是怎么發(fā)生的,而不僅僅是發(fā)生了什么,這一類log通常被當(dāng)做應(yīng)用日志,因?yàn)橐话闶怯蓱?yīng)用系統(tǒng)寫入的。但這一點(diǎn),其實(shí)混淆了log的功能。


Google的財(cái)富,其實(shí),是由一個(gè)建立在(用戶)點(diǎn)擊流和好惡印象(體驗(yàn))之上的相關(guān)性pipeline產(chǎn)生的,而點(diǎn)擊流和印象,就是事件。


各種各樣的專業(yè)數(shù)據(jù)系統(tǒng)的爆發(fā)


這些系統(tǒng)存在的原因:


  • 聯(lián)機(jī)分析(OLAP)

  • 搜索

  • 簡單的在線存儲

  • 批處理

  • 圖譜分析

  • 等等(如spark)


顯然,要將數(shù)據(jù)整合進(jìn)這樣的系統(tǒng)中,對于數(shù)據(jù)集成來講,極為困難。


2.3.3 基于日志結(jié)構(gòu)的數(shù)據(jù)流

每種邏輯意義上的數(shù)據(jù)源,都可以依據(jù)log進(jìn)行建模。


數(shù)據(jù)源可以是記錄了事件(點(diǎn)擊和PV)的應(yīng)用程序,可以是接受更改的數(shù)據(jù)庫表。


每個(gè)訂閱者,都盡可能快地從這些數(shù)據(jù)源產(chǎn)生的log中獲取新的記錄,應(yīng)用于本地的存儲系統(tǒng),并且提升其在log中的讀取偏移(offset)。訂閱者可以是任何數(shù)據(jù)系統(tǒng),比如緩存、Hadoop、另一個(gè)站點(diǎn)的數(shù)據(jù)庫,或者搜索引擎。


Log,實(shí)際上提供了一種邏輯時(shí)鐘,針對數(shù)據(jù)變化,可以測量不同的訂閱者所處的狀態(tài),因?yàn)檫@些訂閱者在log中的讀取偏移不同且相互獨(dú)立,這種偏移就像一個(gè)時(shí)間意義上的“時(shí)刻”一樣。



考慮這樣一個(gè)例子,一個(gè)數(shù)據(jù)庫,和一些緩存服務(wù)器:


Log提供了這樣一種能力,可以使得所有的緩存服務(wù)器得到同步,并推出它們所處的“時(shí)刻”。


假設(shè)我們寫入了一個(gè)編號為X的log,要從某個(gè)緩存服務(wù)器讀取數(shù)據(jù),為了不讀到老數(shù)據(jù),只需要保證:在緩存服務(wù)器將數(shù)據(jù)(同步)復(fù)制到X這個(gè)位置前,我們不從這個(gè)緩存中讀取任何東西即可。


此外,log還提供了作為緩沖區(qū)的能力,以支持生產(chǎn)者和消費(fèi)者的行為以異步的方式進(jìn)行。


最關(guān)鍵的一個(gè)支持異步的原因,是訂閱系統(tǒng)可能會發(fā)生崩潰、因維護(hù)而下線,接著恢復(fù)上線,而在這種情況下,每個(gè)訂閱者都以自己的步調(diào)消費(fèi)數(shù)據(jù)。


一個(gè)批處理系統(tǒng),比如Hadoop,或者一個(gè)數(shù)據(jù)倉庫,是以小時(shí)或天為單位消費(fèi)數(shù)據(jù),而一個(gè)實(shí)時(shí)系統(tǒng),通常在秒級消費(fèi)數(shù)據(jù)。


而數(shù)據(jù)源或者log,對消費(fèi)數(shù)據(jù)的訂閱者一無所知,所以,需要在pipeline中做到無縫的添加訂閱者和移除訂閱者。


更重要的是,訂閱者,只需要知道log,而不需要對其所消費(fèi)的數(shù)據(jù)的來源有任何了解,無論這個(gè)數(shù)據(jù)源是RDBMS、Hadoop,還是一個(gè)最新流行的K-V數(shù)據(jù)庫,等等。


之所以討論log,而不是消息系統(tǒng),是因?yàn)椴煌南⑾到y(tǒng)所保證的特性不同,并且用消息系統(tǒng)這個(gè)詞,難以全面和精確表達(dá)某種語義,因?yàn)橄⑾到y(tǒng),更重要的在于重定向消息。


但是,可以將log理解為這樣一種消息系統(tǒng),其提供了持久性保證及強(qiáng)有序的語義,在通訊系統(tǒng)中,這稱作原子廣播。


2.4 在Linkedin

Linkedin目前的主要系統(tǒng)包括(注:2013年):


  • Search

  • Social Graph

  • Voldemort (K-V存儲)

  • Espresso (文檔存儲)

  • Recommendation engine

  • OLAP query engine

  • Hadoop

  • Terradata

  • Ingraphs (監(jiān)控圖譜及metrics服務(wù))


每個(gè)系統(tǒng),都在其專業(yè)的領(lǐng)域提供專門的高級功能。


(這一段太長太長了,Jay兄十分能侃啊,所以挑重點(diǎn)的來記吧?。?/p>


1) 之所以引入數(shù)據(jù)流這個(gè)概念,是因?yàn)橐趏racle數(shù)據(jù)庫的表之上,建立一個(gè)抽象的緩存層,為搜索引擎的索引構(gòu)建和社交圖譜更新,提供拓展能力。


2) 為了更好的處理linkedin的一些推薦算法,開始搭Hadoop集群,但團(tuán)隊(duì)在此塊的經(jīng)驗(yàn)尚淺,所以走了很多彎路。


3) 開始時(shí),簡單粗暴地認(rèn)為只要將數(shù)據(jù)從oracle數(shù)據(jù)倉庫中拉出來,丟進(jìn)hadoop就可以了。結(jié)果發(fā)現(xiàn):第一,將數(shù)據(jù)從oracle數(shù)據(jù)倉庫快速導(dǎo)出是個(gè)噩夢;第二,也是更糟糕的一點(diǎn),數(shù)據(jù)倉庫中某些數(shù)據(jù)的處理不對,導(dǎo)致了hadoop的批處理任務(wù)不能按預(yù)期輸出結(jié)果,且通過hadoop批處理執(zhí)行任務(wù),通常不可逆,特別是在出了報(bào)表之后。


4) 最后,團(tuán)隊(duì)拋棄了從數(shù)據(jù)倉庫中出數(shù)據(jù)的方式,直接以數(shù)據(jù)庫和logs為數(shù)據(jù)源。接著,造出了一個(gè)輪子:K-V 存儲(Voldemort)。


5) 即使是數(shù)據(jù)拷貝這樣不高大上的活兒,也占據(jù)了團(tuán)隊(duì)大量的時(shí)間去處理,更糟的是,一旦數(shù)據(jù)處理的pipeline中有個(gè)點(diǎn)出錯(cuò),hadoop立馬變得廢柴,因?yàn)樵倥1频乃惴ㄅ茉阱e(cuò)誤的數(shù)據(jù)上,只有一個(gè)后果,就是產(chǎn)生更多的錯(cuò)誤數(shù)據(jù)。


6) 即使團(tuán)隊(duì)構(gòu)建的東西抽象層次很高,針對每種數(shù)據(jù)源還是需要特定的配置,而這也是很多錯(cuò)誤和失敗的根源。


7) 一大批程序員想跟進(jìn),每個(gè)程序員都有一大批的想法,集成這個(gè)系統(tǒng),添加這個(gè)功能,整合這個(gè)特色,或者想要自定義的數(shù)據(jù)源。


8) Jay哥開始意識到:


第一, 雖然他們構(gòu)建的pipelines還很糙,但是卻極其有價(jià)值。即使是解決了數(shù)據(jù)在新的系統(tǒng)(如hadoop)中可用的問題,也解鎖了一大批可能性。以前難做的計(jì)算開始變?yōu)榭赡?。新的產(chǎn)品和分析,僅需要解鎖其它系統(tǒng)中的數(shù)據(jù),并且進(jìn)行整合,就可以容易地做出來。


第二, 很明顯,可靠地?cái)?shù)據(jù)裝載需要更堅(jiān)實(shí)的支撐,如果能夠捕獲所有的結(jié)構(gòu),就可以讓hadoop數(shù)據(jù)裝載完全自動化,不需要加入新的數(shù)據(jù)源或人工修改數(shù)據(jù)的模式。數(shù)據(jù)會神奇地出現(xiàn)在HDFS中,而新的數(shù)據(jù)源加入后,Hive的表會用合適的列自動化地、自適應(yīng)地生成。


第三,數(shù)據(jù)覆蓋度遠(yuǎn)遠(yuǎn)不足。因?yàn)橐幚砗芏嘈碌臄?shù)據(jù)源,很難。


9) 為了解決新數(shù)據(jù)源加入后的數(shù)據(jù)裝載問題,團(tuán)隊(duì)開始了這樣的嘗試:



很快,他們發(fā)現(xiàn)這樣搞行不通,因?yàn)榘l(fā)布和訂閱、生產(chǎn)和消費(fèi),數(shù)據(jù)流通常還是雙向的,這成了一個(gè)O(n^2)的問題。


所以,他們需要的是這樣的模型:



需要將每個(gè)消費(fèi)者從數(shù)據(jù)源隔離,理想的情況下,這些消費(fèi)者只和一個(gè)data repository進(jìn)行交互,而這個(gè)repository可以提供它們訪問任意數(shù)據(jù)的能力。


10)消息系統(tǒng) + log = Kafka,kafka橫空出世。


2.5 Log和ETL、數(shù)據(jù)倉庫的關(guān)系


2.5.1 數(shù)據(jù)倉庫

1) 一個(gè)裝有干凈的、結(jié)構(gòu)化的、集成的數(shù)據(jù)repository,用于分析。


2) 雖然想法很美好,但是獲取數(shù)據(jù)的方式有點(diǎn)過時(shí)了:周期性地從數(shù)據(jù)庫獲取數(shù)據(jù),將其轉(zhuǎn)換為某種可讀性更佳的格式。


3) 之前的數(shù)據(jù)倉庫問題在于:將干凈的數(shù)據(jù)和數(shù)據(jù)倉庫高度耦合。


數(shù)據(jù)倉庫,應(yīng)該是一組查詢功能的集合,這些功能服務(wù)于報(bào)表、搜索、ad hot 分析,包含了計(jì)數(shù)(counting)、聚合(aggregation)、過濾(filtering)等操作,所以更應(yīng)該是一個(gè)批處理系統(tǒng)。


但是將干凈的數(shù)據(jù)和這樣的一種批處理系統(tǒng)高度耦合在一起,意味著這些數(shù)據(jù)不能被實(shí)時(shí)系統(tǒng)消費(fèi),比如搜索引擎的索引構(gòu)建、實(shí)時(shí)計(jì)算和實(shí)時(shí)監(jiān)控系統(tǒng),等等。


2.5.2 ETL

Jay哥認(rèn)為,ETL無非做兩件事:


1) 對數(shù)據(jù)進(jìn)行抽取和清洗,將數(shù)據(jù)從特定的系統(tǒng)中解鎖


2) 重構(gòu)數(shù)據(jù),使其能通過數(shù)據(jù)倉庫進(jìn)行查詢。比如將數(shù)據(jù)類型變?yōu)檫m配某個(gè)關(guān)系型數(shù)據(jù)庫的類型,將模式轉(zhuǎn)換為星型或者雪花模式,或者將其分解為某種面向列的存儲格式。


但是,將這兩件事耦合在一起,問題很大,因?yàn)榧珊蟮?、干凈的?shù)據(jù),本應(yīng)能被其它實(shí)時(shí)系統(tǒng)、索引構(gòu)建系統(tǒng)、低延時(shí)的處理系統(tǒng)消費(fèi)。


數(shù)據(jù)倉庫團(tuán)隊(duì),負(fù)責(zé)收集和清洗數(shù)據(jù),但是,這些數(shù)據(jù)的生產(chǎn)者往往因?yàn)椴幻鞔_數(shù)據(jù)倉庫團(tuán)隊(duì)的數(shù)據(jù)處理需求,導(dǎo)致輸出很難被抽取和清洗的數(shù)據(jù)。


同時(shí),因?yàn)楹诵臉I(yè)務(wù)團(tuán)隊(duì)對和公司的其它團(tuán)隊(duì)保持步調(diào)一致這件事兒不敏感,所以真正能處理的數(shù)據(jù)覆蓋度很低,數(shù)據(jù)流很脆弱,很難快速應(yīng)對變化。


所以,更好的方式是:



如果想在一個(gè)干凈的數(shù)據(jù)集上做點(diǎn)搜索、實(shí)時(shí)監(jiān)控趨勢圖、實(shí)時(shí)報(bào)警的事兒,以原有的數(shù)據(jù)倉庫或者h(yuǎn)adoop集群來作為基礎(chǔ)設(shè)施,都是不合適的。更糟的是,ETL所構(gòu)建的針對數(shù)據(jù)倉庫的數(shù)據(jù)加載系統(tǒng),對其它(實(shí)時(shí))系統(tǒng)點(diǎn)兒用沒有。


最好的模型,就是在數(shù)據(jù)發(fā)布者發(fā)布數(shù)據(jù)之前,就已經(jīng)完成了數(shù)據(jù)的清洗過程,因?yàn)橹挥邪l(fā)布者最清楚它們的數(shù)據(jù)是什么樣的。而所有在這個(gè)階段所做的操作,都應(yīng)該滿足無損和可逆。


所有豐富語義、或添加值的實(shí)時(shí)轉(zhuǎn)換,都應(yīng)在原始的log發(fā)布后處理(post-processing),包括為事件數(shù)據(jù)建立會話,或者添加某些感興趣的字段。原始的log依舊可被單獨(dú)使用,但是此類實(shí)時(shí)應(yīng)用也派生了新的參數(shù)化的log。


最后,只有對應(yīng)于具體的目標(biāo)系統(tǒng)的數(shù)據(jù)聚合操作,應(yīng)作為數(shù)據(jù)裝載的一部分,比如轉(zhuǎn)換為星型或雪花型模式,以在數(shù)據(jù)倉庫中進(jìn)行分析和出報(bào)表。因?yàn)檫@個(gè)階段,就像傳統(tǒng)的ETL所做的那樣,因?yàn)橛辛朔浅8蓛艉鸵?guī)范的數(shù)據(jù)流,(有了log后)現(xiàn)在變得非常簡單。


2.6 Log文件和事件

以log為核心的架構(gòu),還有個(gè)額外的好處,就是易于實(shí)現(xiàn)無耦合的、事件驅(qū)動的系統(tǒng)。


傳統(tǒng)的 捕獲用戶活動和系統(tǒng)變化的方式,是將此類信息寫入文本日志,然后抽取到數(shù)據(jù)倉庫或者h(yuǎn)adoop集群中進(jìn)行聚合和處理,這個(gè)問題和前面所述的數(shù)據(jù)倉庫和ETL問題類似:數(shù)據(jù)與數(shù)據(jù)倉庫的高度耦合。


在Linkedin,其基于kafka構(gòu)建了事件數(shù)據(jù)處理系統(tǒng)。為各種各樣的action定義了成百上千種事件類型,從PV、用戶對于廣告的趕腳(ad impressions)、搜索,到服務(wù)的調(diào)用和應(yīng)用的異常,等等。


為了體會上述事件驅(qū)動系統(tǒng)的好處,看一個(gè)簡單的關(guān)于事件的例子:
在工作機(jī)會頁面上,提供一個(gè)機(jī)會。這個(gè)頁面應(yīng)該只負(fù)責(zé)如何展示機(jī)會,而不應(yīng)該過多地包含其它邏輯。但是,你會發(fā)現(xiàn),在一個(gè)具有相當(dāng)規(guī)模的網(wǎng)站中,做這件事,很容易就會讓越來越多的與展示機(jī)會無關(guān)的邏輯牽扯進(jìn)來。


比如,我們希望集成以下系統(tǒng)功能:


1) 我們需要將數(shù)據(jù)發(fā)送到hadoop和數(shù)據(jù)倉庫做離線處理。


2) 我們需要統(tǒng)計(jì)頁面瀏覽次數(shù),以確保某些瀏覽不是為了抓取網(wǎng)頁內(nèi)容什么的。


3) 我們需要聚合對此頁面的瀏覽信息,在機(jī)會發(fā)布者的分析頁面上呈現(xiàn)。


4) 我們需要記錄某用戶對此頁面的瀏覽記錄,以確保我們對此用戶提供了有價(jià)值的、體驗(yàn)良好的任何適宜此用戶的工作機(jī)會,而不是對此用戶一遍又一遍地重復(fù)展示某個(gè)機(jī)會(想想老婆不在家才能玩的游戲吧,那紅綠藍(lán)閃爍的特效,配合那勁爆的DJ風(fēng)舞曲,或者那搖擺聚焦的事業(yè)峰和齊X小短裙的girls,然后點(diǎn)進(jìn)去才發(fā)現(xiàn)是標(biāo)題黨的ad吧?。?。


5) 我們的推薦系統(tǒng)需要記錄對此頁面的瀏覽記錄,以正確地追蹤此工作機(jī)會的流行度。


很快,僅僅展示機(jī)會的頁面邏輯,就會變得復(fù)雜。當(dāng)我們在移動端也增加了此機(jī)會的展示時(shí),不得不把邏輯也遷移過去,這又加劇了復(fù)雜程度。還沒完,糾結(jié)的東西是,負(fù)責(zé)處理此頁面的工程師,需要有其它系統(tǒng)的知識,以確保上述的那些功能能正確的集成在一起。


這只是個(gè)極其簡單的例子,在實(shí)踐中,情況只會更加復(fù)雜。


事件驅(qū)動可以讓這件事變得簡單。


負(fù)責(zé)呈現(xiàn)機(jī)會的頁面,只需要呈現(xiàn)機(jī)會并記錄一些和呈現(xiàn)相關(guān)的因素,比如工作機(jī)會的相關(guān)屬性,誰瀏覽了這個(gè)頁面,以及其它的有用的與呈現(xiàn)相關(guān)的信息。頁面不需要保持對其它系統(tǒng)的知識和了解,比如推薦系統(tǒng)、安全系統(tǒng)、機(jī)會發(fā)布者的分析系統(tǒng),還有數(shù)據(jù)倉庫,所有的這些系統(tǒng)只需要作為訂閱者,訂閱這個(gè)事件,然后獨(dú)立地進(jìn)行它們各自的處理即可,而呈現(xiàn)機(jī)會的頁面不需要因?yàn)樾碌挠嗛喺呋蛳M(fèi)者的加入而做出修改。


2.7 構(gòu)建可擴(kuò)展的log

分離發(fā)布者和訂閱者不新鮮,但是要保證多個(gè)訂閱者能夠?qū)崟r(shí)處理消息,并且同時(shí)保證擴(kuò)展能力,對于log系統(tǒng)來說,是一件比較困難的事。


如果log的構(gòu)建不具備快速、低開銷和可擴(kuò)展能力,那么建立在此log系統(tǒng)之上的一切美好都免談。


很多人可能認(rèn)為log系統(tǒng)在分布式系統(tǒng)中是個(gè)很慢、重型開銷的活兒,并且僅用來處理一些類似于ZooKeeper更適合處理的元數(shù)據(jù)等信息。


但是Linkedin現(xiàn)在(注:2013年),在kafka中每天處理600億條不同的消息寫入(如果算數(shù)據(jù)中心的鏡像的話,那就是幾千億條寫入)。


Jay哥他們怎么做到的呢?


1) 對log進(jìn)行分割(partitioning the log)


2) 通過批量讀寫優(yōu)化吞吐量


3) 避免不必要的數(shù)據(jù)拷貝


通過將log切為多個(gè)partition來提供擴(kuò)展能力:



1) 每個(gè)partition都是有序的log,但是partitions之間沒有全局的順序。


2) 將消息寫入哪個(gè)partition完全由寫入者控制,通過依照某種類型的key(如user_id)進(jìn)行分割。


3) 分割使得log的附加操作,可以不用在分片(sharding)之間進(jìn)行協(xié)調(diào)就進(jìn)行,同時(shí),保證系統(tǒng)的吞吐量和kafka集群的規(guī)模呈線性關(guān)系。


4) 雖然沒有提供全局順序(實(shí)際上消費(fèi)者或者訂閱者成千上萬,討論它們的全局順序一般沒有啥價(jià)值),但是kafka提供了這樣一種保證:發(fā)送者按照什么順序?qū)⑾l(fā)給某個(gè)partition,從這個(gè)partition遞交出去的消息就是什么順序(什么順序進(jìn),什么順序出)。


5) 每個(gè)partition都按照配置好的數(shù)目進(jìn)行復(fù)制,如果一個(gè)leader節(jié)點(diǎn)掛了,其它的節(jié)點(diǎn)會成為新的leader。


6) 一條log,同文件系統(tǒng)一樣,線性的讀寫模式可被優(yōu)化,將小的讀寫log可以組成更大的、高吞吐量的操作。Kafka在這件事上做的很猛。批處理用在了各種場景之下,比如客戶端將數(shù)據(jù)發(fā)送到服務(wù)端、將數(shù)據(jù)寫入磁盤、服務(wù)器之間的數(shù)據(jù)復(fù)制、將數(shù)據(jù)傳送給消費(fèi)者,以及確認(rèn)提交數(shù)據(jù)等場景。


7) 最后,kafka在內(nèi)存log、磁盤log、網(wǎng)絡(luò)中發(fā)送的log上,采用了很簡單的二進(jìn)制格式,以利于利用各種優(yōu)化技術(shù),比如零拷貝數(shù)據(jù)傳輸技術(shù)(zero-copy data transfer)。


諸多的優(yōu)化技術(shù),匯聚起來,可以讓你即使在內(nèi)存爆滿的情形下,也能按照磁盤或網(wǎng)絡(luò)能提供的最大能力進(jìn)行數(shù)據(jù)讀寫。


2.8 Logs和實(shí)時(shí)處理

你以為Jay哥提供了這么個(gè)美麗的方法把數(shù)據(jù)復(fù)制來復(fù)制去就完了?
你!錯(cuò)!了!


Log是流的另一種說法,logs是流處理的核心。


2.8.1 什么是流處理

Jay哥認(rèn)為:


1)流處理是連續(xù)數(shù)據(jù)處理的基礎(chǔ)設(shè)施。


2)流處理的計(jì)算模型,就如同MapReduce或其它分布式處理框架一樣,只是需要保證低延遲。


3)批處理式的收集數(shù)據(jù)模式,導(dǎo)致了批處理式的數(shù)據(jù)處理模式。


4)連續(xù)的收集數(shù)據(jù)模式,導(dǎo)致了連續(xù)的數(shù)據(jù)處理模式。


5)Jay哥講了個(gè)美國人口普查的方式來解釋批處理。


在linkedin,無論是活動數(shù)據(jù)還是數(shù)據(jù)庫的變化,都是連續(xù)的。


批處理按天處理數(shù)據(jù),和連續(xù)計(jì)算將窗口設(shè)為一天雷同。


所以,流處理是這樣一種過程:


6)在處理數(shù)據(jù)時(shí),帶了一個(gè)時(shí)間的概念,不需要對數(shù)據(jù)保持一個(gè)靜態(tài)的快照,所以可以在用戶自定義的頻率之下,輸出結(jié)果,而不必等數(shù)據(jù)集到達(dá)某種“結(jié)束”的狀態(tài)。


7)從這個(gè)意義上講,流處理是批處理的一種泛化,并且考慮到實(shí)時(shí)數(shù)據(jù)的流行程度,這是一種極其重要的泛化。


8)許多商業(yè)公司無法建立流處理引擎,往往因?yàn)闊o法建立流數(shù)據(jù)收集引擎。


9)流處理跨越了實(shí)時(shí)響應(yīng)式服務(wù)和離線批處理的基礎(chǔ)設(shè)施之間的鴻溝。


10)Log系統(tǒng),解決了很多流處理模式中的關(guān)鍵問題,其中最大的一個(gè)問題就是如何在實(shí)時(shí)的多個(gè)訂閱者模式下,提供可用數(shù)據(jù)的問題(流數(shù)據(jù)收集)。


2.9 數(shù)據(jù)流圖譜

流處理中最有趣的地方在于,其拓展了什么是數(shù)據(jù)源(feeds)這一概念。


無論是原始數(shù)據(jù)的logs、feeds,還是事件、一行一行的數(shù)據(jù)記錄,都來自應(yīng)用程序的活動。


但是,流處理還可以讓我們處理來自其它feeds的數(shù)據(jù),這些數(shù)據(jù)和原始數(shù)據(jù),在消費(fèi)者看來,并無二致,而這些派生的feeds可以包含任意程度的復(fù)雜性。



一個(gè)流處理任務(wù),應(yīng)該是這樣的:從logs讀取數(shù)據(jù),將輸出寫入logs或者其它系統(tǒng)。


作為輸入和輸出的logs,連通這些處理本身,和其它的處理過程,構(gòu)成了一個(gè)圖。


事實(shí)上,以log為核心的系統(tǒng),允許你將公司或機(jī)構(gòu)中的數(shù)據(jù)捕獲、轉(zhuǎn)換以及數(shù)據(jù)流,看作是一系列的logs及在其上進(jìn)行寫入的處理過程的結(jié)合。


一個(gè)流處理程序,其實(shí)不必很高大上:可以是一個(gè)處理過程或者一組處理過程,但是,為了便于管理處理所用的代碼,可以提供一些額外的基礎(chǔ)設(shè)施和支持。


引入logs有兩個(gè)目的:


1) 保證了數(shù)據(jù)集可以支持多個(gè)訂閱者模式,及有序。


2) 可以作為應(yīng)用的緩沖區(qū)。這點(diǎn)很重要,在非同步的數(shù)據(jù)處理進(jìn)程中,如果上游的生產(chǎn)者出數(shù)據(jù)的速度更快,消費(fèi)者的速度跟不上,這種情況下,要么使處理進(jìn)程阻塞,要么引入緩沖區(qū),要么丟棄數(shù)據(jù)。
丟棄數(shù)據(jù)似乎不是個(gè)好的選擇,而阻塞處理進(jìn)程,會使得所有的數(shù)據(jù)流的處理圖譜中的處理進(jìn)程卡住。而log,是一種很大,特大,非常大的緩沖區(qū),它允許處理進(jìn)程的重啟,使得某個(gè)進(jìn)程失敗后,不影響流處理圖譜中的其它進(jìn)程。這對于一個(gè)龐大的機(jī)構(gòu)去擴(kuò)展數(shù)據(jù)流是非常關(guān)鍵的,因?yàn)椴煌膱F(tuán)隊(duì)有不同的處理任務(wù),顯然不能因?yàn)槟硞€(gè)任務(wù)發(fā)生錯(cuò)誤,整個(gè)流處理進(jìn)程都被卡住。


Storm和Samza就是這樣的流處理引擎,并且都能用kafka或其它類似的系統(tǒng)作為它們的log系統(tǒng)。


(注:Jay哥相當(dāng)猛,前有kafka,后有samza。)


2.10 有狀態(tài)的實(shí)時(shí)處理

很多流處理引擎是無狀態(tài)的、一次一記錄的形式,但很多用例都需要在流處理的某個(gè)大小的時(shí)間窗口內(nèi)進(jìn)行復(fù)雜的counts , aggregations和joins操作。


比如,點(diǎn)擊流中,join用戶信息。


那么,這種用例,就需要狀態(tài)的支持。在處理數(shù)據(jù)的地方,需要維護(hù)某個(gè)數(shù)據(jù)的狀態(tài)。


問題在于,如何在處理者可能掛掉的情況下保持正確的狀態(tài)?


將狀態(tài)維護(hù)在內(nèi)存中可能是最簡單的,但抵不住crash。


如果僅在某個(gè)時(shí)間窗口內(nèi)維護(hù)狀態(tài),當(dāng)掛掉或者失敗發(fā)生,那么處理可以直接回退到窗口的起點(diǎn)來重放,但是,如果這個(gè)窗口有1小時(shí)那么長,這可能行不通。


還有個(gè)簡單的辦法,就是把狀態(tài)存在某個(gè)遠(yuǎn)程的存儲系統(tǒng)或數(shù)據(jù)庫中,但是這會損失數(shù)據(jù)的局部性并產(chǎn)生很多的網(wǎng)絡(luò)間數(shù)據(jù)往返(network round-trip)。


回憶下,上文中曾提到的數(shù)據(jù)庫中的表和log的對偶性。


一個(gè)流處理組件,可以使用本地的存儲或索引來維護(hù)狀態(tài):


  • Bdb

  • Leveldb

  • Lucene

  • Fastbit


通過記錄關(guān)于本地索引的changelog,用于在crash后恢復(fù)狀態(tài)。這種機(jī)制,其實(shí)也揭示了一種一般化的,可以存儲為任意索引類型的,與輸入流同時(shí)被分割(co-partitioned)的狀態(tài)。


當(dāng)處理進(jìn)程崩潰,其可以從changelog中恢復(fù)索引,log充當(dāng)了將本地狀態(tài)轉(zhuǎn)化為某種基于時(shí)間備份的增量記錄的角色。


這種機(jī)制還提供了一種很優(yōu)雅的能力:處理過程本身的狀態(tài)也可以作為log被記錄下來,顯然,其它的處理過程可以訂閱這個(gè)狀態(tài)。


結(jié)合數(shù)據(jù)庫中的log技術(shù),針對數(shù)據(jù)集成這一場景,往往可以做出很強(qiáng)大的事:


將log從數(shù)據(jù)庫中抽取出來,并在各種各樣的流處理系統(tǒng)中進(jìn)行索引,那么,與不同的事件流進(jìn)行join就成為可能。


2.11 Log 合并

顯然,用log記錄全時(shí)全量的狀態(tài)變更信息,不太可能。


Kafka使用了log合并或者log垃圾回收技術(shù):


1) 對于事件數(shù)據(jù),kafka只保留一個(gè)時(shí)間窗口(可在時(shí)間上配置為幾天,或者按空間來配置)


2) 對于keyed update,kafka采用壓縮技術(shù)。此類log,可以用來在另外的系統(tǒng)中通過重放技術(shù)來重建源系統(tǒng)的狀態(tài)。


如果保持全時(shí)全量的logs,隨著時(shí)間增長,數(shù)據(jù)將會變得越來越大,重放的過程也會越來越長。


Kafka不是簡單地丟棄老的日志信息,而是采用合并的方式,丟棄廢棄的記錄,比如,某個(gè)消息的主鍵最近被更新了。



2.12 系統(tǒng)構(gòu)建

2.12.1 分布式系統(tǒng)

Log,在分布式數(shù)據(jù)庫的數(shù)據(jù)流系統(tǒng)和數(shù)據(jù)集成中所扮演的角色是一致的:


  • 抽象數(shù)據(jù)流

  • 保持?jǐn)?shù)據(jù)一致性

  • 提供數(shù)據(jù)恢復(fù)能力


你可以將整個(gè)機(jī)構(gòu)中的應(yīng)用系統(tǒng)和數(shù)據(jù)流,看作是一個(gè)單獨(dú)的分布式數(shù)據(jù)庫。


將面向查詢的獨(dú)立系統(tǒng),比如Redis , SOLR , Hive tables 等等,看作是一種特別的、數(shù)據(jù)之上的索引。


將Storm、Samza等流處理系統(tǒng),看做一種精心設(shè)計(jì)過的觸發(fā)器或者物化視圖機(jī)制。


各式各樣的數(shù)據(jù)系統(tǒng),爆發(fā)性的出現(xiàn),其實(shí),這種復(fù)雜性早已存在。
在關(guān)系型數(shù)據(jù)庫的輝煌時(shí)期(heyday),某個(gè)公司或者機(jī)構(gòu)光關(guān)系型數(shù)據(jù)庫就有很多種。


顯然,不可能將所有的東西都丟進(jìn)一個(gè)Hadoop集群中,期望其解決所有的問題。所以,如何構(gòu)建一個(gè)好的系統(tǒng),可能會像下面這樣:


構(gòu)建一個(gè)分布式系統(tǒng),每個(gè)組件都是一些很小的集群,每個(gè)集群不一定能完整提供安全性、性能隔離、或者良好的擴(kuò)展性,但是,每個(gè)問題都能得到(專業(yè)地)解決。


Jay哥覺得,之所以各式各樣的系統(tǒng)爆發(fā)性地出現(xiàn),就是因?yàn)橐獦?gòu)建一個(gè)強(qiáng)大的分布式系統(tǒng)十分困難。而如果將用例限制到一些簡單的,比如查詢這樣的場景下,每個(gè)系統(tǒng)都有足夠的能力去解決問題,但是要把這些系統(tǒng)整合起來,很難。


Jay哥覺得在未來構(gòu)建系統(tǒng)這事兒有三種可能:


1) 保持現(xiàn)狀。這種情況下,數(shù)據(jù)集成依然是最頭大的問題,所以一個(gè)外部的log系統(tǒng)就很重要(kafka?。?/p>


2) 出現(xiàn)一個(gè)強(qiáng)大的(如同輝煌時(shí)期的關(guān)系型數(shù)據(jù)庫)能解決所有問題的系統(tǒng),這似乎有點(diǎn)不可能發(fā)生。


3) 新生代的系統(tǒng)大部分都開源,這揭示了第三種可能:數(shù)據(jù)基礎(chǔ)設(shè)施可被離散為一組服務(wù)、以及面向應(yīng)用的系統(tǒng)API,各類服務(wù)各司其事,每個(gè)都不完整,卻能專業(yè)滴解決專門的問題,其實(shí)通過現(xiàn)存的java技術(shù)棧就能看出端倪:


  • ZooKeeper:解決分布式系統(tǒng)的同步、協(xié)作問題(也可能受益于更高抽象層次的組件如helix、curator).


  • Mesos、YARN:解決虛擬化和資源管理問題。


  • 嵌入式的組件Lucene、LevelDB:解決索引問題。


  • Netty、Jetty及更高抽象層次的Finagle、rest.li解決遠(yuǎn)程通訊問題。


  • Avro、Protocol Buffers、Thrift及umpteen zlin:解決序列化問題。


  • Kafka、bookeeper:提供backing log能力。


從某種角度來看,構(gòu)建這樣的分布式系統(tǒng),就像某個(gè)版本的樂高積木一樣。這顯然跟更關(guān)心API的終端用戶沒有太大關(guān)系,但是這揭示了構(gòu)建一個(gè)強(qiáng)大系統(tǒng)并保持簡單性的一條道路:


顯然,如果構(gòu)建一個(gè)分布式系統(tǒng)的時(shí)間從幾年降到幾周,那么構(gòu)建一個(gè)獨(dú)立的龐大系統(tǒng)的復(fù)雜性就會消失,而這種情況的出現(xiàn),一定是因?yàn)槌霈F(xiàn)了更可靠、更靈活的“積木”。


2.12.2 Log在系統(tǒng)構(gòu)建中的地位

如果一個(gè)系統(tǒng),有了外部log系統(tǒng)的支持,那么每個(gè)獨(dú)立的系統(tǒng)就可以通過共享log來降低其自身的復(fù)雜性,Jay哥認(rèn)為log的作用是:


1) 處理數(shù)據(jù)一致性問題。無論是立即一致性還是最終一致性,都可以通過序列化對于節(jié)點(diǎn)的并發(fā)操作來達(dá)到。


2) 在節(jié)點(diǎn)間提供數(shù)據(jù)復(fù)制。


3) 提供“提交”的語義。比如,在你認(rèn)為你的寫操作不會丟失的情況下進(jìn)行操作確認(rèn)。


4) 提供外部系統(tǒng)可訂閱的數(shù)據(jù)源(feeds)。


5) 當(dāng)節(jié)點(diǎn)因失敗而丟失數(shù)據(jù)時(shí),提供恢復(fù)的能力,或者重新構(gòu)建新的復(fù)制節(jié)點(diǎn)。


6) 處理節(jié)點(diǎn)間的負(fù)載均衡。


以上,大概是一個(gè)完整的分布式系統(tǒng)中應(yīng)提供的大部分功能了(Jay哥確實(shí)愛Log?。O碌木褪强蛻舳说腁PI和諸如一些構(gòu)建索引的事了,比如全文索引需要獲取所有的partitions,而針對主鍵的查詢,只需要在某個(gè)partition中獲取數(shù)據(jù)。


(那把剩下的事情也交代下吧,Jay哥威武!)


系統(tǒng)可被分為兩個(gè)邏輯組件(這強(qiáng)大的理解和功力):


1) Log層


2) 服務(wù)層


Log層,以序列化的、有序的方式捕獲狀態(tài)的變化,而服務(wù)層,則存儲外部查詢需要的索引,比如一個(gè)K-V存儲可能需要B-tree、sstable索引,而一個(gè)搜索服務(wù)需要倒排索引。


寫操作既可以直接入log層,也可以通過服務(wù)層做代理。寫入log會產(chǎn)生一個(gè)邏輯上的時(shí)間戳(log的索引),比如一個(gè)數(shù)字ID,如果系統(tǒng)partition化了,那么,服務(wù)層和log層會擁有相同的partitions(但其各自的機(jī)器數(shù)可能不同)。



服務(wù)層訂閱到log層,并且以最快的速度、按log存儲的順序追log,將數(shù)據(jù)和狀態(tài)變化同步進(jìn)自己的本地索引中。


客戶端將會得到read-your-write的語義:


通過對任一一個(gè)節(jié)點(diǎn),在查詢時(shí)攜帶其寫入時(shí)的時(shí)間戳,服務(wù)層的節(jié)點(diǎn)收到此查詢,通過和其本地索引比較時(shí)間戳,如果必要,為了防止返回過期的老數(shù)據(jù),推遲請求的執(zhí)行,直到此服務(wù)節(jié)點(diǎn)的索引同步跟上了時(shí)間戳。


服務(wù)層的節(jié)點(diǎn),也許需要、也許不需要知道leader的概念。在很多簡單的用例中,服務(wù)層可不構(gòu)建leader節(jié)點(diǎn),因?yàn)閘og就是事實(shí)的來源。


還有一個(gè)問題,如何處理節(jié)點(diǎn)失敗后的恢復(fù)問題??梢赃@樣做,在log中保留一個(gè)固定大小的時(shí)間窗口,同時(shí)對數(shù)據(jù)維護(hù)快照。也可以讓log保留數(shù)據(jù)的全量備份并使用log合并技術(shù)完成log自身的垃圾回收。這種方法,將服務(wù)層的眾多復(fù)雜性移至log層,因?yàn)榉?wù)層是系統(tǒng)相關(guān)(system-specific)的,而log層確可以通用。


基于log系統(tǒng),可以提供一組完備的、供開發(fā)使用的、可作為其它系統(tǒng)的ETL數(shù)據(jù)源、并供其它系統(tǒng)訂閱的API。


Full Stack ?。?/p>



顯然,一個(gè)以log為核心的分布式系統(tǒng),其本身立即成為了可對其它系統(tǒng)提供數(shù)據(jù)裝載支持及數(shù)據(jù)流處理的角色。同樣的,一個(gè)流處理系統(tǒng),也可以同時(shí)消費(fèi)多個(gè)數(shù)據(jù)流,并通過對這些數(shù)據(jù)流進(jìn)行索引然后輸出的另一個(gè)系統(tǒng),來對外提供服務(wù)。


基于log層和服務(wù)層來構(gòu)建系統(tǒng),使得查詢相關(guān)的因素與系統(tǒng)的可用性、一致性等因素解耦。


也許很多人認(rèn)為在log中維護(hù)數(shù)據(jù)的單獨(dú)備份,特別是做全量數(shù)據(jù)拷貝太浪費(fèi)、太奢侈,但事實(shí)并非如此:


1) linkedin(注:2013年)的kafka生產(chǎn)集群維護(hù)了每數(shù)據(jù)中心75TB的數(shù)據(jù),而應(yīng)用集群需要的存儲空間和存儲條件(SSD+更多的內(nèi)存)比kafka集群要高。


2) 全文搜索的索引,最好全部裝入內(nèi)存,而logs因?yàn)槎际蔷€性讀寫,所以可以利用廉價(jià)的大容量磁盤。


3) 因?yàn)閗afka集群實(shí)際運(yùn)作在多個(gè)訂閱者的模式之下,多個(gè)系統(tǒng)消費(fèi)數(shù)據(jù),所以log集群的開銷被攤還了。


4) 所有以上原因,導(dǎo)致基于外部log系統(tǒng)(kafka或者類似系統(tǒng))的開銷變得非常小。


2.13 結(jié)語

Jay哥在最后,不僅厚道地留下了很多學(xué)術(shù)、工程上的有價(jià)值的論文和參考鏈接,還很謙遜地留下了這句話:


If you made it this far you know most of what I know about logs.


終。




本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
日志和實(shí)時(shí)流計(jì)算處理
the log:每個(gè)想玩大數(shù)據(jù)的人都該懂點(diǎn)的實(shí)時(shí)數(shù)據(jù)知識(續(xù))
首席工程師揭秘:LinkedIn大數(shù)據(jù)后臺是如何運(yùn)作的
經(jīng)典大數(shù)據(jù)架構(gòu)案例:酷狗音樂的大數(shù)據(jù)平臺重構(gòu)(長文) | 36大數(shù)據(jù)
這5種必知的大數(shù)據(jù)處理框架技術(shù),你的項(xiàng)目到底應(yīng)該使用其中的哪幾種
經(jīng)典|一文讀懂大數(shù)據(jù)處理框架
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服