文章归档

Haystack

文献原址:Finding a needle in Haystack: Facebook's photo storage 

一:简介:

  1. 2600亿照片,20PB数据量
  2. 每周60TB,10亿照片
  3. 每秒100w张图片的检索速度
  4. 对象存储,我们的图片只写,不修改,很少删除
  5. 传统POSIX文件系统成为瓶颈

论文中提到瓶颈是由于传统的POSIX文件系统是基于目录和metadata来管理文件的,通常取一张图片都会涉及好几个IO操作:

  1. 从文件名得到inode号
  2. 将inode信息从磁盘读取出来
  3. 读取文件。

对于一些稍微复杂的架构,1步骤可能会更频繁些。 Haystack设计的目标:

  1. 高吞吐量和低延迟
  2. 分区容忍性
  3. 低成本。通过两个维度来控制,每TB可用数据的利用率和每TB可用数据的读速率(这里的可用考虑到底层文件系统,磁盘阵列,冗余等各种因素)
  4. 简单。

二、背景

  1. 典型设计,存储集群 + cdn
  2. NFS文件系统

 

CDN通常是用来缓存热数据的,但是对于像facebook这样的互联网站,通常需要产生大量的非热数据内容,而恰恰是这些不太热的数据内容,大量地升高了CDN回源的压力,facebook引用了长尾理论来解析这一效应。在NFS卷里,facebook最初默认是每个目录存储上千个文件,但是由于NAS设备对目录metadata的管理方式,导致在一个目录里存放上千个文件相当困难,因为目录的blockmap太大了。这种情况下读1张图片最少也要10个IO,就算让目录存放的文件数降低到100,也仍然会有3个IO才能读到一张图片。 为了减少磁盘操作的次数,facebook还在Photo Store servers上缓存NAS设备返回的file handle,这个是通过增加内核API(open_by_filehandle)来实现的。facebook从NAS上学到的经验就是:通过缓存来降低磁盘IO的操作是很有限的。 也许有人会说,可以使用memcache来缓存所有的file handles。对此facebook坦言,也许这是一个解决方案,但是只能解决这里部分的问题,因为这么做的话需要NAS设备缓存所有的inodes信息,只不过是一种昂贵的传统存储方案罢了。 

三、设计与实现 

方案:CDN解决热数据问题,Haystack解决长尾效应。 Haystack的主要目的就是为了解决NFS存储方案中高磁盘IO的问题。Haystack的做法是:降低文件系统的metadata的内存占用,因此尽可能的将所有的metadata放在内存里,例如它将多个小文件存在一个大文件里。

1)三个核心组建:Haystack Directory, Haystack cache, Haystack store 

 

Store是由物理卷组成的,容量由物理卷的数量来控制,100个物理卷可提供10TB的存储空间。物理卷还会组合成一个逻辑卷,单个逻辑卷中的所有物理卷数据是相同的,冗余。Directory主要保存应用方面的数据信息,例如每张图片存放在哪个逻辑卷上,还有逻辑卷到物理卷的映射以及逻辑卷的剩余空间。Cache相当于一个内部的CDN。 

2)URL规格

»» 继续阅读全文

goroutine的实现原理

goroutine的实现主要依赖下面这几个API,linux386平台的实现在runtime/asm_386.s文件里。这里只显示API [c]// void gosave(Gobuf*)

// void gogo(Gobuf*, uintptr) // restore state from Gobuf; longjmp

// void gogocall(Gobuf*, void (*fn)(void)) // restore state from Gobuf but then call fn. // (call fn, returning to state in Gobuf)

// void mcall(void (*fn)(G*)) // Switch to m->g0's stack, call fn(g). // Fn must never return. It should gogo(&g->sched) // to keep running g.[/c] 而调度的实现是在runtime/proc.c文件里。

gosave类似于setjmp,但它也保存了当前正在运行的G的状态,PC和SP,gogo类似于longjmp,恢复G的SP和PC。SP和PC是通过一个Gobuf的结构来维护的。gogocall和gogo的作用差不多,但跳转到相应的G之后,会继续执行一个fn函数。mcall稍微复杂点,但也和googcall类似。

通常从M跳转到G的执行,是使用gogo,而从G跳转到M,是使用mcall。这是因为在M的栈上运行的只有一个mstart()函数,而在mstart()函数内主要的工作就是初始化一些数据,然后最后触发调度器schedule(),所以如果是使用gogo从G返回到M,那么M就会执行完毕。

整个过程就是通过一个全局的Sched结构来维护所有的调度状态。比libtask的实现复杂点,和xv6的proc实现也差不多。

lua 5.1虚拟机

  1. The Implementation of Lua 5.0
  2. 手册:http://www.lua.org/manual/5.1/manual.html
  3. lua源码欣赏:http://www.codingnow.com/temp/readinglua.pdf
  4. 指令集:A No Frills Intro To Lua51 VM Instructions.pdf

蛮有用的资料,对vm 5.1的理解很有帮助。

面向软件错误构建可靠的分布式系统

Making reliable distributed systems in the presence of sodware errors

1 问题域

  • 并发(concurrency)
  • 软实时(soft real-time)
  • 分布式(distributed)
  • 硬件交互(hardware interaction)
  • 大型软件系统(large software systems)
  • 复杂的功能(complex functionality)
  • 持续运行(continuous operation)
  • 高质量要求(quality requirements)
  • 容错(fault tolerance)

2 哲学

容错和故障隔离。例如进程和基于消息的交互。

3 系统需求

  • 并发性
  • 错误封装 即一个进程的错误一定不能破坏系统中其他的进程
  • 故障检测 包括本地和网络异常
  • 故障识别
  • 代码升级
  • 持久存储 以便恢复崩溃的系统。

4 语言需求

  • 封装原语
  • 并发性
  • 错误检测原语
  • 位置透明
  • 动态代码升级

5 库需求

  • 持久存储
  • 设备驱动程序
  • 代码升级
  • 运行基础

Lua之魂?

云风翻译了 《Masterminds of Programming: Conversations with the Creators of Major Programming Languages》中关于Lua发明人的一段对话,甚好,看来有必要一读此书

7. Lua

Lua 是一门非常之小,但五脏俱全的动态语言。它由 Roberto Ierusalimschy、Luiz Henrique de Figueiredo 和 Waldemar Celes在1993年创建。Lua 拥有一组精简的强大特性,以及容易使用的 C API ,这使得它易于嵌入与扩展来表达特定领域的概念。Lua在专有软件界声名显赫。例如,在诸多游戏中,比如 Blizzard(暴雪)公司的《魔兽世界》和 Crytek GmbH 公司的《孤岛危机》,还有 Adobe 的 Photoshop Lightroom ,都使用它来作脚本 和 UI 方面的工作。它继承了 Lisp 和 Scheme,或许还有 AWK 的血脉 ; 在设计上类似于 JavaScript、Icon 和 Tcl。

7.1 脚本的威力

你是如何定义 Lua 的?

LHF:一种可嵌入,轻量,快速,功能强大的脚本语言。

Roberto:不幸的是,越来越多的人们使用“脚本语言”作为“动态语言”的代名词。现在,甚至是 Erlang 或者 Scheme 都被称为脚本语言。这非常糟糕,因为我们无法精确的描述一类特定的动态语言。在最初的含义解释中,Lua 是一种脚本语言,这种语言通常用来控制其它语言编写的其他组件。

人们在使用Lua设计软件时,应该注意些什么呢?

Luiz:我想应该是用 Lua 的方式来做事。不建议去模拟出所有你在其它语言中用到的东西。你应该真的去用这个语言提供的特性,我想对于使用任何一门语言都是这样的。就 Lua 来讲,语言的特性主要指用 table 表示所有的东西,用 metamethod 做出优雅的解决方案。还有 coroutine 。

Lua 的用户应该是哪些人呢?

Roberto :我认为大多数没有脚本功能的应用程序都能从 Lua 中受益。

Luiz:问题在于,大多数设计者很长时间都不会意识到有这种需求。当已经有了诸多用 C 或 C++ 编写的代码,为时已晚。应用程序设计者应该从一开始就考虑脚本。这会给它们带来更多的灵活性。而且这样做还可以更好的把握性能问题。因为这样做以后,会迫 使他们去考虑程序中到底哪里是性能关键,而哪些地方无伤大雅。而这些性能不太重要之处,就交给脚本去处理,开发周期短,速度快。

从安全性的观点来看,Lua 能为程序员提供些什么呢?

Roberto:Lua 解释器的核心部分被构建为一个 “独立的应用程序(freestanding application)”。这个术语来自 ISO C,大意是说,这部分不使用任何跟外部环境有关的东西(不依赖 stdio、malloc 等)。所有那些功能都由扩展库来提供。使用这种体系结构,很容易让程序限制对外部资源的访问。具体来说,我们可以在 Lua 自身的内部创建出一个沙盒,把如何我们认为危险的操作从沙盒的外部环境中剔除。(比如打开文件等)

Luiz:Lua

»» 继续阅读全文