博客

Transcendent memory 技术

August 12, 2011
This article was contributed by Dan Magenheimer
Transcendent memory in a nutshell

翻译:李凯、曾怀东、王鑫、朱翊然、靳彬、林业、马少兵

  1. Linux 内核枚举并跟踪其所有的内存,且对于绝大部分的内存,它都可以单独的寻址到每一个字节。transcendent memory (“tmem”)为内核提供更好的利用内存的能力,使其不用再去枚举内存,在某些情况下甚至不用再去跟踪或者不再用去直接去寻址了。对于内核开发者来说,这听起来可能跟他们的直觉相违背甚至是愚蠢的,但是我们将看到其确实是很有用处的;实际上它给内核增加了一个提高灵活性的中间层,这样基于一些微小的内核变化之上,就能够实现一些较复杂的功能。最终的目标是使得内核可以更有效的利用内存,多个内核之间(包括虚拟化环境和非虚拟化环境)实现负载均衡,以期使得单个系统(甚至跨数据中心)可以达到更好的性能更低的RAM开销。这篇文章对transcendent memory 进行概述以及说明这种技术是怎样在Linux内核中运用的。

    【编译者注:如果仅有“地址枚举并直接访问”这一种内存使用模式,那么显然多个虚拟机使用内存就太不灵活了】

    内核与tmem是怎样展开对话的,将在第二部分进行详细的描述。内核管理着适用于 tmem 的若干不同类别的数据。其中"clean pagecache pages" 和 "swap pages"是内核开发者所熟知的两种。处理前者的补丁叫做“cleancache”它已经被并入3.0kernel里面了。处理交换页的补丁是frontswap,现在linux 内核邮件列表中仍然有对其进行审查。可能还有其它类别的数据与tmem能够更好的协同工作。这些对于tmem来说合适的数据源统称为“frontends”,我们将在第三部分详细的介绍。

    tmem使用不同的方法存储数据。对于tmem来说这些实现方式称为“backends”,任一前端都可以应用任一后端(可能使用shim连接它们)。最初的tmem应用是我们所熟知的“Xen tmem”,它允许 Xen hypervisor 的内存为一个或者多个支持tmem的 guest 使用。Xen tmem已经应用在Xen中两年了,从Xen4.0开始的;内核里的shim已经并入3.0版本里了。另一个Xen驱动部件,Xen self-ballooning 驱动,用来支持guest内核更有效的使用tmem,已经并入3.1版本里了,同时也包括“frontswap-selfshrinker”,查看本文最后的附录以了解这部分更多的内容。

    Tmem的第二个应用并不是虚拟化,而是“zcache”,它是内核里面的一种驱动,用来存储压缩页。这其实就是“倍增内存”的方法,对任何能通过tmem前端(例如cleancache, frontswap)使用的内存都能应用,从而减少内存的需求,例如嵌入式内核。Zchache作为staging驱动被合并到在2.6.39版本中。

    Tmem的第三个应用正在实施,称为“RAMster”.在RAMster中,一些“closely-connected”(【编译者注:极高带宽、极低延时的机器之间的互连】)的内核可以有效地共用它们的RAM,这样的话对于一台缺少RAM利用的机器来说可以利用另一台机器上闲置的RAM。RAMster也被称为“peer-to-peer transcendent memory”,通常应用在物理系统之间,但是也可以虚拟机内核进行测试。RAMster最适合用于高速‘exofabric’连接的多系统环境里,在这个环境里,一个系统可以直接寻址到另一个系统内存,其最初的原型是建立在以太网的连接上。

    还有一些其他的tmem实现也被提出:例如,在tmem可能会在何种程度上帮助KVM和/或容器(container)方面发生了一些讨论,随着最近zcache的更改被合并入3.1,部署必要的shims并尝试这些变得很容易;但还没有人加紧做这件事情。另一个例子是,tmem协议可能适用于某些种类的RAM的技术,如“"phase-change”内存(PRAM);这些技术大多具有某种特性,例如有限的写周期,它们可以通过tmem一类的软件接口被有效管理。在一些RAM技术厂商之间已经开始了对此的讨论。还有一个例子是 RAMster的变种:集群中的单台主机作为“内存服务器”并且只在这台主机上增加内存;这些内存可能是RAM,或者是类 RAM 的东东,比如 fast SSD。

    现有的tmem实现和一些未来实现的设想将在第四部分进行介绍。
  2. 内核是如何同transcendent memory通信的

    内核通过一个精心定义的接口同tmem进行通信,它被设计成向tmem的部署提供最大限度灵活性同时把对内核的影响降到最低。tmem接口可能会显得奇怪,但也有其特殊性很好的理由。请注意在某些情况下tmem接口完全是和内核交互,因此它是“API”;在另一些情况下它定义了两个独立软件组件之间的边界(例如,Xen和一个guest Linux kernel),所以它被称为“ABI”更合适。

    (泛泛而读的读者不妨跳过这节)

    Tmem应当被视作“拥有”一些内存的“实体”。这个实体可能是 in-kernel driver,其他内核,或者hypervisor/host。前面已经提到过,tmem不能被内核枚举;内核不知道tmem的大小,tmem可能动态改变,也可能在任意时刻变“满”。因此,对每一个页面请求内核必须“询问”tmem来接受数据或检索数据。

    Tmem不是字节寻址的 —— 只是大段的数据(准确或大约为一个页面的大小)在内核内存和tmem之间进行拷贝。由于内核无法“看到”tmem,API/ABI的tmem侧负责将数据拷贝进/出内核内存。tmem把相关的数据块放入一个池来管理;在池中,内核选择一个唯一的“句柄”来代表数据块的地址。当内核请求创建池的时候,它会指定一些特定属性(这些属性下面会讲到)。如果池创建成功,tmem提供一个“池id”。句柄在同一个池内是唯一的,但是在不同的池之间不是唯一,句柄由192位“对象id”和32位的“索引”组成。大致上,一个对象相当于一个“文件“,索引相当于文件中页的偏移量。

    tmem两个基本操作是”put”和“get”。如果内核希望在tmem中保存数据,它应该使用“put”操作,提供一个池id,一个句柄以及数据的位置;如果put操作返回成功,tmem就复制了数据。如果内核希望获取数据,它应该使用“get”操作,提供池id,句柄,以及位置用于tmem放置数据;如果get成功,返回的数据会被放置在指定的位置。请注意,不像I/O,tmem的拷贝操作是完全同步的。As a result, arbitrary locks can (and, to avoid races, often should!) be held by the caller.

    有两种基本池类型:短暂型和持久型。成功存入短暂型池的页面在内核使用对应的句柄进行后续get操作后,可能会存在也可能消失。成功存入持久型池的页面能够保证在后续get操作后依然存在。(此外,池可能是“共享的”或是“私有的”)。

    内核负责维护tmem数据及内核自己的数据之间的一致性,tmem有两种“刷新”操作来协助保持一致性:为了分离一个句柄和其他tmem数据,内核使用“刷新”操作。为了分离一个对象和对象中的所有数据块,内核使用“刷新对象”操作。在刷新之后,后续的get操作会失败。在(非共享的)短暂型池上的get操作是破坏性的,例如,暗含了刷新操作;否则,get是不具有破坏性的并且需要明确的刷新。(附录B中描述了两个附加的一致性保证)
  3. Transcendent memory frontends: frontswap and cleancache

    尽管还有其它的前端,frontswap和cleancache这两个现有的tmem前端包含了内核内存的主要类型中的两种,这两种对内存压力都很敏感。这两个前端属于互补的:cleancache处理(clean)那些已映射的页面(编译者注:VFS disk cache page),否则那些页面将会被内核回收;frontswap处理(dirty)那些匿名页,否则这些页面将被内核换出。当一个成功的cleancache_get发生时,会避免一次硬盘读。当一个成功的frontswap_put(或get)发生时,则会避免一次swap设备写(或读)。同时,假设tmem比硬盘的paging/swapping都要快得多,那么将会从一个限制在内存中的环境中获得客观的性能提升。

    • Frontswap

      在一个Linux系统中,“虚拟内存”的总量是物理RAM加上所有已配置的swap设备的量之和。当有一个工作量超过物理RAM的大小的“工作集”时,就会发生swapping —— swap设备本质上是用来模仿物理RAM的。但是通常情况下,一个swap设备要比RAM慢上好几阶,因此swapping已经变成了和可怕的性能相同的词语了。结果,聪明的系统管理员会增加物理RAM或者重新分配工作量来保证尽可能地避免swapping。但是如果swapping并不总是那么慢又会怎么样呢?

      Frontswap允许Linux的swap子系统使用 transcendent memory,当有可用的内存的时候,会取代往一个swap设备发送数据或从一个swap设备获得数据。Frontswap本身并不是一个swap设备,也因此它并不要求像swap设备那种的配置。它并没有改变系统中总的虚拟内存的数量,它只是导致了更快的swapping...一些或大多数或几乎所有时候,但并不总是如此。记住, transcendent memory的数量是不可知的和动态变化的。使用frontswap,当一个页面需要被换出,swap子系统会问tmem它是否愿意接收这个页的数据。如果tmem拒绝,swap子系统会像往常一样向swap设备中写这个页。如果tmem接受,swap子系统可以在任何时候请求此数据页,并且tmem保证了数据的可取回。过一会儿,如果swap子系统确信数据不再有效时(比如持有此数据的进程已经退出),它能够将数据页从tmem中flush掉。

      注意,tmem可以拒绝任何frontswap的“put”。为什么这样呢?一个例子就是如果tmem是多个内核的共享资源(又称之为“clients”),就好像Xen tmem或者RAMster的情况;另一个内核可能已经声明了这个空间,或者可能这个内核超过了tmem所管理的限额。另一个例子是,如果tmem在压缩数据,就像zcache中做的那样,并且它认为压缩的数据页太大了,在这种情况下,tmem可能会拒绝掉没有充分压缩的或者甚至如果平均压缩率增大到不可接受的的页面。

      Frontswap的补丁集是一种非侵略性的,当frontswap被禁止掉的时候,它一点都不会影响swap子系统的行为。事实上,一个关键的内核维护者观察到,frontswap看起来是同swap子系统紧密结合在一起的。这是一件好事,因为现在的swap子系统的代码是非常稳定的,而且并不经常使用(因为swapping是如此之慢),但仍然是系统正确性的关键;对swap子系统的巨大改变可能并不明智,frontswap只是修改了它的边缘。

      一些实现的注意点:Frontswap要求开启swap的情况下每页1 bit的metadata。(Linux swap子系统直到最近要求16bits,现在要求每页8bits的metadata,因此frontswap增加了12.5%)这每页的1 bit记录了这个页面是在tmem还是在物理swap设备。因为,任何时候,可能一些页在frontswap中,另一些在物理设备上,swap子系统“swapoff”代码也要求做一些修改。并且因为使用tmem比swap设备空间更有价值,frontswap提供了一些额外的修改来达到可以执行“临时的swapoff”。当然,hooks在read-page和write-page中传输数据到tmem中,并且添加了一个hook用来当数据不再需要时可以被flush掉。补丁部分影响核心的内核组件合计少于100行。
    • Cleancache

      在大部分的工作负载下,内核从慢速的磁盘中取到页,当RAM还有足够的空间时,内核会在内存中保持大部分页的备份,因为假设磁盘中的页使用过一次就很可能会再次使用。当发生两次磁盘读写而又有足够的空闲RAM没有使用的情况是没有意义的。如果在它们当中的一页中写入任何数据,这么变化必须要写回磁盘,但是预期到未来的变化,页(清理过的)会继续保持在内存中。其结果是,在“页缓存”中的清洁页的数量频繁的增长而填满了绝大多数的内存。最终,当内存几乎被填满,或者如果工作量增大而需要更多的内存的时候,内核会“回收”一部分这样的清洁页,数据会被丢弃,页面可以被别的东西利用。没有数据会丢失,因为内存中的清洁页与磁盘中的相同的页面是一致的。然而,如果内核随后决定它确实需要那个页面的数据,它必须再次从磁盘中获取,这种情况叫做“refault”。由于内核不能够预期未来,一些被保持的页再也不会被用到,而一些被回收的页会很快的被“refault”。

      cleancache 允许 tmem 存储少数 rerault 时产生的清洁页缓存页面。当内核回收一个页,而不是丢弃该页面的数据,它把数据放入 tmem 中,标记为 “ephemeral”,这意味着当 tmem 关闭时页的数据可能被丢弃。随后,如果内核决定需要该页的数据,它会要求 tmem 返还此数据。如果 tmem 保留该页,它会返回此数据,否则,内核继续 refault 操作,像平常一样从磁盘中取回数据。

      为了正确的运行,cleancache的“hooks”被放置在页面被回收以及refault操作发生的地方。内核也必须要确保页缓存、磁盘以及tmem间的相干性,所以该hook也会出现在内核使数据无效的地方。由于cleancache会影响内核的VFS层,并且不是所有的文件系统使用到VSF的全部特性,文件系统必须选择是否使用cleancache当它挂载一个文件系统时。

      cleancache有一个有趣的地方:clean pages 可能会保存在tmem中但是在内核的页缓存中已经没有空闲的页面。因此内核必须为页面提供一个在整个文件系统中独一无二的名字(“句柄”)。在一些文件系统中,inode 节点号已经足够了,但是在现代的文件系统中,使用的是192位的“exportfs”的句柄。
    • Other tmem frontends

      一个常见的问题是:用户空间的代码是否可以使用 tmem ?例如,规避页缓存的企业应用是否使用 tmem。当前,答案是否定的,但我们可以通过实现“超内存”系统调用,来实现它。这样可能会产生一致性问题,能否在用户空间中解决这些一致性问题,还有待于研究。

      其它的内核应用是怎样的呢?有人提出,内核的 dcache 可以会为 tmem 提供一个有用的数据源。这也需要进一步的研究。
  4. Transcendent memory backends

    tmem 技术的接口允许多个前端运行在不同的后端之上。尽管将来可能会允许某种形式的层次结构的出现,然而当前,只可以设定一个后端。tmem 技术的后端拥有一些共同特征:一个 tmem 技术后端类似于一块阻塞设备,但它不执行任何I/O,也不调用任何阻塞I/O子系统。事实上,tmem 技术的后端的功能完全是同步的,即在它运行期间,不能进入休眠状态,也不能调用调度程序。当内核中一页的数据被复制后,一个“PUT”完成。当一页数据被复制到内核的数据页时,一个“GET”成功完成。当这些限制对 tmem 技术后端造成一些困难时,他们仍然会保证后端满足“超内存”技术接口的要求,同时对核心内核做出最少的修改。

    • Zcache

      尽管 tmem 被认为是一种在一组内存需求经常变化的客户机之间共享固定资源的方式,同时,在被一个单独内核用于存储N页数据的RAM容量小于N*PAGESIZE,并且这些数据只能以页的粒度进行访问时,也可以很好的工作。Zcache 同时包括了 tmem 实现和内存压缩,以减少 tmem 前端数据的空间需求。因此,在内存用量紧张时,Zcache 可以充分增加RAM中清理缓存与交换缓存的页数,以显著减少磁盘I/O的次数。

      Zcache 当前还是一个开发中的驱动,因此它是可变的;Zcache 可以同时处理持久页(来自于frontswap)与临时页(来自于cleancache),且这两种情况下,它都使用内核中的lzo1x程序压缩/解压缩页中的数据。用于持久页的空间是通过xvmalloc 片,开发中的ZRAM驱动中一个用于存储压缩页的内存分配器获得的。用于临时页的空间是通过内核调用get_free_page()获得的,然后使用一种称之为“compression buddies”的算法对压缩的临时页进行配对。这个算法保证了包含两个压缩的临时页的物理页框,在必要时能够顺利的回收。Zcache 提供了一种收缩策略,以便于那些能够被回收的页框,在需要回收时,由内核使用已存在的内核收缩机制。

      Zcache 很好的证明了 tmem 技术的可伸缩性特征之一:回想下,通常情况下数据可以很好的压缩(两种或多种情况之一),但仍然可能会产生没法很好地压缩的长序列数据。由于 tmem 技术在“put”的时候,可以拒绝任何页,因此Zcache策略可以避免存储这种压缩的不好的数据,而把它交给原始交换设备进行存储,以动态优化存储在RAM中的页的密度。

    • RAMster

      RAMster 仍然在开发中,但概念已经被验证。RAMster 假定系统之间拥有高速互联,专业说法是 "exofabric"。每台机器中都有部分内存被收集起来通过 tmem 做共享资源使用。集群中的每个节点既是 tmem 客户端也是服务端,每个节点可独立配置拿出多少 RAM 做共享。Thus RAMster is a "peer-to-peer" implementation of tmem

      理论上这有点像远程同步DMA,让一个系统去读/写另一个系统的RAM。最初的RAMster概念验证中使用的是一个标准的以太网连接。exofabric 传输速率远高于磁盘读写的速度,肯定能从中得到额外好处。

      有趣的是,RAMster-POC(RAMster概念验证)展示了tmem的一个有用的因素:一旦页面被置入tmem,在需要的时候,只要页面可以被重组,数据就可以以多种多样的方式转换。当页面被应用于RAMster-POC,他们首先被压缩并且使用一个zcache-like tmem backend来本地缓存。随着本地内存限制增加,一个异步的进程会尝试“remotify”页面到集群中另一个节点;即使该节点拒绝了这次尝试,只要本地节点能够跟踪到远程数据所在的位置,还可以尝试其它节点。尽管当前的RAMster-POC 无法实现这一点,但可以remotify很多份从而实现系统更高的可用性(例如,从节点故障中还原)。

      虽然RAMster中这种多层次机制在puts方面很好用,但当前针对gets并没有同样好用的机制。当一个tmem前端需要一个稳定的get时,数据必须被迅速且异步的获取到;请求数据的线程必须处于忙等待状态,并且调度程序没有被调用。因此现有的RAMster-POC对多核处理器是最合适的,其不寻常的机制可以使所有内核都同时处于激活状态。
    • Transcendent memory for Xen
      tmem最初就是为了Xen而构造的,所以其Xen实现是目前最为成熟的,在Xen中,tmem后端利用空闲虚拟层内存来存储数据,支持大量的 guest,并且可随意实现压缩与删除(一个 guest 内或者跨多个 guest)来扩大数据存储容量。tmem前端使用一个shim转换为Xen超级调用。单独用户可能会被使用“self-ballooning”和"frontswap-self-shrinking"组装(linux3.1下两个都存在)以优化其与Xen tmem的交互。Xen tmem同样支持共享短暂池,所以在同一个物理服务器上同地协作的 guest 共享一个cluster fs 时,只需要在tmem中保留一份cleancache page的拷贝。Xen控制层同样完全实现了tmem:一个大量的统计信息集;完全支持tmem-using用户数据动态迁移以及存储恢复,配额/“权重”或许会被应用与tmem用户以避免 DoS。
    • Transcendent memory for kvm
      在linux3.1中,包含在zcache中的in-kernel tmem代码已经更新以支持多重tmem客户端。有了这些代码,一个对tmem的KVM实现应该很容易就可以完成,至少是原型方式。像在Xen中那样,必须有一个shim置入guest以将cleancache和frontswap frontend calls转换为KVM的超级调用。在主机方面,这些超级调用将会需要协同in-kernel tmem的后端代码一起工作。想要在一个KVM发行版中使用这些,一些额外的控制层支持也是必要的。
    • Future tmem backends
      tmem的适应性和动态性表明它对于其它的存储需求和其它的后端计划可能是很有用的。一些RAM扩展的技术的特质,比如SSD和相变(PRAM)已经被认为可能是合适的。since page-size quantities are always used, writes can be carefully controlled and accounted, and user code never writes to tmem, memory ,以前这类内存技术只能被用作一个快速I/O的设备,现在可以作缓慢RAM。这些想法有的已经在调查研究中了。
Appendix A: Self-ballooning and frontswap-selfshrinking

当一个系统运行一段时间后,通常内存会被 clean pagecache 所占用。而那些使用tmem机制的系统,尤其是 xen,把页面放在 tmem 而不是 guest 内存中会很有意义。为了实现这个功能,xen实现了具有破坏性的“自我膨胀”。通过操作 xen ballon driver 来人工地创建内存压力,以回收页帧,从而强迫内核将页面发送到 tmem 。The algorithm essentially uses control theory to drive towards a memory target that approximates the current "working set" of the workload using the "Committed_AS" kernel variable. Since Committed_AS doesn't account for clean, mapped pages, these pages end up residing in Xen tmem where, queueing theory assures us, Xen can manage the pages more efficiently. 【编译者注:不太理解意义何在,可能和避免 OOM 有关系?】

如果工作集的增长速度出乎意料的快,超过了 self-balloon driver ,就需要提供可用的ram,交换页面。但是在大多数情况下,frontswap尽可能将那些交换页面进入到xen的tmem。然而实际上,内核交换子系统保证所有的交换在磁盘上发生,交换页面将保存在磁盘上好长时间,尽管内核知道这些页面可能不会在被使用。这样做的原因是因为磁盘成本低廉且可以重复写。假设这些页面放在frontswap上,将会占据很多有用的空间。

Frontswap-自我压缩技术用于解决这个问题:当frontswap活动比较稳健,以及客户机内核返回了一个状态,说明目前没有内存压力,根据这个压力删除在frontswap中的一些页面,使用一个叫”partial”的swapoff接口,返回信息给内核内存,来根据需要来释放tmem空间以供紧急需要。例如其他的客户机正处在内存饥渴态。

Appendix B: Subtle tmem implementation requirements

Although tmem places most coherency responsibility on its clients, a tmem backend itself must enforce two coherency requirements. These are called "get-get" coherency and "put-put-get" coherency. For the former, a tmem backend guarantees that if a get fails, a subsequent get to the same handle will also fail (unless, of course, there is an intermediate put). For the latter, if a put places data "A" into tmem and a subsequent put with the same handle places data "B" into tmem, a subsequent "get" must never return "A".

This second coherency requirement results in an unusual corner-case which affects the API/ABI specification: If a put with a handle "X" of data "A" is accepted, and then a subsequent put is done to handle "X" with data "B", this is referred to as a "duplicate put". In this case, the API/ABI allows the backend implementation two options, and the frontend must be prepared for either: (1) if the duplicate put is accepted, the backend replaces data "A" with data "B" and success is returned and (2) the duplicate put may be failed, and the backend must flush the data associated with "X" so that a subsequent get will fail. This is the only case where a persistent get of a previously accepted put may fail; fortunately in this case the frontend has the new data "B" which would have overwritten the old data "A" anyway.

Topic: sohulinux

网上闲逛看来的 freemium 商业模式的一些相关链接

  1. quora 上有人提问,MailChimp 现在估值有 1B 了吗?

    这个提问的人根据 MailChimp 的一篇 blog,估算出它的付费用户数,以及付费用户购买各个价位服务的比例,再根据网站上的报价,估算出它的收入水平。。。最后拿一个上市公司 Constant Contact 的财报数据对比,可以看到这两个公司的付费用户数和收入基本是相当的,最后从 CC 的市值推导出 MailChimp 的市值

  2. 正好前不久看到 MailChimp 收购某小公司的新闻,当时看了一下,MailChimp 就是做 EM + DM 的(我现在觉得 EDM 这个名字在中国已经被毁掉了),没想到它居然已经达到 1B —— 这个 sequoia 都认可的投资标准,于是又去研究了一下被引用的 blog

    这篇 blog 讲的是 MailChimp 探索 freemium 这种商业模式一年后的数据情况。我觉得凡是考虑免费用户转化为收费用户的企业都应该好好看看这篇文章

  3. 顺藤摸瓜,又找到 Why Free Plans Don’t WorkCase Studies in Freemium: Pandora, Dropbox, Evernote, Automattic and MailChimp

    看题目都很吸引人,尤其是 Pandora、Dropbox、Evernote,现在可都是资本市场的宠儿啊!

    啊啊啊啊啊啊啊啊啊啊啊!!!!

不管商业模式怎么样,最核心的还是要有漂亮的产品。Dropbox 和 Evernote 在 geek 圈中被推崇的程度就不说了;即使是 MailChimp,看看它的历史,已经成立了 10 年,70 位雇员,包括 4 个设计团队!!!

对于想做 EM + DM 业务的朋友来说,可以去 quora 追一下 Ben Chestnut,MailChimp 的 CEO

电视

我记得小时候家里有一阵子是没有电视机的。想起来这件事情还真很奇怪,因为同学家里几乎都有电视机,我家经济条件肯定算还不错的,而且曾经还有一台黑白来着,但就是不知道为啥就消失了,也一直不再买(也许当时知道原因,但不愉快的记忆被大脑强行抹去了),过了一段这样的时间,直到爸爸有回出国,带回来一台SONY 20寸彩电才结束去别人家蹭动画片的日子。(话说我老爹82年就去美国出差了,我现在还没有去过呢)

直到今天,我白天怒气冲冲的拔掉了有线同轴线缆,然后就出门上班;晚上回来问老妈当年的事情,老妈一乐,“还不是因为当年你们电视看得太多,影响学习,所以才送到老家去了”

看来事情总是在轮回哇。。。但说起来当年不看电视对生活也没啥不利影响,所以我家的政策先执行个一年半载吧。。。等高清节目普及了再说。:)

这个历史事件还有另外一种解读,就是老爸为了升级到彩电,来了这么一出捉放曹,以逃过预算监管。。。哇卡卡

Topic: dada

The MySQL “swap insanity” problem and the effects of the NUMA architecture

翻译:王鑫、朱翊然、李凯、曾怀东、马少兵、林业
时间:2010/09/28
原文地址

The “swap insanity” problem, in brief

在一台包括了2个4核CPU,64GB内存的服务器上,给 MySQL 配置了 48GB 之巨的 InnoDB 缓冲,随着时间的推移,尽管观察到的数据(见最后注1)表示并没有真正的内存压力,Linux 也会把大量的内存交换到磁盘上。通过监控发现,配置的内存超过了实际所需,而且也不存在内存泄漏,mysqld的RSS占用正常且稳定。

通常来说,少量的交换没有什么问题。但在许多情况下,真正有用的内存,尤其是InnoDB缓冲池的主要部分,会被换出。当它再一次被需要时,又会花费很大的性能将它换进,在随机的查询会引起随机的延迟。这可能会在运行系统上造成整体的性能不可预测性,而且一旦开始进行交换,系统可能就会进入性能的“死亡螺旋”。

虽然不是每个系统,或者每个工作负载都会经历这个问题,但是它已经足够普通以至于众所周知,而对于那些十分了解它的人来说,它可能会是一个最主要的麻烦。

The history of “swap insanity”

在过去的二到四年间,已经有过许多关于关闭还是开启Linux swapping和MySQL的讨论,这些总被称为“swap insanity”(我认为这是由Kevin Burton创造的)。我紧密关注这些话题,但是我并没有为此贡献很多,因为我没有添加任何新的东西。在过去的几年间,对此讨论作出主要贡献的是:

  • Kevin Burton — 讨论了Linux下的交换和MySQL。
  • Kevin Burton — 提出使用IO_DIRECT作为解决方案(并未解决)并且讨论了memlock(可能有所帮助,但仍然不是一个完整的解决方案)。
  • Peter Zaitsev — 讨论了交换,内存锁,并且在评论中进行了一系列的展开讨论。
  • Don MacAskill — 提出一个创新的方案来 swap 到 ramdisk,相关有很多有趣的讨论
  • Dathan Pattishall — 描述了禁止交换后的Linux的行为可能会更糟糕,并且提出了使用swapoff来清除它,但并未真正解决。
  • Rik van Riel on the LKML — 给出了一些回答并且提交了Split-LRU补丁
  • Kevin Burton — 讨论了Linux Split-LRU补丁的一些成功之处。
  • Mark Callaghan — 讨论了vmstat和监控方面的事情,并且回顾了一些可能的解决方案。
  • Kevin Burton — 更多地讨论了Linux Split-LRU是优秀的。
  • Kevin Burton — 通过开启了交换而选择了一种折中的方法,但是这样只有少量空间,而且放弃了这场斗争
  • Peter Zaitsev — 更多地讨论了为什么交换是糟糕的,但是依然没有解决方法。

尽管有这么多的这论,但是并没有带来太多的改变。有一些类似于“黑客式”的解决方法来使得MySQL停止交换,但是什么都不能确定。我已经了解这些解决方案和黑客式的手法一阵子了,但是核心的问题从来没有解决:“为什么会发生这?”还有它从来不适合我。我最近尝试去理顺这个问题,希望能够一劳永逸地解决它。因此到目前为止我做了大量关于这个问题的研究和测试。我学到了很多,我认为写一篇博客可能是会分享它的最佳途径。希望大家喜欢。

从几年前,已经有许多讨论和一些工作进入了加入相对较新的交换方法的调整的方面,我认为那可能已经解决了一些原始问题,但是此刻,机器的基础架构已经变为了NUMA,我认为这引入了一些新的问题,这些问题有着极为相似的症状,并且掩去了原始问题修订的成功。

对比SMP/UMA和NUMA两种架构

The SMP/UMA architecture

当PC领域最初拥有多处理器时,它们能够机会均等的进入系统中的所有内存。这叫做对称多处理器(SMP), 或者有时候叫统一访存架构(UMA,特意和NUMA进行对比)。在过去的几年中,每个 socket 上的单个处理器之间访问内存已经不再使用这种架构,但是在每一个处理器的多个核之间仍然盛行:所有的内核拥有均等的进入内存的机会。

The NUMA architecture

运行在 AMD OpteronInter Nehalem 处理器(见注2)上的多处理器的新的架构,叫做非匀称访存架构(NUMA),更确切的说是一致性缓存非匀称存储访问架构(ccMUMA)。在该架构中,每个处理器拥有一个“本地的”存储体,使用它可以较快的访问(延迟小)。整个的系统仍旧可以以整体的形式运行,从任何地方访问所有的内存,但是这样有潜在的高延迟和低性能的可能。

从根本上来说,“本地”的那些内存访问会快些,也就是说,可以比其他的地址(“远程”的和其他处理器关联的那些)以更小的代价访问。如果想得到更详细的关于NUMA实现的讨论以及它在Linux的支持,请去lwn.net上看 Ulrich Drepper 的文章

How Linux handles a NUMA system

当运行在NUMA架构系统上时,Linux会自动的知道这个事实,并且做以下的事情:

  1. 枚举硬件设施,用来得知物理的布局。
  2. 把处理器(并非内核)分成不同“节点”。对于现代的PC处理器,不考虑内核的数量的话,这意味着一个节点对应一个物理处理器。
  3. 将系统中的每个内存模块和它本地处理器的节点绑定在一起。
  4. 收集内部节点通信的代价信息(节点间的“距离”)。

你可以用numactl --hardware命令查看linux是怎么枚举你系统上NUMA的布局

# numactl --hardware
available: 2 nodes (0-1)
node 0 size: 32276 MB
node 0 free: 26856 MB
node 1 size: 32320 MB
node 1 free: 26897 MB
node distances:
node   0   1
  0:  10  21
  1:  21  10

输出结果里讲了这么几件事情:

  • 节点的数量以及这些节点的编号 — 这个例子中,两种节点被标识为0和1
  • 每个节点中可用内存的数量 — 一台双核计算机共有64G的内存,所以在每个节点上理论上可以分得32G内存。但必须指出的是,在这里并不是把64G的内存平均分配,这是因为每个节点的内核需要消耗一些内存。
  • 节点之间的“距离” — 它是从节点1访问节点0上的内存时,所付出的代价的一种表现形式。这个例子里,linux为本地内存声明距离为“10”,为非本地内存声明的距离为“21”

NUMA是如何改变 Linux 工作模式的

从技术层面来说,只要一切运行良好,UMA或者NUMA是没有理由在OS水平级上去改变运行方式。然而,如果要获得最好的性能,那么需要要做一些额外的工作,直接去处理NUMA底层的一些事情。如果把CPU和内存当作一个黑盒子,那么linux会做以下一些意想不到的事情:

  • 每一个进程和线程都继承成它们的父结点的 NUMA 策略。每个线程都可以修改成独立的策略。策略包括该进程/线程可在哪些 CPU 甚至内核上运行,从哪里的内存插槽上申请内存,以及上述两项限制有多严格
  • 初始化时,每一个线程都被分配到一个“首选”的节点上去运行。该线程可以运行在其他任何地方(如果策略允许),但是调度器试图保证它始终运行在首选的结点上。
  • 为进程分配的内存被分配在一个特定的节点上,默认情况下是“current”,这意味着相应的线程会首选在同一个节点上运行。在UMA/SMP架构上,所有的内存是一视同仁的,并且有相同的开销。但是系统如今已经开始考虑它从何而来,这是因为访问非本地内存对性能是有影响的,并可能导致高速缓存的一致性延迟。
  • 无论系统需不需要,分配到一个节点的内存肯定不会移动到另一个节点上去。一旦内存分配到一个节点上,那么它将一直留在那里。

使用numactl这样非常简单的程序,使得任何进程的NUMA策略都是可以改变的,具有广泛深远的影响。除此还能做些额外的工作,即通过链接到libnuma并写一些代码去管理策略,可以使其在细节上做些微调。简单的应用numactl已经可以做一些有趣的事情:

  • 用特殊的策略分配内存
    • 使用 current 节点 — using --localalloc, and also the default mode
    • 使用某个节点,但是如果有必要也能使用其他的节点 — using --preferred=node
    • 总是使用某个或某组节点 — using --membind=nodes
    • 交错使用(round-robin )所有节点 — using --interleaved=all or --interleaved=nodes
  • Run the program on a particular node or set of nodes, in this case that means physical CPUs (--cpunodebind=nodes) or on a particular core or set of cores (--physcpubind=cpus).

What NUMA means for MySQL and InnoDB

InnoDB以及其他所有数据库服务器( 包括 Oracle 在内),对linux来说都表现为非典型的工作负载(以大多数程序的角度):一个单一庞大的多线程进程消耗了系统几乎所有的内存,并且将会不断消耗系统剩余资源。

在基于NUMA的系统中,内存被分配到各个节点,系统如何处理这点不是那么简单。系统的默认行为是为进程运行所在的同一个节点分配内存,这种方式在内存量比较少的情况下效果不错,但是当你希望分配超过半数的系统内存时,这种方式即便只应用于单一NUMA节点,在物理层面上也变得不再可行:在双节点系统,每个节点中只有50%的内存。另外,由于大量不同的查询操作会同时运行在两个处理器上,任何一个单独的处理器都无法优先获取特定查询所需的那部分特定内存。

这显然非常重要。使用 /proc/pid/numa_maps 我们可以看到所有mysqld做的分配操作,还有一些关于它们的有意思的信息。如果你进行大量的查找,anon=size,你可以轻易的发现缓存池(它会消耗超过51GB的内存,超过了设置的48GB)

2aaaaad3e000 default anon=13240527 dirty=13223315
  swapcache=3440324 active=13202235 N0=7865429 N1=5375098

显示的各字段如下:

  • 2aaaaad3e000—内存区域的虚拟地址。实际上可以把这个当做该片内存的唯一ID。
  • default —这块内存所用的NUMA策略
  • anon=number—映射的匿名页面的数量
  • dirty=number —由于被修改而被认做脏页的数量。通常在单一进程中分配的内存都会被使用,变成脏页。但是如果产生一个新进程,它可能有很多copy-on-write pages映射(写时复制页),这些可能不是脏页。
  • swapcache=number —被交换出但是由于被交换出所以没有被修改页面的数量。这些页面可以在需要的时候被释放,但是此刻仍然在内存中。
  • active=number —在“激活列表”中的页面的数量;如果显示了该字段,那么部分内存没有激活(anon减去active),这也意味着这些可能很快被swapper交换出去。
  • N0=number and N1=number —节点0和节点1上各自分配的页面的数量。

整个numa_maps可以用一个简单的脚本 numa-maps-summary.pl 进行快速的总结,这个脚本是我自己编写用于分析这个问题的:

N0        :      7983584 ( 30.45 GB)
N1        :      5440464 ( 20.75 GB)
active    :     13406601 ( 51.14 GB)
anon      :     13422697 ( 51.20 GB)
dirty     :     13407242 ( 51.14 GB)
mapmax    :          977 (  0.00 GB)
mapped    :         1377 (  0.01 GB)
swapcache :      3619780 ( 13.81 GB)

我发现了两件有趣并出乎意料的事情:

  1. 节点0和节点1间内存分配的绝对不平衡。实际上根据默认策略这显然很正常。使用默认NUMA策略,内存优先分配给节点0,节点1被用作备份。
  2. 大量的内存被分配到节点0。这是关键 — 节点0用尽了空闲内存!它总共只有32GB内存,同时它分配了一个超过30GB的内存块放在InnoDB的缓存池中。一些其他进程分配的少量内存把剩余内存耗尽,此刻没有任何剩余内存也无法进行任何缓存。

下图显示的是MySQL数据库的内存分配图:

总体来说,Node 0几乎完全耗尽了空闲的内存,尽管系统有大量的空闲内存(将近有10G用于缓存)给Node 1.如果位于Node 0上的进程调度需要大量的本地内存的话,就会导致已经分配了任务的内存被交换,以满足一些Node 0页面的需要。尽管Node 1上存在大量的内存,但是在许多情况下(对这点,到现在我还不理解,见注3),Linux系统内核宁愿将Node 0上已分配任务的内存交换,也不愿使用Node 1上空闲的内存容量。因为页面调度远远比本地内存处理花销更大。

小变化,大效果
上述问题最容易的解决方案是交叉分配内存,运行:

# numactl –interleave all command

我们可以凭借将脚本mysqld_safe.sh只改动一行,在脚本中添加(cmd="$NOHUP_NICENESS"),使得在启动mysql命令前,启动numactl命令。该脚本为已添加(cmd="$NOHUP_NICENESS")命为的内容:

  1. cmd="$NOHUP_NICENESS"
  2. cmd="/usr/bin/numactl --interleave all $cmd"
  3. for i in  "$ledir/$MYSQLD" "$defaults" "--basedir=$MY_BASEDIR_VERSION"
  4.         "--datadir=$DATADIR" "$USER_OPTION"
  5. do

修改配置后,会发现当MySQL需要内存得时候,它将采用交叉分配的方式,给所有节点进行分配,使得每个节点都承载有效平衡的内存分配。同时也会在每个节点上留下一些空闲的内存空间,允许Linux内核在两个节点之间缓存数据,这种方式仅仅释放缓存的时候(当支持这种情况的时候工作),才允许任何一点节点内存容易释放,而不是页面调度的时候。

通过性能回归测试,我们已比较了两种情况下的性能,使用DBT2标准检测程序(本地内存+溢出内存----交叉内存),最终发现:在一般情况下的性能是等同的,这是可以预料的。突破发生在下面情况:使用交换的所有案例,在重复使用的情况下,系统不再发生交换。

你会看到所有采用numa_maps(NUMA: 非一致内存访问)分配的内存平均分布在Node 0和1上:

2aaaaad3e000 interleave=0-1 anon=13359067 dirty=13359067
  N0=6679535 N1=6679532

And the summary looks like this:

N0        :      6814756 ( 26.00 GB)
N1        :      6816444 ( 26.00 GB)
anon      :     13629853 ( 51.99 GB)
dirty     :     13629853 ( 51.99 GB)
mapmax    :          296 (  0.00 GB)
mapped    :         1384 (  0.01 GB)

图形表示就是这样

关于 zone_reclaim_mode 的一些题外话

配置 /proc/sys/vm 中的 zone_reclaim_mode 可以用来调整 NUMA 系统的内存回收策略。从 linux-mm 列表中的一些讨论表明,该配置对本例子不会改善。

一个更好的解决方案?

我觉得(也得到了linux-mm邮件列表的支持)一定还有更大的优化空间。尽管至今为止我任何的测试都没做。交错化分配是一个方法,如果它真的解决了这个问题的话,我想一个更好的方案就是,使用 libnuma 智能化对待 NUMA 架构。下边是一些涌现出来的想法:

  • Spread the buffer pool across all nodes intelligently in large chunks, or by index, rather than round-robin per page.
  • Keep the allocation policy for normal query threads to “local” so their memory isn’t interleaved across both nodes. I think interleaved allocation could cause slightly worse performance for some queries which would use a substantial amount of local memory (such as for large queries, temporary tables, or sorts), but I haven’t tested this.
  • Managing I/O in and out to/from the buffer pool using threads that will only be scheduled on the same node that the memory they will use is allocated on (this is a rather complex optimization).
  • Re-schedule simpler query threads (many PK lookups, etc.) on nodes with local access to the data they need. Move them actively when necessary, rather than keeping them on the same node. (I don’t know if the cost of the switch makes up for this, but it could be trivial if the buffer pool were organized by index onto separate nodes.)

我不知道以上的想法是否有哪些真的可以在一个真实系统中展现出特别优点,但是我很希望能得到评论或者其它的观点。

====== 这是华丽丽的分割线 =========

Topic: sohulinux

又一次被 Amazon 震惊了

昨天在 HN 上看到这样一篇文章:The quick website launch checklist

别的都还罢了,什么 pagespeed, pingdom 之类;就是 usability testing 这个服务我觉得很诧异,于是点开 feedbackarmy.com——

这个服务也很简单,交15美元,提出若干个关于可用性的问题,然后这个网站返回给 10 个答案。。。

向被测者提出问题的模板如下:

  • 你觉得我这个网站是干嘛的?
  • 这个网站的哪一部分让你特别困惑?
  • 做些什么可以让这个网站更易用?
  • 你感觉这个网站的核心功能是怎么运作的?

对于一个新上线的网站而言,要是花100块钱就能得到10套这样的忠告,我觉得真是物超所值极了!!

但现在我真正好奇的是 feedbackarmy.com 是怎么工作的,于是发现了 mturk,一项 Amazon 的业务。。。很容易想到“众包”甚至“金币工人”诸如此类。。。但 Amazon 真正牛逼的地方在于它把这个做成了 API,这样类似 feedbackarmy 这样的企业可以把这类资源开发出新型的应用出来并且赚钱(想想那个估值已经60亿的Dropbox罢)

人类已经无法阻止 Amazon 了

再看看 feedbackarmy 说为什么我们应该购买它的服务而不是直接找 mturk:

你当然可以这么干! 做到以下几点就行:

  • 申请一个 AWS 账号
  • 想清楚打算花多少钱 (也别忘了 Amazon 还会抽一部分成)
  • 预付款
  • 建立一个“人工智能”任务模板
  • 发布任务
  • 不停刷新页面,并寻找答案(点击浏览器refresh按钮真的很有乐趣哦)
  • 评估答案,并且为你的工作者付款(否则他们不会再鸟你接下来的请求)
Topic: 商业

MySQL 5.6 的 binlog API 很不错

MySQL 5.6 开始,开发者可以通过编程获得 binlog 内容,通过这个 API 可以做很多事情,比如自制备份,比如....

http://intuitive-search.blogspot.com/2011/07/binary-log-api-and-replication-listener.html

这样做搜索更加简单了,对于开发者来说只有 SQL 操作;自动建索引这件事。。。交给MySQL的某个'伪'复制节点自动完成,不需要再编程了!

Topic: 技术

数据仓库

July 20, 2011
This article was contributed by Josh Berkus
Data Warehousing
翻译:马少兵、曾怀东、朱翊然

尽管服务器存储、处理能力得到有效的提高,以及服务器价格的降低,让人们能够负担起大量的服务器,但是商业软件应用和监控工具快速的增加,还是使得人们被大量的数据所困扰。在数据仓库领域中的许多系统管理员、应用开发者,以及初级数据库管理员发现,他们正在处理“海量数据”-不管你准备与否-都会有好多不熟悉的术语,概念或工具。已知该领域大约有40多年的历史,广为人知。这篇文章ss对那些想去了解该领域的人来说是一个起点。

什么是数据仓库呢?

数据仓库不等同于“海量数据”;恰恰相反,而是其子集。海量数据也包含:通过大量的连接提供每秒百万次服务请求的系统,例如Amazon的Dynamo database。数据仓库一般指的是:在相当长的时间内堆积数据,仅仅需要处理大量数据请求中的少部分的系统。

数据仓库真正的答案之一:三种不同的问题--组织归档,数据挖掘或分析。有时它回答了三个结合。

  1. Archiving
    “我想在相当长的时间内存储大量数据,可能对其从不进行任何查询服务”。

    由于HIPAA法案、奥克利斯法案、第8公司法以及其他相关法律,归档成为非常流行(或者、至少、必须)的一种数据。它也被叫做“WORN” (写数据后,从不去读) 数据。公司积累了大量他们不想要的数据,但是却不能扔掉,从理论上来说,数据需要在合理的时间内要去访问。存储的大小范围从GB到TB。

    这种归档系统其中一个非常好的例子是:我帮Comptel and Sun Microsystems建造的关于欧洲手机呼叫完成数据。每个城市呼叫完成数据大小为75TB,可以预料,每周每一个数据库应至少应答一条信息请求。这就允许我们使用非常便宜的PostgreSQL数据库、Solaris和压缩文件系统的组合。

    如果你想建立一个文档服务器,你仅仅的需求是:花费最少的存储成本和确保文档服务器和当前数据同步。一般地,这意味着需要对数据进行压缩、以及一个能够稳定工作非常廉价的硬盘驱动器的数据库或者是磁带库。查询的速度和其他特性不是关心的事情。有趣的是,这是数据库的一种类型,但是却没有很好的开源解决方案。

  2. Data mining
    “我一天堆积了1GB的数据,知道其中有有用的信息,但是不知道那些是。”

    数据挖掘是数据仓库中一种非常普遍的类型;大多数的公司或网站产生很多副作用的数据,然而大多数的公司或者网站不清楚如何利用这些数据,仅仅知道他们有时候会用到这些数据。更可悲的是,我们对这些大量数据的结构和意义却完全不了解;这些数据可能是完整的文档,未知的字段,以及不明确的分类。数据大小一般是从TB到PB。这常常被称为“半结构化”数据。

    Web流量数据分析可能是数据挖掘中的一个最经典的例子。作为结构化和消息文本的混合形式的数据,一般来自web服务器的日志和cookies。 公司收集这些信息,因为他们想在不使用数据库的情况下,通过这些数据逐渐地建立一个查询的集合和报告,来获取趋势数据。

    在数据挖掘解决方案中,最想得到的数据是在高效和快速的情况下,获得CPU的性能和I/O高性能的检索、分类和计算效率。或者,基于多处理器或者多服务器上的并行计算,是最好的结果。对于第二个关注点,数据挖掘数据库常常不得不以每分钟1GB的高速率接受数据。

  3. Analytics
    “我有大量高度结构化的数据,我希望用这些数据生成可视化的结果来帮助商业决策。”

    商业活动通常也会产生他们自己很了解的数据:销售数据,客户账户和调查数据。他们希望利用这些数据生成可以策略性地使用的表格,图表和其他好看的图像。这种数据系统有不少形式,包括分析,business intelligence (BI),决策支持(DSS)以及在线分析处理(OLAP)。

    我曾经使用来自Point Of Sale (POS) 系统的连锁销售数据部署过这类系统中的两个。POS数据几乎完全由数值,库存ID以及分类树组成,所以它能够创建按类别,时间和地理分类的图表。没有什么必要对这样的数据进行挖掘,因为它已经非常容易理解,而且分类计划的变化很频繁。

    大量分析系统功能都集中在分析中间件工具上。用于分析的数据解决方案都是关于大量数据聚合的。像“cubes”(稍后解释)这种支持,对高级分析很有用,这是因为数据被压缩并索引。数据通常通过夜间的批处理导入系统,所以读取方面的快速响应时间没那么重要。

五种类型的数据库

目前市场上,解决数据仓库的这三个基本问题的主要有五种不同类型色数据库系统。这些系统经历了几十年的软件开发。当然,现实生活中的许多大型数据库系统实际上是由以下五种类型混合而成,但我将根据其主要类别列出例子。

  1. 标准关系型数据库

    如果你只有几十或者上百G的数据,标准主流的关系型数据库仍旧是一个的选择。不管你的选择是 PostgreSQL, MySQL, Oracle, 还是 SQL Server,它们都很成熟,灵活而且有大量第三方和厂商的工具可供使用。或许更重要的是,技术人员已经对它们非常熟悉了。

    我为一个小型的连锁零售商的库存管理系统部署了一个分析型数据仓库。最初我们考虑把它设计成一个专有的大型数据库,但是后来我们发现这个数据仓库的最大容量为350G.鉴于此,我们决定采用主流开源的 PostgreSQL,这样一来节省了资金和时间。

    标准的关系数据库在数据归档,数据挖掘以及数据分析这些方面都不突出。但是,它们可以胜任所有这些任务。所以如果你的数据仓库问题规模比较小或者不是对响应时间要求严格,它们可以作为一个选择。

  2. MPP 数据库

    MPP数据库是最早为数据仓库设计的数据库,它诞生于20年前。MPP代表“massively parallel processing”,也就是一种单一的查询在多台机器或多个主板上的多处理器执行的关系数据库。数据库管理员喜欢这种类型的数据库,因为他可以把这种数据库当作一个有一定限制的又大又快的关系型数据库服务器。MPP数据库包括 Teradata, Netezza, Greenplum, 以及DB2的数据仓库版。

    当我在Greenplum工作的时候,我建立了多个“分析点击量”的数据库,在这些数据库中我们为营销公司处理大量的网络日志数据。我们在日志中没有办法知道我们将会看到什么,甚至网站的页面结构。我们不得不做许多CPU密集型处理:解析文本的聚集,运行自定义数据库函数,并建立实体化的视图,16节点的Greenplum数据库是相当快的。

    MPP数据库适用于数据挖掘和分析。其中一些—尤其是Greenplum—也混合了列表中的其他数据库类型。然而,迄今为止,所有产品级的MPP数据库是专有的,任何真正的大数据库通常都非常昂贵。

  3. 基于列的数据库

    在1999年发明,列存储数据库致力于改变用于关系型数据库或者“基于行”的数据库的基础存储模型。在基于行的数据库中,数据存储在属性的连续行中,列通过表的元数据相关。列存储数据库把这个模型转了90度,把列的属性存储在一起,而只通过元数据关联行。这允许了不少的优化,包括各种形式的压缩和非常快的聚合。

    当前的列存储包括 Vertica, Paraccel, Infobright, LucidDBMonetDB. 其中Vertica或许是领先的列存储数据库,后面三个是开源的。此外,一些其他类型的数据库,包括 Aster Data和Greenplum,已经将列存储作为一个选项加入其中。

    我们的客户端之一是为一些TB级别的医院绩效数据创建顶层的射线图表。由于所有的这些数据是数字,评级或者保健类别,Vertica被证明是一个很好的解决方案,它用比标准的关系数据库少得多的时间里返回顶层摘要。

    列存储仅适合于分析,因为所有的数据必须可以很好的被理解,高度的结构化而被存储于压缩的列中。列存储对于数据有很好的效率,可以减少数字和类别列表的数据。它们主要的缺点是更新或者导入数据缓慢,单行更新基本不可能。

  4. MapReduce

    数据仓库的下一个创新是google在不到十年前推广的MapReduce框架。MapReduce是一个算法,当伴随着集群工具,它允许你把单一的请求分为若干小的部分,然后执行于数量巨大的服务器阵列中。当与某种形式的集群或者散列分区存储结合的时候,MapReduce允许用户在数十到数百个节点上执行大量的,长时间运行的请求。Hadoop是占有绝对主导地位的MapReduce框架。当前的基于MapReduce的数据库包括 Hadoop with Hbase, Hadapt, Aster Data, 以及 CouchDB

    在一个项目中,客户需要运行30TB JSON和二进制混合的数据的请求。因为二进制数据的搜索程序是处理器密集型的,它们把这些数据放到HBase并且用Hadoop运行许多的处理程序,把查询结果存储于PostgreSQL中,方便以后的浏览。

    在许多方面,MapReduce是开源的,能够替代MPP数据库,而且主要适用于数据挖掘。它可以扩展到较大数量的节点。然而由于它的通用性质,MarReduce在查询方面比MPP低效多了,也更难写了。多亏了诸如 HivePig 这样的工具修正了这样的缺点,它们让用户用类似SQL的语法写MapReduce查询。此外,MapReduce数据库比前面的三种要年轻许多,使得它们可靠性和文档化相对差点。

  5. Enterprise search

    数据仓库中的“新人”是企业搜索。它仅仅包括了两个开源的产品,它们两个都是Apache Lucene项目的后代:SolrElastic Search(ES)。企业搜索包括以文件形式在大量的半结构化数据上做多服务器分区索引。二者也都支持“facets”,它是实体化的搜索索引,允许用户通过类别,值,范围和复杂的搜索表达式快速的计算和搜索文档。企业搜索也往往给人“近似”的答案,它可以是一个功能或缺陷,这取决于你的设计目标。

    企业搜索在一些令人惊讶的地方是有用的。我们有一个客户端,使用它可以让它们的客户端在非常庞大的法律文件中产生细致入微的汇总统计。把它们放入Solr允许客户端跳过他们需要运行的数据程序而把它放入其他种类的数据库中,同时仍然给它们快速的搜索结果。特别是,Solr索引的预处理计数允许返回文档计数的速度远远超过关系数据库。

    企业搜索服务是数据挖掘和分析的一个子集,这使得它具有广泛的用途。它的最大价值发挥在待搜索的数据已经是HTML,XML或者JSON格式的时候,这样不用在索引之前转换或者变换格式。然而,它是最年轻的数据库类型,这两种产品仍旧有许多可靠性问题以及令人惊讶的局限性。此外,数据库请求仍然和“搜索”模型紧密的结合,这让它很难被用在不同的使用情况下。

其它工具

作为所有数据仓库工程的一部分,你同样将需要一些其它的工具,这些工具可以从源中获取数据从而完成你的报告或者接口。鉴于我无法更详细的叙述他们,下边仅罗列出一些你需要知道的工具

加载(Extract Transform Load/ETL)和数据集成工具:这些工具从初始源中获取最终成为数据库格式的数据。代表性的开源加载工具有 TalendKETTLE,而且有许多类似 Informatica 的专属工具。在现代化的基础设施中,像 ActiveMQRabbitMQ 的开源工具队列平台,许多应用程序所应用的ETL工具正在被自定义代码所取代。

数据挖掘和数据分析工具:像WekaSAS,以及R language中各式各样的项目所提供的从大量的无序数据中获取意义的高级工具。它们帮助你通过统计学分析和机器学习算法找到你的数据中所存在的模式。在这个领域内,Weka以及R这些开源工具居于行业之首,专有工具主要是用于一些遗留的应用。

报表工具:鉴于你需要展示你的数据,你会需要像 BIRT, JasperReports 这样的报表工具,或者像Business ObjectsMicroStrategy 这样的专有平台。这些工具可以提供你的数据以简单的可视化效果,通常是很有交互性的图表和图形格式的。近来,这两大代表性的开源工具在易用性方面与专用工具展开了竞争,但是这恐怕要花费他们一些时间去突出他们的特性。

在线分析处理(OLAP):一个欺诈性的名字总是有很多的事情去做,使用“cubes”提供一个基于导航的用户界面去探索你的数据。OLAP工具,像MondrianCognos,以及 Microsoft Analysis Services创建了一个数据的多维空间图,它可以让用户通过在其内不断移动来查看数据的不同部分。这是开源工具十分落后的一块领域;相比于Oracle和SQL Server,开源数据库的OLAP支持就比较弱,Mondrian是仅有的开源OLAP中间件。

我同样需要提及Pentaho,一种集成了所有开源ETL,数据挖掘,报表工具的开源平台。

总的来说,对于所有级别的数据仓库栈都有开源工具,但是这些工具与其竞争对手相比,经常不太完备并且缺乏特性。但是,如今,在分析与数据挖掘领域拥有最先进技术的是开源界,很有可能在将来的3到5年,它们将会达到一个平衡。

结论

现在你应该对数据仓库领域有了比较深的了解,特别是从数据库角度。我们无法深究这些话题的细节或者工程和项目,至少你知道从哪里开始搜索,并且对于每个数据仓库领域都有许多的工具。同样,你可以在最近的波特兰的 Open Source Bridge conference上以视频格式来看这些材料。

Topic: sohulinux

Xapian 如何发音?

很久很久以前,bluetent 同学还在 zhanzuo.com 的时候,就开始研究这个"虾片"。

最近 bbs.sohu.com 又开始鼓捣这个东西,还是叫它"虾片"。不过现在偶的英文水准又有提高,于是就纠正他们,这么发音绝对不靠谱..

先灌输一个常识,X 打头的英文单词,该怎么发音呢?

生活中很少见到 X 开头的词,即使碰上了,也未必有专业人士告诉你如何发音。。。幸好我碰到过两个这样的人:

  1. 一个是我老婆,告诉我 Xerox (那个很有名的复印机厂商,虽然中国人只知道它叫施乐)发音是 [ˈzɪˌrɑks] ,惹若克斯

  2. 一个是yuhj,告诉我 Xircom (有好几年,我的 vaio 笔记本一直靠这个牌子的 PCMCIA 卡来提供 RJ-45 网络连接)发音是 "惹康姆"

举一反三,于是当摩托罗拉的平板上市的时候,搜狐微博上有人说不知道 Xoom 怎么发音,我很得意的回复——肯定就是 Zoom (据说Mot内部还喊它叫 Mo-pad)

搜索一下 "pronounce xapian",进入 Xapian FAQ。。。正确的读音是 Zap-ian,发音模式蛮类似 Deb-ian 的...

当然,发音成 Zay-pian 也很流行,宅男们除了"A片",玩玩"Z片"也不错

Topic: 技术 文化

时间节奏

中午和方军一起吃饭,说起公司的氛围问题,我这样看:


搜狐这样的企业和startup完全不一样。创业的人一方面是有长期奋斗的心态——通常一个公司从白手起家到上市怎么也得5年以上的时间;另一方面还有按天来计量的节奏——可能明天公司就会倒闭。。。但搜狐呢,总体上都是按照每个季度PM的周期在运作

写出来激励一下自己的状态

Topic: 商业
订阅 RSS - 博客 | BT的花