成人AV在线无码|婷婷五月激情色,|伊人加勒比二三四区|国产一区激情都市|亚洲AV无码电影|日av韩av无码|天堂在线亚洲Av|无码一区二区影院|成人无码毛片AV|超碰在线看中文字幕

了解知乎網(wǎng)站的架構(gòu)演進(jìn)史

初期架構(gòu)選型在2010年10月真正開(kāi)始動(dòng)手做知乎這個(gè)產(chǎn)品時(shí),包含李申申在內(nèi),最初只有兩位工程師;到2010年12月份上線(xiàn)時(shí),工程師是四個(gè)。知乎的主力開(kāi)發(fā)語(yǔ)言是Python。因?yàn)镻ython簡(jiǎn)單且強(qiáng)大,

初期架構(gòu)選型

在2010年10月真正開(kāi)始動(dòng)手做知乎這個(gè)產(chǎn)品時(shí),包含李申申在內(nèi),最初只有兩位工程師;到2010年12月份上線(xiàn)時(shí),工程師是四個(gè)。

知乎的主力開(kāi)發(fā)語(yǔ)言是Python。因?yàn)镻ython簡(jiǎn)單且強(qiáng)大,能夠快速上手,開(kāi)發(fā)效率高,而且社區(qū)活躍,團(tuán)隊(duì)成員也比較喜歡。

知乎使用的是Tornado框架。因?yàn)樗С之惒剑苓m合做實(shí)時(shí)comet應(yīng)用,而且簡(jiǎn)單輕量,學(xué)習(xí)成本低,再就是有FriendFeed 的成熟案例,F(xiàn)acebook 的社區(qū)支持。知乎的產(chǎn)品有個(gè)特性,就是希望跟瀏覽器端建立一個(gè)長(zhǎng)連接,便于實(shí)時(shí)推送Feed和通知,所以Tornado比較合適。

最初整個(gè)團(tuán)隊(duì)的精力全部放在產(chǎn)品功能的開(kāi)發(fā)上,而其他方面,基本上能節(jié)約時(shí)間、能省的都用最簡(jiǎn)單的方法來(lái)解決,當(dāng)然這在后期也帶來(lái)了一些問(wèn)題。

最初的想法是用云主機(jī),節(jié)省成本。知乎的第一臺(tái)服務(wù)器是512MB內(nèi)存的Linode主機(jī)。但是網(wǎng)站上線(xiàn)后,內(nèi)測(cè)受歡迎程度超出預(yù)期,很多用戶(hù)反饋網(wǎng)站很慢。跨國(guó)網(wǎng)絡(luò)延遲比想象的要大,特別是國(guó)內(nèi)的網(wǎng)絡(luò)不均衡,全國(guó)各地用戶(hù)訪(fǎng)問(wèn)的情況都不太一樣。這個(gè)問(wèn)題,再加上當(dāng)時(shí)要做域名備案,知乎又回到了自己買(mǎi)機(jī)器找機(jī)房的老路上。

買(mǎi)了機(jī)器、找了機(jī)房之后又遇到了新的問(wèn)題,服務(wù)經(jīng)常宕掉。當(dāng)時(shí)服務(wù)商的機(jī)器內(nèi)存總是出問(wèn)題,動(dòng)不動(dòng)就重啟。終于有一次機(jī)器宕掉起不來(lái)了,這時(shí)知乎就做了Web和數(shù)據(jù)庫(kù)的高可用。創(chuàng)業(yè)就是這樣一個(gè)情況,永遠(yuǎn)不知道明早醒來(lái)的時(shí)候會(huì)面臨什么樣的問(wèn)題。

這是當(dāng)時(shí)那個(gè)階段的架構(gòu)圖,Web和數(shù)據(jù)庫(kù)都做了主從。當(dāng)時(shí)的圖片服務(wù)托管在又拍云上。 除了主從,為了性能更好還做了讀寫(xiě)分離。為解決同步問(wèn)題,又添加了一個(gè)服務(wù)器來(lái)跑離線(xiàn)腳本,避免對(duì)線(xiàn)上服務(wù)造成響應(yīng)延遲。另外,為改進(jìn)內(nèi)網(wǎng)的吞吐量延遲, 還更換了設(shè)備,使整個(gè)內(nèi)網(wǎng)的吞吐量翻了20倍。

在2011年上半年時(shí),知乎對(duì)Redis已經(jīng)很依賴(lài)。除了最開(kāi)始的隊(duì)列、搜索在用,后來(lái)像Cache也開(kāi)始使用,單機(jī)存儲(chǔ)成為瓶頸,所以引入了分片,同時(shí)做了一致性。

知乎團(tuán)隊(duì)是一個(gè)很相信工具的團(tuán)隊(duì),相信工具可以提升效率。工具其實(shí)是一個(gè)過(guò)程,工具并沒(méi)有所謂的最好的工具,只有最適合的工具。而且它是在整個(gè)過(guò)程中,隨著整個(gè)狀態(tài)的變化、環(huán)境的變化在不斷發(fā)生變化的。知乎自己開(kāi)發(fā)或使用過(guò)的工具包括Profiling(函數(shù)級(jí)追蹤請(qǐng)求,分析調(diào)優(yōu))、Werkzeug(方便調(diào)試的工具)、Puppet(配置管理)和Shipit(一鍵上線(xiàn)或回滾)等。

日志系統(tǒng)

知乎最初是邀請(qǐng)制的,2011年下半年,知乎上線(xiàn)了申請(qǐng)注冊(cè),沒(méi)有邀請(qǐng)碼的用戶(hù)也可以通過(guò)填寫(xiě)一些資料申請(qǐng)注冊(cè)知乎。用戶(hù)量又上了一個(gè)臺(tái)階,這時(shí)就有了一些發(fā)廣告的賬戶(hù),需要掃除廣告。日志系統(tǒng)的需求提上日程。

這個(gè)日志系統(tǒng)必須支持分布式收集、集中存儲(chǔ)、實(shí)時(shí)、可訂閱和簡(jiǎn)單等特性。當(dāng)時(shí)調(diào)研了一些開(kāi)源系統(tǒng),比如Scribe總體不錯(cuò),但是不支持訂閱。Kafka是Scala開(kāi)發(fā)的,但是團(tuán)隊(duì)在Scala方面積累較少,F(xiàn)lume也是類(lèi)似,而且比較重。所以開(kāi)發(fā)團(tuán)隊(duì)選擇了自己開(kāi)發(fā)一個(gè)日志系統(tǒng)——Kids(Kids Is Data Stream)。顧名思義,Kids是用來(lái)匯集各種數(shù)據(jù)流的。

Kids參考了Scribe的思路。Kdis在每臺(tái)服務(wù)器上可以配置成Agent或 Server。Agent直接接受來(lái)自應(yīng)用的消息,把消息匯集之后,可以打給下一個(gè)Agent或者直接打給中心Server。訂閱日志時(shí),可以從 Server上獲取,也可以從中心節(jié)點(diǎn)的一些Agent上獲取。

具體細(xì)節(jié)如下圖所示:

知乎還基于Kids做了一個(gè)Web小工具(Kids Explorer),支持實(shí)時(shí)看線(xiàn)上日志,現(xiàn)在已經(jīng)成為調(diào)試線(xiàn)上問(wèn)題最主要的工具。

Kids已經(jīng)開(kāi)源,放到了Github上。

事件驅(qū)動(dòng)的架構(gòu)

知乎這個(gè)產(chǎn)品有一個(gè)特點(diǎn),最早在添加一個(gè)答案后,后續(xù)的操作其實(shí)只有更新通知、更新動(dòng) 態(tài)。但是隨著整個(gè)功能的增加,又多出了一些更新索引、更新計(jì)數(shù)、內(nèi)容審查等操作,后續(xù)操作五花八門(mén)。如果按照傳統(tǒng)方式,維護(hù)邏輯會(huì)越來(lái)越龐大,維護(hù)性也會(huì) 非常差。這種場(chǎng)景很適合事件驅(qū)動(dòng)方式,所以開(kāi)發(fā)團(tuán)隊(duì)對(duì)整個(gè)架構(gòu)做了調(diào)整,做了事件驅(qū)動(dòng)的架構(gòu)。

這時(shí)首先需要的是一個(gè)消息隊(duì)列,它應(yīng)該可以獲取到各種各樣的事件,而且對(duì)一致性有很高的 要求。針對(duì)這個(gè)需求,知乎開(kāi)發(fā)了一個(gè)叫Sink的小工具。它拿到消息后,先做本地的保存、持久化,然后再把消息分發(fā)出去。如果那臺(tái)機(jī)器掛掉了,重啟時(shí)可以 完整恢復(fù),確保消息不會(huì)丟失。然后它通過(guò)Miller開(kāi)發(fā)框架,把消息放到任務(wù)隊(duì)列。Sink更像是串行消息訂閱服務(wù),但任務(wù)需要并行化處理, Beanstalkd就派上了用場(chǎng),由其對(duì)任務(wù)進(jìn)行全周期管理。架構(gòu)如下圖所示:

舉例而言,如果現(xiàn)在有用戶(hù)回答了問(wèn)題,首先系統(tǒng)會(huì)把問(wèn)題寫(xiě)到MySQL里面,把消息塞到Sink,然后把問(wèn)題返回給用戶(hù)。Sink通過(guò)Miller把任務(wù)發(fā)給 Beanstalkd,Worker自己可以找到任務(wù)并處理。

最開(kāi)始上線(xiàn)時(shí),每秒鐘有10個(gè)消息,然后有70個(gè)任務(wù)產(chǎn)生?,F(xiàn)在每秒鐘有100個(gè)事件,有1500個(gè)任務(wù)產(chǎn)生,就是通過(guò)現(xiàn)在的事件驅(qū)動(dòng)架構(gòu)支撐的。

頁(yè)面渲染優(yōu)化

知乎在2013年時(shí)每天有上百萬(wàn)的PV,頁(yè)面渲染其實(shí)是計(jì)算密集型的,另外因?yàn)橐@取數(shù)據(jù),所以也有IO密集型的特點(diǎn)。這時(shí)開(kāi)發(fā)團(tuán)隊(duì)就對(duì)頁(yè)面進(jìn)行了組件化,還升級(jí)了數(shù)據(jù)獲取機(jī)制。知乎按照整個(gè)頁(yè)面組件樹(shù)的結(jié)構(gòu),自上而下分層地獲取數(shù)據(jù),當(dāng)上 層的數(shù)據(jù)已經(jīng)獲取了,下層的數(shù)據(jù)就不需要再下去了,有幾層基本上就有幾次數(shù)據(jù)獲取。

結(jié)合這個(gè)思路,知乎自己做了一套模板渲染開(kāi)發(fā)框架——ZhihuNode。

經(jīng)歷了一系列改進(jìn)之后,頁(yè)面的性能大幅度提升。問(wèn)題頁(yè)面從500ms 減少到150ms,F(xiàn)eed頁(yè)面從1s減少到600ms。

面向服務(wù)的架構(gòu)(SOA)

隨著知乎的功能越來(lái)越龐雜,整個(gè)系統(tǒng)也越來(lái)越大。知乎是怎么做的服務(wù)化呢?

首先需要一個(gè)最基本的RPC框架,RPC框架也經(jīng)歷了好幾版演進(jìn)。

第一版是Wish,它是一個(gè)嚴(yán)格定義序列化的模型。傳輸層用到了STP,這是自己寫(xiě)的很 簡(jiǎn)單的傳輸協(xié)議,跑在TCP上。一開(kāi)始用的還不錯(cuò),因?yàn)橐婚_(kāi)始只寫(xiě)了一兩個(gè)服務(wù)。但是隨著服務(wù)增多,一些問(wèn)題開(kāi)始出現(xiàn),首先是 ProtocolBuffer會(huì) 生成一些描述代碼,很冗長(zhǎng),放到整個(gè)庫(kù)里顯得很丑陋。另外嚴(yán)格的定義使其不便使用。這時(shí)有位工程師開(kāi)發(fā)了新的RPC框架——Snow。它使用簡(jiǎn)單的 JSON做數(shù)據(jù)序列化。但是松散的數(shù)據(jù)定義面對(duì)的問(wèn)題是,比如說(shuō)服務(wù)要去升級(jí),要改寫(xiě)數(shù)據(jù)結(jié)構(gòu),很難知道有哪幾個(gè)服務(wù)在使用,也很難通知它們,往往錯(cuò)誤就 發(fā)生了。于是又出了第三個(gè)RPC框架,寫(xiě)RPC框架的工程師,希望結(jié)合前面兩個(gè)框架的特點(diǎn),首先保持Snow簡(jiǎn)單,其次需要相對(duì)嚴(yán)格的序列化協(xié)議。這一版 本引入了 Apache Avro。同時(shí)加入了特別的機(jī)制,在傳輸層和序列化協(xié)議這一層都做成了可插拔的方式,既可以用JSON,也可以用Avro,傳輸層可以用STP,也可以用 二進(jìn)制協(xié)議。

再就是搭了一個(gè)服務(wù)注冊(cè)發(fā)現(xiàn),只需要簡(jiǎn)單的定義服務(wù)的名字就可以找到服務(wù)在哪臺(tái)機(jī)器上。同時(shí),知乎也有相應(yīng)的調(diào)優(yōu)的工具,基于Zipkin開(kāi)發(fā)了自己的 Tracing系統(tǒng)。

按照調(diào)用關(guān)系,知乎的服務(wù)分成了3層:聚合層、內(nèi)容層和基礎(chǔ)層。按屬性又可以分成3類(lèi):數(shù)據(jù)服務(wù)、邏輯服務(wù)和通道服務(wù)。數(shù)據(jù)服務(wù)主要是一些要做特殊數(shù)據(jù)類(lèi)型的存儲(chǔ),比如圖片服務(wù)。邏輯服務(wù)更多的是CPU密集、計(jì)算密集的操作,比如答案格式的定義、解析等。通道服務(wù)的特點(diǎn)是沒(méi)有存儲(chǔ),更多是做一個(gè)轉(zhuǎn)發(fā),比如說(shuō)Sink。

這是引入服務(wù)化之后整體的架構(gòu)。

而目前在產(chǎn)品方面,知乎保留著以下幾個(gè)重點(diǎn):1.基礎(chǔ)模塊(1 問(wèn)題-n 回答-n 評(píng)論模塊)

知乎基礎(chǔ)模塊中一個(gè)問(wèn)題對(duì)應(yīng)于 n 個(gè)回答,一個(gè)回答又對(duì)應(yīng)于 n 個(gè)評(píng)論,因此我們可以把基礎(chǔ)模塊稱(chēng)為 1 問(wèn)題-n 回答-n 評(píng)論模塊。假設(shè)知乎架構(gòu)模型中僅存在基礎(chǔ)模塊,將會(huì)是一個(gè)怎樣的場(chǎng)景?那就是信息流隨著時(shí)間的推移不斷生成新的內(nèi)容并把舊信息快速替換沖刷掉,這種對(duì)基礎(chǔ)模塊無(wú)差別的線(xiàn)性陳列,對(duì)用戶(hù)來(lái)說(shuō)將是一個(gè)災(zāi)難:

在簡(jiǎn)單羅列的線(xiàn)性信息海洋中,用戶(hù)汲取其所需信息的成本太高;信息流如同大河奔流,那些有挖掘價(jià)值的信息點(diǎn)稍縱即逝,即信息價(jià)值被嚴(yán)重?fù)]霍;用戶(hù)不能將有價(jià)值的信息點(diǎn)從信息大河里舀”出來(lái),信息可見(jiàn)而不可用,無(wú)法產(chǎn)生長(zhǎng)效作用。知乎的產(chǎn)品設(shè)計(jì)者很好地意識(shí)到了這些潛在的災(zāi)難”,并對(duì)每個(gè)問(wèn)題點(diǎn)做出了針對(duì)性的產(chǎn)品設(shè)計(jì)方案,下面木柄逐一展開(kāi)分析。

2.話(huà)題模塊

話(huà)題模塊用來(lái)解決在線(xiàn)性簡(jiǎn)單羅列的信息海洋中,用戶(hù)汲取所需信息的成本太高”的問(wèn)題。知乎中,每一個(gè)基礎(chǔ)模塊(1 問(wèn)題-n 回答-n 評(píng)論模塊)可以添加話(huà)題”標(biāo)識(shí),話(huà)題”描述了基礎(chǔ)模塊的類(lèi)別”,話(huà)題模塊與基礎(chǔ)模塊是多對(duì)多的映射關(guān)系(many2many)。事實(shí)上,為內(nèi)容添加標(biāo)識(shí)”的做法在以?xún)?nèi)容為核心的網(wǎng)站的組織架構(gòu)模型中屢見(jiàn)不鮮,很多網(wǎng)站將這種標(biāo)識(shí)”稱(chēng)為標(biāo)簽(比如 lofter)。

但是知乎的話(huà)題比普通網(wǎng)站的標(biāo)簽走的更遠(yuǎn):知乎的各個(gè)話(huà)題之間不像標(biāo)簽?zāi)菢邮枪铝⒌?,它定義了一套將話(huà)題組織起來(lái)的數(shù)據(jù)結(jié)構(gòu)。請(qǐng)注意,話(huà)題本身就是對(duì)基礎(chǔ)模塊的一種組織形式,而又存在一套數(shù)據(jù)結(jié)構(gòu)描述了話(huà)題的組織形式,那么我們可以將這種數(shù)據(jù)結(jié)構(gòu)稱(chēng)作描述結(jié)構(gòu)組織的結(jié)構(gòu)組織”,知乎自己是這么介紹這個(gè)描述結(jié)構(gòu)組織的結(jié)構(gòu)組織”:知乎的全部話(huà)題通過(guò)父子關(guān)系構(gòu)成一個(gè)有根無(wú)循環(huán)的有向圖;根話(huà)題即為所有話(huà)題的最上層的父話(huà)題;請(qǐng)不要在問(wèn)題上直接綁定根話(huà)題。

3.發(fā)現(xiàn)模塊

發(fā)現(xiàn)模塊解決了信息流如同大河奔流,那些有挖掘價(jià)值的信息點(diǎn)稍縱即逝,即信息價(jià)值被嚴(yán)重?fù)]霍的問(wèn)題。發(fā)現(xiàn)模塊主要有兩部分內(nèi)容組成:推薦與熱門(mén)。熱門(mén)內(nèi)容是由用戶(hù)群體行為所做出來(lái)的內(nèi)容精選”,而推薦內(nèi)容是知乎運(yùn)營(yíng)人員對(duì)群體行為”的補(bǔ)充完善,最大程度地讓有價(jià)值的信息減緩流速,或者二次逆流”,目的就是讓有價(jià)值的信息得以上浮”與駐留”。

此外值得一提的是,如果說(shuō)發(fā)現(xiàn)模塊是構(gòu)筑在知乎基礎(chǔ)模塊上的信息駐留模塊”, 那么話(huà)題模塊也有一個(gè)針對(duì)其信息的駐留模塊”——話(huà)題精華模塊”。發(fā)現(xiàn)模塊是挖掘全局的有價(jià)值的信息,而話(huà)題精華模塊”挖掘的是該話(huà)題的有價(jià)值的信息,從而使有價(jià)值的信息在不同的組織維度上得到駐留”,而不被浩大的信息流沖的無(wú)影無(wú)蹤。

4.收藏模塊

收藏模塊解決了用戶(hù)不能將有價(jià)值的信息點(diǎn)從信息大河里舀”出來(lái),信息可見(jiàn)而不可用,無(wú)法產(chǎn)生長(zhǎng)效作用的問(wèn)題。收藏功能是很多內(nèi)容為王的網(wǎng)站架構(gòu)中重要的一環(huán),使用戶(hù)可以從浩淼的信息流中舀出其感興趣的那一瓢。知乎的收藏模塊支持創(chuàng)建收藏文件夾,即用戶(hù)可以對(duì)收藏內(nèi)容再組織,存放到相應(yīng)的收藏文件夾中。

此外知乎的收藏模塊還走的更遠(yuǎn),用戶(hù)組織的收藏夾可以設(shè)置為公有”狀態(tài),并分享給其他用戶(hù)。也就是用戶(hù)的利己行為(收藏自己感興趣或者有幫助的內(nèi)容),產(chǎn)生了利他的效果(其他用戶(hù)也能看到由別人的收藏夾并從中獲益)。從內(nèi)容組織角度上來(lái)說(shuō),知乎的收藏夾不但提供了將信息舀”出保存的作用,而且也起到將優(yōu)質(zhì)信息駐留”與上浮”的作用。

5.知乎日?qǐng)?bào)模塊

知乎日?qǐng)?bào)模塊是一個(gè)比較特殊的模塊,它并不是知乎的主體模塊,你可以將其理解成知乎產(chǎn)品的衍生模塊,它事實(shí)上也從另外一個(gè)角度在解答信息價(jià)值被嚴(yán)重?fù)]霍的問(wèn)題。知乎日?qǐng)?bào)模塊與知乎主體模塊采用松耦合的架構(gòu)模式,它是對(duì)知乎這個(gè)龐大的優(yōu)質(zhì)內(nèi)容生產(chǎn)機(jī)器的二次開(kāi)發(fā)。知乎日?qǐng)?bào)采取日?qǐng)?bào)”的方式,每天對(duì)知乎中產(chǎn)生的經(jīng)典內(nèi)容做一次組織成刊。知乎日?qǐng)?bào)簡(jiǎn)單的布局、呈現(xiàn)方式,更加符合人們?cè)谝苿?dòng)端的閱讀習(xí)慣,使那些覺(jué)得在移動(dòng)端使用知乎不方便的用戶(hù),或者想在碎片時(shí)間里進(jìn)行閱讀的用戶(hù),有一個(gè)更加貼心的知乎產(chǎn)品可以選擇。

標(biāo)簽: