Twitter2022

notion image
notion image
  1. 前端 + API层 + GraphQL
  1. Timeline Mixer + Home Mixer + Ranker & Scorer
  1. Prediction service, Manhattan和其他
阅读本系列的希望读者时刻思考Twitter遇到的问题,包括但不限于:
  1. 非常多的请求,包括读与写,且写的频率并不低
  1. 大量实时的数据需要被处理,并实时的反馈到UI上
  1. 大量的微服务,以及微服务间怎样沟通
  1. ...

前端

notion image
用户的请求最先来到前端。Twitter的前端架构叫Twitter Frontend (TFE)。作为中间层,它连接了web, android, iPhone客户端和Twitter的内部服务。它的作用包含反向代理(reverse proxy), API网关(API Gateway), 以及路由器(router)。这三个名词也很好的解释了TFE帮助解决的问题
  • 用户验证,安全验证
  • 数据请求: 在微服务结构下,用户的请求可能需要多个微服务来合作解决。TFE可以把请求分解成对应微服务的请求,并收集和制作response
  • 负载均衡:将请求转递到对应的服务,并平衡服务器的负载
  • 限流:比如限制来自相同IP下的请求次数
  • ...
举个例子,TFE可以验证cookie并将Twitter Identity Assertion headers (Twitter身份认证的一种header)传给对应的后端服务。验证cookie是一件比较复杂的过程,通过TFE完成的话,后端的服务就不需要考虑用户验证了。

API层

notion image
用户的请求经过TFE会到达Federated Strato Column或者TLS-API,到达的API目前是根据用户的客户端类型决定的 (iPhone, web用户会使用Strato API,HTTP和Android用户"可能"会使用TLS-API)。

Federated Strato Column

乍一看,分开这三个词只认识俩,合起来整个直接不知所云。但是经过阅读,Federated, Strato, Column的其实这三个词都非常讲究。
Federated
即federated database (又名virtual database,虚拟数据库), wikipedia给出的定义是这样的:
A federated database system (FDBS) is a type of meta-database management system (DBMS), which transparently maps multiple autonomous database systems into a single federated database. The constituent databases are interconnected via a computer network and may be geographically decentralized. Since the constituent database systems remain autonomous, a federated database system is a contrastable alternative to the (sometimes daunting) task of merging several disparate databases. A federated database, or virtual database, is a composite of all constituent databases in a federated database system. There is no actual data integration in the constituent disparate databases as a result of data federation.
简而言之,federated database解决的问题就是同时获取以及更新来自不同数据库的数据,并且federated database本身不集成数据。拥有这样一个数据的集合对于Twitter成百上千数据库规模的数据管理是非常有帮助的,Twitter的工程师可以使用Strato一个平台直接读取和更新数据,而不是寻找对应的微服务或者数据库完成数据的读取和更新。
Strato
Strato就是这个federated database的名字,这个数据库只在Twitter内部使用。查询这个数据库需要用到的语言叫做StratoQL,它与Scala比较像。
Strato有一个重要的功能叫做query-defined datasets。(在常见的数据库系统里类似的功能叫做View(视图)或者stored procedure(存储过程)),用户可以将业务逻辑写成query-defined datasets并重复查询它们,Strato会自动host这些datasets。
Query-defined datasets能够解决不少微服务架构的问题。比方说,如果我们要找最好的tweet,在微服务架构下我们需要创建一个“best-tweet” (最好的tweet) 的微服务,这个服务需要查询其他的微服务(比方说最有趣的tweet的微服务和最有营养内容的tweet微服务)来判断tweet的质量。然而,如果使用query-defined datasets,我们可以把需要查询的数据直接放入query-defined datasets中而不是创建新的微服务,从而节省了创建和维护微服务的人力物力。
Strato还有其他的一些功能包括自动完成请求的batching和使用用户自行选择的API协议(包括JSON/REST, 和Thrift),这些功能一般都需要开发者主动去选择或优化,但是在Strato里都是默认的行为。
notion image
Strato示意图,其中Strato既可以读写query-defined datasets也可以读写现有的服务和数据库
Column
由于Strato并为开源也无开源的计划,我只能根据现有的信息对Strato的数据格式进行一个估测。通过调查,可以知道的是使用Strato比较简单并且有可能是对于数据库”列“的一种抽象。
notion image
前Twitter Staff Engineer留下的珍贵Strato Column的例子
向Strato添加数据的方式是添加与数据对应的配置文件。上图的例子就是储存Twitter用户生日的一个配置文件。
可以看到这个配置的目的地(dest)是“twitter_db”,数据集是“birthdays”。mapping提到了这个column是一个User ID -> 生日Timestamp的key-value store的形式。[该段落内容均为”开局一张图,剩下全靠编“的体现,Strato既不开源又没有解释清楚这个例子...]。
Strato Column还有一个很大的优势即GraphQL schema的添加。在column中的体现为添加一个名为"graphql"的field。
这样简单的column的形式可以让内部人员不需要学习即可添加Strato Column,并且将Strato Column的hosting和维护交由Strato系统来解决。

TLS-API (being deperacated)

在资料查询的过程中我并没有找到Twitter的TLS-API。板书上的being deprecated也表示了该API正在被Twitter弃用。马斯克在Alex Xu的twitter附加的笔记的第一条就是
Maybe deprecate TLS this week, as only needed if Android app >1 year old.
说明近一年内某次安卓客户端的更新已经弃用了TLS。
简单来说,可能就是twitter曾经使用的是由TLS (Transport Layer Security, 传输层安全协议)加密的API链接方式。为什么不再使用的原因可能是现有的Strato-based方法更优以及GraphQL的使用。

GraphQL

细心的同学可能看到了Federated Strato Column的上方写了GraphQL。作为Twitter最近使用的非常重要的Query Language,本文也想简单讲讲Twitter使用GraphQL的动机和解决问题。

GraphQL的优势

了解GraphQL的优势会对理解Twitter使用GraphQL的动机非常有帮助。
比起传统的REST/HTTP, GraphQL最大的优势在于准确的获取需要的数据。比方说,如果我们要获取每个Twitter用户的生日,但假设我们只有一个/user/{id}的节点(基于user id获取用户信息的节点),传统获取信息的方式为
  1. 获取全部用户的id
  1. Fetch每一个用户的用户信息
  1. 筛选出用户的id,名字,生日并返回
或者我们创建一个/user/birthdays的节点来解决以上的业务逻辑。
然而,使用GraphQL的话,只需要一个query即可解决所有问题
query GetUsersBirthdays { user { id name birthday } }
同时,我们也可以创建fragment将部分业务逻辑存储起来并方便重复使用。
fragment userInfo on User { id name birthday } query GetUsersBirthdays { user { ...userInfo } } # userInfo 可以被复用到其他的query里

使用GraphQL的动机

Twitter API v1.1 通过微服务架构,在公司的早期让开发者大大提高了开发的速度。但与此同时,一个痛点就是大量分散的API节点也同时诞生,并且很多节点的存在只是为了解决很小且特定的需求。
所以在设计Twitter API v2的时候,一个最重要任务就是减少特定业务逻辑的节点数量。这正好对应了我们提到的GraphQL的一大优势,即通过query object获取特定的数据而不是创建新的节点。
上文中我们还提到了fragment的复用,fragment的复用不仅限于逻辑上的复用。更重要的是渲染复用(rendering reuse)。举个栗子,当多个组件同时需要上方的userInfo的时候,每个组件都可以声明(declare) ...userInfo。userInfo在全局只会被fetch一次。从这个角度来想,GraphQL的使用不仅减少了节点的数量,也减少了节点被fetch的次数。

GraphQL和Strato的联系

通过对比Strato的query-defined datasets和GraphQL的fragment,我们注意到,GraphQL和Strato的设计哲学其实是十分相似的 -- 即减少特定的节点数量和逻辑的复用。不同的是,Strato是在数据库层的简化,GraphQL是对于服务层的简化。
事实上,Twitter内部已经有基于Strato设计的GraphQL API,从而保持了federated database -> API层 -> client点对点的数据格式(end-to-end types)。这其中的意义是使用不同数据库、服务的时候,能有统一的方式获取业务逻辑需要的数据。这点对于数据密集型应用是非常有意义的。

总结

  1. TFE作为API Gateway,连接了Twitter的不同类型的客户端和服务
  1. Strato是Twitter打造的Federated Database,其意义在于给予了同时获取或更新不同数据来源的能力
  1. Strato的query-defined datasets是在Federated Database中类似视图的concept,可以减少不必要的业务逻辑服务
  1. GraphQL是Twitter重要的query language,可以帮助业务逻辑准确的获取需要的数据,并对不同组件需要的相同数据进行复用

参考

[1] @beyang. (2017, October 26). Graphql at Twitter. Sourcegraph. Retrieved November 24, 2022, from https://about.sourcegraph.com/blog/graphql/graphql-at-twitter
[2] Hylbert, J. Q., & Cosenza, S. (2020, August 12). Rebuilding twitter's public api. Twitter. Retrieved November 24, 2022, from https://blog.twitter.com/engineering/en_us/topics/infrastructure/2020/rebuild_twitter_public_api_2020
[3] Thinking in relay: Relay. Relay RSS. (n.d.). Retrieved November 24, 2022, from https://relay.dev/docs/principles-and-architecture/thinking-in-relay/
[4] Solomon, M. (2017, December 10). Strato: Twitter's Virtual Database powered by microservices. YouTube. Retrieved November 24, 2022, from https://www.youtube.com/watch?v=E1gDNHZr1NA&ab_channel=FunctionalTV
[5] Xu, A. (2022, November 19). Twitter architecture 2022 vs. 2012. what's changed over the past 10 Years? Twitter. Retrieved November 24, 2022, from https://twitter.com/alexxubyte/status/1594008281340530688
[6] Musk, E. (2022, November 19). Just leaving twitter HQ code review. Twitter. Retrieved November 24, 2022, from https://twitter.com/elonmusk/st
Loading...
目录
文章列表
王小扬博客
产品
Think
Git
软件开发
计算机网络
CI
DB
设计
缓存
Docker
Node
操作系统
Java
大前端
Nestjs
其他
PHP