Arch 类别下的文章

很多人都觉得 eBay 在 QCon (北京) 上的技术讲座不错,但对我来说,其实冲击力没那么大了。eBay 一两年前就是这个 PPT 。不过还是比 Amazon 的 Jeff Barr 强了很多,以后要是开个什么会,你把 Jeff Barr 请来还讲那个销售文档,估计自己都不好意思。

不过,eBay 这次的PPT 总算还是有点更新的。

1)数据分片(Partition Everything)

说是分区(Partition),这里不能简单等同于 Oracle 的分区,理解成分片(Sharding)就好啦。可以参考一下我以前写的科普小文:开源数据库 Sharding 技术 (Share Nothing)。这里要强调一下的是,分片是在数据量的确有规模的时候才适合进行,如果单节点足以应付,那么还是不要冒进。

从分片的模式上,eBay 主要根据功能切分(Functional Segmentation)和水平分割(负载均衡考虑),作为推论,所有会话都是无状态性的。

2)异步处理(Asynchrony Everywhere)

其实对于任何网站来说,过度追求"同步"化设计还是比较糟糕的做法。以用户能观察到的数据为视角进行设计,中间可以最大限度用异步来完成。

eBay 的举例的模式有两个,一个是事件队列(Event Queue),另一个是信息分发(Message Multicast)。前者基本上是个生产者--消费者的模型。后者主要用在搜索的架构上。

eBay_message_multicast.png

注意到图中的消息总线,这才是 eBay 整个架构中的动脉,估计轻易不会批露技术细节

3)自动化(Automate Everything)

这里的自动化举了两个例子,一个是针对运维方面的,另外举了关于机器学习的东西,这是演讲者 Randy Shoup 的强项所在。

eBay 的自动化,在一年前的另一篇文章里可以窥测一点东西。只是这篇文章当初没有被更多人重视,参见:eclipse at eBay。可以看到 eBay 能在自动化方面做得这么好(起码敢出来讲)不是一朝一夕之功。

4)故障检测与回溯(Remember Everything Fails)

更好的失败检测机制: 监控每天超过 2TB 的日志,根据日志中的相关事件得出判断或者预警。这个看起来简单,但实现起来还是需要一点技巧和策略的,重要的是,需要不断根据结果的反馈去改进。

完美回滚: 任何服务都通过服务配置中的标记来识别,无痛回滚。(个人感觉这个非常有难度,尤其是升级的时候)

优雅降级(Graceful Degradation):能够相对容易的对应用标记"Marks down(下线)"

5)拥抱不一致性(Embrace Inconsistency)

举了 CAP 原则,程立将其形象描述为帽子戏法,非常准确。说起一致性,自从 Amazon CTO Werner Vogels的 Eventually Consistent 一出,基本上不需要再废话了,这就是事务处理的九阴真经,大家回家慢慢参详好了。

eBay 也有自己的绝对准则: 绝对没有分布式事务(两阶段提交), 通过状态机与操作顺序最小化不一致性,通过异步事件(消息总线?)达到最终一致性。

--EOF--

另外小道消息:Amazon CTO Werner Vogels 可能会参加六月份在杭州举办的侠客行大会。

以前的老帖子:eBay 的Scalability最佳实践

这次 QCon (北京)会议网站架构案例分析这个 Track ,虽然话题不多,但课程设计时候考虑覆盖的面还是比较广的。作为视频网站代表,优酷带来了一场包含不少实战经验的技术分享。邱丹(优酷网开发副总裁,核心架构师)可能公司的事情比较忙,一直到第二天中午才赶到会场。还半开玩笑说,'怎么这么多人,还以为是小型的会议呢'...

Youku_Qiu.jpg

缓存

缓存黄金原则:让数据更靠近 CPU

CPU-->CPU 一级缓存-->二级缓存-->内存-->硬盘-->LAN-->WAN

讲到了 Youku 自己的内部项目,针对大文件缓存的。目前开源软件中,Squid 的 write() 用户进程空间有消耗,Lighttpd 1.5 的 AIO(异步I/O) 读取文件到用户内存导致效率也比较低下。Youku 不用内存做缓存(避免内存拷贝,避免内存锁)。值得注意的是,缓存技术容易被滥用,也有副作用,比如接到老大哥通知要把某个视频撤下来,如果在缓存里是比较麻烦的。

数据库

优酷对数据库 Sharding 做了不少尝试,而且实现效果应该不错。DB 读写分离上有比较丰富的经验。

Youku_Sharding.png

为了提升数据库 I/O 能力,启用了 SSD 。6 块 SSDRAID 。我在 Twitter 上发了一则 Youku 使用了 SSD 的消息,很多朋友以为是用来存储视频文件,这里需要澄清一下--只是局部使用。

网络吞吐量优化

这是我强烈要求加上来的一节内容。网络优化,视频网站肯定都做得不错。这一节的关键词是 "事件(event)驱动",令人深刻的一句话是 "ePoll 推动当今 Web" ,的确,现在很多比较热的 Web 组件都是以 ePoll 为卖点。

延伸阅读: The C10K problem (我一直想翻译一下这个页面,苦于腾不出时间) 与 Libevent 如果做互联网,遇到扩展性问题,这两个信息点还是避不过去的。

最后一个例子是针对 Memcached 的 Agent 的,这一点和 Facebook 架构中的 Memcached 处理可以对照来看。

演讲结束的时候,有人提问优酷对视频缓存上有什么特别的地方? 回答是一个大视频可能分成多个小文件,这样缓冲的时候就效果更好一点--(并行啦)...其实访问优酷的确比土豆快那么一点点。

--EOF--

PPT 过几天 InfoQ 中文站会发布。稍安勿躁。

Facebook 架构学习

在 QCon 2008 (旧金山站) 上Facebook 做的这个技术分享有不少值得借鉴的东西。所以,暂停对 QCon 北京的回顾,临时插播一贴。

设计原则

  • 尽可能的使用开源软件,并且在需要优化的时候进行优化
  • Unix 哲学。包括,模块化原则;整合化原则;清晰化原则等
  • 任何组件具备扩展性
  • 最小化故障影响
  • 简化,简化,简化!

架构概览

Facebook 是 LAMP 的坚定支持者,也差不多是用 LAMP (或许用 LAM2P 更适合) 实现的最大的动态站点。

Facebook Arch Overview.png

基础组件加上服务,中间用自己实现的一些工具进行粘合。其中关于运维细节的事情基本不会说出来的,这是很多公司的软实力所在。

PHP 经验

参见《Facebook 的 PHP 性能与扩展性》

MySQL 经验

  • 主要用于做 Key-Value 类型的存储操作,数据随机分布在多台逻辑实例上,访问多数基于全局 ID 。
  • 逻辑实例分散在多台物理主机上(超过1800台),负载均衡在物理层进行。
  • 不做读复制。
  • 尽量不做逻辑数据迁移(成本太高)。
  • 不做 JOIN 操作 (豆瓣在 QCon 上也阐述了这一点)。数据是随机分布的,关联操作反而带来了极大的复杂度。
  • 对于数据访问,主要的操作集中在最新的数据上,针对这部分做优化,旧的数据进行归档。
  • 在中心 DB 绝不存储非静态数据。
  • 使用服务或者 Memcached 进行全局查询。

Memcached 经验

参见我以前的笔记:Facebook 的 Memcached 扩展经验。Facebook 对 Memcached 做了不小的改进。另外,顺便说一下,前两天 Memcached 刚在 1.2.7 发布几天之后又发布了新版本 1.2.8,修正了一些问题。

一个比较有价值的是关于个人页面数据的获取的描述。这个就完全是需要做单页面 Benchmark 的细致活儿了,可能还需要产品经理能够理解工程师的"抵抗"。

  • 获取个人信息数据:通过Cache,隐性通过用户所在的 DB 获取(基于 User-ID 获知 DB)
  • 获取朋友连接信息:通过Cache,否则的话通过DB(基于 User-ID 获知 DB)
  • 并行抓取每个朋友的 10个照片相册 ID ,从Cache抓取,如果失效,再从 DB 抓取(基于相册 ID)
  • 并行抓取最近相册中的照片数据
  • 运行PHP 把整个业务逻辑跑出来
  • 返回数据给用户

然后是对 Facebook 非 LAMP 体系的东西做了一番介绍,基本上也开源了。最后参考两个架构图。

Facebook NewsFeed 的架构示意图

Facebook_NewsFeed_Arch.png

Facebook 搜索功能的架构示意图

Facebook_Search_Arch.png

管中窥豹,盲人摸象而已。

--EOF--

这次的 QCon 会议,《豆瓣网技术架构的发展历程》这个议题差不多是最受关注的。洪强宁在演讲开始告诫大家期望值不要太高,我还是相信不会有人觉得失望的。

豆瓣网首席架构师洪强宁在演讲

先说几句题外话,整个演讲听下来,我们会发现豆瓣在发展的过程中也是有点弯路,这些是一个网站发展过程中的宝贵财富,能把自己有周折的地方大大方方的拿出来,是难能可贵的事情。尽管豆瓣批露了很多架构细节出来,也不会(也不可能)有哪个公司一拿到这些东西,就能照猫画虎再做一个豆瓣并且超过豆瓣。从某种程度上来说这体现了豆瓣同学们的气度,这是令国内大多数公司汗颜的。很多公司只愿索取,而不愿奉献哪怕一点点出来,用这样封闭的心态对待技术其实是小家子气,守财奴的思维。技术只有为更多人所用才是大道。

议论说完,再来叙述。写点对豆瓣架构的体会。戏法人人会变,各有巧妙不同。有些东西大家都在用(Nginx),但是有人的用得好,有人用了比不用还差。所以,需要逐渐总结,改进。学习别人的架构设计,不是要照搬,而是借鉴其思想。

技术的选择

一直以来,豆瓣在技术上都给人很前卫的感觉,看起来好像什么新用什么,其实是不是的,他们一直是"用已掌握的技术解决问题",现有的东西如果够用,那么就没必要一定迁移到新的上面去,而转换往往是为了解决当前问题。另外,换用新的东西,要有足够的驾驭能力,从演讲中得知,豆瓣曾有几次在临上线前发现基础库的Bug(比如 Libmemcached 的一致性哈希相关的Bug),技术团队能在第一时间有进行修复并且提交给开源社区。否则的话,就变成了一种错误决策了。

磁盘转速

小话题。如果可能,直接买 15000 转的磁盘好了。10000 转的磁盘可能省钱,但这东西部署了之后几乎就不太可能升级。所以,如果是初创公司,我的建议就是买高速磁盘,因为业务如果发展快了的话,先前对机器的定位也可能发生变化。

杜绝远程 I/O

在普通的 TCP/IP 网络的环境下,不要进行远程数据写入操作。跨网络操作的延时看似没什么大不了的,但一旦达到临界点就回天乏术。这个事情基本是不撞南墙不回头,有的技术人员总要亲身体验一把才肯罢休。

持续保持 URL 友好风格

演讲中有多次提到一致性 URL ,其实体现了豆瓣对 URL Rewrite 的重视,结构调整,或者应用程序变化的时候,URL 最好做到"用户友好"的。这算是"软技术",但是应该加以最大的重视。

数据库复制延迟问题

对于 MySQL 复制的环境,如果Slave 上有读取操作,那么有些情况下可能因为 Master 和 Slave 节点数据不一致对用户造成困惑。如果从一致性的角度上考虑,其实也不复杂:,只需要对"知道数据发生了变化的用户"提供一致性就行了(基本上就是发起变更的用户),不知道数据发生变化的用户对数据的不一致有一定的"容忍程度",当然说着简单,实现起来还是需要技巧和精巧的。

大量小文件同步问题:Merkle tree

关于大量小文件的同步问题,很多上了规模的网站都会遇到,如果设计得不好或者是比较偷懒,用传统的办法(比如 rsync 之类的老模式)很容易触发问题,也浪费资源。DoubanFS 是用 Merkle tree(Hash Tree)的方式进行数据同步的。对这个问题的具体描述可以参见《大量小文件的实时同步方案》。Merkle Tree 是个很精巧的思路,ZFS 在用(refer),Amazon Dynamo 系统也在用。


不会一会儿又有人留言说:我们早就采用这个思路了...... 我这里预先来句回答:拜托,你早点共享啊?

--EOF--

完整的 PPT 过几天 InfoQ 中文站会发布,我这里就不掠美了。

手机之家的架构分享

在上周日奇遇花园咖啡馆举办的 Beta 技术沙龙上,手机之家高春辉和他的战友们带来了他们网站技术架构与大家分享。

之前就手机之家的架构采访过老高,这次是来了图文并茂版了。希望过几天能有个视频的 :) 读了 PPT 之后,比较感兴趣的是关于 Cache 的处理:

...对数据库记录的缓存的访问做了一定的抽象处理,开发出了Cache 处理器。所有的数据访问都经过cache处理器。这样,系统代替程序员接管了缓存的存取访问。缓存的KEY和VALUE由系统处理,从而避免了冲突和混乱。Cache 处理器的引入减少了40%的数据访问层代码!最重要的是,我们采用了Namespace的方法使得缓存能自动清除了。

Arch_Cache_imobile.png

因为身在杭州,不能分身参加。不过第一时间从老高那里要来了 PPT。共享一下。

最后(最重要的是),手机之家还在招聘 PHP/Java 人手,有意者给老高发邮件: [email protected]

--EOF--

QCon(北京) 技术大会预热

再有几天 QCon (Beijing) 技术大会 就开始了。QCon 是这几年出现的最有价值的技术会议,"绝对有技术含量",相信北京这次也会让每个人不虚此行。这还是第一次在国内举办,很多国外的大师都来了,有机会能参加也是一件好事。QCon_Beijing.jpg

受邀主持网站架构案例分析这一场,所以有机会提前看到各位技术演讲人提交的 PPT。前天晚上看到豆瓣首席架构师洪强宁的 《豆瓣技术架构的发展历程》,击节称赞! 这个 PPT 会成为一份相当经典的架构参考文档。

据说现在已经一票难求了,如果要购票的话,可以用我的折扣代码。买票的时候报我的 BLOG 或者我的名字就可以省点钱。

--EOF--

学习 HeroKu 的架构设计

这几天给我印象比较深的是 HeroKu ,提供 Ruby 快速部署环境并提供托管能力,他们的架构图做得十分漂亮,一幅图胜过千言万语,要是对 Web 架构感兴趣,都别问架构师了,看看 HeroKu 的架构估计就明白个差不多了 :)

概览图

好的架构图是画出来的,好的架构未必是设计出来的,最后架构好不好,还要看持续的改进能力。

HeroKu Overview.jpg


HTTP 反向代理

使用 Nginx , 这一层只进行 HTTP-level 的处理。Nginx 现在是不二选择。

HeroKu Reverse Proxy.jpg


HTTP Cache

对于静态内容,使用 Varnish 进行缓存。如果你在 Squid 和 Varnish 之间作选择,这里已经投了一票。

HeroKu HTTP cache.jpg


路由网(Routing Mesh)

Erlang 实现的架构组件,路由寻址,用以提升可用性和扩展性。

HeroKu Routing Mesh.jpg


动态网格(Dyno Grid)

用户部署的代码运行在这里,可以简单看成是应用服务器集群环境,只是粒度更小一点而已。

HeroKu Dyno Grid.jpg

对于 Dyno Grid 的进一步信息:

HeroKu Dyno Grid Arch.jpg

服务器操作系统是 Debian ;Ruby VM 是 MRI ,开源,C 写的;App Server 用的 Thin,他们说 Thin 比 Mongrel 更精炼;Rack,应用服务器接口;Rack 中间件,可选组件;框架,任何 Rack 兼容的都成;最后是客户托管的代码。

数据库

PostgreSQL,也可以采用远程数据库。

HeroKu Database.jpg


Memory Cache

Memcached ,居家旅行架构必备。

HeroKu Memcached.jpg

这几张图看下来,多少算是对 Ruby 环境有了一些感性认识。可以进一步查看 HeroKu 提供的文档,包含了一些代码实现上的准则。

部署是基于 Git 的。不知道大家有没有注意到 Git 在最近一年来的爆发? 超过 SVN 或许不是不可能的。

国内热炒"云计算"的,跟人家学学吧,与其整天帮着客户开发定制软件,还不如给客户提供一些弹性应用托管环境,起码看起来靠谱一些。

HeroKu ,不读 Hero-Ku, 读作 Her-oh-koo, 挺有趣

--EOF--

图的来源:HeroKu Platform Architecture

一直比较好奇 FriendFeed 网站背后的技术信息。Bret Taylor 的一篇 How FriendFeed uses MySQL to store schema-less data 给出了不少有价值的经验。

概览

FriendFeed 用 MySQL 存储绝大部分数据,超过 2.5 亿条记录。对待网站功能的态度: 让既有功能满足更多用户而不是添加更多的功能。

少添加新功能的好处是数据库 Schema 变化更小。在数据库Sharding 的情况下,如果修改 Schema 结构,必然会影响可用性。此外,几乎不进行复杂一点的关系型查询(比如 不做 JOIN 操作 -- 这要用到传统意义上的索引机制 )。FriendFeed 也没有采用什么更新的数据库解决方案(比如 CouchDB ),原因无他,对 MySQL 更谙熟,知道其短长,扬长避短同样能发挥更大的作用。

"Schema-Less"

这是 FriendFeed 对付数据库的基本策略。只存储基本的对象属性,如果需要修改 Schema 层面的东西,只需要存储新的属性即可。其实就是更加"面向对象",由基本的"元数据"一步一步衍生到所有的数据对象。

"去索引化",因为维护索引带来了复杂度,将索引数据存储到到表上。我认为这也是反范式的一个新的思路。在 Bret Taylor 文章的 "Details" 一节中给出了具体的例子。比如要在 user_id 上进行索引,那么创建 index_user_id 表(存储来自所有 Shard 的数据),以 user_id 和 entity_id 为主键即可。这样在修改基表的时候,不需要对其他"索引"表做变动。而删除"索引"也极为方便--删除创建的"索引表"即可。

一致性与原子性

关于一致性可能会有问题,但是可以确定基本原则:

  • 主条目表中存储的属性数据是规范的
  • 索引可能不对应实际的值(这和关系数据库本身的索引有些不同之处)

写入数据的时候按照如下顺序:

  • 写入条目表用 InnoDB 的 ACID 属性来保证
  • 把数据写入到其他 Shard 上的索引表中(猜测可能还是要延迟写)

在读取的时候可能会有短暂的数据不一致性的现象,但很快就能校正。考虑到 FriendFeed 业务的容忍性,这个问题并不严重。

笔记总结

总体感觉,FriendFeed 用了一种非常巧妙的方式进行数据库扩展(多耗费了一点存储空间)。不过这个方式总体上看来,极大减少了手工维护成本。相信 FriendFeed 分享的这个经验能给国内一些需要处理即时信息的站点一些启发。以上只是我的个人理解,如果去看一下 Bret 文章后面的留言,你肯定能得到更多信息(比如为何使用 UUID )。

最后提一下,FriendFeed 用 pickle 做 Python 的对象序列化。当然 Memcached 也是居家旅行必备佳品。

--EOF--

1 2 3 4 5 6 7 8 9 10 11 12

关于归档

本页包含 Arch 类别下的所有文章.

Database 为下一类别.

回到 首页 查看最近发表的文章或者查看所有 归档文章.