# 更简单,更便宜,更快:Playtomic 从.NET 迁移到 Node 和 Heroku
> 原文: [http://highscalability.com/blog/2012/10/15/simpler-cheaper-faster-playtomics-move-from-net-to-node-and.html](http://highscalability.com/blog/2012/10/15/simpler-cheaper-faster-playtomics-move-from-net-to-node-and.html)
![](https://img.kancloud.cn/3c/4c/3c4c9062757740e89247c2070d175cc1_200x50.png)
*这是 [Playtomic](https://playtomic.com/) 首席执行官 Ben Lowry 的特邀帖子。 Playtomic 是一项游戏分析服务,每天大约有 2 千万人在大约 8000 种移动,网络和可下载游戏中实施。*
*这是 [Ben Lowry 在 Hacker News](http://news.ycombinator.com/item?id=4458124) :*上的一个很好的摘要语录
> 昨天有超过 2 千万的人点击了我的 API 700,749,252 次,玩了我的分析平台集成的大约 8,000 款游戏,总播放时间不到 600 年。 就是昨天 有许多不同的瓶颈在等着人们大规模经营。 在我的用例中,Heroku 和 NodeJS 最终以非常便宜的价格缓解了很多。
Playtomic 始于几乎唯一的 Microsoft.NET 和 Windows 体系结构,该体系结构保持了 3 年,然后被 NodeJS 完全重写所取代。 在整个生命周期中,整个平台从单个服务器上的共享空间发展为完全专用,然后扩展到第二专用,然后将 API 服务器卸载到 VPS 提供程序和 4-6 个相当大的 VPS。 最终,API 服务器安装在 Hivelocity 的 8 台专用服务器上,每个服务器都具有超线程+ 8gb ram +运行 500 或 3 个 API 堆栈实例的双 500gb 磁盘的四核。
这些服务器通常为 30,000 至 60,000 个并发游戏玩家提供服务,每秒最多接收 1500 个请求,并通过 DNS 轮询实现负载平衡。
7 月,整个服务器群被 Heroku 托管的 NodeJS 重写所取代,以节省大量资金。
## 使用 NodeJS 扩展 Playtomic
迁移包括两个部分:
1. **专用于 PaaS** :优势包括价格,便利性,利用其负载平衡和降低总体复杂性。 缺点包括没有用于 NodeJS 的 New Relic,非常小的崩溃以及通常不成熟的平台。
2. **.NET 到 NodeJS** :将具有本地 MongoDB 实例和服务预处理事件数据的 ASP.NET/C#体系结构切换到本地,然后将其发送到集中式服务器以完成操作; 到 Heroku + Redis 上的 NodeJS 以及 SoftLayer 上的预处理(请参见 Catalyst 程序)。
## 专用于 PaaS
复杂性的降低是显着的; 我们在托管合作伙伴 Hivelocity 拥有 8 台专用服务器,每台服务器运行 3 或 4 个 API 实例。 每个人都运行一小套软件,其中包括:
* MongoDB 实例
* 日志预处理服务
* 监视服务
* 带有 api 网站的 IIS
部署是通过 FTP 脚本完成的,该脚本将新的 api 站点版本上载到所有服务器。 服务更讨厌部署,但很少更改。
MongoDB 对于在预处理和发送日志之前临时保存日志数据是一个糟糕的选择。 它提供了最初只写内存的巨大速度优势,这意味着写请求几乎立即就“完成”了,这远远优于 Windows 上的常见消息队列,但是它从未回收已删除数据留下的空间,这意味着 db 大小会膨胀到 如果不定期压缩,则超过 100 GB。
PaaS 提供商的优势是众所周知的,尽管它们似乎最成熟并且拥有广泛的技术支持,但对 Heroku 和 Salesforce 的信心最容易,尽管看上去最相似。
过渡到 PaaS 的主要挑战是,人们像在专用服务器上那样,可以与网站一起运行辅助软件的想法已经动摇。 大多数平台都提供了一些可以利用的后台工作线程,但这意味着您需要通过 3 rd 第三方服务或服务器来路由 Web 线程中的数据和任务。
我们最终选择在 Softlayer 上的大型服务器上运行了十二个特定目的的 Redis 实例和一些中间件,而不是后台工作程序。 Heroku 不对出站带宽收费,而 Softlayer 不对入站带宽收费,这巧妙地避免了所涉及的大量带宽。
## 从.NET 切换到 NodeJS
在服务器端使用 JavaScript 是一种混合体验。 一方面,缺乏形式和样板正在解放。 另一方面,没有 New Relic,也没有编译器错误,这使所有事情都变得比原本困难。
有两个主要优点,这使得 NodeJS 对于我们的 API 极为有用。
1. **后台工作程序**与 Web 服务器位于相同的线程和内存中
2. **与 Redis 和 mongodb 的持久共享连接**
### 后台工作者
NodeJS 具有非常有用的功能,可以独立于请求继续工作,允许您预取数据和其他操作,这些操作可以让您非常早地终止请求,然后完成对它的处理。
对于我们而言,将整个 MongoDB 集合复制到内存中(定期刷新)是特别有利的,这样,整个工作类都可以访问当前数据,而不必使用外部数据库或本地/共享缓存层 。
在以下条件下,我们每秒总共节省 100 至 1000 的数据库查询:
* 主 api 上的游戏配置数据
* 数据导出 api 上的 API 凭据
* GameVars,开发人员用来存储配置或其他数据以将其热加载到他们的游戏中
* 排行榜得分表(不包括得分)
基本模型是:
> var cache = {};
>
> module.exports = function(request,response){
> response.end(cache [“ x”]);
> }
>
> 函数 refresh(){
>
> //从数据库中获取更新的数据,存储在缓存对象
> 中。cache [“ x”] =“ foo”;
> setTimeout(refresh,30000);
> }
>
> refresh();
这样做的优点是,您可以与后端数据库建立单个连接(每个 dyno 或实例),而不是每个用户建立一个连接,并且具有非常快的本地内存缓存,该缓存始终具有新数据。
注意事项是您的数据集必须很小,并且此线程与其他所有线程都在同一线程上运行,因此您需要意识到阻塞线程或执行过多的 CPU 工作。
### 持久连接
NodeJS 通过.NET 为我们的 API 提供的另一个巨大好处是持久性数据库连接。 在.NET(等)中进行连接的传统方法是打开您的连接,进行操作,然后将您的连接返回到池中,以便在短期内不再使用或不再使用时可以重新使用。
这是很常见的,除非达到很高的并发性,否则它将正常工作。 并发率很高,因此连接池无法足够快地重用连接,这意味着它会生成新连接,数据库服务器必须扩展这些连接才能处理。
在 Playtomic,我们通常有数十万并发游戏玩家正在发送事件数据,这些事件数据需要被推回到不同数据中心中的 Redis 实例,而使用.NET 则需要大量 连接数量–这就是为什么我们在每台旧专用服务器上本地运行 MongoDB 的原因。
使用 NodeJS,每个 dyno /实例具有单个连接,该连接负责推送特定 dyno 接收的所有事件数据。 它位于请求模型之外,如下所示:
> var redisclient = redis.createClient(….);
>
> module.exports = function(request,response){
>
> var eventdata =“ etc”;
>
> redisclient.lpush(“ events”,eventdata);
>
> }
### 最终结果
**高负载:**
最后一刻的要求
* * *
_exceptions:75 (0.01%) _ 失败:5 (0.00%) 总计:537,151 (99.99%) data.custommetric.success:1,093 (0.20%) data.levelaveragemetric.success :2,466 (0.46%) data.views.success:105 (0.02%) events.regular .invalid_or_deleted_game#2:3,814 (0.71%) events.regular.success:527,837 (98.25%) gamevars.load.success:1,060 (0.20%) geoip.lookup.success:109 (0.02%) Leaderboards.list.success:457 (0.09%) Leaderboards.save.missing_name_or_source#201:3 (0.00%) 排行榜。保存。成功:30 (0.01%) 。
排行榜.saveandlist。成功:102 (0.02%) playerlevels.list.success:62 (0.01%) playerlevels.load.success:13 (0.00%)
* * *
此数据来自在每个实例的后台运行的一些负载监控,将计数器推送到 Redis,然后将其汇总并存储在 MongoDB 中,您可以在 [上查看它们的运行情况 https://api.playtomic.com/load.html](https://api.playtomic.com/load.html) 。
该数据中有几种不同的请求类别:
* **事件** 从 MongoDB 检查游戏配置,执行 GeoIP 查找(开源的非常快速的实现,网址为 https://github.com/benlowry/node-geoip-native) ,然后推送到 Redis
* **GameVars , 排行榜,玩家级别** 都从 MongoDB 中检查游戏配置,然后再检查相关的 MongoDB 数据库
* **数据** 查找被代理到 Windows 服务器,因为 NodeJS 对存储过程的支持不佳
The result is 100,000s of concurrent users causing spectactularly light Redis loads fo 500,000 – 700,000 lpush’s per minute (and being pulled out on the other end):
1 [|| 1.3%] Tasks: 83; 4 running
2 [||||||||||||||||||| 19.0%] Load average: 1.28 1.20 1.19
3 [|||||||||| 9.2%] Uptime: 12 days, 21:48:33
4 [|||||||||||| 11.8%]
5 [|||||||||| 9.9%]
6 [||||||||||||||||| 17.7%]
7 [||||||||||||||| 14.6%]
8 [||||||||||||||||||||| 21.6%]
9 [|||||||||||||||||| 18.2%]
10 [| 0.6%]
11 [ 0.0%]
12 [|||||||||| 9.8%]
13 [|||||||||| 9.3%]
14 [|||||| 4.6%]
15 [|||||||||||||||| 16.6%]
16 [||||||||| 8.0%]
Mem[||||||||||||||| 2009/24020MB]
Swp[ 0/1023MB]
PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
12518 redis 20 0 40048 7000 640 S 0.0 0.0 2:21.53 `- /usr/local/bin/redis-server /etc/redis/analytics.conf
12513 redis 20 0 72816 35776 736 S 3.0 0.1 4h06:40 `- /usr/local/bin/redis-server /etc/redis/log7.conf
12508 redis 20 0 72816 35776 736 S 2.0 0.1 4h07:31 `- /usr/local/bin/redis-server /etc/redis/log6.conf
12494 redis 20 0 72816 37824 736 S 1.0 0.2 4h06:08 `- /usr/local/bin/redis-server /etc/redis/log5.conf
12488 redis 20 0 72816 33728 736 S 2.0 0.1 4h09:36 `- /usr/local/bin/redis-server /etc/redis/log4.conf
12481 redis 20 0 72816 35776 736 S 2.0 0.1 4h02:17 `- /usr/local/bin/redis-server /etc/redis/log3.conf
12475 redis 20 0 72816 27588 736 S 2.0 0.1 4h03:07 `- /usr/local/bin/redis-server /etc/redis/log2.conf
12460 redis 20 0 72816 31680 736 S 2.0 0.1 4h10:23 `- /usr/local/bin/redis-server /etc/redis/log1.conf
12440 redis 20 0 72816 33236 736 S 3.0 0.1 4h09:57 `- /usr/local/bin/redis-server /etc/redis/log0.conf
12435 redis 20 0 40048 7044 684 S 0.0 0.0 2:21.71 `- /usr/local/bin/redis-server /etc/redis/redis-servicelog.conf
12429 redis 20 0 395M 115M 736 S 33.0 0.5 60h29:26 `- /usr/local/bin/redis-server /etc/redis/redis-pool.conf
12422 redis 20 0 40048 7096 728 S 0.0 0.0 26:17.38 `- /usr/local/bin/redis-server /etc/redis/redis-load.conf
12409 redis 20 0 40048 6912 560 S 0.0 0.0 2:21.50 `- /usr/local/bin/redis-server /etc/redis/redis-cache.conf
and very light MongoDB loads for 1800 – 2500 crud operations a minute:
insert query update delete getmore command flushes mapped vsize res faults locked % idx miss % qr|qw ar|aw netIn netOut conn time
2 9 5 2 0 8 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 0|0 3k 7k 116 01:11:12
1 1 5 2 0 6 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 0|0 2k 3k 116 01:11:13
0 3 6 2 0 8 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 3k 6k 114 01:11:14
0 5 5 2 0 12 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 0|0 3k 5k 113 01:11:15
1 9 7 2 0 12 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 0|0 4k 6k 112 01:11:16
1 10 6 2 0 15 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 1|0 4k 22k 111 01:11:17
1 5 6 2 0 11 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 3k 19k 111 01:11:18
1 5 5 2 0 14 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 0|0 3k 3k 111 01:11:19
1 2 6 2 0 8 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 3k 2k 111 01:11:20
1 7 5 2 0 9 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 0|0 3k 2k 111 01:11:21
insert query update delete getmore command flushes mapped vsize res faults locked % idx miss % qr|qw ar|aw netIn netOut conn time
2 9 8 2 0 8 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 4k 5k 111 01:11:22
3 8 7 2 0 9 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 4k 9k 110 01:11:23
2 6 6 2 0 10 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 3k 4k 110 01:11:24
2 8 6 2 0 21 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 4k 93k 112 01:11:25
1 10 7 2 3 16 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 4k 4m 112 01:11:26
3 15 7 2 3 24 0 6.67g 14.8g 1.23g 0 0.2 0 0|0 0|0 6k 1m 115 01:11:27
1 4 8 2 0 10 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 4k 2m 115 01:11:28
1 6 7 2 0 14 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 4k 3k 115 01:11:29
1 3 6 2 0 10 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 0|0 3k 103k 115 01:11:30
2 3 6 2 0 8 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 3k 12k 114 01:11:31
insert query update delete getmore command flushes mapped vsize res faults locked % idx miss % qr|qw ar|aw netIn netOut conn time
0 12 6 2 0 9 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 4k 31k 113 01:11:32
2 4 6 2 0 8 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 0|0 3k 9k 111 01:11:33
2 9 6 2 0 7 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 0|0 3k 21k 111 01:11:34
0 8 7 2 0 14 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 4k 9k 111 01:11:35
1 4 7 2 0 11 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 3k 5k 109 01:11:36
1 15 6 2 0 19 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 0|0 5k 11k 111 01:11:37
2 17 6 2 0 19 1 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 6k 189k 111 01:11:38
1 13 7 2 0 15 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 1|0 5k 42k 110 01:11:39
2 7 5 2 0 77 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 2|0 10k 14k 111 01:11:40
2 10 5 2 0 181 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 0|0 21k 14k 112 01:11:41
insert query update delete getmore command flushes mapped vsize res faults locked % idx miss % qr|qw ar|aw netIn netOut conn time
1 11 5 2 0 12 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 0|0 4k 13k 116 01:11:42
1 11 5 2 1 33 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 3|0 6k 2m 119 01:11:43
0 9 5 2 0 17 0 6.67g 14.8g 1.22g 0 0.1 0 0|0 1|0 5k 42k 121 01:11:44
1 8 7 2 0 25 0 6.67g 14.8g 1.22g 0 0.2 0 0|0 0|0 6k 24k 125 01:11:45
## 相关文章
* [新的 API 服务器:Heroku 和 NodeJS 与专用和.NET](https://playtomic.com/blog/post/86-the-new-api-server-heroku-an)
* [日志处理,从无到有,每天发生十亿个事件](https://playtomic.com/blog/post/68-log-processing-from-nothing)
* [每天在预算范围内实时处理超过 3 亿个事件](https://playtomic.com/blog/post/53-handling-over-300-million-ev)
* [回顾 2010 年-从每月 4000 万事件到每天 3 亿](https://playtomic.com/blog/post/46-looking-back-on-2010)
* [四种让玩家爱上您的游戏的方式](http://www.gamasutra.com/blogs/BenLowry/20111116/8914/Four_ways_to_keep_players_in_love_with_your_game.php)
* [已发布 InkTd Flash 游戏源代码](http://www.emanueleferonato.com/2012/04/19/inktd-flash-game-source-code-released/)
* [黑客新闻主题](http://news.ycombinator.com/item?id=4615799)的相关评论
* [Heroku 成功案例页面](http://success.heroku.com/playtomic)
* [关于黑客新闻](http://news.ycombinator.com/item?id=4655718)
Redis 和 MongoDB 嗯...。 好文章
这是一篇很棒的文章,感谢您的分享。
因此,您切换了三件事:体系结构,部署/操作模型和运行时。
多汁的标题指的是第三部分,它可能是更改的最不重要的部分,而成本最高的部分(因为它需要完全重写)。
不要误会我的意思-我爱我一些 node.js,并且我是 Heroku 的忠实拥护者,但是.NET impl 中指出的所有警告很容易(或不太容易,但比完全重写要容易得多) )可寻址。 因此,您*可以*通过优化现有代码库(而不是重写)并迁移到具有 AppHarbor,Azure 的易于部署的模型(或在 Heroku 上运行 Mono)来获得类似的结果。 而且您还会有 New Relic :)
很想听听您对完整重写的成本收益平衡的看法
写得好!,我们曾经做过类似的事情。 当我们的集合太大时,Node GC 将暂停很长一段时间,并最终会因 JS 内存不足错误(大约 2 Gig)而崩溃。 我们最终创建了一个 NodeJS C ++插件来存储 V8 堆之外的数据,这实际上使我们可以将驻留在内存中的缓存扩展到超过 10 个 Gig。
我对 Node.JS 不太了解,但是 devdazed 的评论提出了我无法解决的问题。 在哪个星球上,NodeJS 内置的 GC 比 JVM(或.NET)更好?
我猜不能与成功争辩-这对他们是有用的。 但是很难相信在 JVM 或.NET 环境中无法轻松实现同一目标,在这些环境中,您不会遇到与 GC 相关的陷阱。 或者至少您发现的那些是众所周知的。
这是一本不错的书,但是我没有得到一些要点:
1.后台工作者。 通过创建一个新线程,Asp.net 可以轻松地做到这一点。 唯一应注意的事情是不会在该线程中引发未处理的异常。
2.持久连接。 为什么不仅仅拥有一个静态的 MongoServer 实例(它是线程安全的类)呢? MongoCollection 类也是线程安全的。 所以我们甚至可以有一个静态的集合实例
究竟是什么使您用 Node.js 取代.NET? ASP.NET 完全支持异步。 通过从.NET 切换到节点,您还可以获得“沉重”(如 3-10 倍)的性能。 如果您的应用切换到 node.js 之后变得更快,那么您首先在.net 方面做错了什么。
您也可以随意处理数据库连接。 您可以使用[ThreadStatic]或其他某种机制使每个线程保持一个打开状态。
@Dmitry:
并不是说我是该领域的专家(也不认为 Node 是灵丹妙药),但也许我会说一些话来为您澄清一下:
1.我不会依赖 ASP.NET 来执行后台任务,因为该实现通常非常脆弱。 ASP.NET 根本不是为此目的而设计的,我想如果您想通过 ASP.NET 应用程序上下文中的线程 API 实现后台工作程序,则需要一个非常非常好的理由。 我宁愿选择 WCF 服务作为 Windows 服务托管,它更可靠。
2.的确如此,拥有静态的 MongoServer / MongoDatabase 实例将使您在应用程序域的整个生命周期中都具有持久的连接。 最后一部分很重要,因为 ASP.NET 应用程序可以出于多种原因(计划的应用程序池回收,web.config 或应用程序文件夹更改等)重新启动。 而且我认为 Node 在这方面更可靠。
但总的来说,我同意其他人的观点,即完全没有必要完全重写(以及移至 Node)(但我认为他们也知道自己在做什么)。
What on earth made you replace .NET with Node.js? ASP.NET supports asynchrony to the fullest. You also take a *heavy* (like 3-10x) perf hit by switching to node from .NET. If your app got faster after switching to node.js you did something wrong on the .net side in the first place.
You are also free to handle your DB connections however you want. You could have kept one open per thread for example with [ThreadStatic] or some other mechanism.
最近所有的 node.js 文章都有什么?
是的,node.js 速度很快,但是它缺少太多基本功能,因此当您重写所有模块时,“神奇”的速度优势将不复存在,而且整个代码库将成为一堆不断调用自身的回调 ,进行简单的更改需要您分析整个过程,就像穿针一样。
Node.js 令人头疼。
我们正在将 StatsD + Graphite 与我们的企业 Node 应用一起使用。 有了它,您可以轻松免费地免费获得 New Relic。
哇,这家伙真的很喜欢过度设计! 在 API 客户端中使用 boost(并迫使 android 用户使用自定义 SDK 进行编译,这对于使用 malkade skd 的用户而言更加痛苦)。
- 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 内容平台的经验教训