qyb的博客

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: 商业

Gawk 4.0.0


http://lwn.net/Articles/450631/
July 7, 2011
This article was contributed by Joe 'Zonker' Brockmeier.

翻译:史玉良/李凯

GNU Awk(简称Gawk)是一款通常不会有什么新消息的常用工具。不过其4.0.0发行版却值得期待。Gawk 6月30日宣布,最新版会引入Gawk的首款调试器、用于运行不信任脚本的沙箱模型、内部修订、大量改动的正则表达式以及对IPv6的兼容性。

Gawk是Awk的GNU版本。Awk的名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。它是一个作为跨UNIX平台标准的脚本语言,我这里所说的“标准”是指Awk从一开始就已经成为了标准UNIX系统(或类似UNIX的系统)的一部分,同时它还是由开放组织所提出的POSIX规范的一部分。虽然Gawk只是Awk众多版本之一,但由于广泛应用而脱颖而出。那么它是用来做什么的呢?Gawk虽然也有人用它编写IRC机器人YouTube下载器、甚至AI编程,但它最著名的是数据处理和分析。

4.0.0中的新特性

Gawk4.0.0较之3.1.8版本有很大的更新。根据发布公告,Gawk不只是封装了大量的新特性、bug修复以及为符合POSIX2008版而做的更新,还包含了一些“内部大修”。

为了找出哪些被更新了以及为什么要更新这些部分,我给Gawk的维护者Arnold Robbins发了封Email。事实表明,这次内部大修有着漫长的历史。Robbins说在几年前John Haque开始用一种字节码引擎来重写Gawk的内核,并且在此过程中引入了一个调试器。不幸的是这项工作并没有被集成进来,并且Haque也转到了其他的工作。在2010年初,Robbins开始尝试把Haque的代码更新到现有程序中。据Robbins说,这次的重写并不会带来性能上的很大改进,不过却引入了一个非常有用的特性:


“性能跟以前的内核相比基本一致(或者略好一些),到目前为止我还没有找到一个case来验证这次改写使得它性能变差了。但是确实因此得到了巨大的好处,这也是为什么我想要做这次改进,gawk现在可以提供一个awk级的调试器(类似于GDB)了。”

目前,dgawk 是可用的,但功能受限的。它还不能报告一个错误是什么,当存在问题时只会报告一个“语法错误”。该调试器只能在命令行运行程序时使用,也就是说它不能 attach 到一个运行的Awk程序中。Gawk的开发者们不大可能去添加这项功能,因为Gawk手册中提到,必须用 dgawk 启动程序,才能进行调试,“对于一个主要用于快速执行以及简短程序的编程语言这貌似更加合理的”。

在4.0.0中Gawk的正则表达式发生了一些变化。区间表达式现在成了Gawk默认语法的一部分,并且不再需要 -W或 -POSIX选项了。区间表达式—— 大括号中包含一个或两个数字(形如{n}或{n,m})来告诉Gawk匹配正则表达式n或者从n到m——不再是初始Awk规范的一部分了。此外,\s和\S被加了进来,分别用于匹配任何空白字符和任何不含空白的字符。

虽然Gawk努力兼容POSIX,但它确实有超出POSIX的功能——在4.0.0版本中又引入了一些。Gawk现在支持两种模式,BEGINFILE和ENDFILE,它们分别用于在读取文件之前执行操作以及在读取文件之后执行操作。和BEGIN/END规则类似,不过用于读取每个文件之前和之后(由于Gawk在运行给定脚本时可能会处理两个或更多的文件)。例如,Gawk程序现在可以在处理一个文件之前可以先测试一下文件的可读性。在早期的Gawk版本中是没有这项功能的——因此如果Gawk接收的文件是不可读取的那么一个脚本就会引发一个致命的错误。

Gawk很早就可以用于处理网络连接。在4.0.0版本中,Gawk通过使用/inet6 或 /inet4来强制使用特定协议

网络上充斥着Awk/Gawk脚本,用户可能想要运行这些脚本但又担心的这些脚本会比所宣传的做的更多。为了解决这个问题,Gawk4.0.0中引入了沙箱选项(--sandbox),用于约束Gawk操作特定的输入数据。这项功能是通过禁用Gawk中的system()函数、使用getline的输入重定向以及使用print和printf函数的输出重定向来实现的。

然而,Robbins告诫不要对其表现出的安全性过分相信:


该功能是由一个有特定需要的同志贡献的代码,就我个人观点,如果用 gawk 开发 Web CGI 脚本,此功能很有意义。用户绝不希望 CGI 处理恶意数据的时候被欺骗而导致被注入攻击。从某些方面看沙盒是有意义的,但这个功能不能做出真正的安全承诺。

Robbins说沙箱模式在默认情况下是不开启的,因为这将打破“无数现有的awk脚本”。总之,这个选项是有用的,但沙箱选项禁用的功能可能不是恶意脚本损坏用户系统的唯一方式。

4.0.0版本是一些选项和一些旧的不支持的操作系统的终点。--compat,--copyleft,以及--usage等冗余选项都将消失。由于没有被实现,原始套接字选项已经被移除。如果仍然使用Amiga, BeOS, Cray, NeXT, SunOS 3.x, MIPS RiscOS以及其它少数的操作系统,, Gawk 3.1.8是最后能在其上运行的版本。Gawk的团队已取消这些平台的支持其实并不奇怪---因为他们维护的版本已经过期很久了。如今去找一款支持BeOS或者Amiga的专有软件确实是件很有挑战性的事情。

随着Gawk 4.0.0的发行,Robbins说接下来的大项目是把Gawk的三个可执行文件合并为一个版本以此来降低安装空间(gawk、pgawk 用来做profiling、dgawk)。他同时也指出,“针对性能方面,Haque有一些其他的计划,但是我在公共场合只能说这些。”Robbins同时也透漏,计划融入一些XMLgawk扩展(XMLgawk是Gawk的一个扩展,它有一个基于Expat XML程序的XML解析库)。

在Robbins的网站上,还有一些观点列在列在Gawk的路线图上,这其中包括对多精度浮点数MPFR的支持,因此gawk可以使用无限精度的数这字。他指出这会是一项“大工程”,而且还要决定是否默认支持MPFR。Gawk 的理念是代码准备好了才发布,所以对于什么时候Gawk能够具有人们所期望的一些特征,目前来看还没有确切的日期。

Gawk的团队不大,但是他们却是一群核心贡献者支持社区健康运行。Robbins说Gawk团队有六位成员维护着不同的系统,一个测试无数不同的Unix系统,一个贡献者已经帮助完成了文档,还有许多其他人诸如xmlgawk开发者以及来自不同的GNU/Linux发行商。自然的,这还包括Robbins和Haque。

虽然在这些年来Awk不是一种特别性感的语言,但是对于系统管理员以及开发者来说它仍然是一个日常工具。很高兴看到GNU 项目不仅在维护Gawk,还增加一些有趣的新特性来帮助其维护相关的功能。

Topic: sohulinux

香港买户外装备

这回去香港,事先查到的几个户外店都去过了:沙木尼、攀山、overlander、保捷行. 总结一下心得

在较大的地图中查看香港户外店

  1. 总体来说,价格还好。比去哈驴买东西要便宜一点点;淘宝上也有比香港价格还便宜很多的,但真假就难说了
  2. 但品种真少。毕竟香港地方小,普通人也就是爬爬狮子山,平日气候也炎热。连始祖鸟冲锋衣我估计主要是为大陆客备的货,香港人有鸟服的需求么???
  3. 攀山没有必要去——货和沙木尼是一样的,折扣也一样(满1500港币八折),在旺角也就沙木尼和overlander两家店走走就可以了
  4. 这几家店都有鸟的冲锋衣,但只有沙木尼才有鸟的抓绒(攀山都没有),切记!!mount hardware也只是在沙木尼/攀山才有,而且量很少!!
  5. 保捷行里vaude多、沙木尼/攀山里Karrimor多、overlander主打的是montbell
  6. overlander 有不少可以直接罩在近视眼镜外面的墨镜牌子,价格也还可以,推荐
  7. 每家店都有所罗门的鞋子,看起来在香港的渠道做得比较好
  8. 北京很少看到的AKU、FiveTen在沙木尼/overlander很多...也有一些户外品牌是走百货店的;比如时代广场7层有patagonia、哥伦比亚、tnf。在大陆哥伦比亚、TNF貌似也是以商场为主......这就是不同的渠道建设思路吧

最后,香港人民上班时间好晚,沙木尼要12点开门,保捷行要11:30开门... 要去购物必须规划好时间... 当然人家下班也比较晚

Topic: 运动

PyPy 计划去掉 GIL

http://morepypy.blogspot.com/2011/06/global-interpreter-lock-or-how-to-kill.html
强烈推荐去原文阅读底下的讨论

翻译:马少兵/刘晓佳

在 EuroPython 会议上,Armin Rigo,也就是我本人,已经提过,PyPy 计划删除已经臭名昭著的全局解释器锁,那个妨碍 CPython 多线程并发能力的东东。

Jython 很久以前已经去除了 GIL。它非常小心地给所有 mutable 内置类型加锁,从而达到目的;由于依赖的底层 Java 平台可以较有效的完成实现,这种情况下效率比 CPython 里通过类似的机制达到 GIL-less 要快。另外,“非常小心地”,我的意思是非常非常小心地;例如‘dict1.update(dict2)’,需要同时锁住dict1和dict2,但一个粗糙的实现,也许会导致另一个线程执行‘dict1.update(dict2)’时进入死锁。

PyPy,CPython 以及 IronPython 都依赖 GIL。现在我们正在考虑一种不同于 Jython 这种加锁的机制,而是用 Software Transactional Memory 来去掉 GIL。STM 是计算机科学的一个最新发展,给出了一种不同于锁机制的很好的解决方案。下面通过一个简短的例子说明

假设你想通过pop方法从list1中得到值,并且利用append将该值附加给list2,函数如下:

def f(list1, list2):
x = list1.pop()
list2.append(x)

f 并不是线程安全的(甚至在有 GIL 的情况下也是如此)。假设你在thread1中调用f(l1,l2),在thread2中调用f(l2,l1)。你期望线程之间互相之间是没有影响(x将从一个list移动到另外一个,然后返回),但最后结果也许是两个列表的数据发生了交换,这个取决于并发时候的时间顺序。

通过一个全局锁可以防止该错误:

def f(list1, list2):
global_lock.acquire()
x = list1.pop()
list2.append(x)
global_lock.release()

另外一种更好的方法就是将相关的list进行加锁:

def f(list1, list2):
acquire_all_locks(list1.lock, list2.lock)
x = list1.pop()
list2.append(x)
release_all_locks(list1.lock, list2.lock)

第二种解决方案就是 Jython 的模型,而第一种是以Cpython为模型的。的确我们可以看出,在 CPython解释器中,我们获得GIL,执行一个字节码(或者执行100个字节码)以后,然后释放该锁;然后重复上述过程

第三种方案是STM:

def f(list1, list2):
while True:
t = transaction()
x = list1.pop(t)
list2.append(t, x)
if t.commit():
break

在这种解决方案下,我们首先需要创建一个事务对象,然后在所有的读写list操作中使用它。上面我们介绍了几种不同的模型,下面我们主要对STM做详细的介绍。在一个事务处理期间,我们不需要改变全局内存,相反使用一个局部线程的事务对象,存储它到一个可以进行读写操作的地方。在这个事务结束前,我们利用“commit”方法提交它。提交的过程可能由于其他的提交此时也在进行而失败,在这种情况下,事务将中止,且必须重新开始。

正如前两个方案分别是CPython和Jython模型, STM方案看起来像是PyPy未来将采用的模型。在这种模型中,解释器会启动一项事务,操作字节码,然后关闭事务,反复这样下去。这与在CPython使用GIL非常类似。特别是,这意味着它给程序员做出和GIL模式一样的保证。唯一的区别是,只要代码不会互相干扰,就能够真正并行运行多个线程。(当然如果你需要的不仅仅是GIL而是多线程程序中的锁,即使有了STM你还是需要获得锁。如果你希望用类似 STM 的机制来避免使用锁的话,也许可以用额外的内建模块将 STM 暴露给Python程序,不过那就是另一个问题了)

为什么不把这种思想应用到CPython中呢?因为这样做的话,我们可能会改变一切。你也许已经注意到了,在上面的例子中,我们不再调用list1.pop()函数,改为调用list1.pop(t);这种方式说明为了实现事务性的完成任务,所有方法的实现都需要改变。这意味着为了避免改变全局内存,必须用 transcation object 记录改变。如果我们的解释器像CPython一样用C写,那么我们需要显式的在每个地方写。相反,如果我们如PyPy那样用高层语言写,我们可以加入这种行为,把它作为解释规则的一部分,然后在需要的地方自动应用。而且,还可以提供一个解释期选项:你可以得到GIL版本“pypy”,或者STM版本。STM 由于增加了额外记录可能会变得更慢。(有多慢?我无法提供线索,但可以猜一猜,也许会慢2-5倍。如果你有足够的CPU内核,只要扩展性够出色,那不是问题。)

最后需要注意:由于STM的研究是最近的事(始于2003年),现在并不确定它的几个变种之中哪个更好。就我目前所了解的,“A Comprehensive Strategy for Contention Management in Software Transactional Memory”[PDF] 看起来是最美好的一种可能,在各种情况下都还不错。

那么什么时候能实现呢?我无法确定。现在仍旧处在创意阶段,不过我想会实现的。需要花多久来写呢?也没有线索,不过我们认为得几个月而不是几天。我打算在9月1日欧洲之星当前的赞助到期后,我就开始全职做这件事情。目前我们打算通过 crowdfunding 的模式融资支持我的全职工作。可能很快就有一篇相关的博客发表,看起来这会是 crowdfunding 的一个很好的案例——我相信至少有数千人愿意花10欧元来去掉GIL。下面就等着我们的消息吧

Topic: sohulinux
订阅 RSS - qyb的博客