地址 suggestion_Google Auto-Suggestion服务的系统设计分析。

地址 suggestion

重点 (Top highlight)
重点 (Top highlight)

System design is one of the most important and feared aspects of software engineering. This opinion comes from my own learning experience in an associate architecture course. When I started my associate architecture course, I had a hard time understanding the idea of designing a system.

系统设计是软件工程中最重要和最令人担忧的方面之一。 这种观点来自我自己在助理架构课程中的学习经验。 当我开始助理架构课程时,我很难理解设计系统的想法。

One of the main reasons was that the terms used in software architecture books are pretty hard to understand at first, and there is no clear step by step guidelines. Everybody seems to have a different approach. And of course, there is a mental block also that these topics might be very hard to understand.

主要原因之一是,一开始很难理解软件体系结构书籍中使用的术语,并且没有明确的分步指南。 每个人似乎都有不同的方法。 当然,还有一个心理障碍是这些主题可能很难理解。

So I set out to design a system based on my experience of learning architecture courses. For the first one, we will try to design the Auto Suggestion service for a real-time search like Google.

因此,我根据学习建筑课程的经验着手设计一个系统。 对于第一个,我们将尝试为像Google这样的实时搜索设计自动建议服务。

is tiktok banned? banned is come after user type is tiktok. google search auto suggestion example
visuals on 视觉Unsplash Unsplash拍摄

Autosuggestion enables users to search for known and frequently searched words. As the user types in the Google search box, it tries to predict the query based on the characters that are entered and give a list of suggestions to complete the query. A lot of us wonder how this occurs in real-time. In this article, we will try to design an autosuggestion service!! (Not because Google needs it, but to help people understand how to design a system!).

自动提示使用户可以搜索已知和经常搜索的单词。 当用户在Google搜索框中输入内容时,它会尝试根据输入的字符来预测查询,并给出一系列建议以完成查询。 我们许多人想知道这种情况是如何实时发生的。 在本文中,我们将尝试设计一种自动建议服务!! (不是因为Google需要它,而是为了帮助人们了解如何设计系统!)。

系统定义 (Definition of the System)

We need to clarify the goal of the system. System design is such a vast topic, if we don’t narrow it down to a specific goal then it will become very difficult to design the system, especially for newbies. Sometimes constraints are good for the system. It helps to focus on the main feature you are trying to design.

我们需要澄清系统的目标。 系统设计是一个巨大的主题,如果我们不将其缩小到特定的目标,那么设计系统将变得非常困难,特别是对于新手。 有时,约束对系统有利。 它有助于集中精力于您要设计的主要功能。

So, we have users who can write a query or text in the search bar. That’s our input in the system. And we will give the top five suggestions based on user typed query and prediction of our system what the user may need. For simplicity, we are taking only English language words here. The suggestion should be sorted according to the frequency of previous search results.

因此,我们拥有可以在搜索栏中写查询或文本的用户。 这就是我们在系统中的输入。 我们将根据用户键入的查询和对我们系统的需求预测给出最重要的五个建议。 为简单起见,我们在这里仅使用英语单词。 该建议应根据先前搜索结果的频率进行排序。

系统要求: (The requirement of the system:)

Here we decide the features of the system. What are the requirements we need to focus on? We can divide these requirements into two parts:

在这里,我们决定系统的功能。 我们需要关注哪些要求? 我们可以将这些要求分为两部分:

  • Functional requirement:

    功能要求:

When a user types their search query, our service suggests the top five terms starting with whatever the user has typed. This is a requirement that the system has to deliver. It is the main goal of the system.

当用户键入他们的搜索查询时,我们的服务会从用户键入的内容开始,建议前五个词。 这是系统必须交付的要求。 这是系统的主要目标。

  • Non-Functional requirement:

    非功能需求:

Now for the more significant requirements that need to be analyzed. If we don’t fulfill this requirement, it will be harmful to the business plan of the project.

现在对于需要分析的更重要的要求。 如果我们不满足此要求,将对项目的业务计划有害。

The suggestion list should appear in real-time. Let’s say the suggestion should be seen by the user within 500 milliseconds (ms). So, when the user is typing a text, the suggestion list should take no longer than 500 ms to appear. If our suggestion list comes much later, say after 2 minutes, there is no point in using this system. The suggestion list must appear on the user screen in real-time. Otherwise, the auto-suggestion will not be helpful for the user. So, we might consider faster response time at the expense of accuracy if needed (accuracy is diminished because it is tough to accurately predict what the user wants).

建议列表应实时显示。 假设用户应该在500毫秒(ms)内看到建议。 因此,当用户键入文本时,建议列表的显示时间应不超过500毫秒。 如果我们的建议清单来得很晚,例如2分钟后,则说明没有必要使用此系统。 建议列表必须实时显示在用户屏幕上。 否则,自动建议将对用户没有帮助。 因此,如果需要的话,我们可能会考虑以更快的响应时间为代价而牺牲准确性(准确性降低了,因为很难准确预测用户的需求)。

Performance, modifiability, availability, scalability, reliability, etc. are some important quality requirements in system design. These ‘ilities’ are what we need to analyze for a system and determine if our system is designed properly.

性能,可修改性,可用性,可伸缩性,可靠性等是系统设计中的一些重要质量要求。 这些“缺陷”是我们需要对系统进行分析并确定系统设计是否适当的条件。

In this system, we need to be faster to respond to a query user typed. So, performance is the most important factor here. Normally, availability and scalability are important features for system design. Performance is by default important, nobody wants to build a system with worse performance, right?!

在这个系统中,我们需要更快地响应用户键入的查询。 因此,性能是这里最重要的因素。 通常,可用性和可伸缩性是系统设计的重要功能。 默认情况下,性能很重要,没有人愿意构建性能较差的系统,对吗?

数据流: (Data flow:)

Always start with the data storing system. It will be a good starting point for the design. If you are not sure where to start, always start with the data. It will help to keep your focus on track with the goal of the system. How the data needs to be stored, how data will flow in the system etc.

始终从数据存储系统开始。 这将是设计的良好起点。 如果不确定从哪里开始,请始终从数据开始。 这将有助于您集中精力跟踪系统的目标。 数据如何存储,数据如何在系统中流动等。

Here, our input data is only text. So, we need to store them as a string. But it’s tough to search data from string and complexity will be more. If a user searches with “is TikTok” we will need to get the next strings that might be searched by the user. So, user input is prefix here and our output will be the suffix.

在这里,我们的输入数据仅为文本。 因此,我们需要将它们存储为字符串。 但是很难从字符串中搜索数据,而且复杂度会更高。 如果用户使用“是TikTok”进行搜索,我们将需要获取该用户可能搜索到的下一个字符串。 因此,用户输入在此处为前缀,而我们的输出将为后缀。

数据如何构造? (How does the data need to be structured?)

We need to store a lot of strings that users can search for using any prefix. Our system will provide the next word that will match the prefix. For example, our database contains the following words: “to”, “tour”, “tolerate”, and “toast”.

我们需要存储许多字符串,用户可以使用任何前缀搜索这些字符串。 我们的系统将提供与前缀匹配的下一个单词。 例如,我们的数据库包含以下单词:“ to”,“ tour”,“ tolerable”和“ toast”。

We cannot use a database for this, however, we can use the TRIE data structure that can efficiently store data and queried quickly. Normally search queries are not case sensitive. It has the complexity of O(L) time, L is the length of the query/text. Space is also optimized here.

我们不能为此使用数据库,但是,我们可以使用TRIE数据结构,该结构可以有效地存储数据并快速进行查询。 通常,搜索查询不区分大小写。 它具有O(L)时间的复杂度,L是查询/文本的长度。 这里的空间也得到了优化。

TRIE data structure
Figure: TRIE example
图:TRIE示例

热门建议: (Top Suggestion:)

We can find all the terms for a given query. But we need to find the top five suggested list for any written prefix term. So we will need to find ways to get top suggestion lists using TRIE.

我们可以找到给定查询的所有术语。 但是我们需要找到任何书面前缀术语的前五名建议列表。 因此,我们将需要找到使用TRIE获得最高建议列表的方法。

根据频率对单词进行排名 (Rank words based on the frequency)

We can count the search frequency that terminated at each node. If users searched about the word “Doll” 10 times and “Dog” 50 times, we can store the number with the last character of the word. Now if the user types “Do” we know the top most searched word under the prefix “Do” is “Dog”. So, find the top suggestion for a given prefix, we can traverse the subtree under it.

我们可以计算在每个节点处终止的搜索频率。 如果用户搜索“ Doll”一词10次,“ Dog”一词50次,我们可以将数字与该词的最后一个字符一起存储。 现在,如果用户键入“ Do”,我们知道前缀“ Do”下搜索次数最多的单词是“ Dog”。 因此,找到给定前缀的最佳建议,我们可以遍历其下的子树。

TRIE data structure use for system design
Figure: TRIE with the total frequency count
图:TRIE与总频率计数

问题: (Problem:)

How much time will it take to traverse its subtree? Given the huge amount of data we need to index, we should expect a huge tree. Even traversing a subtree would take a long time. For example “system design analysis” is 19 levels of deep traversal. But we have a latency requirement. So, we need to improve the efficiency of the solution. Latency is the response time between user action and server response.

遍历其子树需要多少时间? 鉴于我们需要建立索引的大量数据,我们应该期待一棵巨大的树。 即使遍历子树也需要很长时间。 例如,“系统设计分析”是19个深度遍历。 但是我们有一个延迟要求。 因此,我们需要提高解决方案的效率 延迟是用户操作与服务器响应之间的响应时间。

预计算列表 (Precompute the list)

We may try to store the top suggestions with each node as this can speed up the searches. Doing this, we can store the top 5 suggestions at each node which we can then return to the user. We have to increase the storage capacity to get efficiency which will speed up the response time of the search.

我们可能会尝试将热门建议与每个节点存储在一起,因为这可以加快搜索速度。 这样做,我们可以将前5个建议存储在每个节点上,然后返回给用户。 我们必须增加存储容量以获得效率,这将加快搜索的响应时间。

But we will need a lot of extra storage. The memory vs performance tradeoff needs to be analyzed here. As real-time suggestion is our main goal, we may still go with this tactic. Memory nowadays seems to not matter that much.

但是我们将需要大量额外的存储空间。 内存与性能之间的权衡需要在这里进行分析。 由于实时建议是我们的主要目标,因此我们仍然可以采用这种策略。 如今的记忆似乎并不重要。

Image for post
Figure: TRIE list sorted list in each node
图:TRIE列表在每个节点中的排序列表

永久存储: (Persistent Storage:)

We need to save the TRIE in a database. We can not generate it every time as we can do in contest programming. Though we can index all the data in one server we can still use partitioning to improve efficiency and lower the response time.

我们需要将TRIE保存在数据库中。 我们不能像比赛编程那样每次都生成它。 尽管我们可以在一台服务器中索引所有数据,但仍然可以使用分区来提高效率并降低响应时间。

我们如何更新TRIE (How do we update TRIE)

Let’s say, we have 1 billion search queries every day, which would give us approximately 12K queries per second. We will need multiple servers to handle such a huge amount of requests. If we update our TRIE for every user search, it will hamper the read requests. We can use one of these following tactics:

假设我们每天有10亿个搜索查询,这将使我们每秒大约有12,000个查询。 我们将需要多个服务器来处理如此大量的请求。 如果我们为每个用户搜索更新我们的TRIE,它将阻碍读取请求。 我们可以使用以下策略之一:

i) We can update after a time interval. We can track the frequency of a word and after a word is searched more than 1000 times, we will update the word in TRIE. This way we will get only the top sorted list and TRIE need not be updated every second. We might not always get the proper data in this case. If one word is searched 999 times, it still would not be updated in TRIE.

一世) 我们可以在一段时间后进行更新。 我们可以跟踪单词的出现频率,并且在搜索单词超过1000次之后,我们将在TRIE中更新单词。 这样,我们将只获得排序最高的列表,而TRIE不需要每秒更新。 在这种情况下,我们可能不会总是获得正确的数据。 如果搜索一个单词999次,则在TRIE中仍然不会更新。

ii) We can make a copy of the TRIE on each server to update it offline. Once done, we can switch to start using it and discard the old one. Synchronization will be an issue here.

ii)我们可以在每台服务器上制作一份TRIE副本以离线更新它。 完成后,我们可以切换到开始使用它并丢弃旧的。 同步将成为一个问题。

master slave architecture
Figure: Master-slave configuration
图:主从配置

iii) Another option is to have a master-slave configuration for each TRIE server. We can update the slave while the master is serving the traffic. Once the update is completed, we can sync the master with the slave.

iii)另一个选择是为每个TRIE服务器具有主从配置。 我们可以在主服务器为流量服务时更新从服务器。 更新完成后,我们可以将主机与从机同步。

从TRIE删除单词 (Remove a word from TRIE)

Now if a term is not popular in recent days how can we remove it from TRIE? We can add a filter on the server which will remove any term before sending the output to the user. But modifiability would be affected. We need to configure the server-side with a separate module for it.

现在,如果一个词在最近几天不受欢迎,我们如何将其从TRIE中删除? 我们可以在服务器上添加一个过滤器,该过滤器会在将输出发送给用户之前删除所有术语。 但是可修改性会受到影响。 我们需要为服务器端配置一个单独的模块。

限制字长 (Limit word length)

We don’t need to give a suggestion for the whole query. Let’s say that the average user query contains 25 characters with five characters strung together (so five words). After that, if our suggestion is not working, then the user might have a need which is new or they don’t care about the suggestion. So, we can limit the word length for the suggestion.

我们不需要为整个查询提供建议。 假设平均用户查询包含25个字符,其中五个字符串在一起(所以五个单词)。 此后,如果我们的建议不起作用,则用户可能有新需求或他们不在乎该建议。 因此,我们可以限制建议的单词长度。

快取: (Cache:)

We can use caching for top searched terms in the cache. This will be very helpful to lower the latency. Caching is a common technique for performance. The server should check the cache server before hitting database servers to see if the search list is already in the cache. In this case, the suggested list should be ready in the cache. So, list preparation time is omitted, response time is decreased. We can have cache in the servers in front of database servers containing the most frequently searched terms and their suggestions. And update them with LRU caching technique. As recent search results have a higher chance of being searched.

我们可以将缓存用于缓存中搜索次数最多的字词。 这对降低延迟非常有帮助。 缓存是提高性能的常用技术 在访问数据库服务器之前,服务器应检查高速缓存服务器,以查看搜索列表是否已在高速缓存中。 在这种情况下,建议的列表应已在缓存中准备好。 因此,省略了列表准备时间,减少了响应时间。 我们可以在数据库服务器前面的服务器中缓存,其中包含最常搜索的术语及其建议。 并使用LRU缓存技术更新它们。 由于最近的搜索结果被搜索的可能性更高。

可扩展性: (Scalability:)

We are considering 1 billion searches per day which is a huge number. So, we need to provide the result for 12K queries every second. We can partition data to distribute the read request on servers. Not only computation power but also data also needs to be partitioned.

我们正在考虑每天进行10亿次搜索,这是一个巨大的数字。 因此,我们需要每秒提供12K查询的结果。 我们可以对数据进行分区,以在服务器上分发读取请求。 不仅需要计算能力,还需要对数据进行分区。

数据库分区 (Database Partitioning)

i) We can partition the database based on the first letter of a word. We can put words starting with ‘A’ in one server, ‘B’ in another server. The problem with this approach is that it can lead to unbalanced partitioning. For example, there are very few words starting with ‘Z’.

一世) 我们可以根据单词的第一个字母对数据库进行分区 。 我们可以在一个服务器中以“ A”开头的单词,在另一台服务器中以“ B”开头的单词。 这种方法的问题在于,它可能导致分区不平衡。 例如,很少有以“ Z”开头的单词。

ii) We can also partition based on the hash of the words. The hash function will generate a server number and we will store the word in that server. This can make the distribution random. But the problem is that we might need to ask all the servers to find a suggested list and merge them together to get the result. So, response time latency might be increased.

ii) 我们也可以 根据单词的散列进行分区 。 哈希函数将生成一个服务器号,我们将单词存储在该服务器中。 这可以使分布随机。 但是问题在于,我们可能需要让所有服务器查找建议列表,然后将它们合并在一起以得到结果。 因此,响应时间延迟可能会增加。

So, we can go with the first approach. Those characters with fewer terms, we can merge them in one server.

因此,我们可以采用第一种方法。 这些带有较少术语的字符,我们可以将它们合并到一台服务器中。

可用性和可靠性: (Availability and Reliability:)

We need to have replicas of database servers for fault tolerance. We will need to have a load balancer to balance out the queries to different servers. In case one server goes down, we can have a master-slave architecture data replication.

为了容错,我们需要数据库服务器的副本。 我们将需要一个负载平衡器来平衡对不同服务器的查询。 万一一台服务器出现故障,我们可以进行主从架构数据复制。

复写 (Replication)

As our system is read-heavy, we can have replication using master/slave architecture. Here master/primary server will take all writes and other (slave) servers will take read operations. Master-Slave Replication for Data will remove a single point of failure and provide backup. We can keep multiple read replication to ensure TRIE server reliability.

由于我们的系统是重载的,因此可以使用主/从体系结构进行复制。 主/主服务器将执行所有写操作,而其他(从属)服务器将执行读操作。 数据主从复制将消除单点故障并提供备份。 我们可以保留多个读取复制,以确保TRIE服务器的可靠性。

If the master TRIE data server is down, one of the slaves can take over after failover. For any server that comes back, we can rebuild the trie based on the last snapshot.

如果主TRIE数据服务器已关闭,则其中一个从属可以在故障转移后接管。 对于返回的任何服务器,我们都可以根据上一个快照重建特里。

There might be some problems with consistency. We can use the synchronous replication strategy for data replication.

一致性可能存在一些问题。 我们可以使用同步复制策略进行数据复制。

Now another important aspect we need to think is that the server which will handle the requests also needs to be replicated. Because if there exist only one server handling requests and that is down, we will not have the service availability. We can use a load balancer to distribute the request numbers uniformly to various servers.

现在,我们需要考虑的另一个重要方面是,处理请求的服务器也需要复制。 因为如果只有一台服务器处理请求并且该服务器已关闭,我们将无法获得服务可用性。 我们可以使用负载平衡器将请求号均匀地分配到各种服务器。

google search auto suggestion architecture
Figure: AutoSuggeestion System
图:自动建议系统

Redundant application servers and database has a cost. But we need to have redundancy to remove a single point of failure. For improving our ranking we may also consider personal search history and user location in addition to frequency counting. The server should push some parts of the cache to CDNs for efficiency.

冗余应用程序服务器和数据库需要一定的成本。 但是我们需要有冗余以消除单点故障。 为了提高我们的排名,除了频率计数外,我们还可以考虑个人搜索历史和用户位置。 服务器应将缓存的某些部分推送到CDN,以提高效率。

客户端注意事项: (Client-side Considerations:)

The client application should request the server if the user does not press the key for 50ms. If the user is typing and the client is sending requests it will tough for a server to handle so many requests in such a small amount of time.

如果用户在50ms内没有按键,则客户端应用程序应请求服务器。 如果用户正在键入并且客户端正在发送请求,则服务器将很难在这么短的时间内处理如此多的请求。

Client-side should wait until the user types a couple of characters. The client can prefetch some popular search queries for the client for future requests. And also use user recent history for search as there is a high chance that the user is searching for something he is already working on.

客户端应等到用户键入几个字符。 客户端可以为客户端预取一些流行的搜索查询,以供将来使用。 并且还将用户最近的历史记录用于搜索,因为用户很有可能正在搜索他已经在处理的内容。

结论: (Conclusion:)

In this design, we considered only the English language for simplification. Autosuggestion is a realtime service. So, performance is more important than any other quality-requirements of the system. For ensuring the availability of services we used replication of servers so that if one goes down, others can still give service. Databases are also replicated to ensure data reliability. Client-side may store some popular queries to speed up the search.

在此设计中,为了简化起见,我们仅考虑英语。 自动提示是一项实时服务。 因此,性能比系统的其他任何质量要求都更为重要。 为了确保服务的可用性,我们使用服务器复制,以便在其中一台出现故障时,其他服务器仍然可以提供服务。 数据库也被复制以确保数据可靠性。 客户端可能会存储一些受欢迎的查询以加快搜索速度。

For newbies, please remember, “If you are not sure where to start in the system design, always start with the data flow.

对于新手,请记住,“ 如果不确定在系统设计中从哪里开始,请始终从数据流开始。

This article is inspired by Grokking the System Design course. Looking forward to comments and suggestions on improvement of this article! Thank you for reading the article. Have a good day 🙂

本文受Grokking系统设计课程的启发。 期待对本文的改进提出意见和建议! 感谢您阅读这篇文章。 有一个美好的一天 🙂

翻译自: https://codeburst.io/system-design-analysis-for-auto-suggestion-service-d28bf1701658

地址 suggestion

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值