关于数据保留时长,候选人提出按 5 年甚至 1 年滚动采购存储进行估算,认为旧系统在长期演进中会被淘汰。面试官立刻纠正并明确产品原则:“We don't want to lose data. Data is everything in Facebook.” 用户直到今天仍能查看自己 10 年前的历史状态,系统必须支持永久存储;底层架构应做到动态水平扩展(horizontally scalable),按年扩容是运维层面的事,架构设计必须保证持久保留。
候选人准备转向 API 设计,但面试官直接打断并强调核心重点:“Let's go to architecture. I'm really interested in architecture here. I want to see how to handle architecture.” 面试官希望深入剖析其服务解耦、拓扑流转与数据合并机制。
候选人开始绘制系统架构拓扑图。他将整个在线链路拆分为用户发帖与用户读 Feed 两条主干线:
1. **写流程(Post Pipeline)**:客户端调用 Post Service,服务将帖子元数据(发布者 ID、内容、创建时间戳等)写入 Post Storage,而图片、视频等多媒体文件剥离存入专门的 Media Storage(如前述的对象存储)。
2. **读流程(Feed Pipeline)**:客户端向 Feed Service 发起拉取请求。为了组装用户关注者的动态,Feed Service 必须与 Relation Service(关系服务)交互,由其查询出该用户关注的所有好友与主页列表(Followees)。
3. **数据聚合与多路归并(Fan-out-on-read / Pull Model)**:Feed Service 拿到所有的 Followee IDs 之后,再批量向 Post Storage 请求这些关注者近期发布的帖子列表。由于每位被关注者的发帖在底层存储中均按时间戳或自增 Post ID 建立了索引,Feed Service 可以直接使用归并排序(k-way merge),将来自多个好友的有序动态合并成一条全局按时间排序的时间线(Timeline),最后回传给客户端。
```mermaid
flowchart LR
accTitle: Hybrid Fan-out and Pull Architecture
accDescr: Hybrid pipeline showing fan-out for normal users and pull-merge for celebrities
候选人随即修正逻辑:当用户滑动到当前页面底部时,客户端可以提取当前页中最小的帖子 ID(Minimum Post ID),携带 `Limit`(例如单页 3 条)作为入参请求 Feed Service。Feed Service 在 Sorted Set 中查找 ID 小于该界限的历史记录并切片返回。
此时面试官进一步指出了方案中一个潜在的致命前提:“你把 `PostID` 和 `Timestamp` 混用来判断大小关系,这里存在一个非常大的前置假设——即你默认帖子 ID 是像 Twitter Snowflake 那样按时间递增生成的。但并不是每家公司或每个系统都具备或采用 Snowflake 这种强时间有序的全局 ID 生成器。如果 ID 不包含时间递增语义,你单纯比较 ID 大小就会完全出错。”面试官建议应当将时间范围判定(Timestamp / Score Range)与物理主键的依赖解耦,不要在系统设计中轻易引入未经确认的 ID 自增性假设。
候选人最初设想在 Feed Service 层进行近实时合并,引入广告服务(Ad Service)以及特别关注(Interested Follower)等上游通知源。但面试官随即打断并澄清了核心痛点:“你还是没有完全抓住我的问题。”面试官指出,Feed 的排序分数处于动态流转中,数据来源五花八门——好友动态、广告推送、公共主页(Public Page)、同城信息或群组通知均有各自的分数。系统不仅要保证每次请求都向用户呈现最高分、最吸引人的内容,更关键的是**绝对不能向用户返回重复的内容(Non-repeating Feeds)**。面对这一挑战,候选人提出在 Feed Service 前置一个“过滤服务”(Filter Service),在每次返回帖子列表之前,利用布隆过滤器(Bloom filter)记录已读 Post ID 或 Ad ID,剔除重复数据后再下发。
```mermaid
flowchart LR
accTitle: Multi-source Feed Ranking and Filter Flow
accDescr: Incoming feeds from ads, friends, and pages pass through ranking and a filter service before being returned to users.
subgraph Sources["数据来源 (Feed Sources)"]
S1["广告服务 (Ad Service)"]
S2["好友动态 (Friends Post)"]
S3["公共主页 (Public Page)"]
S4["群组/同城 (Groups / City)"]
end
引入布隆过滤器的方案立刻引发了激烈的架构探讨。面试官直接提出质疑:“我们这里用 Bloom Filter 的具体 Use Case 是什么?”面试官阐明,布隆过滤器通常用于超大规模的“稀疏矩阵”(Sparse Map),用来快速判断某个元素是否存在于海量离散空间中。然而,对于常规用户的个人信息流(Homeline Feed),数据是系统为每个特定用户预先定制或推送的,结构非常密集(Dense),并不属于典型的稀疏数据集,直接套用布隆过滤器显得并不合理。
候选人据理力争,认为广告和公共主页大 V(Influencer)的动态对全量用户而言恰好符合稀疏矩阵的定义:大 V 拥有庞大粉丝群,单条帖子被全网某些特定用户零散浏览,这种浏览记录在用户-帖子空间中高度稀疏。为了避免布隆过滤器无限膨胀,候选人进一步完善了生命周期管理:
- 推荐系统具有时间局部性,通常只推荐最近一个月或一周的新鲜内容,无需永久去重。
- 过滤服务可采用滚动窗口(Rolling / Scroll Service),以“周”为单位维护布隆过滤器实例,例如同时保留“本周”、“上周”和“两周前”三个过滤器。
- 键值设计采用 `User ID + Post ID`。随着时间推进进入新的一周,系统直接剔除最老一周的过滤器并新建实例,滚动淘汰过期数据,保证低内存开销。
面试官认可了按时间窗口淘汰过期的设计思想(“You don't want to filter it forever”),但依然强调在实际工业界方案中,必须根据数据特性采用混杂模式(Hybrid Model),不可一刀切地将所有帖子都推向布隆过滤器。
```mermaid
flowchart TD
accTitle: Facebook Ads Serving Parallel Architecture
accDescr: Ads Finder fans out queries in parallel to multiple Ads Indexers, dropping timeouts, and then aggregates and ranks results.
UserReq["客户端请求 (User Request)"] --> Finder["Ads Finder (聚合与分发中枢)"]
```mermaid
flowchart LR
accTitle: Facebook TAO 异构图数据模型示例
accDescr: 展示用户、帖子与地理位置节点之间通过点赞、发布及位置关联构成的异构图结构。
subgraph Nodes["实体节点 (Entities)"]
U1["用户: Scott"]
U2["用户: 林世耀"]
U3["用户: 景祥"]
P["帖子: Hiking Post"]
L["位置: Golden Gate Bridge"]
end
U1 -- "发布 / 关联" --> P
U2 -- "共同参与" --> P
P -- "发生地" --> L
U3 -- "点赞 (Like)" --> P
```
为了兼顾全球访问体验与性能,TAO 实现了极为复杂的多数据中心复制缓存(Multi-datacenter replicated caching)。其缓存分为单 Region 内的 Memcached 缓存,以及跨 Region 的 Multi-Master TAO 机制。虽然大部分标准场景倾向于 Single Master TAO 架构,但面对跨地域延迟挑战时也会启用 Multi-Master。多层级缓存体系的引入必然伴随一致性代价:在写后读保障(Read-your-writes assumption)失灵、Lost Update,甚至是可线性化(Linearizability)被破坏等场景下,极易出现用户 A 发帖后被删除,或用户 A 看到帖子而用户 B 刷不出来的边缘异常。
## Notable quotes
> [05:00](https://www.youtube.com/watch?v=36-RK5RUMUg&t=300s) We don't want to lose data. Data is everything in Facebook. — Scott Shi
> [10:00](https://www.youtube.com/watch?v=36-RK5RUMUg&t=600s) Let's go to architecture. I'm really interested in architecture here. I want to see how to handle architecture. — Scott Shi
> [20:00](https://www.youtube.com/watch?v=36-RK5RUMUg&t=1200s) 我非常怀疑这种设计能否支撑高并发的 Scale。 — Scott Shi
> [29:50](https://www.youtube.com/watch?v=36-RK5RUMUg&t=1790s) 这个利用率太低了。你上来如果先抛出一个很单纯的规范化模型,面试官心里就会打一个大大的问号(Doubts)。其实你心里早已经想好了 Hybrid 方案,但面试是非常看重 Perception(第一印象与专业感知)的。 — Scott Shi
> [29:50](https://www.youtube.com/watch?v=36-RK5RUMUg&t=1790s) 设计这个系统通常有 Normalized 和 Denormalized 两种思路,由于纯拉取模型存在巨大的读放大与资源浪费,我建议一开始就采用兼顾两者的 Hybrid Solution。 — Scott Shi
> [40:00](https://www.youtube.com/watch?v=36-RK5RUMUg&t=2400s) 你还是没有完全抓住我的问题。 — Scott Shi
> [45:00](https://www.youtube.com/watch?v=36-RK5RUMUg&t=2700s) 我们这里用 Bloom Filter 的具体 Use Case 是什么? — Scott Shi
> [45:00](https://www.youtube.com/watch?v=36-RK5RUMUg&t=2700s) You don't want to filter it forever — Scott Shi
[5:00] Scott Shi: We don't want to lose data. Data is everything in Facebook.
[10:00] Scott Shi: Let's go to architecture. I'm really interested in architecture here. I want to see how to handle architecture.
[20:00] Scott Shi: 我非常怀疑这种设计能否支撑高并发的 Scale。
[29:50] Scott Shi: 这个利用率太低了。你上来如果先抛出一个很单纯的规范化模型,面试官心里就会打一个大大的问号(Doubts)。其实你心里早已经想好了 Hybrid 方案,但面试是非常看重 Perception(第一印象与专业感知)的。
[29:50] Scott Shi: 设计这个系统通常有 Normalized 和 Denormalized 两种思路,由于纯拉取模型存在巨大的读放大与资源浪费,我建议一开始就采用兼顾两者的 Hybrid Solution。
[40:00] Scott Shi: 你还是没有完全抓住我的问题。
[45:00] Scott Shi: 我们这里用 Bloom Filter 的具体 Use Case 是什么?
[45:00] Scott Shi: You don't want to filter it forever
Original transcript
[0:00] 我现在是在Uber工作工作了Uber在Uber工作了两年多然后之前是在微软微软工作了一年半然后调查调调过来的Uber主要是做那个Data Infra相关Data Infra 你做哪一块啊 记得在乌版内部的 Flink啊, fling control我不是有分一个吗我一直有那个Athena是吧?对对对对OK OK make sense 嗯然后我们这边的话就是今天讲那个Facebook feeds啊Facebook feeds其实他也publish过一些paper我觉得比较好的paper就是那个陶Facebook陶这边paper还是挺值得大家读一下的然后啊然后这个这个陶这边paper呢就是我我9月份我去年11月的时候加入了一个Uber的一个strike team,当时也是sign了Illegal的,就不能disclose做啥。然后但是我们当时设计了一个graph,然后就写了一个graph,就写了一个relationship。然后和这个Facebook淘很像,但是我这写完以后才读到Facebook淘,然后发现其中好多想法是相似的。Facebook Fiz,如果大家感兴趣的话,可以对一本Paper叫Facebook的那个Tao,TAO。它也是inspire了很多Paper的设计。像Uber Schemeless也是Tao inspired的。然后Facebook Feet的话,中间还是有很多优化的然后还是挺有趣的,那我们现在就开始好了,然后你晒下你的screen,这样的话我们可以看着这个线。OK,so,这个description我是copy的那个,因为我自己不用Facebook,我Facebook的基本上我不用Facebook, 我就不喜欢把我的Data disclose, 然后就没有用Facebook, 所以我现在的话这个Face如果有什么新的Fature, 我不胜手, 上一次用已经好久年了, 14年, 13年的时候。好,现在的话就是我就copy了一个Glocking Interview的FacebookFace, 我觉得它设计的中间最重要的问题没有解答, 但是我们这块的requirements是copy在那里的, 所以这块的话,NewsFace就是OK,so if we want to design a new space,newsfades should be generated by some posts from other people.我可以申请一下权限吗?应该refresh一下,应该有的。你应该是有ID的前线的对吧? -Oh, cool. -OK,我应该给你了,对。然后,OK, let's design a newsfeed feed for the Facebook.so the newsfeed will be generated based on posts from other people and groups and also page other users follow and you may have many friends follow a large number of grouppages and group and the face me content image and videos and I'll just text and our service support support a pending new post as a right for the to the news feeds are for our users. So it should be另一位用者,和另一位用者,所以你也可以说你去去一些地方,你去到某些地方,你去到某些地方for example I can go to Golden Gate Bridge and leave a post there. And additionally, so you should be able to support you at new ads. That's the main revenue for Facebook. there is actually a lot of details, user experience details, but let's actually get started. Assume that you want to have a user have a non-broken experience, you want to have a good experience.you're going to have a lot of interesting requirements along the way Sure, sure. For the first one, like a user may have many friends. What is the average number for the friends? I think Facebook friends are pretty a lot. It's not like WeChat. Let's assume that you have 500.I think I read this part. I think they have total user is2.7 billionI remember 2 times 7 billion users2.5.5 is fine, yeah. They have that money, yeah. It's impressive. Monthly active user.OK,so for the day actively active user,how many there?Yeah,so let's for daily active user,let's just your one billion maybe.所以我认为
[5:00] The alignment here is quite clear. Let's first focus on the uh, We should have a How many? Like the K-- functions. Focus... Thanks. So user can post. and the user can get fit. Okay. Amen. And can also comment. and like. Thank you. So, For the post one, Suppose one user for one day, one day, one use of only postal one. then The total poster should be one billion. Thank you. And for each poster likes For the only text posted that could be... Oh. one KB should be enough, right? Can we suppose? - Yeah, one KB is probably for text posts. That's probably good enough. - Every time. So for one day, the data the storage will be Like when they... Eh... This is the one that like, This is... One can be. One, two, three. Okay. Thank you. This is one terabyte, right? I think it's around similar, roughly right level, yeah. Yeah, for one day, the data could be one terabyte. And suppose we need to store the data for five years. Let's assume that you want to stop much longer. I can still see my posts like 10 years ago. So you want to start forever, maybe. Forever? Yeah. But the system could be deprecated. in the long run. - System could, well, you can decorate the system, but you can migrate data to a new system, right? We don't want to last data. Data is everything in Facebook. Okay, now we can do this way like a week every year we are at a new storage so we can only estimate the data for one year. It should be dynamically horizontal scalable, right? That's a requirement, right? You want your service to be horizontal scalable. Yeah, but we will keep adding the storage on that one. like for the scalability is supported by the the architecture. Like we can-- easily to add storage. Sounds good. Yeah, we don't need to put all the data, all the storage there. in the beginning, so we can suppose one year. Thank you. So It's around the terabyte. Like we will also have some videos or images Like for this kind of post, can we support like user will have a less uh, post on that one. I think you actually have more video posts than image posts than the text posts. Okay. I don't know because I don't use Facebook also. - Yeah, you probably have more image and video posts and text posts. Okay, so that's a majority of posts, I think. One billion. For the video or the image, it could be much Baker. So, Can we... For the image, like one megabyte, Thank you. It's not. I think here it's you're storing in a different database, unless you want to store in the same database. So the storage size doesn't matter here in my own opinion. Okay, so you mean that we don't need to calculate this kind of things. Anyway, for this kind of files, we can store it in HDFS. So for the HDFS, it's quite flexible and scalable. Okay, so this is some part I don't really like. I think it's actually not a good design. So you don't want to start in HDFS because the Lunden C2 HDFS are optimized for throughput. It means that it's a-- it means that the
[10:00] throughput for HDFS is a kills optimization. So it's like a TCP, it means that you can get your you know, transfer throughput maximum, but the latency will be very high. If you're familiar with HDFS, I think some of the call can take more than one minute. So Yeah, for the raw HDFS, then we need to find the directory and find the pass and get the get the file, but we can build it based on the edge base. - Oh, okay. - And the storage is still rely on the HDFS, but the the SQL engine, the, the, Yeah, will be the edge base. Okay. Thank you. uh, So, yeah, I think you can just mention you want to use like the out of box service like Amazon S3 and maybe add a cache on top of it. That makes more sense. Well, you can do your own service as well. If you want to rebuild the MLS3, that's your choice. You have an auto box service you can use. - Sure, sure, yeah. And also like for the For the video, it could be larger. Thank you. Thank you. All right, bye. This is gonna be a huge storage. For the QPS like we have one billion user and suppose one post, one every day. So on the And for one day it's about... 10 soldants. Thank you. Seconds. Oh, no. Thank you. 100. - One hundred thousand, right? And so the Thank you. Thank you. QPS would be one. - Be ready. Thank you. So it is a lot Okay. Thank you. This one. For the Yeah. Okay, I see. It's a user QPS. That's the right QPS you're trying to see? Yeah. That's right. Post-ocue. Post-ocue. Okay. So the peak QPS Let's see, we can multiply five. or 10. Thanks, Alron. Can you use one? So for the read, Actually, for the red QPS, it could be way higher than this one. Uh... Great. Thank you. Thank you. Thank you. Let's see one billing user - I think one day that could be, Thank you. Thank you. 10 times. to refresh the app in the website. So that one would be... Hi. Thank you. We can also still use Thank you. Thank you. Thank you. Yeah, I think it's a reasonable estimation. Mm-hmm. Thank you. Okay, so... Let's go to the Firstly, let's go to the API design. Let's go to architecture. I'm really interested in architecture here. I want to see how to handle architecture. OK, sure. Like, how was this? this one. So we can draw in on this one. suppose This is a user. And the user can host Thank you. uh service So one user do the post. Thank you. you can contact the poster service. And for the poster service, we need to have a storage - Uh...
[15:00] there will be multiple since we need to start. Uh, Let's see. Post. It's... Thank you. - It's sale. And we also need to have the Let's keep the terminology thing. Let's call it feed, feed service. Thank you. It's a feed, right? Yeah. Sorry, Facebook feed system. it's a data system but the user needs to foster the poster the poster, right? And then for the like for the user, They try to get their feet. Then we have another one we can call it Thank you. Thank you. Fade this service. Thank you. Thank you. So this one will contact with user to Feather the Feeds We can go to the workflow first. Like look at the user can post the one. in the posted service. And the poster service will store store the data in the storage. The data contains the post the content and who posted this one. And also, like, for the poster, we can have some... video or image So for that media file, then we can putting in another like media. Store, change. Thank you. Thank you. Mm-hmm. Thank you. uh, So uh, The basic model can be all the posts are stored in the post storage. And then we have another We have this feed service this feed service will get some relationship. Let's see, relation. So for this one, if. it can provide the function like one user, we can find all the followers, followers of this user. And then You get the... All... Thank you. .com Thank you. follow each. So then the basic function could be, Zs1 to Thank you. This one can get the... Thank you. Thank you. Thank you. "Order for... Yes. Thank you. post. And then to do And not this. Thank you. Thank you. and then merge all the poster for the followings. So one user can request to the feed service periodically. And this one will get the user ID. to the relation service. the relation service can get all the user followees, then the follow the feed service used the follow-e uh, IDs to Uh, query the post and storage and retrieve all the data And here. because all the a full-year post could be sorted in the, in either by the timestamp or by the ID of the post. then we can easily merge it several
[20:00] We can call it the timeline, right? Yeah, we can call you the timeline. So we can merge all the timelines. So this is the-- basic model, like, It's... It's called the... This is a... Yeah, this is now this. This is a relational model. This is a normalized model. I mean like One user want to get the fit. then it will find out the traffic. and to query all the flowyets and the query all the posts and the merge it. Yeah, this is a normalized model. OK, let's give you some questions. Some very interesting questions. Let's actually go something simple. how many posts per user you want to fetch. Like, For the Facebook, I'm not sure like, In one page, it's maybe only 10. Okay, and then we can multiply five. So Bye. who Okay. 50 hosts. Thank you. So, OK, so you want to get 50 posts. And then how are you going to do it? You have 500 friends here and how many posts you're going to get for each friend. Thank you. Here for each friend, in case some friends doesn't post anything, so at least for each friend, 52. So for each friend, for 500 friends, each friend, you get 50 posts. Yeah. Okay, so now you're actually reading 500 times 50. That's actually-- 25,000 posts and at the end you only return 50 posts. Mm. OK, so this is first thing, right? Second thing is that-- We want to optimize latency. So you can think of if your request is only reading only one database. It means that most of the time, like P99, probably 10 milliseconds. I... Yeah, for this one, we don't go in. to details of this database. They could be the noSQL so we don't need to do the sharding And also, we can also use MySQL or some other IDMs A relational database, then we can do the sharding on the service level. But still, you're actually-- So when you get post-- from 500 users. When you get posts from 700 users, you actually do a 500 API database call. Yeah. like if you're looking at the implementation and say this 500 API call, it could go to totally different partition and shardings of the database. So your reading call, when users reading call, you know, we don't see this amplification but if the read amplification is 500, Yeah, so I mean, this is a basic design. Then we can also do a find out to-- decrease the latency of the uh New state. OK, yeah, let's say it's optimization, because I highly doubt this design will scale. - Yeah, yeah. uh... once the user posted poster survey post poster. then we can do a found at this moment. So we don't let the user to actively pull all the posts. then we can uh, to generate the post-align. or the news feed line. for the for the followers. Let's see. We have another Let's see. This is a poster service. then we can send the poster service to fan alt service So this one, it will basically also do the same thing. Like... In the relations service, it will request the relation series. to get all the followers. Thank you. Thank you. Thank you. What about the numbers? And then for each followers, we can have a
[25:00] line. This could be a timeline. And we can also have the post line, So, we can We can store all the timeline in the, like we can see the Catch. all the Stay the best. So... Thank you. Thank you. So with Once the poster is reached to the final service, And we'll... calculated based on the relation. and found out the poster to each followers. post line. So when the user comes to you, get the fit fit. Right. then it can go to firstly to check check the Thank you. Thank you. check the post line storage. and to direct if there is a post line there. for this user. then it could be returned the result directly. If not, then we will still go to the the basic line to get all the flowees and merge all the posts So For the final service, like it still could have some issue like you mentioned in the requirement there is a Page. And for each page, it could have a lot of followers. So like See, if there's one million followers, This file will insert to the 1 million users. post line. that it could be a big effort. So for that kind of service, we can also how Another we can call Uh... user. Thank you. Tier source So, it's basically store the Oh. either user or web page. Like, if the user or page have more than 1K or 10K followers. then we consider it as a celebrating. So in the founds, we don't do the Don't do the fine outs. we are ignore this, we are directly ignore this, operation. So If we add this one, then... in the field service, there will be a merge. for the last minute. There will be extra merge service. Oh, shit. So the workflow could be one user come to the feed service. Then the failed service will go to the catch and all the database. to get all the posts the post line for this user. Meanwhile, so it will also check the relationship service to find all the for the following is who is the we can call it a celebrity. who has a large number of the you Followers. Then, we can go to this one. to Get the large number of followers posts and then do the merge. So here, Then we can merge the post line with this one. and the return to the users. Yeah, I think this is a hybrid model, a normal solution. The number solution. This is actually also a design very similar to how Twitter is designed to their face. Yeah. Okay, so I want to say this is the "表述相关"
[30:00] 但是这个利用率太低了 你看这个你读一个follower 500个follower然后每个在读50个post 读了25000个post 最后返回50个 这个利用率这个利用率只有不到0.5%0.59% 这个利用太低了,所以你肯定得说一下,我上来就叫一个hybrid solution,有nomalized denomalized solution你一上来就把这个酱的话能减少很多的Douts 是吧OK对这个跟表述相关其实你上来这些设计已经想好了但是这个跟表述相关就是你上来还是要这么说的这个会影响Perception,最后可能其实也没有什么影响,但可能会影响Perception嗯所以你上来的时候就你想好这个hybrid solution,就上来就说这个hybrid solution,这个的话还是很重要的好OK然后我想想OK,所以,所以,好,你遇到更新的新配置。例如,你读了一篇,有新的新一篇,你想要表明,I think when there is a new post coming, you will show someone who already uploaded, someone posted a new thing, you want to notify your user如果你再次投入了一张how do you handle that part because all the posts and feeds are ever changing不是不像是否有效果所以你意思是一 user already got the post line here, and then one of the followers already posted a new one, how do we notify this user?是的, how do you notify the user, and what about subsequent rate? How are you going to handle subsequent rate?嗯所以我可以与你相似的 scenarios所以第一次是You pull the post and then after 10 seconds you pull the poster again, you pull the phase again, so you pull the phase十秒钟,你再看了一个随时的随时,你再看了一个随时,你再看了一个随时,然后你留下了一半时间后一半时间你会不会Puza phase again第三 scenario is that you open the face at early morning and then it'stime goes by然后在后面你开会的一样,你会开会的一样,Data Scheme和Data Model像是for thePortline serviceand the storage we need to store like啊好for each user we can have a like suppose wewe are using the redis actually i think twitter user redisfor all this stuff所以我们可以用Rat is donefor each user it can have a post line在这个Post line 它可以好sorted the set谢谢谢谢谢谢大家and for this one啊forsorty set for each one we can usePostID谢谢 suppose this poster storage will supposeincrementalIDand also with a timestampand also the content一些像one poster could contains a photo or thevideo, then you could have a media谢谢大家谢谢Links嗯然后in the beginning, user can query the feed service, then feed service will return all the posts.for each poster it willWe also have the POSTID and TASTAtimes downand also other content media link嗯 then the media link will, a user can directly call another media service去找image, all the videosbut for this one like say在早上,他已经有了好一天后嘿可以去的 feedback service位置Let's see嗯好Current
[35:00] post id And the Max. timestamp. So, use this to use this to keep Hmm. parameters, the field service can with from the the poster line storage and only extracted that the data bigger than the current post ID. Also, like, bigger later than this timestamp. Sorry, I got confused. So you assume that the post ID is actually time indexed? So the ID actually has timestamping it. Yeah. Okay, so what if you don't have any data? Like you look into the new timeline, you pull it very frequently. Like one minute you feel like 50 pulls and you want to pull again. For this one, when you use a poster into the poster service, it will find out to this. this cache or this DB, this storage. Right. Like, if this is missing here, Either this one is already-- this service is done. all the service has some legacy. here. Thank you. So my question is on how-- so here, you actually have a list. Do you want to keep the list, or do you want to keep the list ongoing? Oh For this one, it will clean the list for some time. OK, so you want to-- so the list is actually limited list, right? You will clean it up if it's too long ago. OK. In that case, when you fetch the data-- Help me understand this. Are you going to do the subsequent run will fetch the more newer data or the older data? The newer data. The newer data, okay. Yeah. But the first fetch will be the newest data. Yeah. Okay, so if you pull it a subsequent only, just, you know, after you pull the first page, you want to look at a second page, you don't get any data there. Mm-hmm. Thank you. Oh, you mean this one? It's timeline, right? So if you get-- I think one of the common use cases is that when you look at the first page of data, the second page data is like older posts, not like newer posts. Then we can like Suppose we already see the Like you can have this one. Suppose we already got the first page. Thank you. then we have the post ID for this page. and we can take the minimum post ID. And then we can use that one. uh, as a parameter to query the fit service. Also, we can add a limit. So it means-- Like, suppose we have a-- We have a poster 1, 2, 3, 4, 5, 6. Thank you. So for each page, we only return three. And firstly, it will query with the feed service Nothing. And then we can get the five, six, seven. And then when we screw down in the page. we can take the file. as a current post ID. So, We can also add a limit to like three. So when the fit service get this request, it will check the post ID smaller than the... the file. and retrieve three posts. back to the user. Okay, so here, I don't think, so I can do a post ID. Time stamp, so you should have a big assumption. Post ID, you can't show your idea. You can't show your time stamp. You can't show your snowflake ID. Twitter Snowflake ID, so post ID and timestamp has a big assumption. So I would recommend you not use post ID and timestamp, because this assumption is not... I'm sure Twitter Snowflake is like post ID and timestamp. and that's a not that companies have. If not, you may still use other determiners. to look at the range of the range I think my bigger issue here is that Um, So for example, I think the phase here--assume that you have phase
[40:00] - Sweet. five seven. first. you know, that's an initial phase, like 1, 3, 5, 7. The bigger number it is, the higher priority you want to recommend to the user. Assume that, right? You probably want to add some machine learning there. I mean, Okay, you mean... Because you mean the poster ranking. Poster ranking, right? You want to have some machine learning there to rank the post. to make sure you give the user, because the ultimate KPI for your So your service is a user You know how how user going to you know, once they have to user or user like your platform. We want to recommend the user. Posted by people who care or please he care, you know, you want to deprioritate post if he's to next to you are some people he don't like. Right. So you do have some ranking post here. But here, let's assume that they offer to the first cops. You only help post one, three, five, seven. And then later, when you do the second part, you have two full six inserted. how do you go to return the result? I think the insert in the inserted poster should be merging on the fit side since it could be, uh, nearly real time. like see we have some Another service here. Thank you. Like it can could be the ad service you want to add ads. And also the Hapjeda um Trust either. Follow. let's say, like-- you mark someone as a interested follower. So you... once. this guy posted one poster, you want to get the notification. And For this one, Hmm. Like. Thank you. So we have the Pérez. When user queries the fit service, it can have the basic order of the posts. And then suppose Firstly, we support that All the ads, all the interested followers poster is not here. then we can use some to more disease based on the ranking. Like for example, even this one, this Let's see. So I think you still don't get my question. My question is the face, sir, you know, the ranking of the fit is ever changing. And how do you make sure your return You don't return repeatable feed. repeated feed and also you want to return the feed like most attractive to the user. And, you know, that could be another thing. I could say, you can set aside on like a ranking score for the SSL, you know, based on who paid highest price, right? Mm-hmm. Right. But generally speaking, you want to make sure-- assume that you have you'll have a fit list of different ranking scores. And the source of the fit can come from ad surveys. posting from ad service, the posting from your friends, of posting from public page and posting from maybe city information or group information. So you have a steady phase stream of different rankings got, but how do you make sure that You serve your user like non-repeating And each time you, You look at a phase that you return user, highest the rankings got, now it fits. So then we need to have a filter service. than to like every time before this service retains the poster list. we can go to this filter. Thank you. service. to filter all the retain data posts. in here. we can maintain We can make a bloom filter. Let's see. Thank you. Thank you. Thank you. Mm-hmm. Okay. Like for this one, in the bloom filter, we can use a You can
[45:00] Post ID or the ads ID to do the filtering. However, there is a thing like... So why do we need a Bloom filter here? What's the use case for Bloom filter? Like one user can, suppose we return users this post line, one to seven. So the six, it is the ads. and then next time when he come back to query the fit fit service and get a new list one so we still have this as six here but we don't want to return the this ad to user again yeah so you don't want to you don't want to return something already shows a user right You don want to show the user repeated information But blue filter is you know in a sparse map Blue filter is in a sparse map You don't, you want to identify the potential mark, you know, if an object existing in this sparse map. And I don't think it's a sparse map here. Like, the data is very sparse here. Because you generate a feed for each of the users. not really a sparse right yeah so but but for the this could be sparse here I think you're still using the you know you still push your ads to the push your ads to the to the feed service yeah but I do see a point on this first map here as far as I think the public page and user public page post and the user maybe as far set sparse like if it's a public public figure for example it has a lot of followers if it if if influence answer publish a feed and and if you view the feed that probably a bloom filter I think that could be a potential include theater because that a sparse app sparse map Yeah Like also we suppose that the recommendation could be the recently one reason post, like we don't recommend one year ago or three months ago. So in this filter service, it meant maintain the Bloom filter, we can only store the data for maybe a recent one month. So we, for, let's say we only reserved for the one week, like the key should be user ID, plus the post ID. So see this, we have several things, like for this one, it's this week. This week means all the post ID generated in this week then the filter operation will go to this one So there could be last week. There could be two weeks ago. So every week, suppose we only maintain three weeks, then every week if this is we reach to the next week then we can just delete this one and then start a new one. So it's kind of a scroll service to deprecate the old data and only maintain the latest data. So every time there is a a new recommendation, it will go to the corresponding filter service to check if the user already got this fit. Okay, I think it makes sense. You don't want to filter it forever. Here, I just want to mention, I just want to mention, you do a blue filter, you should be a hybrid model, so in the blue filter,
[50:00] 影响的Post,因为你这个UserFriendsPost其实是非常一个Count Dance的一个Poster所以那块你的filter应该是不用filter,用不同的东西来filter的吧嗯你 Bloom Filter 肯定是一个 sparse 的 map 你去 这个 map 就是这个你这个X轴和纵轴它这个点是比较零星的,你才去做bloom filter吧,你这个做的话像比如说那个一个 Influencer 的 post,然后对于所有的 user 有没有看过这 Influencer 的 post这个做Bloom Filter是make sense的 但你是个Hybrid Model嘛 你还有个UserFeed的Table你其实这个Feed Service 你里面上来说要一个一个读的嘛那你这个用Broom Filter就不make sense 吧嗯我理解这样的话也是很spass的你如果是那样子的话,你是个List,我觉得做Blue Filter其实是一个overkill,你这个谢谢我总体感觉是不适用于做 Bloom Filter谢谢大家你实际上就可以mark那个fit as read 吗?就是你read了以后你就把这个fit说我这个fit e read 过了然后你再读的时候跳过fit e 就行了吗?那它得是存在一个DB或者一个Cache里面对吧?就存在一个Redis,Memcache,找个Inmemory的DB就行了但是Cache它会一直clean的呀对吧? 开始会一直clean的,为什么会一直clean的? 因为我可能只maintain100个host line或者200个你把Post上面标上读过就行了谢谢谢谢大家谢谢但是比如说我的post,比如说我就产生一些add,我这个add不存在这个里面。我这个Ad就是用一些其他的技艺学习服务。你的Ad和Influencer的Pose,你是Hybrid Model吗?一方面是你有一个Steady的一个你有一个 sequence 有一个 feed 吗可能不是 influencer post 的那这个的话你就直接mark它读过Mail就行了另一方面的话是Influencer的就是有点用Normalized的Data Model来join那你这个的话就可以用不一种filter的嘛啊对对它已有的data在这里面是可以存起来的你可以存起来就是readnought就行了嘛就是已有的data加个boom filter的话其实你这个use case不对嘛就是boom filter不是sparse嘛Sparse Map这个不是Sparse Map啊如果把它变成一个Map的话这Map里面任何一个Post你都很快要读到了但是UserID加Post就是完全不一样的Post ID 它是连续的。是这样子吗?我想怎么说你读这个user homelight table的时候,你不是从一个sparse的一个map里读的你logical上是一个sparce map就是从逻辑层上是个SparceMap的但是你从实践层上你就从一个table里面读的就从table里面读出给我准备好的一个Fade所以你读的时候就是读这个Fade然后是给我准备的Fade就是这个所以你其实不是一个Sparce Map,但是你要读比如说这个Influencer的Post和这个User之间关系是不是可读的,这个是个Sparce Map,因为它这个实践的时候,你也是个Sparce Map。对,这就有你们的确是我们可以存在这里面对吧是这么说的吧嗯谢谢大家我看林世耀在,林世耀,你这话有什么额外要说的吗?点评的吗?因为世耀在Facebook工作了五年了请不吝点赞 订阅 转发 打赏支持明镜与点点栏目请不吝点赞 订阅 转发 打赏支持明镜与点点栏目谢谢大家- 大家听得到吗? - 冷听得到?- 我刚刚在干活,没有太认真听 - 好,阿信你肺子没有那么熟,肺子比较熟一点,肺子没有那么熟那个谢谢你们的问题是什么?他这块用了,也没有什么问题吧,就是看有什么做的不一样的地方,这块是用了一个Normalize Model和Denormalize Model,然后Normalize Model是Influencer的话用个Normalize Model,所以他读,如果是你读Influencer的Post的话你是 join 他的 post table 然后是如果你是读Friends的话,你Friends不是一个influencer的话,它是把那个data翻到你各个user的homeline,home table,就是那个home page的这个timeline table里面然后你读的时候是从这个TimelineTable里读然后在读上你的那个你follow的influencer的post然后
[55:00] 你要鉴别怎么样是哪一部分是可读的话哪一部分已经读过的话是如果是Influencer的Post的话这个Sparce Map是用这个是Sparse Map所以是用这个Bloom Filter来看你是不是读过这个Influencer的Post吗然后其实不用写的Filter行,你直接读一个Last View History行,就是View History也可以吧,读起来。然后如果是你给你生存的这个Homeline,就是Home的timeline table的话,你就是读过的话就把它mark 从读过,然后你只说的subsequent 读的话,你是跳过你读过的fism然后这边说的费是用rank费,用machine learning,不管是machine learning,来自于machine learning,还是来自于这个 ads,就是如果你想给一个user的Home的Timeline Table里面Insert费的话你要给我一个feed 然后content 然后再加一个recommendations- 然后他按这个recommendations-更relevant的更排到前面,然后less relevant排到后面一点嗯嗯谢谢大家好就是听一下你的想法因为我感觉你一直在工作这么久有什么comments啊嗯我是有点好,我是...我不知道怎么讲啊,我比较熟在这样子,但是我知道每一个就是大家看到的Timeline,或是Wall,或是Feed,他们Implementation可能都不太一样,像IG跟FB的TimelineImplementation也不一样,但是IDEA上应该是就是有Recommendation,有Score,有Ranking那个...大部分是有的,但是我印象中每一个系统好像是完全不一样,就是groups的那个叫wall,然后beats的是我自己的一套,IG的又不一样,IG的全部都是走另外一套系统 叫做Shots所以我现在因为我刚刚没有完全发我中间这个design 这些失误,所以我刚才有比较严重的bug,所以我现在比较没有办法直接等会扛我的东西。好吧,没事。你可以简单说一下,就是里面大概怎么设计的,high level 的可以讨论一下,怎么样设计的,简单聊一下。OK- 嗯,不可以啊 - 可是好要call infra的东西哦,call infra的东西因为最早版本跟现在已经应该差非常非常远了,最早版本跟现在差非常远那个好谢谢如果是什么?主持人:取历阿子好了 阿子好像就是你想要不秀给user就是repetitive的东西的话那就是基本上你是在做一个叫做realtime streaming system而且要low latency就是你的那个Response Time要非常非常快就是所以那个好像Industry有两种做法嘛 一种做法是就是用那个batch加Streaming的那个project 那叫什么Longda Architecture- 哇有点剧起来那个... - Lambda architecture,叫lambda architecture,叫lambda architecture,这是一个常见的做法那困难点就在于你又有real time 的东西,然后又有一个batch 的东西,例如说spark + storm,那你中间要怎么去?去取舍,因为Batch,Catavistic,跟那个跟Streaming不一样那这个是业界常见的状况,但是我记得Facebook的做法是完全不一样的他做法就是有个 serving system叫做做 as index, as finder, as index那他是centralizer让那个叫做AdSFinder就是它是一个as finder 非闹到很多as indexer有query的时候 read的时候就不断的建index吧大概high level是这样就是indexes is highly parallelized然后他们之间就是就是本来说 user information is not as find as finder 非闹到很多 indexer 然后fetch 在一定的时间内 return 就是relevant as list
[60:00] 那就譬如说非常多个例子Return回来 那如果太久Timeout 那个就直接就可能就drop掉 然后而Finder之后还要再做一次Aggregate就是所谓的Ranking的部分,所以Sourcing的部分是FinderSourcing给index然后return之后再merge,然后那个叫做Ranking的部分,那IG又整个不一样了,他的做法是谢谢他的作法他中间层是一个叫下的东西,所以他不是反就是Finder index他是有个叫Shots然后呢他的另外一个Ranking是一个叫什么啊 叫Barkey反正那个就是high level 它里面很多细节又不太一样了 我要复习一下 我才能够把它点评出来OK 所以它这款其实还是把它翻案成了吗 就是您给一个案子然后写到 相当是写index 就是不一定是直接写到user timeline但是它其实是写到user的predicate的一个排卵就是比如说18岁我懂了就是这个爱子比如说你post一个爱子说我不是说直接卖不到这个user我更多是卖不到比如说18岁男性比如说白人然后在这个California然后我读的时候如果我满足这个user的trades和他满足我就读到这个爱子是这样子吧谢谢大家类似的他就是他基本上不会就是因为我刚刚没有follow你们那个table怎么存,他不会直接把哪些东西直接存在一起所以它其实增加了一个中间层就是把user呢就是把那个孩子呢对,他add placement insertion是另外做的,就是在render feed 中你可以想说RenderFeed Content是一个一个Concurrent Pass, and Adds Insertion是另外一个Concurrent Pass.所以这个比较make sense,因为你其实这个Ads的Feed确实不一样嘛,Feed的话你可能也有根据其他的trades来做。但Ads 的话这个确实是比较相对来说也比较intuitive因为你post Ad的时候你要说比如说我这个target的用户就是50岁以上的女性是吧50岁以上中西部女性是吧你就post到50岁以上中西部女性然后你就那个scout也比较高一点是吧然后如果你来一个user的话你就读这个50岁以上中西部如果是满足这个的话你就会读到这个是吧但是你post的时候其实是你ads其实是没有说是直接把ads push到user的timeline但你是push到一个user的tradestimeline读其中几个trades的话你会adjust这个score然后再决定读不读然后最后的话aggregate一下然后如果bounce的话timeout就timeout所以feet的本身跟social graph比较titedly couple,就是你现在跟你的那些friends,这个static,就比较static的那个social graph的状态就是会去driven你的feet怎么显示,但是阿子就问你,比方阿子跟你当时发的那个request 当下的一些讯息所以跟你Social Group其实是比较远的,就是他并不是Anchor了,Social Group,就是我大概如果要很High的话是这样可是Groops就简单很多,Groops基本上他那个叫Mo那那个就比较早期发现 我记得应该是chronological就是reverse chronological的做法他比较没有缩行的Ranking,他是一个比较基于query吧,就是...怎么讲啊,query就是有一套系统有 API 类的叫 GraphQL 但是它本身的 return 的那个 order 是它的那个有一个 intrinsic order 那个就是怎么说啊 就是 GraphQL 是基于在 tau cache 类的上的东西 那 tau 每一笔资料其实有一个 time-send 股 所以那个 time-send 是它的 intrinsic order所以那个Response回来的时候如果你没有加条件的话一般就是那种Crincy Order 所以是在Application Layer 再去调整它那个就是显示的那个顺序 就是这好像是Groove的作品 他们没有太Fancy的东西这边的话,Facebook现在主要用的是TaoDB还是CassandraDB我
[65:00] G是在Cassandra上,Facebook大部分是在TOW上,TOW是一个cashwareTaus cash的底层是一个叫UDB的东西基本上就是至于基于MySQL吧 如果你要有strong consistency的话是基于UTV 但是如果你不需要双 consistency 例如你只要 read after write 这种 consistency 可能会有一些 KV ストア像是ZPTVZBTV是基于ROXTV的东西,ROXTV是基于LevelTV的一个改版东西所以那个...所以这个就是...怎么讲?就是跟IG完全不一样,开G是完全基于Cassandra,所以IG在Consistence上就会相对弱嗯OK, makes sense, makes sense.这块的话,这个TaoDB其实跟Uber的Schemeless有点像,但是它增加那个shard key,所以它你实际上是可以specify the partition key 的,然后其次的话TaoDB它不只是一个DB 它实际上也把它就是它这个Data Model和这个Philosophy写进去了它这个TAUTP是个Graph他认为这个他认为所有的Facebook的Fadescomments Facebook like 都是叫 Hintergenius Graph 或者是Hintergenius Graphs 翻译成中文就是hintergenius graph 说白了是 你这个node可以是一个user你这个graph里面弄的可以是个user 可以是个post然后可以是一个location所以你比如说假设我和林世耀去一个月前去Golden Gate Bridge 然后去hiking了是吧那我post 一个状态然后另一位同学景祥表示like这个post那其实这个就是个graph嘛,这里面的entity就是我和林赤耀,然后另一个entity是什么呢,Golden Gate Bridge然后另一个atelier是什么呢?就是这个post本身然后还有一个like呢like是一个relationship就是在那个graph里面一个edge然后这个 entity 是锦箱所以相当于是我和林是要作为两个 entity同时在这个Post中被就是related to post, and this post related to Golden Gate Bridge. And this post is related to the Golden Gate Bridge.景祥跟景祥的关系是被景祥like了所以是relationship是like所以它变成了一个intergenius graph嗯就是它这个里面Hintergenius Graph说的node可以是任何entity然后这个relationship可以是like 可以是post post然后可以是跟这个post相关也有可能是比如说这个location是吧,位于这个location,还有很多其他的可以有可能是ownership,这个relationship相对来说比较多元化一点,所以它这个TAUDB不只是sharded mySycle加一个Caching那样它Caching其实它那块写的也挺复杂的写的挺多的它是一个Multi Data CenterMarket Data Center replicated cachingMARTI data center replicated caching然后他同时也把这个Graph的Data Model的Philosophy写进去了它的Cache蛮复杂的Cache有好几层,它有1Region的Cache叫MemCache,有MultiRegion叫做MultiMasterTal,就是每个Region有一个Master,那FindTune就是看你Region要切得多细但是大部分装潢还是Single Master Tau 吗?Mori Master Tau 只有在那个就是你Performance 就是你有一些latency的concern其实就没有办法用一个很简单的设计来盖国外所有的状况,我相信应该是不同的状况他们用的Cashware都完全不一样一定会所以那个不太能够用几句话 盖瓜起来如果有这么多开始的话,有几个常见的问题是,你刚写的post,radial right assumption,其实是比较难guarantee的。所以一个是radial right assumption,其次的话,你可能会出现lost update,或者叫lineability可能会被violated。比如说你读的时候你朋友读的时候你刚post了一个post然后又delete掉了或者比如说你刚post了一个post然后你user A 读了以后,然后看到这个 post,然后user B 在读的时候却没有看到这个 post,这个其实是就是 violation of the linear ability 是吧 我刚刚就是上周四刚刚谈过 violation of linear ability其实这个是比较难 guarantee的可能需要 special 设计但是如果你没有设计好的话因为你有这么多层cacheRadiol Red的这个
[70:00] 这个 violation 可能也是有的就是你刚写完以后在读的时候读不到你的 right所以我觉得这个可能不同的没错我觉得他们是不同 product team 之后决定不同 take the style如果你只看 performance 的话大部分就是例如说选TACO,TACO就是一个Pure in memory的Cache,不是Persist然后anyway就是这个要跟每一个team谈过的知道他们女主要选什么才会知道他们所有就是Trader无常牺牲的哪些那些东西那这边的话是不是你作为一个user来说他所有读过的费子应该是要被记录一下了吧就是他user读过哪些费子是要被记录一下了吧嗯应该是有的肯定OK我以为对于read your rights这个东西其实有很多hanky的方法吧就比如说像facebook这种东西你你post上去之后你其实前端可以做一些tricky的东西也不一定毕竟全需要DB存储存的前端的话会有一个问题是你可能是multi-device的就是你比如说你手机post了一个然后用这个desktop pool了一下然后没读到的话也是影响user experience对,但那个是小case,大部分产品并不保证multi device,这是我的理解。很多产品组他们并不保证consistency of close device谢谢对,简单确实也可以做的,就是你读的时候,实际上你就不从DB读了,你读的时候就从Local读就行,从Mobile上读就行谢谢大家Mobile部分他们的optimization我相信绝对不concision,因为他们好像是in favor of pre-tatch所以其实你Mobile上看到很多data都是事先读好不是real time 所以通常是你在StartApp的时候就prefetch了很多东西 所以我觉得你的看到的绝对是比较delay的就是主要是在App Store还是好?我有几个问题还是挺有趣的就是你们来说就是Facebook里面来说读Ads的SLA和读Face的SLA一般是多少?这个我没有当他们很 close 所以我不知道我知道那个IG、Prada、SLA是三个九 没有很大就是availability是39,但是latency的SLA呢?Latency看不同的产品,如果是fee会特别太大谢谢Feed,我记得好像,我忘了它实际上速度好,但是它regression是很严格,我记得好像0.2,0.3个regression都是有问题的1.5%的requation就是Lacency regression基本上就过不去了所以他这个SLA是Lentons的SLA是非常严格的是吧但实际上他们现在的数字因为我们去他们主张 code 我有点忘了 但是我大概知道他们 latency 是费上比较可能剩 latencyOK OK OK 相对来说这个Lantins也肯定还是很影响的因为你毕竟是monetarized的这个你要读的一秒钟没刷出来可能就不看了所以很多Hacky的东西居然在Application上做,例如说Image的部分他们有那种就举个例好了,我知道现在还是这样,我以前看过的,他们有把image hash成一个day64,就是一小段Stream,然后那个在prefetch的时候就是就读下来,所以你就有一个很 blurry 的 image 就先 display 然后之后那个真正的 image 才是从 CDN 过了。就是为了优化这个 CDN 这个 Lentense 就是先读一个 BIS 64 的然后显示一个非常模糊的,然后再从 CDN 读到 image 来读。对,可是这应该也是好一阵,不知道我们现在有没有,再去改进这个事情。因为Facebook很多practice跟industry都不一样像Long的architecture我们就没来用可是我觉得...Labda architecture挺常见的其实它虽然是最早好像是Twitter的一个engineer推出的但是其实应用的地方挺常见的
[75:00] Uber有一个Lambda architecture是PigitPiget其实也是一个Lambda architecture大家可以看到的事其实是 算是提出的时候是for whatever reason,但是其实在工业界应用还挺挺常见的谢谢大家好,对啊,我觉得相对来说还是比较有趣的,就是你其实这个中间这个Facebook这个怎么样做这个费费、management,然后对他费费费然后像蜥蜥线管理的那个Cassandra nodes也有四五千 应该是最大的Cassandra nodes好Cluster好的我们还有五分钟啊,然后我这边说一下,我觉得就是李翔这个设计,我觉得没有问题的,就是中间有一些discussion也是没有问题的,然后然后我觉得表达的话可能上来的时候就说你要做一个hybrid model比较重要我觉得这样的话否则的话面试官可能一上来会有很多问题但你要上来说是个hybrid mode 的话我觉得可能面试官的问题就会少很多然后我们这块的话没有cover一些feature design就比如说是怎么样设置一下comments 怎么样设置一下like然后这些没有cover 但是这个的话其实大家我觉得最好的还是读一下那个Facebook的Paper 这Paper其实写得非常不错我觉得写的非常不错的对于问题理解也很深然后你读完这个Tot paper然后你可以在subsequently读下这个scheme list然后Uber Stimulus Designs,也有Engineering Blog的没有写配备有个 Uber-EngBlock, 这些是 这个然后你可以想一下为什么如果Uber的同学的话可以想一下为什么从Schemless到Docs到了这还是有原因的 从Schemless到Docs到还是有原因的并且你可以就一下Dogstar的这个设计好他怎么样做的那些implement这个其实好像你就直接search Facebook 讨论我也忘了哪个期刊上的就直接search 也可以然后这把设计我总体来说我觉得思路还是蛮清晰的有一些detail的事情就是可能要再写一些细节比如说你可以这块的话我觉得可以写一个对于一个Face来说一个Life cycle是怎么样的然后对于一个User来说你来自于不同的Face是什么样子的然后这块的话用FacebookFace的话你肯定还是要提个RankingRanking Facebook Facebook Ranking和Scout这个其实没有提到吧 这个其实明显是很重要的一部分因为你这个50个user每个pass 500个user每个人post 500个face 其实25000个face那我怎么样显示200个face 是吧 25000 怎么样白里挑一选到200个就让user addictive的这个adicted这个feeds其实是非常有研究的 然后可以优化很多的然后对 然后今天的话施耀也分享了一下这个就是现在Facebook用什么database啊,我觉得这还是挺有趣的,然后包括怎么样怎么样把这个Ads push到Relative User它不是push到每个User的这个Timeline 它是push到一个一个group user,把group user traits,然后从group user traits找到更matched的user,然后push过去好李翔你有什么额外想说的吗好我就想问这个,因为我之前跳槽的时候,那时候面的系统设计其实也挺简单的,因为当时在工作一年多。然后现在这个就是,因为这次Mock就相当于不是那么的完整,就是一般design的时候不都会涉及到data schema?怎么设计就比如说这里面有好几个storage,每一个storage要怎么设计这个一般是说我们给面试官说完了这个OEU的architecture,然后就开始进入底层的这些东西。对,schema是和database相关的,你必须根据,就是这边的话,首先我觉得流程最好的是这样子,就是你首先计算一下这个scalability,就是你QPS是多少,然后ray的write ratio有多少然后read QPS 多少write QPS 多少然后再根据你的需求选择一下这个database是吧你是read heavy 还是write heavy 然后这个选择一下database然后根据database的设计schema因为你DenemoDB或Cassandra的schema和MySQL的包括sharded SQL的都是完全不一样的如果你用Facebook淘的话,你partition key怎么设计是吧包括你用Presenter, PartitionKey怎么设计, PrimaryKey怎么设计,也是不一样的。所以这个Schema,DatabaseSchema肯定和Database是直接相关的嘛。然后所以这个甚至有时候可能设计完了以后发现之前的不对可能也要退到重来一遍也有可能就是你最后你最后所以一定要把那个requirement这个tradeoff写到最前面这个tradeoff写到最前面你比如说这个的话我们
[80:00] 看这个Facebook这个Face的设计其实这个Lentense也是更重要的availability 3.9其实很糟糕了 3.9一年可以到八个小时这个availability其实很糟糕但这个lentency要是多0.2%都是过不了的,Lentense其实是最重要的所以你必须把这个trade off写到前面然后再选architecture 设计architecture 选database然后再设计dataschema如果不work的话你退导重来一遍这个是很正常的但是算这些东西的话就直接就超过了15分钟我估计我个人建议算的时候快点这个算的其实相对来说说实话你是四个九还是五个九我并不care十的四字方也十的五字方我并不care因为这个horizontal scalable现在都是用horizontal scalable的你这个对于淘来说你加几个server或者减几个server就是你比如说四个酒变成五个酒你可能加十倍的server反正都无所谓的像Uber的Skinless也是一样的四个九五个九并不是很开玩意你可以自己把这些时间压缩到几分钟之内就表示你有keep this in mind,最主要的是最主要的三个方面是Architecture, Database和Data Model然后Database那块的话你很多时候是要根据你的Isolation Level consistency level 然后来选这个database所以这块的discussion可以很多也可以很深入的Data Schema的话Data model和Data schema的话 你必须在Database之后才能行因为不同database的schema是完全不一样的我觉得对然后并且这样的话一般来说你看你面试什么level了如果面试senior level的话任何问题都有可能问的Senior Level是任何问题都有可能问的好因为我觉得Comparsense的瓶颈期比较早到CNR就是个Terminal levelC年往上是不要求的所以到C年来我就supposedly能做任何independent做任何东西的,所以任何问题都有可能问。我去所以这个对可能这个System Design会更难一点好的谢谢大家我没什么问题了。好的,我们有什么其他东西有什么额外的问题吗?我可以回答一下。或者直接说就可以了谢谢大家优优独播剧场——YoYo Television Series Exclusive没有的话就到这好了我再等试验走没有的话就到这好了有个问题,你刚刚说的那个Bloom Filter,你打算是怎么做呀?就是这个Filter Service,你是要用什么DB还是想用别的?就怎么做这个东西? Bloom Filter 是 Memory 啊你就直接申请一个memory块,然后里面都是一个bit好那是不是这个就不太那么scalebloom filter是为了审内层啊你也可以用什么memb cache或redis来做甚至你可以用db来做但是就会慢嘛然后分键成那你那个就只能在单台机器上了对吧就是你就是在inmemory单台机器上搞你可以单台机器对Bloom Filter 可以非常Efficient,我记得好像那个群里面有一位在研究Database的同学发了一个PhD,发了一个Bloom Filter,我看了一下他说8GB的Memory,其实这个Bloom Filter的Duplication Rate就很低了可以算一下我觉得它有几个指标的一个是K一个是Value还有一个什么有个P值什么的,反正就是它有不同的但是从前来说你有8GB的memory,它这个duplication rate就很低了你可以读一下那一块,我觉得这个还是挺efficient的之前有人发过 还是挺efficient的你有什么问题吗 轻易我想问一下,就是那个,在那个,就是Stall,在各种用户的费用时,通常是按时间顺序去费用,但是在买的时候,它的排式有可能是按照一定的位置去费用这样的话其实这个start的时候就应该按ranking来startstart的时候就按ranking来start你读的时候就按ranking来读 你如果按时间start来ranking来读的话这个本身就不知很合理哦,我试,我试你知道的时候你没必要钱是最新的吗只不过最新的ranking会更高吗你比如说你的RankingScore里面可以可以你可以你的Ranking不一定是固定死的值啊你的这个Ranking可以加一个Timeindication 就是你ranking 比如说10小时前ranking是10的
[85:00] 和一小时前ranking时的你肯定会decade它吗你可能会有个 decay algorithm去 decay 它的 0r ranking 值所以是在他fan out的时候就已经把ranking算了?你的ranking只是说这块有很多优化的地方了,我直观猜想就是你ranking,比如说你10小时前ranking是10的,然后那你和一小时前ranking是实的那你肯定有个decaying就是decay一下之前的ranking是什么你用个指数型decay就可以了嘛对然后我发现这个Facebook要是我打开 第一次打开然后过5分钟再打开,然后前面的5个feet都是不一样的。我每次read完之后,它这个ranking都会upgrade。就是我可以多一会儿的对,然后它Ranking肯定和时间是相关的吧,你最后的RankingScore肯定和你读的时间相关吗?因为你ranking score 你不可能说每小时以后再把user的ranking score全部改一下然后把所有的userranking score降低个1什么的 这不可能的所以你ranking stock肯定是有时效性的然后你读的时候跟随你的时间把那Ranking Spot discount然后你读的时候你refresh的时候你肯定是说我把所有的就是没有读过的我现在对这个user来说我把所有的没有读过的费字然后再按ranking的从高到低然后显示一边我觉得这样比较make sense 一点。 哦,对对对,它可能是先filter and read。 然后这块有个同学问几年算senior,这个其实时间比较flexible,有十几年多的senior,也有三年的senior,两年的senior。我们组最年轻的一个senior2只有三年半的工作经验,本科毕业三年半的senior2了。但是他是美国本地人然后他其次的话从9岁就开始编成Local,然后九岁开始变成,所以他三年半就送到CDR2了。CDR的话,我觉得是从三年到十五年,甚至二十年都正常了。Depends on you want to take the responsibility你有时候有非常非常有野心的人,ambitious的人,可能三年就想面一个CNR之边,有的人他看着不一样,可能25年的话做CNR也挺好的好所以没有一个hard answer底盘知道你自己觉得能不能做这两个好 如果没有额外问题就到这里好了 今天非常感谢大家 然后下周还有一个Mock-Interior,下周Mock-Interior candidates比较强,他上来说自己想做Candidate还是可以做Interviewer都可以所以我们下周到时候看讨论什么题目他应该有很多interview我的experience所以我也不知道我能不能interview他或者说可能他出的想法比我更前面一点我还是比较期待的下周的这个interview非常感谢大家在这里为止谢谢大家