《千億級(jí)eBay平臺(tái)的Kafka深度實(shí)踐》要點(diǎn):
本文介紹了千億級(jí)eBay平臺(tái)的Kafka深度實(shí)踐,希望對(duì)您有用。如果有疑問(wèn),可以聯(lián)系我們。
方偉
eBay中國(guó)研發(fā)中心 資深軟件工程師2010年加入eBay,一直在系統(tǒng)平臺(tái)部負(fù)責(zé)設(shè)計(jì)和開(kāi)發(fā)工作.最初負(fù)責(zé)整個(gè)eBay的數(shù)據(jù)庫(kù)應(yīng)用層的開(kāi)發(fā)和優(yōu)化;接著從事用戶行為數(shù)據(jù)的收集,數(shù)據(jù)管道的建立以及部分?jǐn)?shù)據(jù)分析工作,是開(kāi)源項(xiàng)目PulsarIO的主要貢獻(xiàn)者之一;
目前致力于 eBay 的實(shí)時(shí)數(shù)據(jù)傳輸和計(jì)算平臺(tái),基于 Kafka 和 Storm 等開(kāi)源軟件.對(duì)建設(shè)高可用,高擴(kuò)展性,并且可自動(dòng)化運(yùn)維的分布式系統(tǒng)有豐富經(jīng)驗(yàn).
本文主題是我們最近一年做的,基于 Kafka 做的企業(yè)級(jí)數(shù)據(jù)傳輸平臺(tái),我們實(shí)現(xiàn)這個(gè)平臺(tái),以及這個(gè)平臺(tái)最終上線并在對(duì)它運(yùn)維過(guò)程中,得到的心得體會(huì)和經(jīng)驗(yàn)教訓(xùn).
這是本文主要分四部分:
首先是平臺(tái)的概述,什么是數(shù)據(jù)傳輸平臺(tái),我們?yōu)槭裁匆罱ㄟ@個(gè)平臺(tái).
其實(shí)在互聯(lián)網(wǎng)企業(yè)當(dāng)中有很多系統(tǒng),一般來(lái)講我們可以把互聯(lián)網(wǎng)當(dāng)中各個(gè)系統(tǒng)分成兩類:
一類是在線系統(tǒng),在線系統(tǒng)是直接跟用戶打交道的站點(diǎn)系統(tǒng),比如對(duì)于電子商務(wù)網(wǎng)站來(lái)說(shuō),我們有商品瀏覽,商品搜索.我們有賣家發(fā)布商品,我們有商品發(fā)布系統(tǒng).
另一類是離線系統(tǒng),離線系統(tǒng)最主要的比如我們做BI分析,站點(diǎn)報(bào)表,包括財(cái)務(wù)方面的報(bào)表,以及用戶行為的分析,離線系統(tǒng)里我們一般有一些產(chǎn)品,比如大數(shù)據(jù),最近我們會(huì)用 hadoop 做一些數(shù)據(jù)挖掘.
其實(shí)離線系統(tǒng)這些數(shù)據(jù)最終來(lái)源也是從在線系統(tǒng)來(lái)的,那我們?cè)趺礃訌凝嫶笤诰€系統(tǒng)中,把數(shù)據(jù)傳輸?shù)诫x線系統(tǒng),這就是我們需要解決的問(wèn)題.
對(duì)于 eBay 來(lái)講,它的在線系統(tǒng)肯定有好幾萬(wàn)臺(tái),比如我們要采集用戶行為,系統(tǒng)里有好幾個(gè) PB 的關(guān)系型數(shù)據(jù)庫(kù)存儲(chǔ),我們要從數(shù)據(jù)庫(kù)當(dāng)中,把數(shù)據(jù)庫(kù)變化傳輸?shù)胶笈_(tái)離線系統(tǒng)當(dāng)中,怎么做呢?
近年來(lái),對(duì)實(shí)時(shí)計(jì)算的需求越來(lái)越多,很多比如像欺詐檢測(cè),像用戶個(gè)性推薦,這種類型的系統(tǒng),都要求實(shí)時(shí)性,我不想等到一夜過(guò)后這個(gè)數(shù)據(jù)才過(guò)來(lái),我希望馬上拿到數(shù)據(jù),能夠進(jìn)行計(jì)算,得到計(jì)算結(jié)果,然后反饋到其他在線系統(tǒng).
在這種情況下,我們需要一個(gè)實(shí)時(shí)平臺(tái),把數(shù)據(jù)從在線系統(tǒng)傳輸?shù)诫x線系統(tǒng),所以這就是我們?yōu)槭裁匆罱ㄟ@個(gè)傳輸平臺(tái).
我們?yōu)槭裁匆?Kafka ,這里不對(duì) Kafka 做過(guò)多介紹,說(shuō)一下我們看中了 Kafka 哪些點(diǎn),我們?yōu)槭裁磿?huì)最終選用 Kafka 做數(shù)據(jù)傳輸平臺(tái).
其實(shí)我們數(shù)據(jù)傳輸平臺(tái)是很典型消息中間件,消息中間件市面上有很多產(chǎn)品,為什么要用 Kafka 呢?
除此之外它也有很好的伸縮性,你增加 Kafka 節(jié)點(diǎn),處理是直線性增長(zhǎng)的,同時(shí)也可以保證高可用性,像 Kafka 一些節(jié)點(diǎn)宕掉的話,不會(huì)影響到數(shù)據(jù)完整性.
既然選用了 Kafka ,那么 eBay 在 Kafka 上有多少數(shù)據(jù)呢?我們大概放了哪些數(shù)據(jù)在 Kafka 上呢?
目前我們大概有三十多個(gè) Kafka 集群,這些 ?Kafka ?集群主要建立在 eBay 自己的私有云上面,我們基于 OpenStark 搭建的自己私有云,所以我們 Kafka 的節(jié)點(diǎn)都是虛擬機(jī).
我們總共有800多臺(tái)虛擬機(jī),在這些集群里我們總共有1200多個(gè)應(yīng)用跑在上面,這些應(yīng)用總數(shù)加起來(lái)超過(guò)2.5萬(wàn)個(gè),每天消息達(dá)到1000億次以上.所以這個(gè)可以看出這是很典型的大數(shù)據(jù)實(shí)時(shí)傳輸?shù)睦?
那我們?yōu)槭裁匆诌@么多 Kafka 集群?
這個(gè)非常類似數(shù)據(jù)庫(kù)的分庫(kù),我們基于業(yè)務(wù)垂直劃分 Kafka 集群,比如所有用戶行為,用戶點(diǎn)擊、搜索、對(duì)商品的瀏覽等等用戶行為,我們同樣會(huì)放到 Kafka 集群里,對(duì)于所有數(shù)據(jù)庫(kù)變化,比如當(dāng)一個(gè)賣價(jià)要修改一個(gè)價(jià)格,這個(gè)數(shù)據(jù)變化我們會(huì)放在 Kafka 集群里.
比如還有一些站點(diǎn),本身自己想發(fā)出一些業(yè)務(wù)事件,比如當(dāng)一個(gè)商品成交了,這些業(yè)務(wù)事件我們會(huì)放在另外一個(gè)基于 Kafka 的業(yè)務(wù)集群了.
我們知道 LinkedIn 是最初提出 Kafka 的,他們應(yīng)該有60多個(gè) Kafka .
那我們有 Kafka 這樣的開(kāi)源產(chǎn)品,我們是不是可以直接拿來(lái)用呢?不需要做任何事情呢?
當(dāng)然不是,其實(shí) Kafka 提供的是單元功能,作為企業(yè)應(yīng)用來(lái)講,你要做企業(yè)實(shí)時(shí)傳輸平臺(tái)解決方案,需要基于 Kafka 做很多額外服務(wù),每個(gè)企業(yè)總歸該是有一些自身需求,比如企業(yè)對(duì)安全考慮,每個(gè)企業(yè)實(shí)現(xiàn)方式不一樣,企業(yè)數(shù)據(jù)中心分布也是不一樣,對(duì)于不同企業(yè)自身的需求,我們需要做一些額外服務(wù)支持它.
eBay 做了哪些服務(wù)呢?舉一些很簡(jiǎn)單的例子,比如我們想讓一個(gè)用戶在集群上創(chuàng)建他自己的 Kafka ?topic,你不是直接讓他到一個(gè)節(jié)點(diǎn)上,這顯然是不夠安全,同時(shí)也不夠方便.
這樣我們必然要有一個(gè)提供管理功能的服務(wù)器,我們希望提供一個(gè)統(tǒng)一的入口,以及統(tǒng)一的 topic 名稱空間,那么我們就需要引入原數(shù)據(jù)中心的服務(wù).
比如我們?cè)谏虾!⒈本┒加袛?shù)據(jù)中心.我們?cè)趺窗褦?shù)據(jù)從上海遷到北京,這時(shí)候就需要有數(shù)據(jù)鏡像服務(wù).
再比如我們剛剛講到,整個(gè) Kafka 集群是在 openstack 云上面,當(dāng)我們需要建立一個(gè)新集群的時(shí)候,或者一片集群需要修復(fù),或者為這個(gè)集群需要新增節(jié)點(diǎn),或者廢棄節(jié)點(diǎn)的時(shí)候.
我們需要怎樣調(diào)用 openstack 功能完成?同時(shí)我們還有很多監(jiān)控功能的服務(wù),系統(tǒng)日志服務(wù).
我們都是把所有服務(wù)通過(guò)界面形式暴露出來(lái),同時(shí)把它的下端用戶直接到界面上做一些事情,不用非要找到系統(tǒng)管理員才能做,他們可以自己直接做.
以上是我們這個(gè)系統(tǒng)擁有的一些服務(wù),下面我會(huì)就這個(gè)系統(tǒng)里面的服務(wù)做稍微詳細(xì)一點(diǎn)的介紹.
首先是元數(shù)據(jù)服務(wù),為什么要提出元數(shù)據(jù)服務(wù),因?yàn)槲覀兿Mo大家邏輯上提供一個(gè)統(tǒng)一的 topic 名稱空間,比如我希望訪問(wèn)到用戶行為數(shù)據(jù),如果我們沒(méi)有這個(gè)服務(wù)的話,我必須要讓用戶知道你的用戶行為的 Kafka 集群在哪里,還要知道你連到哪一個(gè).
然后 topic 名稱是什么?比如我們從服務(wù)里面直接查詢一個(gè)用戶行為,你直接找到這個(gè) topic,服務(wù)后面會(huì)找到真正的 Kafka 集群在哪里,然后再返回給客戶端,讓它連上來(lái).
除了提供統(tǒng)一名稱空間之外,我們還提出了叫做 topic 分裝的概念,為什么會(huì)有這種東西呢?
因?yàn)槲覀儎偛耪f(shuō)到自服務(wù),我們希望用戶自己創(chuàng)建,如果說(shuō)讓它無(wú)限制創(chuàng)建的話,對(duì)系統(tǒng)資源肯定是傷害,因?yàn)樗恢滥阌卸嗌儋Y源還在那邊,如果他創(chuàng)建太多了,會(huì)把 Kafka 集群宕掉.
這時(shí)候就需要有配額管理,我們這邊引入的單位就是 topic 組,我們創(chuàng)建 topic 的時(shí)候需要系統(tǒng)管理員做審批.
一旦審批通過(guò)了,我會(huì)給 topic 組分配一些配額,比如我在上面創(chuàng)建多少 topic,在上面發(fā)生的網(wǎng)絡(luò)帶寬是多少都可以配置.所以這個(gè)也是便于后面的運(yùn)維管理.
剛才我說(shuō)了這些,都是要由元數(shù)據(jù)服務(wù)提供,那元數(shù)據(jù)服務(wù)怎么工作的呢?
在 Kafka 集群里,你不可能用這些集群本身所帶的管理 topic 去管理元數(shù)據(jù),所以我必須要有元數(shù)據(jù)存儲(chǔ).
我們引入了邏輯層對(duì)三十多個(gè)集群看起來(lái)就像一個(gè)集群,在這種情況下,用戶是不是在使用 Kafka API 的時(shí)候有問(wèn)題,因?yàn)?API 并不能知道你要用哪一個(gè).
我們看這個(gè) Kafka 代理完全實(shí)現(xiàn)了 Kafka 的協(xié)議,這個(gè)協(xié)議定義了很多操作,這些操作是基于 TCP 層的.
我們?nèi)ミ@樣一個(gè)代理,可以完全模擬 Kafka 本身 group 的協(xié)議.對(duì)于客戶端來(lái)說(shuō),是可以用原本 Kafka 的 API 訪問(wèn),這個(gè) API 連接代理就像連接到單獨(dú)的 Kafka 集群一樣,這其實(shí)不是一個(gè)真正的 Kafka 集群,而是后面帶了三個(gè) Kafka 集群.
下面講一下我們鏡像服務(wù),其實(shí)我們有多個(gè)數(shù)據(jù)中心, Kafka 數(shù)據(jù)來(lái)源本身也是來(lái)自數(shù)據(jù)中心.那么我們大家怎樣搭建 Kafka 集群呢?
這里我們有一個(gè)模式 Tier—Aggregation,比如上海和北京都有用戶行為.我們希望做數(shù)據(jù)分析的時(shí)候,要能夠同時(shí)分析到上海、北京的數(shù)據(jù),我需要把兩個(gè)地區(qū)的數(shù)據(jù) run 起來(lái).
比如我們只有兩個(gè)數(shù)據(jù)中心,我們創(chuàng)建四個(gè) Kafka 集群,其中有兩個(gè) location 的數(shù)據(jù).
我們同時(shí)也做到跨數(shù)據(jù)中心的數(shù)據(jù)冗余,比如北京數(shù)據(jù)中心燒掉了,我們上海數(shù)據(jù)中心依然可以把所有數(shù)據(jù)拿出來(lái).
這個(gè)其實(shí)最是也是由 LinkedIn 提出的比較推薦的方式,雖然引入了很多數(shù)據(jù)冗余,但是它保證了它的運(yùn)行.
因?yàn)?Kafka 本身有自己的 location,每個(gè)數(shù)據(jù)來(lái)了以后會(huì)引起三份網(wǎng)絡(luò)流量,這個(gè)網(wǎng)絡(luò)流量是為了讓 Kafka 集群高可用.
如果 Kafka 集群跨數(shù)據(jù)中心的話,所謂的網(wǎng)絡(luò)流量就會(huì)是跨數(shù)據(jù)中心,我們?cè)趺窗褦?shù)據(jù)一個(gè)數(shù)據(jù)中心傳輸?shù)搅硪粋€(gè)數(shù)據(jù)中心,這就是需要用到鏡像服務(wù).
鏡像服務(wù)這方面其實(shí)我們會(huì)有很多管理,比如我多少開(kāi)多少節(jié)點(diǎn),多少線程,怎么啟動(dòng),怎么截止,所有管理工作我們都需要有具體服務(wù)做這樣的事情,也就是我們所說(shuō)的鏡像服務(wù),要實(shí)現(xiàn)具體的服務(wù),但是它暴露出一個(gè)服務(wù)器,讓上層應(yīng)用再去做數(shù)據(jù)鏡像的管理.
除此之外我們還有 Schema 注冊(cè)服務(wù),對(duì)于普通平臺(tái)來(lái)講,所有經(jīng)過(guò)平臺(tái)的數(shù)據(jù)都是可以進(jìn)行管理的,我要求數(shù)據(jù)格式所有人都認(rèn)識(shí),所以我們定義了統(tǒng)一數(shù)據(jù)模式在平臺(tái)里.
Kafka 本身提供了 Schema 組件,背后用 Kafka 做存儲(chǔ),而且高可用也做到了,我們是直接把它拿過(guò)來(lái)用,但是沒(méi)有百分百拿過(guò)來(lái)用.
因?yàn)樗幸欢ǖ木窒扌?比如它不支持健全,所有人都可以來(lái)改,所有人都可以進(jìn)行版本增加.
剛才所講的服務(wù),不管是對(duì)用戶來(lái)講,還是管理員來(lái)講,我們都需要有一個(gè)界面操作它,因?yàn)椴豢赡芩腥硕纪ㄟ^(guò) SSH 去連服務(wù)器.
所以我們有一個(gè)用戶自服務(wù) portal,從 consumer 注冊(cè),producer 注冊(cè),topicgroup 注冊(cè),schema 的注冊(cè).
剛才說(shuō)到了要?jiǎng)?chuàng)建一個(gè)集群,對(duì)集群地面的一些節(jié)點(diǎn)進(jìn)行替換,我們要新增新的節(jié)點(diǎn)等等,我們都需要調(diào) openstack 的功能,但是這個(gè)地方我們需要一個(gè)很迷你的 PaaS 完成這個(gè)系統(tǒng).
我們其實(shí)是基于 openstack 搭建了一個(gè)小的迷你 PaaS,除了提供功能工作流之外,還提供的運(yùn)行工作流管理的功能.
openstack 提供了一套接口做這種事情,但是接口后面必須要選擇一個(gè)基于 ALQP 的協(xié)議,同樣對(duì)于配置也是一樣, Kafka ?默認(rèn)配置是什么樣的,我們也有一些配置優(yōu)化,改了一些配置讓它對(duì)所有節(jié)點(diǎn)優(yōu)化,怎么管理這些配置也是在 Prism 服務(wù)器里做的.
那么說(shuō)了這么多,平臺(tái)最終上線的時(shí)候,我們要對(duì)它進(jìn)行運(yùn)維,運(yùn)維里最重要的是我們要把系統(tǒng)監(jiān)控好,并且當(dāng)它出現(xiàn)問(wèn)題的時(shí)候我們要及時(shí)修復(fù)它.對(duì)于這個(gè)系統(tǒng)監(jiān)控是非常重要的課題.
可以看出來(lái),我們?cè)谶@個(gè)系統(tǒng)中,其實(shí)是涉及到很多節(jié)點(diǎn),對(duì)所有的我們打包起來(lái),讓它完成一個(gè)業(yè)務(wù)語(yǔ)義.
在監(jiān)控方面我們肯定要有統(tǒng)一視角看到一系列集群運(yùn)行狀況,對(duì)于所有集群節(jié)點(diǎn)來(lái)說(shuō),并不是說(shuō)宕一個(gè)節(jié)點(diǎn)就不行了,因?yàn)?Kafka 有數(shù)據(jù)冗余,宕一兩個(gè)節(jié)點(diǎn)是沒(méi)有問(wèn)題的.
所以這里我就列出運(yùn)營(yíng)的節(jié)點(diǎn)是宕的,還是說(shuō)健康的,我們運(yùn)維人員對(duì)宕掉的節(jié)點(diǎn)進(jìn)行修復(fù).我們目前還是用人工的方式進(jìn)行修復(fù),因?yàn)槲覀冃枰治鲞@些也點(diǎn)宕掉的原因.
目前來(lái)講,系統(tǒng)運(yùn)行時(shí)間并沒(méi)有超過(guò)一年,所以我們目前采用了人工的方式.以后我們會(huì)考慮當(dāng)任何一個(gè)節(jié)點(diǎn)出現(xiàn)問(wèn)題的時(shí)候,進(jìn)行自動(dòng)替換,自動(dòng)替換的時(shí)候必然要引入一些規(guī)則,什么情況下可以自動(dòng)停,什么情況下不能自動(dòng)停.
對(duì)于 Kafka 來(lái)講,我們對(duì)每個(gè)節(jié)點(diǎn),還有 Kafka 本身狀態(tài)的監(jiān)控.對(duì)于 Kafka 系統(tǒng)運(yùn)維人員來(lái)說(shuō),這個(gè)節(jié)點(diǎn)的系統(tǒng)資源也是需要監(jiān)控很重要的內(nèi)容,對(duì)于管理員來(lái)講系統(tǒng)狀態(tài)是很重要的.
還有一種情況不僅對(duì)管理員重要,對(duì)用戶也是很重要的,比如 Kafka 狀態(tài)監(jiān)控,對(duì)于用戶來(lái)講,比如我想知道我昨天進(jìn)入 Kafka 集群有多少數(shù)據(jù),所以這個(gè)方面的監(jiān)控,除了給運(yùn)維人員,也提供給系統(tǒng)的用戶.
對(duì)于 consumer 也是一樣,對(duì)于 Kafka 來(lái)講很重要的監(jiān)控是我要知道我的 consumer 到底有一個(gè) leg.
如果這個(gè) leg 一直增加的話,就說(shuō)明 consumer 的應(yīng)用肯定有問(wèn)題的,我必須要對(duì)它進(jìn)行一定處理,所以這個(gè)地方相當(dāng)于我們幫助用戶把這些問(wèn)題嚴(yán)控起來(lái).
發(fā)生問(wèn)題的時(shí)候,不僅 consumer 管理員要知道,它的用戶也要知道,所以報(bào)警系統(tǒng)也是通知到用戶.另外我們有些應(yīng)用是有端到端要求的,我們必須知道數(shù)據(jù)從應(yīng)用發(fā)出來(lái),到進(jìn)到 Kafka ,到底有多長(zhǎng)時(shí)間.
那么在 Kafka 里面,在運(yùn)維過(guò)程我們發(fā)現(xiàn)有一個(gè)很重要的課題,對(duì)于慢節(jié)點(diǎn)怎么處理,什么叫慢節(jié)點(diǎn)?
其實(shí) Kafka 能夠很好的處理節(jié)點(diǎn)壞掉的情況,因?yàn)殄吹粢粌蓚€(gè)節(jié)點(diǎn)對(duì)于它來(lái)說(shuō)不要緊,它可以很快把壞的節(jié)點(diǎn)拿掉,它可以從別的節(jié)點(diǎn)上迅速選過(guò)來(lái).
但是這種慢節(jié)點(diǎn)并沒(méi)有死掉,只是比較慢的工作,比如正常情況下,它的吞吐率只有原來(lái)的1/10,那 Kafka 就不能把它拿掉,我們發(fā)現(xiàn)大部分系統(tǒng)都是存在這種問(wèn)題.
為什么說(shuō)一個(gè)節(jié)點(diǎn)出現(xiàn)性能問(wèn)題,會(huì)影響整個(gè) Kafka 集群呢?我們只有 Kafka 是做數(shù)據(jù)集群的.一旦這個(gè)節(jié)點(diǎn)性能出現(xiàn)問(wèn)題,你到所有其他節(jié)點(diǎn)網(wǎng)絡(luò)連接的數(shù)據(jù)都會(huì)有問(wèn)題.
相當(dāng)于它會(huì)拖累很多其他節(jié)點(diǎn),出去 Kafka 集群在這個(gè)時(shí)候把這個(gè)節(jié)點(diǎn)干掉了,如果沒(méi)有干掉,這個(gè)拖累會(huì)一直存在.
所以這就是我們?yōu)槭裁匆诼?jié)點(diǎn)檢測(cè),慢節(jié)點(diǎn)比死掉的節(jié)點(diǎn)處理更麻煩,因?yàn)檫@種也點(diǎn)還在.比如我們可以看你的 CPU 在多長(zhǎng)時(shí)間達(dá)到多少以上,我們要建立一些規(guī)則.
同時(shí)我們也要對(duì)磁盤(pán)進(jìn)行監(jiān)控,IO 的性能是不是出現(xiàn)了大的問(wèn)題.同時(shí)要對(duì)系統(tǒng)日志異常進(jìn)行分析,最后還有一個(gè)更為直接的方式,我們創(chuàng)建一些 footprint topic,我定期對(duì) topic 進(jìn)行測(cè)試,首先看看通不通,再看看速率有沒(méi)有問(wèn)題,這樣我就可以知道節(jié)點(diǎn)有沒(méi)有問(wèn)題.
如果我檢測(cè)出來(lái)慢節(jié)點(diǎn)之后怎么處理?
最簡(jiǎn)單的處理方式,就是把它停掉,其實(shí)把它停掉還是安全的,如果你覺(jué)得停掉對(duì)系統(tǒng)吞吐率造成影響的話,我們可以采取重啟的方式,但是對(duì)于很多慢節(jié)點(diǎn)來(lái)說(shuō),你把它重啟了它還是會(huì)慢.
如果一個(gè)節(jié)點(diǎn),一個(gè)盤(pán)占用需非常高,這就說(shuō)明資源分配很不均勻,這個(gè)我們引入 partition ?reassignrnert 來(lái)處理就不太好做,還是需要人工去處理.
剛才我們說(shuō)了我們的 Kafka 集群是在每個(gè)數(shù)據(jù)中心有獨(dú)立拷貝的,比如北京數(shù)據(jù)中心整個(gè) Kafka 宕掉了,那我能不能切到上海數(shù)據(jù)中心繼續(xù) consumer,那怎么做到這一點(diǎn),不用人為干預(yù)情況下,會(huì)自動(dòng)的切過(guò)去?
這就需要用到 Kafka 的代理,如果代理知道數(shù)據(jù)中心出問(wèn)題了,把 Kafka 返回的信息發(fā)回到另一個(gè)數(shù)據(jù)中心,這時(shí)候就可以進(jìn)行很好的處理.
對(duì)于 consumer 需要做另外一個(gè)事情,因?yàn)閷?duì)于同一個(gè)信息在不同數(shù)據(jù)中心是不一樣的.
比如上海數(shù)據(jù)中心比北京數(shù)據(jù)中心的 Kafka 早上一個(gè)月,那這個(gè)就肯定會(huì)有索引量偏移,所以我們就需要一個(gè)工具能夠找到這個(gè)偏移量多大.好在后續(xù)版本 Kafka 就提升了一條索引機(jī)制在 Kafka 服務(wù)器里,但是我們?cè)趯?shí)現(xiàn)這個(gè)功能的時(shí)候,那個(gè)版本還沒(méi)有出來(lái).
先說(shuō)一下為什么 Kafka 有這么大的吞吐率和性能.
首先它是保證了磁盤(pán)順序讀寫(xiě),因?yàn)槲覀冎来疟P(pán)順序讀寫(xiě)是很好的,只要你不引入文件讀寫(xiě).我們知道它這個(gè)特性之后,怎么樣保證磁盤(pán)讀寫(xiě)正常運(yùn)行呢?我們不要讓它的磁頭經(jīng)常跳,什么情況下磁頭經(jīng)常跳呢?
受到一個(gè) Kafka 里節(jié)點(diǎn)太多了,不同文件切換的時(shí)候,就會(huì)引起順序讀寫(xiě)的方式.還有比如應(yīng)用程序里,也會(huì)影響大數(shù)據(jù)讀寫(xiě)的性能.如果要保證它是順序讀寫(xiě)的話,盡量避免剛才說(shuō)的操作.
還有一個(gè)是 Kafka 通過(guò) Page Cache 保持很高的性能,對(duì)于 Kafka 端,如果你跟上的話,它永遠(yuǎn)是從內(nèi)部讀數(shù)據(jù),不是從磁盤(pán)讀數(shù)據(jù).
因?yàn)楝F(xiàn)在操作系統(tǒng)里我們會(huì)有 Page ?Cache 來(lái)監(jiān)控?cái)?shù)據(jù)處理,我們?cè)谶\(yùn)維當(dāng)中,發(fā)現(xiàn)對(duì)于 Page ?Cache 來(lái)說(shuō),千萬(wàn)不能有 Swap,一旦發(fā)生 Swap,節(jié)點(diǎn)的性能馬上會(huì)下降.
如果你是基于云的,特別是基于公有云的,這是很麻煩的事情,你需要在 Hypervisor 上進(jìn)行設(shè)置.我們?cè)谑褂卯?dāng)中也發(fā)現(xiàn)了 NUMA 不平衡的問(wèn)題,這個(gè)會(huì)導(dǎo)致其他虛擬機(jī)所在的 CPU 內(nèi)存沒(méi)有很好的運(yùn)營(yíng)起來(lái),它在后續(xù)版本的 OpenStack 里,會(huì)讓你在分配 CPU 的時(shí)候,強(qiáng)行 PIN 的操作.
除此之外 Linux 也對(duì) Page Cache 有一些優(yōu)化的設(shè)置.有人可能會(huì)問(wèn)我寫(xiě)盤(pán)了異步的,如果數(shù)據(jù)來(lái)了之后,在數(shù)據(jù)真正寫(xiě)到盤(pán)子之前,我的也點(diǎn)宕掉怎么辦?
Kafka 是除了在本節(jié)點(diǎn)之外,他會(huì)在其他節(jié)點(diǎn)上也有,它先進(jìn)行保存,然后異步寫(xiě)盤(pán)過(guò)程才會(huì)把這個(gè)消息真正落到盤(pán)里面去.
最后一點(diǎn), Kafka 用到 linux 操作系統(tǒng)之后,Zero Copy 很簡(jiǎn)單,當(dāng)我的磁盤(pán)來(lái)的時(shí)候,可以不用直接進(jìn)用戶內(nèi)存,而是直接丟到網(wǎng)絡(luò)端口去,這里不是優(yōu)化的,我們一定要小心 Zero Copy 會(huì)失效.
我們做 Kafka 升級(jí)的時(shí)候,有可能數(shù)據(jù)格式會(huì)變,比如從0.9變到1.0,如果說(shuō)你直接強(qiáng)行切過(guò)來(lái)的話,就會(huì)破壞 Kafka .
那怎么解決這個(gè)問(wèn)題,其實(shí)在1.0升級(jí)的說(shuō)明里有一個(gè)很復(fù)雜很詳盡的說(shuō)明,如果有人要做升級(jí)的話,一定要詳細(xì)看清楚這些說(shuō)明.
同時(shí)另外一個(gè)導(dǎo)致 Zero Copy 失效就是可能引入 SSL/TLS,這個(gè)怎么處理呢?那你只能權(quán)衡一下安全性和性能.
另外還有一些其他參數(shù)也可以對(duì) Kafka 進(jìn)行優(yōu)化,有一個(gè)是 File ?Descriptor 一定要很大.
包括在高吞吐率節(jié)點(diǎn)上,一定要增加 Max ?socket ?buffer ?size.權(quán)衡 unclean.leader.electionbenable,增加 fetch 線程數(shù)量 num.replica.fetchers,處理 leader 選舉 outo.leaderrebalance.enoble.
原文來(lái)自微信公眾號(hào):高效運(yùn)維
轉(zhuǎn)載請(qǐng)注明本頁(yè)網(wǎng)址:
http://www.snjht.com/jiaocheng/4310.html