据半年前的数据统计,用户在 Medium 上阅读时间的总和已经达到 2600年,每月有2500万阅读者,每周有数万篇新文章发布


技术团队


团队负责人曾就职于Google,负责过 Google+、Gmail 等项目,团队成员是一帮 聪明、好奇心强、思路独特的工程师


团队以任务来驱动,不以功能模块划分,大家都有机会接触到架构中的各个技术,工程师们都很喜欢去做不同的东西,这让他们掌握了更多的技能


工作方式上,团队设定季度目标,鼓励大家小步迭代,工程师可以灵活的安排自己的工作


初期技术体系


网站部署在 Amazon 弹性云计算平台 EC2,使用Node.js 开发,数据库采用 Amazon 的DynamoDB


一个单独服务器负责图片处理,结合了强大的图片处理库 GraphicsMagick 


还有一台服务器用作后台任务队列处理


Amazon 的云存储 S3 存放静态资源,CDN服务使用 CloudFront


Nginx 做为反向代理服务器


监控和告警使用 Datadog + PagerDuty


前端使用 Closure Library(js库,在google的很多产品中使用普遍)Closure Compiler(可以让js更快的下载和运行)Handlebars.js 模板库


现在的技术体系


运营环境


部署在Amazon的虚拟私有云,系统管理工具使用Ansible


Nginx + HAProxy 作为反向代理和负载均衡


监控和告警依旧使用 Datadog + PagerDuty


通过 ELK (Elasticsearch, Logstash, Kibana) 管理日志,帮助定位产品问题


采用面向服务的架构,目前运行着数十个service


主要的服务还是使用Node.js来开发,可以方便的在server和client间共享代码,Node.js 工作得很好,但在某些时候会出现事件阻塞,导致性能问题,为解决问题,在每台服务器上运行了多个实例,分担任务的处理工作,还对V8运行环境进行分析,看哪些任务占用时间长,然后进行优化,逐渐的解决了性能问题


有一些辅助服务是用Go写的,Go非常容易编译打包和部署,提高了一致性


数据库


DynamoDB 还是主要的数据库,但由于用户的剧增,引发了热键性能问题,便在DynamoDB前面增加了 Redis cluster


也使用了 Amazon Aurora,他可以提供比DynamoDB更灵活的查询和过滤


使用图形数据库 Neo4j 存储实体间的关系,1主2从结构,图形结构中有两个重点:节点、边


节点包括:人、文章、标签等,边是动态创建,在用户执行某些操作(例如关注、推荐)时建立


有了丰富的图形数据后,可以遍历图形,做一些分析操作,例如文章的过滤和推荐等


数据平台


数据的增加突出了数据分析框架的重要,可以辅助商务和产品的决策


使用 Amazon Redshift 作为数据仓库,他提供了可扩展的数据存储和数据处理能力


有了仓库,就需要把大量的重要数据导入进去,例如用户和文章数据、文章浏览等日志信息


对于数据的操作,技术团队自己开发了一个job系统,进行任务管理、数据依赖、监控等,使用了基于断言的模式,每个任务的执行都必须是他依赖的任务已经正确完成,并分离数据生产者和消费者


Apache Spark 的使用也越来越多,他有很好的灵活性,可以很好的支持系统的增长和扩展


Protocol Buffers是一种数据描述语言,类似于XML,能够将结构化数据序列化,可用于数据存储、通信协议等方面


使用Protocol Buffers来保持整个分布式系统中各个层面schema的同步,例如移动应用、web service、数据仓库,schema中包含了很多细节的配置,例如表名、索引、字符串最大长度验证等


编译 测试 部署


采用持续集成、持续交付的方式,通过 Jenkins管理整个流程


初期使用 Make 进行系统编译,后来迁移到了Pants


测试包括单元测试和http层面的功能测试,所有commit在merge前必须经过测试,由于测试的工作量很大,使用了 ClusterRunner 来提高测试效率,他能够以并行的方式执行测试集,让测试过程更快更高效


修改的代码会被尽快部署到临时环境,测试通过后,就等待部署到正式环境


正式环境的部署采用蓝绿部署策略,先部署到金丝雀实例,然后经过一个测试和监控的过程,没有问题后再部署到全部实例,有问题的话就执行回退,采用内部DNS切换的方式进行回退