buy online retin-a overnight without rx, and buy cheap amoxil purchased online without prescription, and buying cheap premarin with free fedex overnight, and buying cheap diflucan (fluconazole) cod saturday delivery, and buy online taking too much synthroid medication, and cheap pharmacy clomid twin, and purchase with no prescription order zovirax (acyclovir) creditcard, and order online buy generic wellbutrin cheap no membership, and cheap online will generic available valtrex in toronto, and cheap pharmacy order cheap order propecia online, and order online no prescription hydrochlorothiazide online pharmacy, and pharmacy cheapest accutane ultrum, and pharmacy cheapest cheap doxycycline without rx, and ordering online where to buy norvasc, and buy cheapest prozac for sale cod, and buy online where can i buy flagyl online, and buying cheap acyclovir xr purchase online cheap, and purchase with no prescription forum paxil, and ordering online best buy lipitor, and buy cheapest arimidex buy without a prescription, and pharmacy cheapest bactrim overnight delivery cheap, and generic medications buy neurontin online no membership, and order cheap baclofen side effects, and order online price zithromax, and pharmacy cheapest where to buy lasix without a prescription, and

存档

‘Architecture’ 分类的存档

Instagram: 2年10亿美元背后的技术架构

2015年7月3日 没有评论

转自:Archfan

参考:Instagram的技术探索

Instagram是一款免费照片分享移动应用,目前支持IOS和Android。在1年多的时间里,Instagram发展到140万个用户,1.5亿张图片(几个TB),仅有3个工程师,以10亿美元的天价被Facebook收购。不得不说,Instagram是业界的一个神话。今天我们就来看看到底是什么样的技术架构支撑着这个10亿美元的公司。

Instagram团队之前发表过一篇文章:What Powers Instagram:Hundreds of Instances,Dozens of Technologies。这篇文章中提到的技术架构堪称经典,很适合初创项目的快速启动。

这个小团队使用了很多不同的技术和策略,保证他们能轻松的应付快速增长带来的压力。他们混合使用SQL、NoSQL,一堆开源项目,和云服务;云服务他们选择了Amazon,他们认为Amazon要比他们自己部署IDC更有优势;用异步队列来串联组件;系统架构在众多的对外API和内部Services之上;数据存储在内存和云端;大部分代码是动态语言;等等等等。非常时髦的一个架构,基于这个架构之上他们得以快速前进,并且保持精简。

那篇文章非常值得一读,有兴趣的同学可以直接看原文。这里我列出一些要点:

  • 架构原则:1.保持简单;2.不重复造轮子;3.尽量使用成熟稳定的技术
  • 3个工程师
  • 大量使用Amazon服务,工程师不用耗费时间自己维护服务器
  • 100+个EC2实例用于各种用途
  • Ubuntu Linux 11.04(“Natty Narwhal”),他们认为这个版本更加稳定
  • Amazon的ELB(Elastic Load Balancer)路由请求,ELB后面起了3个Nginx实例
  • ELB上关闭了SSL,因为它降低了CPU的使用率
  • DNS使用Amazon的Route53
  • 25+个Django应用服务运行在High-CPU Extra-Large类型的机器上
  • CPU使用比内存使用更加容易达到边界值,所以使用High-CPU Extra-Large的实例来平衡内存和CPU
  • Gunicorn是他们的WSGI服务器。Apache更难配置,更耗CPU
  • Fabric被用来在所有机器上并行执行命令。部署花费更少的时间。
  • PostgreSQL(存储用户,照片元数据,标签等)运行在12个Quadruple Extra-Large Memory实例上
  • 12个PostgreSQL副本运行在不同的节点上
  • PostgreSQL的Master-Replica使用流复制模式,利用EBS的快照来频繁备份
  • EBS部署在软件RAID上,使用mdadm以获取适当的IO
  • 将所有工作中的数据集存储在内存中,因为EBS每秒磁盘寻道次数有限
  • Vmtouch(轻量级的文件系统缓存诊断工具)被用来管理内存数据,尤其是当故障转移时目标机器没有足够空余的内存
  • 用XFS做文件系统,保证数据快照时RAID阵列上数据的一致性
  • Pgbouncer用作PostgreSQL的连接池
  • 有几个TB的照片存在Amazon S3上
  • 用Amazon CloudFront做CDN
  • Redis用来支撑feed,活动消息,session系统和其它服务
  • Redis运行在几台Quadruple Extra-Large Memory实例上,偶尔也会做下切分
  • Redis也是Master-Replica,副本持久化到磁盘上,并由EBS通过快照备份(这么搞是因为他们发现直接在Master上做dump相当吃力)
  • Geo-Search使用Solr,Solr提供的JSON接口也很简单易用
  • 6个memcached实例做缓存,因为Amazon Elastic Cache服务并不便宜,mmc客户端使用pylibmc和libmemcached
  • Gearman用做:向Twitter,Facebook等平台异步分享照片;新照片发布的通知;feed的反送
  • 200个Python进程处理Gearman的任务队列
  • Pyapns处理超过10亿条Apple的push通知,异常稳定
  • Munin用做监控和系统度量工具,用Python-Munin写了很多图表插件,如每分钟注册人数,每秒钟图片发表数等等
  • Pingdom做内部服务的监控
  • PagerDuty用来处理通知和事件
  • Sentry用来做Python的错误报告

以上就是Instagram的博文里面提到的技术要点,怎么样,准备好构建下一个10亿美元的应用了么?

知识共享图书《开源应用程序架构》

2011年5月28日 1 条评论

知识共享图书《The Architecture of Open Source Applications 》以 Creative Commons Attribution 3.0 Unported 许可方式发布,其内容覆盖 Asterisk, Berkeley DB, Hadoop, CMake, Eclipse, LLVM, Mercurial, Continuous Integration, NoSQL Ecosystem, Python Packaging, Erlang 等优秀开源软件和精彩内容,完全免费开放,别错过。

在线阅读

下载电子书 epub

分类: Architecture 标签:

深入 Facebook 消息应用服务器

2011年5月4日 没有评论

英文来源:Inside Facebook Messages’ Application Server
中文出处:开放博客,由灰狐翻译小组制作

要点:

  1. Facebook 统一消息系统(邮件、短信、聊天、消息等);
  2. HBase 作为后端存储设施,每个用户数据存储在 HBase 的单独一行里,每个实体(文件夹、主题、消息等等)都存储在自己的HBase列中;
  3. 涉及 HayStack 图片处理基础设施;
  4. 使用 Apache Lucene 维护反向索引列表;
  5. 镜像了大约 10% 用户的实时聊天和收件箱中的信息到测试集群中,并通过 dark launch 进行测试。

Facebook Messages 是我们曾经所创建的最具技术挑战性的一个代表产品。

当我们发布Facebook Messages 时所提到的是我们需要打造一个专门的应用服务器来管理其基础架构。

我们最近讨论了消息后台和我们如何处理所有来自 email, SMS, Facebook Chat 和 Inbox 的通信。

今天我们将深入消息应用服务器的核心。

应用服务器的业务逻辑

应用服务器集成了众多Facebook服务和保护(shields)来自各种终端的复杂性。它提供了一个简单接口方便客户端进行标准消息处理,包括:创建、读取、删除、更新消息和收件箱。

下面是每一部分的流程。

当创建一个新消息或回复消息时,应用服务器代表发送者传递消息到收件人。如果收件人是通过其邮件地址,则服务器通过HayStack获得附件(如果有的话),构造HTML主体,并创建一个RFC2822消息。

输出流

当消息发送给用户时,如果地址是一个回复处理,服务器将从存在的邮件地址和传递的输入消息中获得正确收件人的信息。服务器最终将消息传递到用户邮箱,运行所有必要的预处理和后期处理过程,并决定基于多个信号的文件夹和主题的消息路由。

输入流

当读取消息时,服务器取得有关用户邮箱的多个统计,如容量;消息、主题和回复数;朋友的数量等。同时也获得文件夹相关统计和属性,各种搜索条件的主题列表(文件夹,属性,作者,关键字等等),主题属性和这个主题的其它消息。

当删除消息时,服务器标记要删除的消息和主题。一个离线任务具体清除消息内容。

当更新消息和主题时,服务器改变消息或主题属性,如读取和到达状态,标签等等。同时也处理多个用户对主题的订阅和取消订阅的请求。

管理群组主题

Facebook Messages 使用一个聊天室模型管理群组消息主题。用户能加入(订阅)和离开(取消订阅)。

当邮件地址是是这个主题的指定接收者时这个模型是必须的,应用服务器创建一个回复处理器,类似聊天室ID。当一个邮件接收者回复了主题,则消息会被发送到回复处理器地址。

为了优化读取性能和简化移植和备份处理,消息主题以一种非规格化(denormalized)的方式存储。于是每个用户都拥有一份主题元数据和消息的拷贝,服务器广播订阅和取消订阅事件,在一个分散的方式中同步所有接收者订阅和回复处理的主题元数据。服务器也管理类似用户仍旧使用老的收件箱或通过他们的邮件地址订阅的情形。

缓存用户元数据

当用户访问收件箱时,应用服务器装载最常用的用户元数据(也称活动元数据)并将它们保存在最近最少使用的缓存中(a least recently used cache,也就是LRU算法)。随后,同一用户的请求会通过少量的HBase查询被快速的处理。

我们需要减少HBase查询,因为HBase不支持join, 为处理一个读请求,服务器可能需要在分开的HBase查询中查找多个索引和匹配元数据和消息体。HBase的最佳化体现在写操作而不是在读取上,用户行为通常拥有好的时间和地域性(good temporal and spatial locality),于是缓存能帮助解决这个问题并提升性能。

我们也在通过减少用户内存占用和转移到细粒度模式进而提升缓存的有效性方面做出了很多努力。我们能缓存5%-10%的用户量和95%的活跃元数据缓存命中率。我们在全局的memcache层缓存了访问极为频繁的数据(如在Facebook首页显示没有阅读的消息数)。当新消息到达时应用服务器标记缓存为(dirties)(注:dirties表示修改了但还没有写到数据文件的数据)。

同步

HBase对事务隔离提供了有限的支持。针对同一用户的多个更新可能同时发生。为解决它们之间的潜在冲突,我们使用应用服务器作为用户请求的同步点。一个用户在任何给定的时间里由独有的服务器提供服务。这样,同一用户请求就可以在应用服务器中以一种完整孤立的方式(Fashion)同步和执行。

存储模式

MTA代理特性附件和大量消息实体,在它们能到达应用服务器之前被存储在Haystack中。然而,元数据,包含索引数据和小的消息体,它们存储在HBase中并由应用服务器维护着。每个用户的收件箱都是独立于任何其它用户的;用户数据不会在HBase中共享(shared)。每个用户数据存储在HBase的单独一行里,它包含了以下部分:

元数据实体和索引

元数据实体包含收件箱对象属性,如文件夹、主题、消息等等。每个实体都存储在自己的HBase列中。不像关系型数据库(RDBMS),HBase没有提供用于索引的本地支持 。我们在应用级维护辅助索引(Secondary Indexes),同样以键/值对的方式存储在分开的列中。

比如,要回答查询“loading unread threads on the second page of the Other folder,” 应用服务器首先搜寻元数据索引以获得符合条件的主题列表,然后取出指定主题的元数据实体,以它们的属性构造响应。

正如我们前面所提到的,缓存和有效的预装载能减少HBase查询量以获得更好的性能。

活动日志

用户邮箱中的任何更新(如发表和删除消息,标记主题为已读等等)会立即以时间的顺序添加到列中,这称为一个活动日志(action log)。小的消息实体也存储在活动日志中。

我们能通过回放(replaying )活动日志的方式构造或恢复用户邮箱的当前状态,我们使用最后活动日志的ID以元数据实体和索引的版本回放。当用户邮箱被加载,应用服务器比较元数据版本和最后活动日志ID,如果元数据版本滞后(lags behind)则更新邮箱内容。

活动日志存储在应用级带来极大的灵活性:

  • 我们能通过回放活动日志无缝切换到一种新的模式并且能通过一个离线的 MapReduce 任务或在线的应用服务器自身生成新的元数据实体和索引。
  • 我们能在一个批处理中执行大量HBase异步写以节省网络带宽和减少HBase压缩成本。
  • 它是与其它组件交换持久性数据的标准协议。比如,我们通过将活动日志写到记录日志(Scribe log)做应用级的备份。这个移植管道转化用户老的收件箱数据到活动日志并且通过离线MapReduce生成元数据和索引。

搜索索引

为支持全文检索,我们维护着一个从关键字到匹配消息的反向索引。当一个新消息到达时,我们使用 Apache Lucene 去解析和转化它到一个(keyword, message ID, positions)元组(tuples)中,然后以递增的方式加入到 HBase 的列中。每个关键字都拥有自己的列。所有的消息,包括聊天记录,邮件和短信都被实时索引。

dark launch 测试

应用服务器是我们从零开始构建的一个全新软件,因此在将它推向5亿用户前我们需要监控它的性能、可靠性和伸缩性。我们最初开发了一个压力测试机器人(robot)用来生成模拟请求,但是我们发现这样的结果可能会受到其它一些新因素的影响,如消息长度,不同类型请求的分发,用户活跃度的分布等等。

为了仿真一个真实的产品负荷,我们制作了 dark launch,我们镜像了大约10%用户的实时聊天和收件箱中的信息到测试集群中。Dark launches 帮助我们发现更多性能问题和识别瓶颈。我们也使用它作为一个有说服力的指标来评价我们所做的很多改进 。接下来,我们会继续努力为我们的所有用户提供崭新的消息系统。

作者:Jiakai 是 Facebook Messages 开发小组成员。

分类: Architecture, Facebook 标签:

Facebook 的系统架构

2011年4月30日 没有评论

英文来源:http://www.quora.com/What-is-Facebooks-architecture (由Michaël Figuière回答)

中文出处:享受编程和技术所带来的快乐 – http://coolshell.cn

根据我现有的阅读和谈话,我所理解的今天Facebook的架构如下:

  • Web 前端是由 PHP 写的。Facebook 的 HipHop [1] 会把PHP转成 C++ 并用 g++编译,这样就可以为模板和Web逻贺业务层提供高的性能。
  • 业务逻辑以Service的形式存在,其使用Thrift [2]。这些Service根据需求的不同由PHP,C++或Java实现(也可以用到了其它的一些语言……)
  • 用Java写的Services没有用到任何一个企业级的应用服务器,但用到了Facebook自己的定制的应用服务器。看上去好像是重新发明轮 子,但是这些Services只被暴露给Thrift使用(绝大所数是这样),Tomcat太重量级了,即使是Jetty也可能太过了点,其附加值对 Facebook所需要的没有意义。
  • 持久化由MySQL, Memcached [3], Facebook 的 Cassandra [4], Hadoop 的 HBase [5] 完成。Memcached 使用了MySQL的内存Cache。Facebook 工程师承认他们的Cassandra 使用正在减少,因为他们更喜欢HBase,因为它的更简单的一致性模型,以到其MapReduce能力。
  • 离线处理使用Hadoop 和 Hive。
  • 日志,点击,feeds数据使用Scribe [6],把其聚合并存在 HDFS,其使用Scribe-HDFS [7],因而允许使用MapReduce进行扩展分析。
  • BigPipe [8] 是他们的定制技术,用来加速页面显示。
  • 用来搞定用户上传的十亿张照片的存储,其由Haystack处理,Facebook自己开发了一个Ad-Hoc存储方案,其主要做了一些低层优化和“仅追加”写技术 [11].
  • Facebook Messages 使用了自己的架构,其明显地构建在了一个动态集群的基础架构上。业务逻辑和持久化被封装在一个所谓的’Cell’。每个‘Cell’都处理一部分用户,新 的‘Cell’可以因为访问热度被添加[12]。 持久化归档使用HBase [13]。
  • Facebook Messages 的搜索引擎由存储在HBase中的一个倒置索引的构建。 [14]
  • Facebook 搜索引擎实现细节据我所知目前是未知状态。
  • Typeahead 搜索使用了一个定制的存储和检索逻辑。 [15]
  • Chat 基于一个Epoll 服务器,这个服务器由Erlang 开发,由Thrift存取 [16]

关于那些供给给上述组件的资源,下面是一些信息和数量,但是有一些是未知的:

  • Facebook估计有超过60,000 台服务器[16]。他们最新的数据中心在俄勒冈州的Prineville,其基于完全自定设计的硬件[17] 那是最近才公开的 Open Compute 项目[18]。
  • 300 TB 的数据存在 Memcached 中处理 [19]
  • 他们的Hadoop 和 Hive 集群由3000 服务器组成,每台服务器有8个核,32GB的内存,12TB的硬盘,全部有2万4千个CPU的核,96TB内存和36PB的硬盘。 [20]
  • 每天有1000亿的点击量,500亿张照片, 3 万亿个对象被 Cache,每天130TB的日志(2010年7月的数据) [21]

参考引用

[1] HipHop for PHP: http://developers.facebook.com/blog/post/358
[2] Thrift: http://thrift.apache.org/
[3] Memcached: http://memcached.org/
[4] Cassandra: http://cassandra.apache.org/
[5] HBase: http://hbase.apache.org/
[6] Scribe: https://github.com/facebook/scribe
[7] Scribe-HDFS: http://hadoopblog.blogspot.com/2009/06/hdfs-scribe-integration.html
[8] BigPipe: http://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919
[9] Varnish Cache: http://www.varnish-cache.org/
[10] Facebook goes for Varnish: http://www.varnish-software.com/customers/facebook
[11] Needle in a haystack: efficient storage of billions of photos: http://www.facebook.com/note.php?note_id=76191543919
[12] Scaling the Messages Application Back End: http://www.facebook.com/note.php?note_id=10150148835363920
[13] The Underlying Technology of Messages: https://www.facebook.com/note.php?note_id=454991608919
[14] The Underlying Technology of Messages Tech Talk: http://www.facebook.com/video/video.php?v=690851516105
[15] Facebook’s typeahead search architecture: http://www.facebook.com/video/video.php?v=432864835468
[16] Facebook Chat: http://www.facebook.com/note.php?note_id=14218138919
[17] Who has the most Web Servers?: http://www.datacenterknowledge.com/archives/2009/05/14/whos-got-the-most-web-servers/
[18] Building Efficient Data Centers with the Open Compute Project: http://www.facebook.com/note.php?note_id=10150144039563920
[19] Open Compute Project: http://opencompute.org/
[20] Facebook’s architecture presentation at Devoxx 2010: http://www.devoxx.com
[21] Scaling Facebook to 500 millions users and beyond: http://www.facebook.com/note.php?note_id=409881258919

(全文完)

分类: Architecture, Facebook 标签:

并发编程的 15 条建议(转)

2010年10月19日 没有评论

内核专家 Bryan Cantrill 和 Jeff Bonwick 在 2008 年 9 月的《ACM Queue》上发表了《Real-world Concurrency》 一文,提出了 15 条并发编程的建议,这里简单摘录如下。注:Bryan Cantrill 是 dtrace 的主要作者,Jeff Bonwick 是 ZFS 和 Slab allocator 的发明者。

1. Know your cold paths from your hot paths. 弄清楚代码里的热门执行路径和冷门执行路径。

对冷门路径,用粗粒度的锁即可。对热门路径——也就是那些必须高度并发才能实现所期望的高吞吐量的代码,应该更加小心,加锁的策略必须简单明了且细粒度。

2. Intuition is frequently wrong—be data intensive. 直觉常常是错的,要靠数据说话。

【陈硕】比如线程切换到底有多大开销,普通 mutex 加锁到底有多大代价,系统调用的开销如何,gettimeofday() 在 x86-64 Linux 是不是真的系统调用等等,都要靠数据说话。

3. Know when—and when not—to break up a lock. 知道什么时候把一个锁拆成多个,并知道什么时候不必这样做。

除了把全局锁拆成多个锁,另外一种常用的避免线程争用 (contention) 的办法是减少加锁的范围。比方说从共享的数据结构里移除(remove and delete)元素,其实 delete 这一步可以放到锁外面。

4. Be wary of readers/writer locks. 警惕读写锁。

初学者常犯的一个错误是,见到某个数据结构频繁读而很少写,那么就把 mutex 替换为 rwlock。这不见得是正确的。

【陈硕】这条深得我心,muduo thread lib 目前就没有提供读写锁的封装。另外,这一条也能鉴别另一篇关于线程争用的文章不靠谱。

5. Consider per-CPU locking. 考虑用每个 CPU 用一个锁。

6. Know when to broadcast—and when to signal. 知道什么时候用单个唤醒,什么时候用广播唤醒。

notifyAll() 通常表示状态变更,而 notify() 通常表示资源变得可用。滥用 notifyAll() 会导致惊群现象

【陈硕】 muduo thread lib 的 ThreadPool 区分使用 notify() 和 notifyAll(),可作参考。

7. Learn to debug postmortem. 学会验尸。

【陈硕】 在程序中只使用 Scoped locking 来加锁的话,很容易从 call stack 查出死锁。参考《多线程服务器的常用编程模型》第 6 节 线程间同步。

8. Design your systems to be composable. 设计系统,使之能扩充。

【陈硕】 比方说,把对对象的修改操作都挪到同一个线程,这样就不必加锁。参考 muduo 的 EventLoop::runInLoop()。

9. Don’t use a semaphore where a mutex would suffice. 如果 Mutex 就能解决问题的话,不要使用信号量 semaphore。

【陈硕】muduo thread lib 有意识地不提供信号量的封装。

10. Consider memory retiring to implement per-chain hash-table locks. 考虑用内存“退休”法来实现哈希表的按桶加锁。

11. Be aware of false sharing. 知道什么是伪共享。

跟多 CPU 的 Cache 有关,值得了解。

12. Consider using nonblocking synchronization routines to monitor contention. 考虑使用非阻塞的加锁来观察线程争用。

13. When reacquiring locks, consider using generation counts to detect state change. 在重新加锁时,考虑使用版本号来检测状态变更。

14. Use wait- and lock-free structures only if you absolutely must. 只在别无它法时才使用无锁数据结构。

15. Prepare for the thrill of victory—and the agony of defeat. 准备接受成功的喜悦和失败的痛苦。

中文转自: 陈硕的 Blog

这是个长期的研究课题,做个备份,以后边读边实践,并加入自己的理解。

分类: Architecture 标签: ,

Dreaming Infrastructure 我的架构学习笔记[转]

2009年12月24日 没有评论