据半年前的数据统计,用户在 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切换的方式进行回退