大数据存取的选择:行存储还是列存储?

上个月参加了一个云存储的技术讨论会。这一个月里,陆续收到几位同学讨论大数据保存和处理的邮件。今天是周末,索性把这个月的交流内容整理写下来,供各位参考。

目前大数据存储有两种方案可供选择:行存储和列存储。业界对两种存储方案有很多争持,集中焦点是:谁能够更有效地处理海量数据,且兼顾安全、可靠、 完整性。从目前发展情况看,关系数据库已经不适应这种巨大的存储量和计算要求,基本是淘汰出局。在已知的几种大数据处理软件中,Hadoop的HBase 采用列存储,MongoDB是文档型的行存储,Lexst是二进制型的行存储。在这里,我不讨论这些软件的技术和优缺点,只围绕机械磁盘的物理特质,分析 行存储和列存储的存储特点,以及由此产生的一些问题和解决办法。

一.结构布局

行存储数据排列

列存储数据排列
 

表格的灰色背景部分表示行列结构,白色背景部分表示数据的物理分布,两种存储的数据都是从上至下,从左向右的排列。行是列的组合,行存储以一行记录 为单位,列存储以列数据集合单位,或称列族(column family)。行存储的读写过程是一致的,都是从第一列开始,到最后一列结束。列存储的读取是列数据集中的一段或者全部数据,写入时,一行记录被拆分为 多列,每一列数据追加到对应列的末尾处。

二. 对比

从上面表格可以看出,行存储的写入是一次完成。如果这种写入建立在操作系统的文件系统上,可以保证写入过程的成功或者失败,数据的完整性因此可以确 定。列存储由于需要把一行记录拆分成单列保存,写入次数明显比行存储多,再加上磁头需要在盘片上移动和定位花费的时间,实际时间消耗会更大。所以,行存储 在写入上占有很大的优势。

还有数据修改,这实际也是一次写入过程。不同的是,数据修改是对磁盘上的记录做删除标记。行存储是在指定位置写入一次,列存储是将磁盘定位到多个列 上分别写入,这个过程仍是行存储的列数倍。所以,数据修改也是以行存储占优。 数据读取时,行存储通常将一行数据完全读出,如果只需要其中几列数据的情况,就会存在冗余列,出于缩短处理时间的考量,消除冗余列的过程通常是在内存中进 行的。列存储每次读取的数据是集合的一段或者全部,如果读取多列时,就需要移动磁头,再次定位到下一列的位置继续读取。 再谈两种存储的数据分布。由于列存储的每一列数据类型是同质的,不存在二义性问题。比如说某列数据类型为整型(int),那么它的数据集合一定是整型数 据。这种情况使数据解析变得十分容易。相比之下,行存储则要复杂得多,因为在一行记录中保存了多种类型的数据,数据解析需要在多种数据类型之间频繁转换, 这个操作很消耗CPU,增加了解析的时间。所以,列存储的解析过程更有利于分析大数据。

三. 优化

显而易见,两种存储格式都有各自的优缺点:行存储的写入是一次性完成,消耗的时间比列存储少,并且能够保证数据的完整性,缺点是数据读取过程中会产 生冗余数据,如果只有少量数据,此影响可以忽略;数量大可能会影响到数据的处理效率。列存储在写入效率、保证数据完整性上都不如行存储,它的优势是在读取 过程,不会产生冗余数据,这对数据完整性要求不高的大数据处理领域,比如互联网,犹为重要。

改进集中在两方面:行存储读取过程中避免产生冗余数据,列存储提高读写效率。

如何改进它们的缺点,并保证优点呢?

行存储的改进:减少冗余数据首先是用户在定义数据时避免冗余列的产生;其次是优化数据存储记录结构,保证从磁盘读出的数据进入内存后,能够被快速分 解,消除冗余列。要知道,目前市场上即使最低端CPU和内存的速度也比机械磁盘快上100-1000倍。如果用上高端的硬件配置,这个处理过程还要更快。

列存储的两点改进:1.在计算机上安装多块硬盘,以多线程并行的方式读写它们。多块硬盘并行工作可以减少磁盘读写竞用,这种方式对提高处理效率优势 十分明显。缺点是需要更多的硬盘,这会增加投入成本,在大规模数据处理应用中是不小的数目,运营商需要认真考虑这个问题。2.对写过程中的数据完整性问 题,可考虑在写入过程中加入类似关系数据库的“回滚”机制,当某一列发生写入失败时,此前写入的数据全部失效,同时加入散列码校验,进一步保证数据完整 性。

这两种存储方案还有一个共同改进的地方:频繁的小量的数据写入对磁盘影响很大,更好的解决办法是将数据在内存中暂时保存并整理,达到一定数量后,一 次性写入磁盘,这样消耗时间更少一些。目前机械磁盘的写入速度在20M-50M/秒之间,能够以批量的方式写入磁盘,效果也是不错的。

四. 总结

两种存储格式各自的特性都决定了它们不可能是完美的解决方案。 如果首要考虑是数据的完整性和可靠性,那么行存储是不二选择,列存储只有在增加磁盘并改进软件设计后才能接近这样的目标。如果以保存数据为主,行存储的写 入性能比列存储高很多。在需要频繁读取单列集合数据的应用中,列存储是最合适的。如果每次读取多列,两个方案可酌情选择:采用行存储时,设计中应考虑减少 或避免冗余列;若采用列存储方案,为保证读写入效率,每列数据尽可能分别保存到不同的磁盘上,多个线程并行读写各自的数据,这样避免了磁盘竞用的同时也提 高了处理效率。 无论选择哪种方案,将同内容数据聚凑在一起都是必须的,这是减少磁头在磁盘上的移动,提高数据读取时间的有效办法。

  

关于作者:

袁萌,现就职于国际商用机器(IBM)中国有限公司,主要从事大规模数据产品的设计/开发工作,存储数据高可用性以及数据生命周期管理,积攒了大量的设计及工作经验。专注于金融、电信、制造等大型数据中心存储架构设计。对业界主流的云储存产品以及技术有着深刻的认识。

文/InfoQ

少即是极多 – Go 语言设计理念

这是一篇翻译练习。力图保留原意。若有不准确处,求速速指出。猛击此处(墙)看原文。作者为Rob Pike,贝尔实验室来的大牛,现在就职于Google。他主导了Go语言的创建工作。下面是正文——

——————————————正文分隔线——————————————

这是我在2012年6月的Go SF上演讲的文本。

这是一个个人演讲。 我承认,虽然面前的团队让Go诞生并延续,但是我的观点并不代表任何其他Go语言小组成员的意见。 我也想感谢Go SF的组织者提供这个和你们交流的机会。

几星期前我被问起:“你在推出Go的过程中遇到的最大的惊奇是什么?”我立即意识到了答案: 虽然我们希望C++程序员意识到Go是个较好的选择,但是令人意外的是,大多数Go程序员来自Python和Ruby这样的动态语言,而很少有来自C++的。

我们——Ken,Robert和我——是C++程序员(译者: Ken也用C++?),当时在为解决我们所写的这类软件产生的问题设计一个新的语言。 这似乎有点自相矛盾,因为别的C++程序员根本不关心这些问题,更不会去设计一个语言。

我今天想说的是关于那些激发我们创造Go的事情,和为什么它本不应令我们如此惊讶。 我保证这些内容更多与Go相关而不是C++,所以即使你不很了解C++你也能跟得上。

回答可以这样归结: 你认为”少即是多”呢,还是”少就是少”?

这里有个比喻,将以真实故事的形式给出。 贝尔实验室中心原来发放3位数号码: 物理研究是111,计算科学研究是127,如此这般。 1980年代早期,一个便笺飞过来说”鉴于你们对研究的理解有所加深,将为你们的号码多加上一位,以便更好地体现你们的工作”。 所以我们中心的号码变成了1127。 Ron Hardin半当真地开玩笑说如果我们真的理解我们的世界更好一点的话,我们将丢掉一位数字,将127变成27。 当然主管没听到这个笑话(这也不是我们希望的),但是我想这里面有点值得思考的东西。 少即是多。 你理解得越好,你将变得越简洁。

 

先记住这句话。

回到2007年9月,我在做一个庞大的Google C++项目的细微但核心的部分。 开发必须交互进行,但是我这部分在我们的Google编译集群上要编译45分钟。 同时,有个消息传过来说一群在C++社区的Google员工将开一场讲座,介绍即将到来的C++0x(现在称为C++11)。

在那场持续一小时的讲座中,我们听说了诸如计划中的35个新特性的说法——事实上还有更多,但是那场讲座只说有35个。 有些特性当然是细微的,但是讲座中谈到的至少是足够重要的。 提到的特性中,有些十分微妙并难以理解,比如右值引用(rvalue references); 有些特别符合C++范儿,比如可变参数模板(variadic templates); 还有些十分疯狂,比如用户定义的字面量(user-defined literals)。

那时候我问了自己一个问题: C++社区真的觉得C++错在没有足够多的特性么? 显然,从Ron Hardin的笑话的角度看,简化语言将比添加新特性取得更好的效果。 当然,对C++来说这很不靠谱,但是先记住这点。

在这场讲座的几个月之前我做了一场讲座(你可以通过YouTube看到),讲的是一个我1980年代做的一个玩具并发编程语言。 这个语言叫Newsqueak,而且显然地,它成为了Go的前身。

在我在Google工作的过程中,我发现我丢掉了Newsqueak中的一些点子。 现在我将重新思考它们,所以我才做了那场讲座。 我相信它们会让服务器端编程变得更容易,而且Google能真正从中获益。

我真的尝试将这些点子加入到C++中,可惜失败了。 我实在难以将一组并发操作融入到C++的控制流程中去——当真融进去的话,它们将变得十分丑陋,从而难以看到优越性。 另外,C++将它变得十分臃肿(虽然我从来没真正发现C++苗条过)。 所以我放弃了这个想法。

但是C++0x的讲座使我再次思考。 一件事十分困扰我——我相信也困扰着Ken和Robert——C++的新内存模型居然新增了原子类型。 为这个不堪重负的类型系统加上这么个细致精巧到极致类型机制十分的不靠谱,不是么? 将语言和今日的硬件绑在一起似乎有点目光短浅并且不明智,因为硬件过几年就有大变。

那场C++0x讲座结束之后,我们回到办公室。 我开始了另一个编译(译者笑),转过转过我的椅子,面对Robert,然后开始问一些尖锐的问题。 在编译完成之前,我们拉拢了Ken,并决定做些什么。 我们再也不想写C++了,并且我们——尤其是我——在写Google代码时,想让并发拿来就用。 同时我们也想解决”大系统编程”的问题,容后细说。

我们在白板上写下一组我们需要的东西——迫切需要的那种。 我们规划出大体的轮廓,忽略了语法细节和语义。

我仍然有一条碉堡了的那周的邮件线索。 这是一些摘录:

Robert: 起点: C,修补一些显而易见的瑕疵,去除繁杂的东西。 新增一些特性。

Rob: 命名为’go’。 你可以为这个名字编造各种理由,但是它确实拥有很多好的特性。 它短小,易于打出。 工具么: goc,gol,goa。 如果有个交互式调试器/解释器,可以直接叫’go’。 代码后缀是。go。

Robert: 空接口: interface {}。 将被所有接口实现(译者: 原文如此),并且可以取代void*。

我们并没有立即全部设计出来。 比如我们花了一年多才设计出了数组(array)和切片(slice)。 不过相当一部分重要的设计在最初的几天中浮现。

注意到Robert说C是起点,并非C++。 对于这点我不是很确定,不过我相信他说的是C,因为Ken在场(译者笑)。 但是最后我们并没有从C开始,这倒是真的。 我们从最初的草稿开始,仅仅从其它语言中借鉴琐碎的东西,比如运算符,各种括号和一些常见的关键字。(当然我们也借鉴了我们所知道的语言中的思想。)不管 怎么说,我们破而后立,从头做起,以此来响应C++。 我们并非想做一个更好的C++,甚至不是一个更好的C。 它仅仅是一个对我们所关心的软件来说更好的语言。

最后,我们得到了既不同于C也不同于C++的东西,甚至比许多人意识到的还要不同。 我列了一个对于C和C++的Go的重要的简化的列表:

  • 常规的语法(不需要一个符号表来辅助解析)
  • GC机制(仅仅是GC)
  • 没有头文件
  • 显式依赖关系
  • 没有循环依赖
  • 数字常量仅仅是数字(译者: 没有类型)
  • int和int32不是同种类型
  • 字母大小写将确定可见性
  • 任何类型都可以有方法(没有类)
  • 没有子类型继承(没有子类)
  • 包级别的初始化和良好定义的初始化顺序
  • 同一个包的文件一起编译
  • 包级别的全局定义可以以任意顺序进行
  • 没有算术类型转换(常量可以弥补)
  • 接口是隐式实现的(没有”implements”声明)
  • 嵌入的结构体(没有类型提升和子类)
  • 方法像函数一样定义(不必定义在特殊的地方)
  • 方法就是函数
  • 接口就是方法(没有数据)
  • 方法仅仅靠名字匹配(不是靠类型)
  • 没有构造函数和析构函数
  • 后置增量/减量运算符仅仅是语句,而不是表达式
  • 没有前置增量/减量运算符
  • 赋值号是语句,不是表达式
  • 表达式求值顺序在赋值和函数调用时确定(没有所谓的”sequence point”)
  • 没有指针算术
  • 内存总是初始化为0
  • 对本地变量取地址是合法的
  • 方法中没有叫this的指针
  • 分段式栈
  • 没有常量或其它类型的注记
  • 没有模板
  • 没有异常
  • 内建字符串,切片和映射(map)
  • 数组边界检查

并且,我相信通过这一系列的简化,Go将比C或C++更具有表现力。 少即是多。

但是我们没法一下子把所有部分都做出来。 我们需要构建最基础的部分,比如说类型系统的表示,能良好应用于实际的语法,和一些无法形容的但能让库更容易相互操作的东西。

我们同样增加了C或C++中没有的东西,比如切片和映射,组合字面量(?),文件顶层的表达式(这虽是件大事,但是几乎不为人知),反射机制,GC等等。 自然,还有并发。

一个显眼的缺少的东西是类型的继承。 请允许我粗暴地对待它一分钟。

早先构建Go的时候有人跟我说,他无法想象用一门没有泛型的语言工作。 正如我在别处说明的那样,我觉得这是个很诡异的言论。

公平起见,他用自己的话说可能是他真的很喜欢C++中STL的那些容器。 以辩论为目的的话,我们来正面看看他的言论。

他说的意味着: 他发现写一个容器,比如以int为元素类型的链表,或字符串映射是一种不能忍的重负。 我发现这是个很诡异的言论,因为我几乎没把时间花在那些个问题上,即使我在用没有泛型的语言。

但是,更重要的是,他说的那些表示类型系统将会解除这种负担。 类型系统。 不是多态函数,或语言级原语,或其它类型的辅助手段(helpers),而仅仅是类型系统

这就是粘住我的那个细节。

从C++或Java来Go的程序员怀念和类型系统在一起的日子,特别是带继承和子类的那部分。 也许我在类型系统方面是粗暴了些,但是我绝不觉得那套玩意非常具有表现力。

我已故的朋友Alain Fournier一次告诉我说他认为学术工作的最底层是分类学。 然后信不信由你,类型继承正是分类学。 你必须决定哪个萝卜扔哪个坑里,每个类型的父类型,A是否继承B或者B是否继承A。 一个可排序的数组是一个带有sort方法的数组呢,还是一个长得像数组的排序器呢? 如果你觉得类型系统能解决所有设计上的问题,你必须做出这个无意义的选择。

我相信对编程来说那是个荒诞的思路。 真正的重点不在于事物之间的继承关系,而在于它们能提供些什么。

因此,接口这个概念进入了Go。 但是它们都是主要部分——真正的Go之道——的一部分。

如果C++和Java注重类型继承和类型系统的分类学,那末Go就注重组合。

Doug Mcilroy,Unix管道的最终发明人,在1964年(!)写道:

我们应该有一些机制能将程序耦合(串)起来,像花园软管那样——当我们需要另一种方式传送数据时,拧紧另外一段即可。 I/O也可以这么做。

这也是Go所提倡的道路。 Go吸收这个观点,然后把它推进得十分远。 这是一门关于(功能上的)组合和(调用上的)耦合的语言。

一个显然的例子是接口是组合各部分的途径。 关键是,那些部分是什么并不重要,如果某类型实现了M方法我就可以把这个方法填到接口里去。

另一个重要的例子是如何让并发性提供给我们不同的独立计算部分的组合。

并且还有一种不同寻常(但十分简单)的类型组合形式: 嵌入。

————————————————————————

我想提一个和之前不太相关的Go设计: Go被设计为大型团队用来写大型程序的语言。

这里有个概念是”大型编程”,并且不知何故C++和Java主宰了这个领域。 我相信这只是因为其历史巧合,或者是工业上的巧合。 但是被广泛接纳的观点是他们和面向对象设计有关。

我压根不相信这点。 大型软件需要确定的方法,但是更重要的是它需要强依赖性管理,干净的接口抽象和优越的文档工具。 C++没一点做得好的(虽然Java明显要好很多)。

我们还不知道Go语言能做到何种程度,因为现在还没有足够的软件是用Go写的。 但是我非常有信心于Go将会成为一个优越的大型编程语言。 时间会说明一切的。

————————————————————————

现在,回到我们演讲开始提的那个问题:

为什么Go,作为从头被设计为符合C++使用者习惯的语言,没有吸引很多C++程序员?

严肃点说,我觉得是因为Go和C++在哲学方面有着巨大的不同。

C++是将所有东西提到你指尖上(译者: 即多范式)。 我在C++11的FAQ上找到了这段引用:

C++能优雅地,灵活地,零损耗地(相比于手工操纵代码)表达抽象的能力大幅提升了。

Go并非这种”围绕式”的。 你并不需要所有的东西都内建好。 你不需要对每个执行细节进行精细的控制。 比如,你不需要RAII,但你拥有一个垃圾回收器,也意味着你不需要执行释放内存的操作。

你得到的是一组非常强有力但易于理解,易于用来构建积木的功能,这些积木可以用来组合出一个你需要的问题的解法。 这并不意味着它能像别的一些语言创造的解法一样快速,复杂,或带来思想上的激励,但是它总能保证易于书写,易于阅读,易于理解,易于维护,而且可能更安全。

从另一个角度说,这当然算作过度简化:

Python和Ruby程序员转到Go,因为他们不需要牺牲表达能力,却获得了性能的提升,并且能好好玩并发系统了。

C++程序员并没有转到Go是因为他们好不容易获得了对程序的精细控制,并且不想牺牲它们的任何一部分。 对他们而言,写软件不仅包括把事情做完,而且包括用特定的方式完成。

关键是,在将来,Go的成功将会颠覆他们的世界观。

并且从一开始我们就应该意识到这点。 对于C++11的新特性很兴奋的人们并不关心一个拥有如此少特性的语言。 即使最后他提供了如此多。

谢谢。

诺基亚的 B 计划:Android

如果WP8系统失败,诺基亚将会把安卓系统作为后盾,诺基亚董事会成员Risto Siilasmaa在接受芬兰电视台采访时提道,这不再是一个假设方案。

Nokia Keeps Android As a Backup Plan If Windows Phone 8 Fails

这是一个让人们惊奇的消息,要知道之前这家伙死活不愿意接受安卓系统,看来是受市场战略失败检验后的反省,夕日巨人在担心即将推出的新款智能手机。

当然,这位理事会成员对目前研发部的产品开发还算满意,所以目前为止这个B计划还不在考虑范围。

文/雷锋网

Digg 被 Betaworks 收购,其模式影响深远

Digg 被 Betaworks 收购,据传价格为 50 万美元。若该价格是真的,Digg 可谓贱卖。不过 TechCrunch 辟谣,称 Digg 的收购价“明显超过” 50 万美元

Betaworks 的 CEO John Borthwick 将担任 Digg 的 CEO,Digg 的业务将与 Betaworks 的手机新闻应用 News.me 整合。Betaworks 还是著名的短网址服务 Bit.ly 的开发商。

Borthwick 承诺,他将重新打造 Digg 团队,让它回到初创团队的状态,“低预算、小团队、快速反应”。Borthwick 称公司过去六个月时间里一直思考,如何令 Digg 回归原来的价值,真正帮助用户发现互联网中的内容。根据 comScore 的数据,目前 Digg 平均每月依然有 700 万人浏览。

曾经的 Digg 是耀眼的明星,是网络上最受欢迎的网站之一,被视为 web 2.0 大潮中的翘楚。它的基本运行模式是由网友提交内容,其他网友按下“Digg”按钮来给文章投票,得票数高的文章将出现在得票数低的文章的前面。而且,网友 还可以直接在文章的链接下面进行讨论,有一段时间 Digg 成为了网络舆论的集散地,Digg 形成了一个相当活跃的社区。

2006 年,网站创始人 Kevin Rose 还登上了《商业周刊》的封面,当时的标语是“这个孩子如何在 18 个月内赚 6000 万美元”。2008 年,Google 还曾打算出价 2 亿美元收购 Digg,然而这笔收购从未完成过。

但随着用户量增长,Digg 也不可避免遭到垃圾用户的骚扰。2009 年,这个问题开始变得严重,虚假投票、垃圾留言在 Digg 上横行。这些都损害了 Digg 作为一个社区网站的价值,也违背了网站设立的初衷,无法发现网络中有价值的内容。许多 Digg 核心用户开始离开。他们发现了新天地:Twitter、Facebook、Reddit、BuzzFeed、StumbleUpon 等等。

最糟糕的是,创始人也不爱 Digg。TechCrunch 的创始人阿灵顿惊讶地发现,离开 Digg 之后的 Rose,平均每四天才登陆一次 Digg,甚至更少。在 2010 年 12 月,他至少有 22 天没有登录过 Digg。Rose 爱 Twitter 更甚于自己创立的 Digg。

现在,Digg 被收购了,但它对网络的影响是深远的。不少社区依然继承了它的设计精神,不管是 Reddit、HackerNews,还是 Facebook 的“赞一下”。

题图来自 digitaltrends

为什么你需要一个自己的公司

本文的作者:CD Baby的创始人Derek Sivers

本文的作者:CD Baby的创始人Derek Sivers

那是在2008年年初。我最终同意了卖掉我的公司——过去10年里让我一直魂牵梦绕的公司。各种手续正在办理。

泡温泉

该死的我有85个员工呢。这成了一种罪孽。我需要离开,清理一下脑子。

我去了一个不能再远的地方——日本南部顶端的火山上泡温泉。(视频.)

我静静的坐着。蒸。泡。我在海的声音里入眠。

不可能再悠闲了。我脑子里一片空白。

十年来头一次,我不需要去做任何事情。没有责任。没有计划。

太惬意了,不是吗?你可以想象出来吗?

我带了一本伟大的书,《Seeking Wisdom》,在安静的面海的小屋里读着。

这本书写的太好了。Charlie Munger关于经济行为的思想即精彩又独树一帜。这本书是我所有企业创意的灵感来源!

 

当我还在CD Baby公司的时候,我可以立即去执行我的这些想法。(“如果我们来个5美元的减价会怎样?” “如果我们和card swipers合作会怎样?” “如果我们支持多语言会怎样?”) 任何时候我想到一个主意,我都能在几天内测试它。

但现在,10年来的第一次,因为公司没了,我不能测试我的新想法了!我能做的只有阅读,思考,或许写点什么。该死!

这时候,我意识到了,我需要一家新公司。不是为了钱。不是因为“无聊”。而是因为公司是你的想法的一个试验室。(“实验室”是指一个可以做研究、实验或分析的屋子。我把它当成一个沙盒或绘图板。)

当在安宁的温泉里意识到这些,我跳上列车就返回了福冈,马上开始行动。

我创办了MuckWork,这样我可以做大众外包,帮助人们解决他们那些无聊的任务。

我重新启动了MusicThoughts,来实验全功能的多语言网站,创办了lang.pro,来组织翻译工作。

我创办了Now Now Now,一个创业投资/控股公司,来做另外一个实验。

所有我的以教育为目的的项目(介绍成功故事,文档,培训),我正在把它们打包成一个更大的主题。

这让我比无所事事更快乐。这不是工作,这是在玩。这是我实验我的想法的乐园。

我们都需要一些休息时间。给自己一个调整的机会。在压力大的时候给自己一份安宁和安慰。长时间的压力会毁了自己。

但是,对那些认为逃离工作就是进入天堂的人,不要忘了:我们需要游乐场,而你的公司就是你最好的游乐场。

“如果你看到一个真正高兴的人,你会发现他是在造一条船,写一首交响乐,教育他的儿子,或在沙漠戈壁里看恐龙孵蛋。” —— 澳大利亚精神病专家 W. Béran Wolfe

“找到一个高兴的人,你也找到了一个高兴的事业。” – Sonja Lyubomirsky
疯狂科学家