# 阿尔及利亚分布式搜索网络的体系结构
> 原文: [http://highscalability.com/blog/2015/3/9/the-architecture-of-algolias-distributed-search-network.html](http://highscalability.com/blog/2015/3/9/the-architecture-of-algolias-distributed-search-network.html)
![](https://img.kancloud.cn/0b/4d/0b4d37074532f3b377fa7fa66c5f7b3f_1600x681.png)
*[Julien Lemoine](https://www.linkedin.com/in/julienlemoine) 的共同发布者的 CTO [阿尔及利亚 ]](http://www.algolia.com/) ,开发人员友好的搜索即服务 API。*
Algolia 于 2012 年作为移动设备的离线搜索引擎 SDK 开始。 目前,我们还不知道在两年内我们将建立一个全球分布式搜索网络。
如今,阿尔戈利亚每月在全球 12 个地区提供超过 20 亿个用户生成的查询,我们的平均服务器响应时间为 6.7 毫秒,其中 90%的查询在不到 15 毫秒内得到答复。 我们的搜索不可用率低于 10 <sup>-6</sup> ,这表示每月少于 3 秒。
离线移动 SDK 面临的挑战是移动性质带来的技术限制。 这些挑战迫使我们在开发算法时会采取不同的思路,因为经典的服务器端方法无法正常工作。
从那时起,我们的产品有了很大的发展。 我们想分享我们在这些算法之上构建和扩展 REST API 的经验。
**我们将说明我们如何使用分布式共识来实现全球不同地区的数据的高可用性和同步,以及如何通过任意播 DNS** 将查询路由到最近的位置 。
# 数据大小误解
在设计架构之前,我们首先必须确定我们需要支持的主要用例。 在考虑我们的扩展需求时尤其如此。 我们必须知道我们的客户是否需要索引千兆字节,太字节或 PB 的数据。 架构会有所不同,具体取决于我们需要处理多少个用例。
当人们想到搜索时,大多数人会想到非常大的用例,例如 Google 的网页索引或 Facebook 的数万亿帖子索引。 如果停下来想一想每天看到的搜索框,则大多数搜索框都不会搜索大型数据集。 **Netflix 搜索约 10,000 种图书,亚马逊在美国的数据库包含约 200,000,000 种产品。 这两种情况下的数据都可以存储在单台机器** **中!** 我们并不是说拥有一台计算机是一个很好的设置,但是要记住所有数据都可以在一台计算机上存储是非常重要的,因为跨计算机同步是复杂性和性能损失的主要来源。
# 高可用性之路
构建 SaaS API 时,高可用性是一个大问题,因为消除所有单点故障(SPOF)极具挑战性。 我们花了数周的时间为我们的服务集体讨论理想的搜索架构,同时牢记我们的产品将面向面向用户的搜索。
## 主从与主从
通过将问题暂时限制为存储在单个计算机上的每个索引,我们将高可用性设置简化为托管在不同数据中心的多台计算机。 通过这种设置,我们想到的第一个解决方案是进行主从设置,其中一台主机接收所有索引操作,然后将它们复制到一个或多个从机。 使用这种方法,我们可以轻松地在所有计算机之间负载均衡搜索查询。
这种主从方法的问题在于我们的高可用性仅适用于搜索查询。 所有索引操作都需要转到主服务器。 对于服务公司来说,这种架构风险太大。 要做的只是使主服务器停机,这将发生,并且客户端将开始出现索引错误。
**我们必须实现主-主架构** **!** 启用主-主设置的关键要素是要在一组机器之间就单个结果达成一致。 我们需要在所有机器之间共享**知识,这些知识在所有情况下**都保持一致,即使机器之间存在网络分离。
## 引入分布式一致性
对于搜索引擎,引入此共享知识的最佳方法之一是**将写入操作视为必须按特定顺序应用的唯一操作流**。 当我们有多个操作恰好同时出现时,我们需要为其分配一个序列 ID。 然后,可以使用该 ID 来确保将序列完全相同地应用于所有副本。
为了分配序列 ID(每个作业后一个数字递增 1),我们需要在机器之间的下一个序列 ID 上具有共享的全局状态。 [ZooKeeper](http://zookeeper.apache.org/) 开源软件是针对集群中分布式知识的实际解决方案,我们最初开始按以下顺序使用 ZooKeeper:
1. 当机器收到作业时,它将使用临时名称将作业复制到所有副本。
2. 然后,该机器将获得分布式锁。
3. 读取 ZooKeeper 中的最后一个序列 ID,并发送命令以在所有机器上将临时文件复制为序列 ID + 1。 这等效于两阶段提交。
4. 如果我们从计算机(定额)中获得大多数肯定答案,则将序列 ID +1 保存在 Zookeeper 中。
5. 然后释放分布式锁。
6. 最后,将结果通知发送作业的客户端。 如果有大多数提交,这将是成功的。
不幸的是,此顺序不正确,因为如果获取锁的机器在步骤 3 和 4 之间崩溃或重新启动,我们可能会以作业在某些机器上提交的状态结束,这需要更复杂的顺序。
ZooKeeper 通过 TCP 连接作为外部服务打包非常困难,并且需要使用较大的超时(默认超时设置为 4 秒,表示两个滴答声,每个滴答声为 2 秒)。
因此,无论是硬件还是软件,每个失败事件都将在此超时时间内冻结整个系统。 这似乎是可以接受的,但在我们的案例中,我们想经常在生产中测试故障(例如 Netflix 的 Monkey 测试方法)。
## 木筏共识算法
大约在我们遇到这些问题的时候, [RAFT 共识算法](https://raftconsensus.github.io/) 已发布。 显然,该算法非常适合我们的用例。 RAFT 的状态机是我们的索引,日志是要执行的索引作业的列表。 我已经知道 PAXOS 协议,但是对它以及所有变体的理解不够深刻,不足以使我自己有信心实施它。 另一方面,RAFT 更清晰。 如果可以完美地满足我们的需求,即使当时没有稳定的开源实现,我也有足够的信心将其实现为我们架构的基础。
实现共识算法最困难的部分是确保系统中没有错误。 为了解决这个问题,我选择了一种猴子测试方法,即在重新启动之前使用睡眠方式随机杀死进程。 为了进一步测试,我模拟了通过防火墙的网络掉线和性能下降。 这种测试有助于我们发现许多错误。 一旦我们运行了几天,没有任何问题,我非常有信心实施正确。
## 在应用程序或文件系统级别复制吗?
我们选择将写操作分配给所有计算机并在本地执行,而不是在文件系统上复制最终结果。 我们做出此选择的原因有两个:
* 更快。 索引在所有计算机上并行完成,比复制可能很大的二进制文件要快
* 它与多个区域兼容。 如果我们在建立索引后复制文件,则需要一个将重写整个索引的过程。 这意味着我们可能要传输大量数据。 如果您需要将数据传输到世界各地(例如纽约到新加坡),则传输的数据量非常低。
每台机器将以正确的顺序接收所有写操作作业,并独立于其他机器尽快处理它们。 **这意味着确保所有机器处于相同状态,但不必同时处于同一状态** 。 这是因为更改可能不会在同一时间在所有计算机上提交。
## 一致性的妥协
在分布式计算中, [CAP 定理](http://en.wikipedia.org/wiki/CAP_theorem) 指出,分布式计算系统不可能同时提供以下三个功能:
* 一致性:所有节点同时看到相同的数据。
* 可用性:确保每个请求都收到有关成功还是失败的响应。
* 分区容限:尽管任意消息丢失或系统部分出现故障,系统仍可继续运行。
根据该定理,我们在一致性 上折衷了 **。 我们不保证所有节点都能在同一时间看到完全相同的数据,但是它们都将收到更新。 换句话说,在少数情况下,机器不同步。 实际上,这不是问题,因为当客户执行写操作时,我们将该作业应用于所有主机。** **在第一台机器和最后一台机器上的应用时间之间相距不到一秒钟,因此最终用户通常看不到它。 唯一可能的矛盾是上一次收到的更新是否已经应用,这与我们客户的用例兼容。**
# 通用体系结构
## 集群的定义
为了拥有高可用性基础结构,必须在机器之间拥有分布式共识,但是遗憾的是存在很大的缺陷。 **此共识需要机器** **之间进行多次往返,因此每秒可能达成共识的数量与不同机器**之间的延迟直接相关。 他们需要接近才能每秒获得大量共识。 为了能够支持多个区域而不牺牲可能的写入操作的数量,这意味着我们需要有多个集群,每个集群将包含三台充当完美副本的机器。
每个区域只有一个集群是达成共识所需的最低要求,但仍远非完美:
* 我们无法使所有客户都适合一台机器。
* 我们拥有的客户越多,每个唯一客户每秒可以执行的写操作数量就越少。 这是因为每秒的最大共识数是固定的。
为了解决此问题,我们决定在区域级别应用相同的概念: **每个区域将具有由三个计算机组成的几个群集** 。 一个集群可以容纳一个到几个客户,具体取决于他们拥有的数据大小。 这个概念与虚拟化在物理机上所做的事情很接近。 我们能够将几个客户放在一个集群上,但一个客户可以动态增长并更改其使用情况。 为此,我们需要开发和自动化以下过程:
* 如果群集中的数据太多或写入操作数量过多,则将其迁移到另一群集。
* 如果查询量太大,则将新计算机添加到群集。
* 如果数据量太大,则更改分片的数量或将一个客户分散在多个群集中。
如果我们拥有这些流程,则不会将客户永久分配给集群。 分配将根据其自身的使用以及集群的使用而变化。 这意味着我们需要一种将客户分配给集群的方法。
## 将客户分配给集群
管理此分配的标准方法是每个客户拥有一个唯一的 DNS 条目。 这类似于 Amazon Cloudfront 的工作方式。 每个客户都被分配一个格式为 customerID.cloudfront.net 的唯一 DNS 条目,然后可以根据该客户针对不同的计算机集。
我们选择了相同的方法。 **为每个客户分配一个唯一的应用程序 ID,该 ID 链接到格式为 APPID.algolia.io 的 DNS 记录**。 该 DNS 记录以特定群集为目标,该群集中的所有计算机都是 DNS 记录的一部分,因此可以通过 DNS 进行负载平衡。 我们还使用运行状况检查机制来检测计算机故障,并将其从 DNS 解析中删除。
即使 DNS 记录上的 TTL 值非常低(TTL 是允许客户端保留 DNS 答复的时间),运行状况检查机制仍不足以提供良好的 SLA。 问题在于主机可能会关闭,但用户仍将主机保留在缓存中。 用户将继续向其发送查询,直到缓存过期。 更糟糕的是,因为 TTL 并不是一门精确的科学。 在某些情况下,系统不遵守 TTL。 我们已经看到一些 DNS 服务器将一分钟 TTL 转换为 30 分钟 TTL 的 DNS 记录。
为了进一步提高高可用性并避免机器故障影响用户,我们为每个客户生成了另一组 DNS 记录,格式为 APPID-1.algolia.io,APPID-2.algolia.io 和 APPID- 3.algolia.io。 这些 DNS 记录的思想是允许我们的 API 客户端在达到 TCP 连接超时(通常设置为一秒)时重试其他记录。 我们的标准实现是对 DNS 记录列表进行混洗,并按顺序尝试它们。
与我们的 API 客户端中精心控制的重试和超时逻辑相结合,这被证明是比使用专门的负载平衡器更好,更便宜的解决方案。
后来,我们发现时髦的.IO TLD 并不是性能的理想选择。 与.NET 相比,.IO 的任意播网络中的 DNS 服务器更少,并且那里的服务器已经饱和。 这导致大量超时,从而减慢了名称解析的速度。 此后,我们通过切换到 algolia.net 域解决了这些性能问题,同时通过继续支持 algolia.io 来保持向后兼容性。
# 集群的可伸缩性如何?
我们选择使用多个集群使我们能够添加更多客户,而不会因为集群之间的隔离而对现有客户造成太大的风险。 但是我们仍然担心需要解决的一个集群的可伸缩性。
群集可伸缩性中的第一个限制因素是由于共识而导致的每秒写入操作数。 为了缓解这一因素,我们从共识的角度出发,在 API 中引入了批处理方法,该方法将一组写操作封装在一个操作中。 问题在于,某些客户仍然不分批地执行写操作,这可能会对群集的其他客户的索引速度产生负面影响。
为了减少对性能的影响,我们对体系结构进行了两项更改:
* 我们从共识的角度出发,通过在一个唯一的操作中自动聚合每个客户的所有写操作,从而在共识存在争议时添加了批处理策略。 在实践中,这意味着我们正在重新排列作业的顺序,但不影响操作的语义。 例如,如果有 1,000 个待达成共识的作业,而 990 个来自一个客户,则即使有其他客户的作业交错在一起,我们也会将 990 个写入操作合并为一个。
* 我们添加了一个共识调度程序,该调度程序控制每秒为每个应用程序 ID 输入共识的写入操作数。 这避免了一个客户能够使用共识的所有带宽。
在实施这些改进之前,**我们通过返回 429 HTTP 状态代码**尝试了限速策略。 很快就很明显,这对于我们的客户来说太痛苦了,以至于不得不等待这种响应并实施重试策略。 如今,我们最大的客户每天在三台计算机的单个群集上执行超过 10 亿次写操作,平均每秒执行 11,500 次操作,突发次数超过 15 万次。
第二个问题是找到最佳的硬件设置,并避免可能影响群集可伸缩性的任何潜在瓶颈(例如 CPU 或 I / O)。 从一开始,我们就选择使用自己的裸机服务器,以完全控制我们的服务性能并避免浪费任何资源。 选择正确的硬件被证明是一项艰巨的任务。
在 2012 年底,我们从一个小型设置开始,包括:Intel Xeon E3 1245v2、2 个 Intel RAID 320 系列,RAID 0 中的 120GB 和 32GB RAM。 该硬件价格合理,比云平台更强大,使我们能够在欧洲和美国东部启动该服务。
此设置使我们能够调整内核的 I / O 调度和虚拟内存,这对于我们利用所有可用的物理资源至关重要。 即使这样,我们很快发现我们的限制是 RAM 和 I / O 的数量。 我们使用了大约 10GB 的 RAM 来建立索引,而仅剩下 20GB 的 RAM 用于缓存用于执行搜索查询的文件。 我们的目标一直是在内存中存储客户索引,以便针对毫秒级的响应时间优化服务。 当前的硬件设置是为 20GB 的索引数据而设计的,该数据太小了。
首次设置后,我们尝试了具有单插槽和双插槽 CPU,128GB 和 256GB RAM 以及不同型号/大小的 SSD 的不同硬件机器。
我们终于找到了一台包含 Intel Xeon E5 1650v2、128GB RAM 和 2x400GB Intel S3700 SSD 的机器的最佳设置。 SSD 的型号对于耐用性非常重要。 在找到可以在生产中使用多年的正确型号之前,我们烧掉了许多 SSD。
最后,我们构建的最终体系结构使我们仅需一个条件即可在所有领域进行良好的扩展:我们需要随时拥有免费资源。 在 2015 年,要处理必须管理裸机服务器的痛苦似乎有些疯狂,但是我们在为客户提供的服务质量和价格方面所获得的收益是值得的。 我们能够提供一个完全打包的搜索引擎,该引擎可以复制到三个不同的位置(在内存索引中),并且在比 AWS 更高的位置上具有出色的性能!
# 操作复杂吗?
## 限制进程数
**每台机器仅包含三个进程** 。 第一个是 Nginx 服务器,其中所有查询解释代码均作为模块嵌入其中。 为了回答查询,我们在内存中映射了索引文件并直接在 nginx worker 中执行查询,而无需与其他进程或机器进行通信。 唯一的例外是,当客户数据不适合一台机器时,这种情况很少发生。
第二个过程是 Redis 键/值存储,我们使用它来检查速率和限制以及存储每个应用程序 ID 的实时日志和计数器。 这些计数器用于构建我们的实时信息中心,当您连接到帐户时可以查看。 这对于可视化您的最后一个 API 调用和调试很有用。
最后一个过程是构建器。 这是负责处理所有写入操作的过程。 当 nginx 进程接收到写操作时,它将操作转发给构建器以执行共识。 它还负责构建索引,并包含许多监视代码,用于检查我们的服务中的错误,例如崩溃,索引编制缓慢,索引编制错误等。根据问题的严重性,SMS 通过 Twilio 的 API 报告某些错误 而其他则直接报告给 PagerDuty。 每次在生产中检测到新问题且未报告时,我们确保将来添加一个新探针以监视此类错误。
## 易于部署
**此堆栈的简单性使部署变得容易** 。 在部署任何代码之前,我们应用一堆单元测试和非回归测试。 一旦所有这些测试通过,我们便逐渐部署到集群。
我们的部署永远不会影响生产,也不会对最终用户可见。 同时,我们还希望以协商一致的方式产生主机故障,以便检查一切是否按预期进行。 为了实现这两个目标,我们独立部署群集的每台计算机,并应用以下过程:
1. 获取新的 Nginx 和生成器二进制文件。
2. [正常重启 nginx](http://nginx.org/en/docs/control.html#upgrade) Web 服务器,并使用新的二进制文件重新启动 nginx,而不会丢失任何用户查询。
3. 杀死构建器并使用新的二进制文件将其启动。 这会触发每台计算机部署 RAFT 失败,从而使我们能够确保故障转移按预期进行。
操作系统的简单性是我们体系结构的重要目标。 我们既不希望也不相信部署应该受到体系结构的限制。
## 实现良好的全球覆盖范围
服务正在变得越来越全球化。 仅在全球一个地区提供搜索查询远非最佳。 例如,在美国东部地区托管搜索将在可用性方面有很大不同,具体取决于用户从何处进行搜索。 对于美国东部用户来说,延迟时间将从几毫秒到亚洲用户的数百毫秒,这还不包括饱和的海外光纤的带宽限制。
我们已经看到一些公司在搜索引擎之上使用 CDN 来解决这些问题。 最终,这给我们带来了比价值更大的问题,因为使缓存无效是一场噩梦,并且仅提高了很少一部分频繁执行的查询的速度。 我们很清楚,为了解决这个问题,我们需要将索引复制到不同的区域,并将它们加载到内存中,以便有效地回答用户查询。
我们需要的是在现有群集复制之上的 **区域间复制** 。 副本可以存储在一台机器上,因为该副本仅用于搜索查询。 所有写操作仍将转到客户的原始群集。
**每个客户都可以选择他们希望拥有的一组数据中心** 作为复制对象,因此特定区域中的复制计算机可以从多个群集中接收数据,并且一个群集可以 将数据发送到多个副本。
此架构的实现是基于我们基于共识的操作流建模的。 在达成共识之后,每个集群都将其自己的写操作流转换为每个副本的版本,以确保用无操作作业替换与此副本无关的作业。 然后,此操作流作为一批操作发送到所有副本,以避免尽可能多的延迟。 一次发送作业将导致重复的往返次数过多。
在群集上,写操作将保留在计算机上,直到所有复制对其进行确认为止。
DSN 的最后一部分是将最终用户直接重定向到最近的位置。 为此,我们以 APPID-dsn.algolia.net 的形式添加了另一个 DNS 记录,该记录负责解决最接近的数据中心的问题。 我们首先使用了 Amazon 的 Route53 DNS 服务,但很快达到了极限。
* 基于延迟的路由仅限于 AWS 区域,并且我们有印度,香港,加拿大和俄罗斯等 AWS 未覆盖的位置。
* 基于地理位置的路由非常糟糕。 您需要为每个国家/地区指定 DNS 解析度。 这是许多托管 DNS 提供商所采用的经典方法,但是对于我们而言,这将是一个噩梦,无法提供足够的相关性。 例如,我们在美国有几个数据中心。
经过大量基准测试和讨论,出于以下几个原因,我们决定使用 [NSOne](http://www.nsone.net) 。
* 对我们来说,他们的 Anycast 网络非常出色,并且比 AWS 更好的平衡。 例如,他们在印度和非洲拥有 POP。
* 他们的滤波器逻辑非常好。 对于每个客户,我们可以指定与其关联的机器(包括复制机器)列表,并使用地理位置过滤器按距离对它们进行排序。 这样我们就可以保持最好的状态。
* 它们支持 EDNS 客户端子网。 这对我们来说很重要,以便更具针对性。 我们使用最终用户的 IP 而不是其 DNS 服务器的 IP 进行解析。
在性能方面,我们已经能够在第二级达到全球范围内的全球同步。 您可以在 [Product Hunt 的搜索](http://www.producthunt.com/) (托管在美国东部,美国西部,印度,澳大利亚和欧洲)或 [Hacker News 上进行尝试。 搜索](https://hn.algolia.com/) (托管在美国东部,美国西部,印度和欧洲)。
## 结论
我们花费了大量时间来构建我们的分布式和可伸缩体系结构,并且遇到了许多不同的问题。 我希望本文能使您更好地了解我们如何解决这些问题,并提供有关如何设计自己的服务的有用指南。
我看到越来越多的服务目前正面临着与我们类似的问题,全世界的受众都拥有多区域的基础架构,但是却拥有一些全球一致的信息,例如登录名或内容。 为了获得出色的用户体验,如今必须拥有多区域基础架构。 例如,可以使用这种方法来分发在全球范围内一致的只读数据库副本!
如果您有任何问题或意见,我将很乐意回答。
[在 HackerNews 上](https://news.ycombinator.com/item?id=11185713)
FWIW,Raft 和 Paxos 之间的主要区别在于,如果在故障转移期间发生写操作,则 Raft 保证数据丢失。 Paxos 直接将写入与主选举过程联系在一起,以使写入不会丢失。 两者还可以在部分网络故障的情况下锁定到位; 根据具体实施情况,Raft 倾向于留在那里并接受数据一段时间。 因此,尽管 Raft 更简单/更轻松,但这是因为它使您能够以非常糟糕的方式破坏 Paxos 明智地处理的事情。
这篇文章将来会发表。 可能弄乱了一些提要阅读器。
您是否考虑过使用 Kafka 在集群中实现“状态机”复制?
我是作者,并回复评论:
以色列:RAFT 和 Paxos 的保证是相同的:当共识成功时,就可以保证没有数据丢失。 您能否详细说明为什么您认为并非如此?
凯恩:由于多个地区的部署,卡夫卡不是一个选择。 我们需要对复制的序列 ID 分配进行更底层的控制
您在搜索引擎中使用什么技术?
@Jeyendran 如简介中所述,这是我们自己的引擎,以低级 C ++开发,并作为模块嵌入在 nginx 中。 由于以下几个原因,我们不是基于像 lucene / sphinx 这样的开源引擎:
-我们处理关联性的方式非常不同,这意味着对现有引擎
进行了巨大的重构-在即时搜索中具有非常好的性能 用例(键入时进行搜索),我们具有不同的数据结构。 我将尝试写一篇博客文章来解释我们所有的算法/数据结构差异
可能是我读过的最好的文章!
我很高兴看到其他人考虑了“三个进程”机制,并在 nginx 和其他进程之间使用了 mmap 文件。 和强大的)集群技术。
谢谢您的出色工作。
您提到过,在使用 RAFT 协议的一致性上存在折衷。 根据我的理解,RAFT 并没有给出分区容限,因为每个状态机都需要互相交谈以复制状态。 因此,这是 CAP 定理的 CA 系统,在这里我们可以最终保持一致。
我喜欢你的文章。 感谢分享 :))
嗯,是的,Raft 和 Paxos 都提供了类似的一致性保证。 甚至还有自动的正确性证明:https://github.com/uwplse/verdi/pull/16
该帖子说他们使用 Raft 来协调故障转移,并且分别决定损害一致性,而不是他们使用 Raft 损害了的一致性*。 您可以维护有关某些事物(例如,当前哪个节点是主节点)的始终一致的信息,而不能维护其他事物(例如,您正在服务的索引的实际内容)。*
也许 Raft 不一致的想法来自对 https://aphyr.com/posts/316-jepsen-etcd-and-consul 的误解,(正确地)它说 Raft 的两个广泛使用的实现缺少了使 读取速度较慢,但有必要避免以下情况:1)您在分区的少数一方 2)先前的主机太 3)选出新的主机,并且有人在第一秒内向其中写入新数据,或者 因此,4)您在写完之后阅读。
两种系统最终都提供了没有异常的模式,这是由于 Raft 的实现不完整所致,而不是 Raft 本身的缺陷。
非常感谢您的帖子。 我学到了很多。
- LiveJournal 体系结构
- mixi.jp 体系结构
- 友谊建筑
- FeedBurner 体系结构
- GoogleTalk 架构
- ThemBid 架构
- 使用 Amazon 服务以 100 美元的价格构建无限可扩展的基础架构
- TypePad 建筑
- 维基媒体架构
- Joost 网络架构
- 亚马逊建筑
- Fotolog 扩展成功的秘诀
- 普恩斯的教训-早期
- 论文:Wikipedia 的站点内部,配置,代码示例和管理问题
- 扩大早期创业规模
- Feedblendr 架构-使用 EC2 进行扩展
- Slashdot Architecture-互联网的老人如何学会扩展
- Flickr 架构
- Tailrank 架构-了解如何在整个徽标范围内跟踪模因
- Ruby on Rails 如何在 550k 网页浏览中幸存
- Mailinator 架构
- Rackspace 现在如何使用 MapReduce 和 Hadoop 查询 TB 的数据
- Yandex 架构
- YouTube 架构
- Skype 计划 PostgreSQL 扩展到 10 亿用户
- 易趣建筑
- FaceStat 的祸根与智慧赢得了胜利
- Flickr 的联合会:每天进行数十亿次查询
- EVE 在线架构
- Notify.me 体系结构-同步性
- Google 架构
- 第二人生架构-网格
- MySpace 体系结构
- 扩展 Digg 和其他 Web 应用程序
- Digg 建筑
- 在 Amazon EC2 中部署大规模基础架构的六个经验教训
- Wolfram | Alpha 建筑
- 为什么 Facebook,Digg 和 Twitter 很难扩展?
- 全球范围扩展的 10 个 eBay 秘密
- BuddyPoke 如何使用 Google App Engine 在 Facebook 上扩展
- 《 FarmVille》如何扩展以每月收获 7500 万玩家
- Twitter 计划分析 1000 亿条推文
- MySpace 如何与 100 万个并发用户一起测试其实时站点
- FarmVille 如何扩展-后续
- Justin.tv 的实时视频广播架构
- 策略:缓存 404 在服务器时间上节省了洋葱 66%
- Poppen.de 建筑
- MocoSpace Architecture-一个月有 30 亿个移动页面浏览量
- Sify.com 体系结构-每秒 3900 个请求的门户
- 每月将 Reddit 打造为 2.7 亿页面浏览量时汲取的 7 个教训
- Playfish 的社交游戏架构-每月有 5000 万用户并且不断增长
- 扩展 BBC iPlayer 的 6 种策略
- Facebook 的新实时消息系统:HBase 每月可存储 135 亿条消息
- Pinboard.in Architecture-付费玩以保持系统小巧
- BankSimple 迷你架构-使用下一代工具链
- Riak 的 Bitcask-用于快速键/值数据的日志结构哈希表
- Mollom 体系结构-每秒以 100 个请求杀死超过 3.73 亿个垃圾邮件
- Wordnik-MongoDB 和 Scala 上每天有 1000 万个 API 请求
- Node.js 成为堆栈的一部分了吗? SimpleGeo 说是的。
- 堆栈溢出体系结构更新-现在每月有 9500 万页面浏览量
- Medialets 体系结构-击败艰巨的移动设备数据
- Facebook 的新实时分析系统:HBase 每天处理 200 亿个事件
- Microsoft Stack 是否杀死了 MySpace?
- Viddler Architecture-每天嵌入 700 万个和 1500 Req / Sec 高峰
- Facebook:用于扩展数十亿条消息的示例规范架构
- Evernote Architecture-每天有 900 万用户和 1.5 亿个请求
- TripAdvisor 的短
- TripAdvisor 架构-4,000 万访客,200M 动态页面浏览,30TB 数据
- ATMCash 利用虚拟化实现安全性-不变性和还原
- Google+是使用您也可以使用的工具构建的:闭包,Java Servlet,JavaScript,BigTable,Colossus,快速周转
- 新的文物建筑-每天收集 20 亿多个指标
- Peecho Architecture-鞋带上的可扩展性
- 标记式架构-扩展到 1 亿用户,1000 台服务器和 50 亿个页面视图
- 论文:Akamai 网络-70 个国家/地区的 61,000 台服务器,1,000 个网络
- 策略:在 S3 或 GitHub 上运行可扩展,可用且廉价的静态站点
- Pud 是反堆栈-Windows,CFML,Dropbox,Xeround,JungleDisk,ELB
- 用于扩展 Turntable.fm 和 Labmeeting 的数百万用户的 17 种技术
- StackExchange 体系结构更新-平稳运行,Amazon 4x 更昂贵
- DataSift 体系结构:每秒进行 120,000 条推文的实时数据挖掘
- Instagram 架构:1400 万用户,1 TB 的照片,数百个实例,数十种技术
- PlentyOfFish 更新-每月 60 亿次浏览量和 320 亿张图片
- Etsy Saga:从筒仓到开心到一个月的浏览量达到数十亿
- 数据范围项目-6PB 存储,500GBytes / sec 顺序 IO,20M IOPS,130TFlops
- 99designs 的设计-数以千万计的综合浏览量
- Tumblr Architecture-150 亿页面浏览量一个月,比 Twitter 更难扩展
- Berkeley DB 体系结构-NoSQL 很酷之前的 NoSQL
- Pixable Architecture-每天对 2000 万张照片进行爬网,分析和排名
- LinkedIn:使用 Databus 创建低延迟更改数据捕获系统
- 在 30 分钟内进行 7 年的 YouTube 可扩展性课程
- YouPorn-每天定位 2 亿次观看
- Instagram 架构更新:Instagram 有何新功能?
- 搜索技术剖析:blekko 的 NoSQL 数据库
- Pinterest 体系结构更新-1800 万访问者,增长 10 倍,拥有 12 名员工,410 TB 数据
- 搜索技术剖析:使用组合器爬行
- iDoneThis-从头开始扩展基于电子邮件的应用程序
- StubHub 体系结构:全球最大的票务市场背后的惊人复杂性
- FictionPress:在网络上发布 600 万本小说
- Cinchcast 体系结构-每天产生 1,500 小时的音频
- 棱柱架构-使用社交网络上的机器学习来弄清您应该在网络上阅读的内容
- 棱镜更新:基于文档和用户的机器学习
- Zoosk-实时通信背后的工程
- WordPress.com 使用 NGINX 服务 70,000 req / sec 和超过 15 Gbit / sec 的流量
- 史诗般的 TripAdvisor 更新:为什么不在云上运行? 盛大的实验
- UltraDNS 如何处理数十万个区域和数千万条记录
- 更简单,更便宜,更快:Playtomic 从.NET 迁移到 Node 和 Heroku
- Spanner-关于程序员使用 NoSQL 规模的 SQL 语义构建应用程序
- BigData 使用 Erlang,C 和 Lisp 对抗移动数据海啸
- 分析数十亿笔信用卡交易并在云中提供低延迟的见解
- MongoDB 和 GridFS 用于内部和内部数据中心数据复制
- 每天处理 1 亿个像素-少量竞争会导致大规模问题
- DuckDuckGo 体系结构-每天进行 100 万次深度搜索并不断增长
- SongPop 在 GAE 上可扩展至 100 万活跃用户,表明 PaaS 未通过
- Iron.io 从 Ruby 迁移到 Go:减少了 28 台服务器并避免了巨大的 Clusterf ** ks
- 可汗学院支票簿每月在 GAE 上扩展至 600 万用户
- 在破坏之前先检查自己-鳄梨的建筑演进的 5 个早期阶段
- 缩放 Pinterest-两年内每月从 0 到十亿的页面浏览量
- Facebook 的网络秘密
- 神话:埃里克·布鲁尔(Eric Brewer)谈银行为什么不是碱-可用性就是收入
- 一千万个并发连接的秘密-内核是问题,而不是解决方案
- GOV.UK-不是你父亲的书库
- 缩放邮箱-在 6 周内从 0 到 100 万用户,每天 1 亿条消息
- 在 Yelp 上利用云计算-每月访问量为 1.02 亿,评论量为 3900 万
- 每台服务器将 PHP 扩展到 30,000 个并发用户的 5 条 Rockin'Tips
- Twitter 的架构用于在 5 秒内处理 1.5 亿活跃用户,300K QPS,22 MB / S Firehose 以及发送推文
- Salesforce Architecture-他们每天如何处理 13 亿笔交易
- 扩大流量的设计决策
- ESPN 的架构规模-每秒以 100,000 Duh Nuh Nuhs 运行
- 如何制作无限可扩展的关系数据库管理系统(RDBMS)
- Bazaarvoice 的架构每月发展到 500M 唯一用户
- HipChat 如何使用 ElasticSearch 和 Redis 存储和索引数十亿条消息
- NYTimes 架构:无头,无主控,无单点故障
- 接下来的大型声音如何使用 Hadoop 数据版本控制系统跟踪万亿首歌曲的播放,喜欢和更多内容
- Google 如何备份 Internet 和数十亿字节的其他数据
- 从 HackerEarth 用 Apache 扩展 Python 和 Django 的 13 个简单技巧
- AOL.com 体系结构如何发展到 99.999%的可用性,每天 800 万的访问者和每秒 200,000 个请求
- Facebook 以 190 亿美元的价格收购了 WhatsApp 体系结构
- 使用 AWS,Scala,Akka,Play,MongoDB 和 Elasticsearch 构建社交音乐服务
- 大,小,热还是冷-条带,Tapad,Etsy 和 Square 的健壮数据管道示例
- WhatsApp 如何每秒吸引近 5 亿用户,11,000 内核和 7,000 万条消息
- Disqus 如何以每秒 165K 的消息和小于 0.2 秒的延迟进行实时处理
- 关于 Disqus 的更新:它仍然是实时的,但是 Go 摧毁了 Python
- 关于 Wayback 机器如何在银河系中存储比明星更多的页面的简短说明
- 在 PagerDuty 迁移到 EC2 中的 XtraDB 群集
- 扩展世界杯-Gambify 如何与 2 人组成的团队一起运行大型移动投注应用程序
- 一点点:建立一个可处理每月 60 亿次点击的分布式系统的经验教训
- StackOverflow 更新:一个月有 5.6 亿次网页浏览,25 台服务器,而这一切都与性能有关
- Tumblr:哈希处理每秒 23,000 个博客请求的方式
- 使用 HAProxy,PHP,Redis 和 MySQL 处理 10 亿个请求的简便方法来构建成长型启动架构
- MixRadio 体系结构-兼顾各种服务
- Twitter 如何使用 Redis 进行扩展-105TB RAM,39MM QPS,10,000 多个实例
- 正确处理事情:通过即时重放查看集中式系统与分散式系统
- Instagram 提高了其应用程序的性能。 这是如何做。
- Clay.io 如何使用 AWS,Docker,HAProxy 和 Lots 建立其 10 倍架构
- 英雄联盟如何将聊天扩大到 7000 万玩家-需要很多小兵。
- Wix 的 Nifty Architecture 技巧-大规模构建发布平台
- Aeron:我们真的需要另一个消息传递系统吗?
- 机器:惠普基于忆阻器的新型数据中心规模计算机-一切仍在变化
- AWS 的惊人规模及其对云的未来意味着什么
- Vinted 体系结构:每天部署数百次,以保持繁忙的门户稳定
- 将 Kim Kardashian 扩展到 1 亿个页面
- HappyPancake:建立简单可扩展基金会的回顾
- 阿尔及利亚分布式搜索网络的体系结构
- AppLovin:通过每天处理 300 亿个请求向全球移动消费者进行营销
- Swiftype 如何以及为何从 EC2 迁移到真实硬件
- 我们如何扩展 VividCortex 的后端系统
- Appknox 架构-从 AWS 切换到 Google Cloud
- 阿尔及利亚通往全球 API 的愤怒之路
- 阿尔及利亚通往全球 API 步骤的愤怒之路第 2 部分
- 为社交产品设计后端
- 阿尔及利亚通往全球 API 第 3 部分的愤怒之路
- Google 如何创造只有他们才能创造的惊人的数据中心网络
- Autodesk 如何在 Mesos 上实施可扩展事件
- 构建全球分布式,关键任务应用程序:Trenches 部分的经验教训 1
- 构建全球分布式,关键任务应用程序:Trenches 第 2 部分的经验教训
- 需要物联网吗? 这是美国一家主要公用事业公司从 550 万米以上收集电力数据的方式
- Uber 如何扩展其实时市场平台
- 优步变得非常规:使用司机电话作为备份数据中心
- 在不到五分钟的时间里,Facebook 如何告诉您的朋友您在灾难中很安全
- Zappos 的网站与 Amazon 集成后冻结了两年
- 为在现代时代构建可扩展的有状态服务提供依据
- 细分:使用 Docker,ECS 和 Terraform 重建基础架构
- 十年 IT 失败的五个教训
- Shopify 如何扩展以处理来自 Kanye West 和 Superbowl 的 Flash 销售
- 整个 Netflix 堆栈的 360 度视图
- Wistia 如何每小时处理数百万个请求并处理丰富的视频分析
- Google 和 eBay 关于构建微服务生态系统的深刻教训
- 无服务器启动-服务器崩溃!
- 在 Amazon AWS 上扩展至 1100 万以上用户的入门指南
- 为 David Guetta 建立无限可扩展的在线录制活动
- Tinder:最大的推荐引擎之一如何决定您接下来会看到谁?
- 如何使用微服务建立财产管理系统集成
- Egnyte 体系结构:构建和扩展多 PB 分布式系统的经验教训
- Zapier 如何自动化数十亿个工作流自动化任务的旅程
- Jeff Dean 在 Google 进行大规模深度学习
- 如今 Etsy 的架构是什么样的?
- 我们如何在 Mail.Ru Cloud 中实现视频播放器
- Twitter 如何每秒处理 3,000 张图像
- 每天可处理数百万个请求的图像优化技术
- Facebook 如何向 80 万同时观看者直播
- Google 如何针对行星级基础设施进行行星级工程设计?
- 为 Mail.Ru Group 的电子邮件服务实施反垃圾邮件的猫捉老鼠的故事,以及 Tarantool 与此相关的内容
- The Dollar Shave Club Architecture Unilever 以 10 亿美元的价格被收购
- Uber 如何使用 Mesos 和 Cassandra 跨多个数据中心每秒管理一百万个写入
- 从将 Uber 扩展到 2000 名工程师,1000 个服务和 8000 个 Git 存储库获得的经验教训
- QuickBooks 平台
- 美国大选期间城市飞艇如何扩展到 25 亿个通知
- Probot 的体系结构-我的 Slack 和 Messenger Bot 用于回答问题
- AdStage 从 Heroku 迁移到 AWS
- 为何将 Morningstar 迁移到云端:降低 97%的成本
- ButterCMS 体系结构:关键任务 API 每月可处理数百万个请求
- Netflix:按下 Play 会发生什么?
- ipdata 如何以每月 150 美元的价格为来自 10 个无限扩展的全球端点的 2500 万个 API 调用提供服务
- 每天为 1000 亿个事件赋予意义-Teads 的 Analytics(分析)管道
- Auth0 体系结构:在多个云提供商和地区中运行
- 从裸机到 Kubernetes
- Egnyte Architecture:构建和扩展多 PB 内容平台的经验教训
- 缩放原理
- TripleLift 如何建立 Adtech 数据管道每天处理数十亿个事件
- Tinder:最大的推荐引擎之一如何决定您接下来会看到谁?
- 如何使用微服务建立财产管理系统集成
- Egnyte 体系结构:构建和扩展多 PB 分布式系统的经验教训
- Zapier 如何自动化数十亿个工作流自动化任务的旅程
- Jeff Dean 在 Google 进行大规模深度学习
- 如今 Etsy 的架构是什么样的?
- 我们如何在 Mail.Ru Cloud 中实现视频播放器
- Twitter 如何每秒处理 3,000 张图像
- 每天可处理数百万个请求的图像优化技术
- Facebook 如何向 80 万同时观看者直播
- Google 如何针对行星级基础设施进行行星级工程设计?
- 为 Mail.Ru Group 的电子邮件服务实施反垃圾邮件的猫捉老鼠的故事,以及 Tarantool 与此相关的内容
- The Dollar Shave Club Architecture Unilever 以 10 亿美元的价格被收购
- Uber 如何使用 Mesos 和 Cassandra 跨多个数据中心每秒管理一百万个写入
- 从将 Uber 扩展到 2000 名工程师,1000 个服务和 8000 个 Git 存储库获得的经验教训
- QuickBooks 平台
- 美国大选期间城市飞艇如何扩展到 25 亿条通知
- Probot 的体系结构-我的 Slack 和 Messenger Bot 用于回答问题
- AdStage 从 Heroku 迁移到 AWS
- 为何将 Morningstar 迁移到云端:降低 97%的成本
- ButterCMS 体系结构:关键任务 API 每月可处理数百万个请求
- Netflix:按下 Play 会发生什么?
- ipdata 如何以每月 150 美元的价格为来自 10 个无限扩展的全球端点的 2500 万个 API 调用提供服务
- 每天为 1000 亿个事件赋予意义-Teads 的 Analytics(分析)管道
- Auth0 体系结构:在多个云提供商和地区中运行
- 从裸机到 Kubernetes
- Egnyte Architecture:构建和扩展多 PB 内容平台的经验教训