热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

知乎网站架构变迁史——阅读心得

初期架构选型在2010年10月真正开始动手做知乎这个产品时,包含李申申在内,最初只有两位工程师;到2010年12月份上线时,工程师是四个。知乎的主力开发语言是Python。因为Py

初期架构选型

2010年10月真正开始动手做知乎这个产品时,包含李申申在内,最初只有两位工程师;到2010年12月份上线时,工程师是四个。

知乎的主力开发语言是Python。因为Python简单且强大,能够快速上手,开发效率高,而且社区活跃,团队成员也比较喜欢。

知乎使用的是Tornado框架。因为它支持异步,很适合做实时comet应用,而且简单轻量,学习成本低,再就是有FriendFeed 的成熟案例,Facebook 的社区支持。知乎的产品有个特性,就是希望跟浏览器端建立一个长连接,便于实时推送Feed和通知,所以Tornado比较合适。


最初的想法是用云主机,节省成本。知乎的第一台服务器是
512MB内存的Linode主机。但是网站上线后,内测受欢迎程度超出预期,很多用户反馈网站很慢。跨国网络延迟比想象的要大,特别是国内的网络不均衡,全国各地用户访问的情况都不太一样。这个问题,再加上当时要做域名备案,知乎又回到了自己买机器找机房的老路上。最初整个团队的精力全部放在产品功能的开发上,而其他方面,基本上能节约时间、能省的都用最简单的方法来解决,当然这在后期也带来了一些问题。

买了机器、找了机房之后又遇到了新的问题,服务经常宕掉。当时服务商的机器内存总是出问题,动不动就重启。终于有一次机器宕掉起不来了,这时知乎就做了Web和数据库的高可用。创业就是这样一个情况,永远不知道明早醒来的时候会面临什么样的问题。

 

 知乎网站架构变迁史——阅读心得

 

 

这是当时那个阶段的架构图,Web和数据库都做了主从。当时的图片服务托管在又拍云上。 除了主从,为了性能更好还做了读写分离。为解决同步问题,又添加了一个服务器来跑离线脚本,避免对线上服务造成响应延迟。另外,为改进内网的吞吐量延迟, 还更换了设备,使整个内网的吞吐量翻了20倍。

2011年上半年时,知乎对Redis已经很依赖。除了最开始的队列、搜索在用,后来像Cache也开始使用,单机存储成为瓶颈,所以引入了分片,同时做了一致性。

知乎团队是一个很相信工具的团队,相信工具可以提升效率。工具其实是一个过程,工具并没有所谓的最好的工具,只有最适合的工具。而且它是在整个过程中,随着整个状态的变化、环境的变化在不断发生变化的。知乎自己开发或使用过的工具包括Profiling(函数级追踪请求,分析调优)、Werkzeug(方便调试的工具)、Puppet(配置管理)和Shipit(一键上线或回滚)等。

日志系统

知乎最初是邀请制的,2011年下半年,知乎上线了申请注册,没有邀请码的用户也可以通过填写一些资料申请注册知乎。用户量又上了一个台阶,这时就有了一些发广告的账户,需要扫除广告。日志系统的需求提上日程。

这个日志系统必须支持分布式收集、集中存储、实时、可订阅和简单等特性。当时调研了一些开源系统,比如Scribe总体不错,但是不支持订阅。Kafka是Scala开发的,但是团队在Scala方面积累较少,Flume也是类似,而且比较重。所以开发团队选择了自己开发一个日志系统——Kids(Kids Is Data Stream)。顾名思义,Kids是用来汇集各种数据流的。

Kids参考了Scribe的思路。Kdis在每台服务器上可以配置成Agent或 Server。Agent直接接受来自应用的消息,把消息汇集之后,可以打给下一个Agent或者直接打给中心Server。订阅日志时,可以从 Server上获取,也可以从中心节点的一些Agent上获取。


知乎网站架构变迁史——阅读心得

 

  

 

具体细节如下图所示:


知乎网站架构变迁史——阅读心得

 

  

 

 

 

知乎还基于Kids做了一个Web小工具(Kids Explorer),支持实时看线上日志,现在已经成为调试线上问题最主要的工具。(Kids已经开源,Github上可见。)

事件驱动的架构

知乎这个产品有一个特点,最早在添加一个答案后,后续的操作其实只有更新通知、更新动 态。但是随着整个功能的增加,又多出了一些更新索引、更新计数、内容审查等操作,后续操作五花八门。如果按照传统方式,维护逻辑会越来越庞大,维护性也会 非常差。这种场景很适合事件驱动方式,所以开发团队对整个架构做了调整,做了事件驱动的架构。


 
这时首先需要的是一个消息队列,它应该可以获取到各种各样的事件,而且对一致性有很高的
要求。针对这个需求,知乎开发了一个叫Sink的小工具。它拿到消息后,先做本地的保存、持久化,然后再把消息分发出去。如果那台机器挂掉了,重启时可以 完整恢复,确保消息不会丢失。然后它通过Miller开发框架,把消息放到任务队列。Sink更像是串行消息订阅服务,但任务需要并行化处理, Beanstalkd就派上了用场,由其对任务进行全周期管理。架构如下图所示:

 知乎网站架构变迁史——阅读心得

 

 

 

举例而言,如果现在有用户回答了问题,首先系统会把问题写到MySQL里面,把消息塞到Sink,然后把问题返回给用户。Sink通过Miller把任务发给 Beanstalkd,Worker自己可以找到任务并处理。

最开始上线时,每秒钟有10个消息,然后有70个任务产生。现在每秒钟有100个事件,有1500个任务产生,就是通过现在的事件驱动架构支撑的。

页面渲染优化

知乎在2013年时每天有上百万的PV,页面渲染其实是计算密集型的,另外因为要获取数据,所以也有IO密集型的特点。这时开发团队就对页面进行了组件化,还升级了数据获取机制。知乎按照整个页面组件树的结构,自上而下分层地获取数据,当上 层的数据已经获取了,下层的数据就不需要再下去了,有几层基本上就有几次数据获取。

结合这个思路,知乎自己做了一套模板渲染开发框架——ZhihuNode。

经历了一系列改进之后,页面的性能大幅度提升。问题页面从500ms 减少到150ms,Feed页面从1s减少到600ms。

面向服务的架构(SOA)

随着知乎的功能越来越庞杂,整个系统也越来越大。知乎是怎么做的服务化呢?

首先需要一个最基本的RPC框架,RPC框架也经历了好几版演进。

第一版是Wish,它是一个严格定义序列化的模型。传输层用到了STP,这是自己写的很 简单的传输协议,跑在TCP上。一开始用的还不错,因为一开始只写了一两个服务。但是随着服务增多,一些问题开始出现,首先是 ProtocolBuffer会 生成一些描述代码,很冗长,放到整个库里显得很丑陋。另外严格的定义使其不便使用。这时有位工程师开发了新的RPC框架——Snow。它使用简单的 JSON做数据序列化。但是松散的数据定义面对的问题是,比如说服务要去升级,要改写数据结构,很难知道有哪几个服务在使用,也很难通知它们,往往错误就 发生了。于是又出了第三个RPC框架,写RPC框架的工程师,希望结合前面两个框架的特点,首先保持Snow简单,其次需要相对严格的序列化协议。这一版 本引入了 Apache Avro。同时加入了特别的机制,在传输层和序列化协议这一层都做成了可插拔的方式,既可以用JSON,也可以用Avro,传输层可以用STP,也可以用 二进制协议。

再就是搭了一个服务注册发现,只需要简单的定义服务的名字就可以找到服务在哪台机器上。同时,知乎也有相应的调优的工具,基于Zipkin开发了自己的 Tracing系统。

按照调用关系,知乎的服务分成了3层:聚合层、内容层和基础层。按属性


 
又可以分成
3类:数据服务、逻辑服务和通道服务。数据服务主要是一些要做特殊数据类型的存储,比如图片服务。逻辑服务更多的是CPU密集、计算密集的操作,比如答案格式的定义、解析等。通道服务的特点是没有存储,更多是做一个转发,比如说Sink。

知乎网站架构变迁史——阅读心得

 

这是引入服务化之后整体的架构。

 

 

 知乎网站架构变迁史——阅读心得

 

 原文地址:https://mp.weixin.qq.com/s?__biz=MjM5NTg2NTU0Ng==&mid=403282668&idx=3&sn=c9d5c13f797adfde514c144e8f1cfce0&scene=21#wechat_redirect


推荐阅读
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 本文介绍了在使用Python中的aiohttp模块模拟服务器时出现的连接失败问题,并提供了相应的解决方法。文章中详细说明了出错的代码以及相关的软件版本和环境信息,同时也提到了相关的警告信息和函数的替代方案。通过阅读本文,读者可以了解到如何解决Python连接服务器失败的问题,并对aiohttp模块有更深入的了解。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
author-avatar
峡谷人123_742
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有