AirJD 焦点
AirJD

没有录音文件
00:00/00:00
加收藏

知乎架构变迁史 by 李申申

发布者 arch
发布于 1448931712712  浏览 6109 关键词 架构, DevOps, 存储 
分享到

第1页

知乎架构变迁史

李申申



第2页

李申申是谁



第8页

RU 11M+ MAU 80M+ MPV 220M+



第9页

2010.10



第11页

You jump off a cliff and you assemble an



aeroplane on the way down.








Reid Hoffman



第12页

Linode 512M



第15页

你永远不知道明早醒来会面对什么问题



第16页

宕机@知乎



第18页

Picture Upload Picture Storage



LVS Nginx Web

M MySQL



LVS Nginx Web

S MySQL



Mailgun

Mail

M Redis

S Redis



第19页

MySQL 经典问题

主从延迟



第20页

资源隔离



第21页

内网优化



第22页

硬盘升级



第23页

应用层灵活调用



第24页

Redis Shard



第25页

node3 计算 hash

Key

计算 hash



0/232



node1



计算 hash



Key



计算 hash



计算 hash node4



计算 hash node2



第26页

github.com/zhihu/redis-shard



第27页

工具是一个过程 用大小形状都合适的物体,以最有效的方式完成工作



第28页

Profiling



第29页

Werkzeug



第30页

Puppet



第31页

Shipit



第32页

知乎邀请制



第34页

申请注册



第36页

日志系统



第37页

分布式收集 集中存储 可订阅

实时 简单



第38页

Scribe Kafka Flume



无法订阅

Scala Java



第39页

Kids

Kids is Data Stream



第40页

App App



Publish



Publish

Agent



App

Publish

Agent



Agent



Agent



Subscribe



Kids Server



Log Analyzer



Psubscribe



Subscribe



Log Analyzer



Log Analyzer



第41页

MultipleStore



⑥ Notify Storer



Storer Thread

Fetch Global Message Queue



Store



BufferStore PriorityStore



Worker Thread

Client Client



④ Push ③ Publish



Message Latest



Message Latest



Message Latest



⑦ Fetch



Worker Thread



Client



⑤ Notify Worker



② Accept



Master Thread



① Connect



Accept



Connect



Subscribe⑧/PMsuebssscargibee



Client



App (Publisher)



App (Subscriber)



第43页

github.com/zhihu/kids



第44页

添加回答



更新通知



更新动态



更新搜索索引 ?

失效缓存



判断是否 Spam



更新回答计数



判断内容质量



更新个人主页







是否非法



内容审核



??







第45页

Event Driven Architecture



第46页

Miller Master

Miller Worker

Worker 01 Worker 02

Worker N



Sink Beanstalkd



第47页

① ②

MySQL



Web

④ ③

Sink

④④



noti-miller Master





search-miller Master





Beanstalkd









noti-miller Worker



noti server



search-miller Worker



indexer



第48页

In 100+ Out 1500+



第49页

Miller Master

Miller Worker Worker 01 Worker 02

Worker N



Sink Beanstalkd



LVS Nginx Web

M MySQL



LVS Nginx Web

S MySQL



M Redis

S Redis



第50页

页面渲染优化



第52页

HomeUI



FeedUI



SidebarUI



Item1UI



Item2UI



NavigatorUI



Data



QuestionUI



AnswerUI



第53页

HomeNode



FeedNode



SidebarNode



Data



Item1Node



Item2Node



NavigatorNode



QuestionNode AnswerNode



第54页

ZhihuNode



第55页

class AnswerVoteBarV2(ZhihuNode):

!  def init(self, answer_id):    self.answer_id = answer_id

!  def template_v2(self):    return "v2_uimodule_answer_votebar.html"

!  def prime(self):     models.AnswerDAO.prime_get_vote(self.login_id, self.answer_id)

 def obj(self): vote = models.AnswerDOA.get_vote(self.login_id, self.answer_id) return ObjectDict(vote=vote)



第56页

Question 500ms -> 150ms Feed 1s -> 600ms



第57页

Service-oriented architecture



第58页

RPC 框架变迁史



第59页

Wish

Protocol Buffers STP TCP



第60页

Snow

JSON STP TCP



第61页

Zone



第62页

Protocol Versioning



Apache Avro IDL API Protocol



Protocol Generator



Sync Client Async Client



Connection Pool



Communication
 &


Transport Protocols



Async Server



第63页

Apache Avro - IDL



// Google Protocol Buffer



// Apache Avro



message CalcResponse {



protocol Calc {



enum Result {



error ZeroDivision {



OK = 0;



string message;



ZERO_DIVISION = 1;



}



}  



required Result result = 1;



int divide(int a, int b) throws ZeroDivision;



optional int32 c = 2;



}



}



message CalcRequest {



int32 a = 1;



int32 b = 2;



}



service Calc {



rpc Divide (CalcRequest) returns (CalcResponse);



}



第64页

Apache Avro - API Protocol File



// Wish’s generated files… xxx_pb2.py xxx_stub.py descriptor_pb2.py



// Apache Avro’s generated file, simply a snippet of JSON {

"Calc": { "messages": { "divide": { "errors": ["ZeroDivision"], "reqest": [{"name": "a", "type": "int"}, {"name": "b", "type": "int"}], "response": "int"}}, "namespace": None, "protocol": "Calc", "types": [ {"fields": [{"name": "message", "type": "string"}], "name": "ZeroDivision", "type": "error"} ]

} }



第65页

Server Example



import snow class Calc(snow.APIBase): 

def divide(self, a, b): if b == 0:

 return {"code": 1, "msg": "Zero division."}

return {"code": 0, "c": a / b}

!

snow.Server(Calc(), port=9000).run()



import zone from proto import protos

!

class Calc(zone.ZoneAPI):

! def divide(self, a, b): if b == 0: raise zone.ZoneCustomException(name="ZeroDivision")

return a / b

!

zone.Server([Calc(protos["Calc"])], port=9000).run()



第66页

Header



Body



Serializer (Avro / JSON)



Transporter (Binary/STP)



TCP



第67页

Consul



第68页

Tracing



第69页

知乎业务服务结构图



聚 合 话题 Feed 层



⾸首⻚页 Feed



发现



搜索



推荐



收藏



圆桌







容 问答



专栏



通知



私信



已读







基 础 ⽤用户 层



评论



图⽚片



推送



分享



话题



邮件



短址



数据服务



逻辑服务



通道服务



第70页

Miller Beantalk



LVS01



keepAlived



LVS02



Nginx01



Nginx02



Web01



Web02



WebN



Haproxy01



keepAlived



Haproxy02



Feed Service



Member Service



···



前端展⽰示层 后端业务逻辑层



Sink



Kids



MySQL



Redis



Cassandra



存储&通信层



第71页

知乎专栏的全新实践



第72页

传统网站的开发模式

前后端代码交叉 工程师互相等待 前端代码部署成本高



第73页

Web App RESTful API Server

RPC Server



MySQL



Redis



Workers



第74页

前后端分离,逻辑更清晰 AngularJS:代码复用、快速开发

并行开发 独立部署



第75页

<(▰˘◡˘▰)>

产品设计师也能修改代码了



第76页

工具要不断跟上



第77页

Dash



第78页

Heroin



第79页

Radius



第80页

CFB



第81页

Crony



第82页

Oops



第83页

Boxen



第84页

想各种办法发挥自我创新 其实就是找各种办法刺激工程师们



第85页

Hackathon



第87页

Tink Day



第91页

谢谢



支持文件格式:*.pdf
上传最后阶段需要进行在线转换,可能需要1~2分钟,请耐心等待。