[譯]從LinkedIn,Apache Kafka到Unix哲學

jopen 9年前發布 | 27K 次閱讀 Apache Kafka

原文鏈接:
http://www.confluent.io/blog/apache-kafka-samza-and-the-Unix-philosophy-of-distributed-data
作者:Martin Kleppmann
譯者:杰微刊-macsokolot(@gmail.com) 

 

當我在為我的書做 研究時,我意識到現代軟件工程仍然需要從20世紀70年代學習很多東西。在這樣一個快速發展的領域,我們往往有一種傾向,認為舊觀念一無是處——因此,最 終我們不得不一次又一次地為同樣的教訓買單,這真艱難。盡管現在電腦已經越來越快,數據量也越來越大,需求也越來越復雜,許多老觀點至今仍有很大的用武之 地。


在這篇文章中,我想強調一個陳舊的觀念,但它現在更應該被關注:Unix哲學(philosophy)。我將展示這種哲學與主流數據庫設計方式截然不同的原因;并探索如果現代分布式數據系統從Unix中學到了一些皮毛,那它在今天將發展成什么樣子。


[譯]從LinkedIn,Apache Kafka到Unix哲學


特別是,我覺得Unix管道與 ApacheKafka有很多相似之處,正是由于這些相似性使得那些大規模應用擁有良好的架構特性。但在我們深入了解它之前,讓我稍稍跟你提一下關于 Unix哲學的基礎。或許,你之前就已經見識過Unix工具的強大之處——但我還是用一個大家相互都能討論的具體例子來開始吧。
假設你有一個web服務器,每次有請求,它就向日志文件里寫一個條目。假設使用nginx的默認訪問日志格式,那么這行日志可能看起來像這樣:


216.58.210.78 - - [27/Feb/2015:17:55:11 +0000] "GET /css/typography.css HTTP/1.1"
200 3377 "http://martin.kleppmann.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X
10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36"


(這里實際上只有一行,分成多行只是方便閱讀。)此行的日志表明,服務器在2015年2月27日17:55:11從客戶端地址216.58.210.78收到了一個文件請求/css/typography.css。它還記錄了其他各種細節,包括瀏覽器的用戶代理字符串。


許多工具能夠利用這些日志文件,并生成您的網站流量報告,但為了練練手,我們建立一個自己的工具,使用一些基本的Unix工具,在我們的網站上確定5個最熱門的網址。首先,我們需要提取出被請求的URL路徑,這里我們可以使用awk.


awk并不知道nginx的日志格式——它只是將日志文件當作文本文件處理。默認情況下,awk一次只能處理一行輸入,一行靠空格分隔,使之能夠作為變量的空格分隔部件$1, $2, etc。在nginx的日志示例中,請求的URL路徑是第7個空格分隔部件:


[譯]從LinkedIn,Apache Kafka到Unix哲學


現在我們已經提取出了路徑,接下來就可以確定服務器上5個最熱門的網站,如下所示:


這一系列的命令執行后輸出的結果是這樣的:


4189 /favicon.ico
3631 /2013/05/24/improving-security-of-ssh-private-keys.html
2124 /2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html
1369 /
915 /css/typography.css


[譯]從LinkedIn,Apache Kafka到Unix哲學


如果你并不熟悉Unix工具的 話,上述命令看起來有點難懂,但它真的很強大。這幾條簡單的命令能夠在幾秒鐘內處理千兆字節的日志文件,而且你可以根據需要,非常容易地更改分析內容。比 如說,你現在想統計訪問次數最多的客戶端IP地址,而不是最熱門的那幾個網頁,只需更改awk的參數'{print $1}'


按需求使用這些組合命令awk, sed, grep, sort, uniq , xargs的話,海量數據分析能夠在幾分鐘內完成,其性能表現讓人出乎意料。這不是巧合,是Unix設計哲學的結果。


[譯]從LinkedIn,Apache Kafka到Unix哲學


Unix哲學就是一套設計準 則, 在20世紀60年代末與70年代初,這些準則是在設計和實現Unix系統時才逐漸出現的。關于Unix哲學有非常多的闡述,但有兩點脫穎而出,由Doug McIlroy, Elliot Pinson 和Berk Tague在1978年描述如下:


1. 每個程序只做好一件事。如果有新的任務需求,那就編寫一個新的程序而不是在一個舊的程序上加一個新的“功能”,使其越來越復雜。


2. 期望每個程序的輸出都能是其他程序的輸入,即使是未知的程序。


這些準則是能把各種程序連接成管道的基礎,而有了管道就能完成復雜的處理任務。這里的核心思想就是一個程序不知道或者說不需要關心它的輸入是從哪里來的,輸出要往哪里去:可能是一個文件,或者操作系統的其他程序,又或者是完全由某個開發者開發的程序。


[譯]從LinkedIn,Apache Kafka到Unix哲學


操作系統附帶的工具都是通用的,但是它們被設計成能夠組合起來執行特定任務的較大的程序。


Unix的設計者遵循這種程序 設計方法所帶來的好處有點像幾十年后出現的Agile 和DevOps的成果:腳本與自動化,快速原型編碼(rapid prototyping),增量迭代,友好的測試(being friendly to experimentation),以及將大型項目分解成可控的模塊。再加上CA的改變。(Plus ?a change.)


[譯]從LinkedIn,Apache Kafka到Unix哲學


當你在shell里為2個命令加上管道的標示符,那么shell就會同時啟動這2個命令程序,然后將第一個程序處理的輸出結果作為第二個程序的輸入。這種連接機構由操作系統提供管道系統調用服務。

請注意,這種線性處理不是由程序本身來完成的,而是靠shell——這就使得每個程序之間是“松耦合”,這使得程序不用擔心它們的輸入從哪里來,輸出要往哪里去。


[譯]從LinkedIn,Apache Kafka到Unix哲學


1964年,管道(Pipe)由Doug McIlroy發明,他首次在Bell實驗室內部備忘錄里將其描述為:“我們需要一些連接各種程序的方法就像花園里的軟管——當它成為另一種必要的消息數據時,需要擰入其他的消息段。” Dennis Richie后來將他的觀點寫進了備忘錄


[譯]從LinkedIn,Apache Kafka到Unix哲學


他們也很早就意識到進程間的通信機制(管道)與讀寫文件機制非常相似。我們現在稱之為輸入重定向(用一個文件內容作為一個程序的輸入)和輸出重定向(將一個程序的結果輸出到一個文件)。


Unix程序之所以能夠有這么高的組合靈活性,是因為這些程序都遵循相同的接口:大多數程序都有一個數據輸入流(stdin)和兩個輸出流(stdout常規數據輸出流和stderr錯誤與診斷信息輸出流)。


[譯]從LinkedIn,Apache Kafka到Unix哲學


程序通常除了讀stdin流和寫stdout流之外,它們還可以做其它的事,比如讀取和寫入文件,在網絡上通信,或者繪制一個用戶界面。然而,該stdin/stdout通信被認為是數據從一個Unix工具流向另一個的最主要的途徑。


其實,最令人高興的事莫過于任何人可以使用任意語言輕松地實現stdin/stdout接口。你可以開發自己的工具,只要其遵循這個接口,那么你的工具能和其他標準工具一樣高效,并能作為操作系統的一部分。


[譯]從LinkedIn,Apache Kafka到Unix哲學


舉個例子,當你想分析一個 web服務器的日志文件,或許你想知道來自每個國家的訪問量有多少。但是這個日志并沒有告訴你國家信息,只是告訴了你IP地址,那么你可以通過IP地理數 據庫將IP地址轉換成國家。默認情況下,你的操作系統并沒有附帶這個數據庫,但是你可以編寫一個將IP地址放進stdin流,將輸出國家放進stdout 流的工具。


一旦你把這個工具寫好了,你就可以將它使用在我們之前討論過的數據處理管道里,它將會工作地很好。如果你已經使用了Unix一段時間,那么這樣做似乎很容易,但是我想強調這樣做非常了不起:你自己的代碼程序與操作系統附帶的那些工具地位是一樣的。


圖形用戶界面的程序和Web應用似乎不那么容易能夠被拓展或者像這樣串起來。你不能用管道將Gmail傳送給一個獨立的搜索引擎應用,然后將結果輸出到wiki上。但是現在是個例外,跟往常不一樣的是,現在也有程序能夠像Unix工具一樣能夠協同工作。


[譯]從LinkedIn,Apache Kafka到Unix哲學


換個話題。在Unix系統開發的同時,關系型數據模型就被提出來了,不久就演變成了SQL,被運用到很多主流的數據庫中。許多數據庫實際上仍在Unix系統上運行。這是否意味著它們也遵循Unix哲學?


[譯]從LinkedIn,Apache Kafka到Unix哲學


在大多數據庫系統中數據流與 Unix工具中非常不同。不同于使用stdin流和stdout流作為通信渠道,數據庫系統中使用DB server以及多個client。客戶端(Client)發送查詢(queries)來讀取或寫入服務器上的數據,server端處理查詢 (queries)并發送響應給客戶端(Client)。這種關系從根本上是不對稱的:客戶和服務器都是不同的角色。


[譯]從LinkedIn,Apache Kafka到Unix哲學


Unix系統里可組合性和拓展性是指什么?客戶端(Clients)能做任何他們喜歡的事(因為他們是程序代碼),但是DB Server大多是在做存儲和檢索數據的工作,運行你寫的任意代碼并不是它們的首要任務。


也就是說,許多數據庫提供了一些方法,你能用自己的代碼去擴展數據庫服務器功能。例如,在許多關系型數據庫中,讓你自己寫存儲過程,基本的程序語言如PL / SQL(和一些讓你在通用編程語言上能運行代碼比如JavaScript)。然而,你可以在存儲過程中所做的事情是有限的。


其他拓展方式,像某些數據庫支持用戶自定義數據類型(這是Postgres的早期設計目標),或者支持可插拔的數據引擎。基本上,這些都是插件的接口:

你可以在數據庫服務器中運行你的代碼,只要你的模塊遵循一個特定用途的數據庫服務器的插件接口。


這種擴展方式并不是與我們看到的Unix工具那樣的可組合性一樣。這種插件接口完全由數據庫服務器控制,并從屬于它。你寫的擴展代碼就像是數據庫服務器家中一個訪客,而不是一個平等的合作伙伴。


[譯]從LinkedIn,Apache Kafka到Unix哲學


這種設計的結果是,你不能用管道將一個數據庫與另一個連接起來,即使他們有相同的數據模型。你也不能將自己的代碼插入到數據庫的內部處理管道(除非該服務器已明確提供了一個擴展點,如觸發器)。


我覺得數據庫設計是很以自我為 中心的。數據庫似乎認為它是你的宇宙的中心:這可能是你要存儲和查詢數據,數據真正來源,和所有查詢最終抵達的唯一地方。你得到管道數據最近的方式是通過 批量加載和批量傾倒(bulk-dumping)(備份)操作,但這些操作不能真正使用到數據庫的任何特性,如查詢規劃和索引。


如果數據庫遵循Unix的設計 思想,那么它將是基于一小部分核心原語,你可以很容易地進行結合,拓展和隨意更換。而實際上,數據庫猶如極其復雜,龐大的野獸。Unix也承認操作系統不 會讓你真的為所欲為,但是它鼓勵你去拓展它,你或許只需一個程序就能實現數據庫系統想要實現所有的功能。


[譯]從LinkedIn,Apache Kafka到Unix哲學


在只有一個數據庫的簡單應用中,這種設計可能還不錯。


然而,在許多復雜的應用中,他們用各種不同的方式處理他們的數據:對于OLTP需要快速隨機存取,數據分析需要大序列掃描,全文搜索需要倒排索引,用于連接的數據圖索引,推薦引擎需要機器學習系統,消息通知需要的推送機制,快速讀取需要各種不同的緩存表示數據,等等。


一個通用數據庫可以嘗試將所有 這些功能集中在一個產品上(“一個適合所有”),但十有八九,這個數據庫不會為了某個特定的功能而只執行一個工具程序。在實踐中,你可以經常通過聯合各種 不同的數據存儲和檢索系統得到最好的結果:例如,你可以把相同的數據并將其存儲在關系數據庫中,方便其隨機訪問,在Elasticsearch進行全文搜 索,在Hadoop中做柱狀格式分析,并以非規范化格式在memcached中緩存。


當你需要整合不同的數據庫,缺乏Unix風格的組合性對于整合來說是一個嚴重的限制。(我已經完成了從Postgres中用管道將數據輸出到其他應用程序,但這還有很長的路要走,直到我們可以簡單地用管道將任一數據庫中的數據導出到其他數據庫。)


[譯]從LinkedIn,Apache Kafka到Unix哲學


我們說Unix工具可組合性是因為它們都實現相同的接口——stdin,stdout和stderr——它們都是文件描述符,即:可以像文件一樣讀寫的字節流。這個接口很簡單以致于任何人都可以很容易地實現它,但它也足夠強大,你可以使用它做任何東西。


因為所有的Unix工具實現相 同的接口,我們把它稱為一個統一的接口。這就是為什么你可以毫不猶豫地用管道將gunzip數據輸出WC中去,即使開發這兩個工具的作者可能從來沒有交流 過。這就像樂高積木,它們都用相同的模式實現節位和槽位,讓你堆樂高積木的時候能夠隨心所欲,不用管它們的形狀,大小和顏色。


[譯]從LinkedIn,Apache Kafka到Unix哲學


Unix文件描述符的統一接口 并不僅僅適用于輸入和輸出的過程,它是一個非常廣泛的應用模式。如果你在文件系統上打開一個文件,你將得到一個文件描述符。管道和Unix套接字提供一個 文件標識符,這個標示符能夠在同一機器上為其它程序提供一個通信通道。在Linux中,/dev下的虛擬文件是設備驅動程序的接口,所以你在這里面可以跟 USB端口甚至GPU打交道。/proc下的虛擬文件是內核的API,但是它是以文件形式存在,你可以使用相同的工具,以普通文件的方式訪問它。


即使是通過TCP連接到另外一臺機器上的程序也是一個文件描述符,雖然BSD套接字API(最常用來建立TCP連接)不像Unix。Plan 9顯示,即使是網絡可以被完全集成到相同的統一接口中去。


可以做這樣一個類比,所有東西 在Unix里都是一個文件。這樣的統一性從邏輯上來說將Unix下的工具就像一根線分成了很多段,使其更加能夠靈活組合。 sed 根本就不需要關心與其交互的是一個管道還是其他的程序,或者一個套接字,或者設備驅動程序,又或者是一個真正在文件系統上的文件。因為這些都是一樣的。


[譯]從LinkedIn,Apache Kafka到Unix哲學


一個文件是一些字符流,或許在某個位置會有文件末尾(EOF)的標識,這就說明這個字符流到此為止了(字符流可以是任意長度,因此程序不能提前預知這個輸入流有多長)


一些工具(如gzip)純粹是操作字節流,而不關心數據的結構是什么樣子。但是大多數工具需要對輸入流進行轉碼,以便能做更有用的事情。為此,大多數Unix工具在一行的每個記錄上,在制表符或空格或逗號分隔的區域上使用ASCII碼。


如今,這種字節流文件顯然是一種很好的統一接口的體現。然而,Unix的實現者對文件的處理卻是截然不同的。例如,他們也許用函數回調接口處理方式,使用一個事務在進程與進程之間傳遞記錄。或者他們用共享內存的方式(像之后的System V IPC o mmap一樣)。又或者使用比特流而不是字節流的處理方式。


在某種意義上講,字節流是能夠達統一的最低標準— —可能是最簡單的接口。一切都可以用字節流來表示,但是對于傳輸媒介來說根本不知道它是什么(與另一個進程連接的管道,磁盤文件、TCP 連接、磁帶等等)。這也是一種劣勢,我們稍后再討論這個問題。


[譯]從LinkedIn,Apache Kafka到Unix哲學


我們看到Unix為軟件開發帶來了很多很好的設計原則,而數據庫系統走的卻是另一條大道。我很高興能夠看到這樣一個未來:我們能從這兩家學習到各自的核心思想,然后將它們結合起來。


那么怎么樣把Unix哲學運用到21世紀的數據系統中,使其變得更好呢?在接下來的內容中,我將探索數據庫系統的世界到底會變成什么樣。


[譯]從LinkedIn,Apache Kafka到Unix哲學


首先,讓我們承認,Unix并不完美。盡管我認為簡單,統一接口的字節流是非常成功的,這使得這個生態系統擁有靈活性,可組合性,以及擁有功能強大的工具,但Unix也有一定的局限性:


1.  它只能在單一機器上使用。隨著應用程序需要處理更多數據和流量,并要求更高的正常運行時間,因此分布式系統將成為必然趨勢。雖然TCP連接似乎能夠被當成 文件處理,但我不認為這是合理的方案:因為這只在雙方連接都已經打開的情況下工作,而且這里還有一點語義混亂的味道(somewhat messy edge case semantics)。


縱然TCP很好,但作為分布式管道的實現,它過于低級了。


2. Unix中管道被設計成只有一個發送者進程和一個接受者進程。你不能通過管道將輸出發送到多個進程,或者從幾個進程中收集輸入。(你可以用tee分支一條管道,但一個管道本身就是一對一。)


3. ASCII文本(或者,UTF-8)能夠很好使數據更加可控(explorable),但這很快就會變得很糟糕。每個進程需要給各自的輸入進行轉碼:首先,將字節流分解成記錄(通常通過換行符分隔,當然有人主張用 0x1e-ACSII記錄分割器)。然后將記錄再分解成各個域,就像在前文awk提到的$7。出現在數據中的分隔字符需要以某種方式進行轉義。即使是一個相當簡單的工具如xargs,約有大半的命令選項來確定輸入需要怎樣進行解析。基于文本接口使用起來相當好,但回想起來,我敢肯定,更豐富的數據模型,清晰的事務模式會更好些。


4. Unix處理進程通常不能長久的運行。例如,如果處于管道中間的處理進程崩潰了,那么沒有辦法從當前輸入管道恢復,使得整個管道任務失敗,必須從頭開始運 行。如果這些命令運行只有幾秒鐘那是沒有問題的,但如果一個應用程序預計需要連續運行多年,這就需要更好的容錯能力。

我想我們可以找到一個解決方案,既克服這些缺點,又傳承Unix哲學。


[譯]從LinkedIn,Apache Kafka到Unix哲學


最令人興奮的事是,這樣的解決方案其實早就存在,那就是這兩個開源項目—— KafkaSamza,它們協同工作能夠提供分布式流處理服務。


你也許在這個博客其他文章中已經了解到這兩個項目,Kafka是一個可擴展分布式消息代理,而Samza是一個框架,這個框架讓你的代碼能夠生產和消費數據流。


[譯]從LinkedIn,Apache Kafka到Unix哲學


事實上,當你用Unix標準去剖析Kafka,它看起來很像一個管道——將一個進程的輸出與另一個進程的輸入相連。Samza看起來更像一個標準的庫,這個庫可以幫助你讀stdin流和寫stdout流(還有一些有用的功能,如部署機制,狀態管理,度量工具(metrics)和監測)。


Kafka 和Samzaz中,流處理任務的風格,有點像Unix傳統的精簡且可組合的工具。


1.  在Unix中,操作系統內核提供了一個管道,一個進程從另一個進程中獲取字節流的傳輸機制。


2.  在流處理中,Kafka提供了發布-訂閱流(publish-subscribe streams),一個流處理任務能夠從另一個流處理任務獲取消息的傳輸機制。


[譯]從LinkedIn,Apache Kafka到Unix哲學


Kafka解決了我們前面討論過的有關Unix 管道的缺點:


1. 單機限制被解除:Kafka本身就是分布式的,并且任何使用它的流處理器也可以分布在多臺機器上。


2. Unix管道連接一個進程的輸出與一個進程的輸出,而Kafka流可以有多個生產者和消費者。多輸入對于在多臺機器上分布的服務至關重要,而多輸出使卡夫 卡更像一個廣播頻道。這非常有用,因為它允許相同的數據流獨立地、因為不同的目的而被消耗(包括監控和審核的目的,這些往往是外部應用程序本身)。在 Kafka中,消費者往往來去都比較自由,而不會影響其他消費者。


3. Kafka還提供了良好的容錯性:數據被復制到多個Kafka節點,所以如果一個節點失敗,另一個節點可以自動接管。如果某個流處理器節點出錯并重新啟動,那它可以在其最后一個檢查點恢復處理操作。


4. Kafka提供的是一個消息流而不是字節流,這個消息流存儲了第一步輸入的轉碼狀態(將字節流分解成序列化記錄)。每個消息流其實是一個字節數組,因此你 可以使用你最喜歡的序列化格式來定制你的消息:JSON, XML, Avro, Thrift或者Protocol Buffers,這些都是合理的選擇。將一種編碼標準化是非常有意義的,Confluent為Avro提供了一種非常好的架構管理支持。這使得應用程序能用有意義的字段名稱的作為處理對象,不必擔心輸入解析或輸出轉義。它還提供良好的事務推進支持而不會破壞兼容性。


[譯]從LinkedIn,Apache Kafka到Unix哲學


關于Kafka與Unix管道還是有一些不同的,這里指的提一提:


1. 上文提到,Unix管道提供字節流,而Kafka提供的是消息流。特別值得注意的是,如果有多個進程同時對相同的流進行寫入:在一個字節流,來自不同作者 字節流可以交叉存取,將導致出現無法解析錯誤。因為消息具有粗粒度(coarser-grained)和自包含(self-contained)的特性, 它們就可以安全地進行交叉存取,使其多個進程能夠安全地同時寫入相同的流。


2. Unix管道只是一個較小的內存中的緩沖區,而Kafka持續地將所有消息都寫入到磁盤。在這方面,Kafka不太像一個管道,更像是一個寫臨時文件的進 程,而其他幾個進程不斷地讀取這個文件,通過的尾綴-f(每個消費者獨立的跟蹤該文件)。Kafka的這種方式提供了更好的容錯性,因為它允許在消費者出 錯并重新啟動的情況下,不跳過消息。Kafka自動能將這些“臨時”文件分割成段,并能在日程配置里配置舊段垃圾收集計劃。


3. 在Unix中,如果在管道中的消費進程讀取數據非常緩慢,導致緩沖區已滿并阻塞了管道中的發送進程。這是背壓式(backpressure)的一種。在 Kafka中,生產者和消費者都更解耦: 慢消費者有輸入緩沖池,所以它不會使生產者或其他消費者慢下來。只要緩沖區在Kafka的可用磁盤空間內,較慢的消費者也能后來居上。這使得系統對個別緩 慢組件的不太敏感,而組成更強大的整體。


4. 在Kafka中數據流稱為一個topic,你可以參考它的名字(這使它更像Unix中被稱之為的管道pipe)。一個Unix程序管道通常是運行一次,所以管道通常不需要確切的名字。另一方面,一個長期運行的應用程序隨著時間的遷移通常有比特添加,刪除或替換,所以你需要名字,以告訴系統你想連接到哪里。命名也有助于檢索和管理。


盡管有這些不同,我仍然認為Kafka是作為分布式數據的Unix管道。例如,他們有一個共同點是,Kafka讓信息有一個固定的順序(就像Unix管道,使字節流有一個固定的順序一樣)。對于事件日志數據,這是一個非常有用的屬性:事件發生的順序通常是有意義的,這需要保護好。其他類型的消息代理,像AMQP和JMS,就并沒有這種有序性。


[譯]從LinkedIn,Apache Kafka到Unix哲學


所以我們知道Unix工具和流處理器看上去十分相似。都是讀相同輸入流,然后以某種方式修改或改轉換它,并產生一個輸出流,從某種程度上這都來自于輸入。


更重要的是,處理工作不修改輸 入(input)本身:它仍然是不可改變的。如果你在相同的輸入文件上運行AWK,該文件還是處于未修改的狀態(除非你明確選擇覆寫它)。同時,大多數 Unix工具是確定的,即如果你給他們同樣的輸入,他們總是產生相同的輸出。這意味著你可以重新運行相同的命令,想多少次就多少次,然后逐步迭代成你想做 的工作程序。這是個很棒的實驗,因為如果你混亂地進行處理,你還是可以隨時返回到你的原始數據。


這種確定性和無副作用的效果處理看起來很像函數式編程。這并不意味著你必須使用象 Haskell 那樣的函數式編程語言 (如果你想這么做的話也非常歡迎),但你仍然能從函數式代碼中收獲很多。


[譯]從LinkedIn,Apache Kafka到Unix哲學


這種類Unix設計準則的 Kafka,使其能夠構建一個大型的可組合的系統。在大型的公司中,不同的團隊能夠通過Kafka發布各自的數據。每個團隊能夠獨立的開發和維護處理任務 ——消費各種流和生產新的流。因為一個流可以有很多獨立的消費者,產生一個新的消費者不需要事先協調。


我們將這種思想成為流數據平臺。在這種架構中,Kafka數據流扮演的是不同團隊系統溝通的通道。每個組在整個系統中只是負責自己的那部分,并且將這一塊事情做好。正如Unix工具能夠被組合而完成數據處理任務一樣,分布式流系統也以被組合成一個超大規模的處理組織


Unix 方法是通過降低耦合性來控制大系統的復雜性: 多虧了流接口的統一性,每個部件能夠獨立的開發和部署。由于良好的容錯性和管道的緩存性 (Kafka),當問題發生在系統的某個部分時,它仍然只是局部。并且策略管理允許對數據結構作出更改使其更加安全,以便每個團隊可以加快腳步而不打亂其他團隊的步伐。

[譯]從LinkedIn,Apache Kafka到Unix哲學



為總結全文,讓我們思考下發生在 LinkedIn的 一個真實的例子。如你所知,公司可以在 LinkedIn 上發布他們空缺的職位,求職者可以瀏覽并申請這些職位。那么,如果 LinkedIn 會員 (用戶) 查看了這些發布的職位,會發生什么?


知道誰看過哪些職位非常有用,因此該服務會處理職位瀏覽記錄,隨即發布一個事件給Kafka,類似于“會員123在789時刻瀏覽了編號為456的職位”。


現在這些信息都在Kafka里了,那么它將被用來干好多有用的事情:


1. 監視系統:公司用LinkedIn發布他們空缺的職位,因此確保該網站能夠正常的工作很重要。如果職位瀏覽率意外地驟降,那么就應該給出警示,因為這暗示著這里存在問題,需要展開調查。


2. 相關推薦:持續給用戶看同樣的一種東西,那他會很惱火,因此跟蹤并統計用戶瀏覽哪些職位和次數的是一種好的做法,這樣就能將這些數據給評分程序。持續跟蹤哪些用戶瀏覽了什么也能夠對推薦進行協同過濾(用戶既瀏覽了X,也瀏覽了Y)。


3. 防止濫用:LinkedIn并不希望人們能夠把所有職位都瀏覽,然后提交垃圾郵件,或者違反網站服務條款。知道誰在做什么是檢測和阻止濫用的第一步。


4. 職位海報分析:發布職位空缺的公司希望看到統計數據(谷歌分析的一種方式),誰正在查看他們的帖子,例如,他們可以測試哪些措辭能夠吸引最佳候選者。


5. 導入到Hadoop和數據倉庫:可以是LinkedIn的內部業務分析,可以為高層管理人員的提供向導,用于處理數字數據——能在華爾街進行發布,用于A / B測試評估,等等。


所有這些系統都是復雜的,由不同的團隊來維護。Kafka提供了一個可容錯,可擴展式的管道。基于Kafka的數據流的平臺,允許所有這些不同的系統能夠獨立開發,并以強大的方式連接和集成。


如果你喜歡這篇文章,你將同樣會喜歡由O’Reilly出版的Designing Data-Intensive Applications


感謝 Jay Kreps, Gwen Shapira, Michael Noll, Ewen Cheslack-Postava, Jason Gustafson, 和Jeff Hartley 為這篇文章的初稿提出了意見和建議,也要感謝Jay提供了“LinkedIn職位瀏覽”的這樣一個例子。


相關文章


Compression in Apache Kafka is now 34% faster


Getting started with Kafka in node.js with the Confluent REST Proxy


Making Apache Kafka Elastic With Apache Mesos


Hands-free Kafka Replication: A lesson in operational simplicity

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!