抽象泄漏定律

原文:https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/

作者:Joel Spolsky,翻译:张吉

TCP 协议是互联网的基石,我们每天都需要依靠它来构建各类互联网应用。也正是在这一协议中,时刻发生着一件近乎神奇的事情。

TCP 是一种可靠的数据传输协议,也就是说,当你通过 TCP 协议在网络上传输一条消息时,它一定会到达目的地,而且不会失真或毁坏。

我们可以使用 TCP 来做很多事情,从浏览网页信息到收发邮件。TCP 的可靠性使得东非贪污受贿的新闻能够一字一句地传递到世界各地。真是太棒了!

和 TCP 协议相比,IP 协议也是一种传输协议,但它是不可靠的。没有人可以保证你的数据一定会到达目的地,或者在它到达前就已经被破坏了。如果你发送了一组消息,不要惊讶为何只有一半的消息到达,有些消息的顺序会不正确,甚至消息的内容被替换成了黑猩猩宝宝的图片,或是一堆无法阅读的垃圾数据,像极了台湾人的邮件标题。

这就是 TCP 协议神奇的地方:它是构建在 IP 协议之上的。换句话说,TCP 协议能够使用一个不可靠的工具来可靠地传输数据

阅读全文

Hive 并发情况下报 DELETEME 表不存在的异常

在每天运行的 Hive 脚本中,偶尔会抛出以下错误:

1
2
3
4
5
6
7
8
2013-09-03 01:39:00,973 ERROR parse.SemanticAnalyzer (SemanticAnalyzer.java:getMetaData(1128)) - org.apache.hadoop.hive.ql.metadata.HiveException: Unable to fetch table dw_xxx_xxx
at org.apache.hadoop.hive.ql.metadata.Hive.getTable(Hive.java:896)
...
Caused by: javax.jdo.JDODataStoreException: Exception thrown obtaining schema column information from datastore
NestedThrowables:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'hive.DELETEME1378143540925' doesn't exist
at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:313)
...

查阅了网上的资料,是 DataNucleus 的问题。

问题背景

背景1:我们知道 MySQL 中的库表信息是存放在 information_schema 库中的,Hive 也有类似的机制,它会将库表信息存放在一个第三方的 RDBMS 中,目前我们线上配置的是本机 MySQL,即:

1
$ mysql -uhive -ppassword hive

使用 DBS 表存放元数据

阅读全文

Ansible FAQ

本文是从原Ansible官网的FAQ页面翻译而来,网站改版后该页面已无法访问,但可以从Github历史提交中获得。翻译这篇原始FAQ文档是因为它陈述了Ansible这款工具诞生的原因,设计思路和特性,以及与Puppet、Fabric等同类软件的比较,可以让我们对Ansible有一个整体的了解,所以值得使用者一读。

目录

  • 为什么命名为“Ansible”?
  • Ansible受到了谁的启发?
  • 与同类软件比较
    • Func?
    • Puppet?
    • Chef?
    • Capistrano/Fabric?
  • 其它问题
    • Ansible的安全性如何?
    • Ansible如何扩展?
    • 是否支持SSH以外的协议?
    • Ansible的适用场景有哪些?

为什么命名为“Ansible”?

我最喜爱的书籍之一是奥森·斯科特·卡特的《安德的游戏》。在这本书中,“Ansible”是一种能够跨越时空的即时通讯工具。强烈推荐这本书!

阅读全文

Apache Hadoop YARN - 项目背景与简介

原文:http://hortonworks.com/blog/apache-hadoop-yarn-background-and-an-overview/

日前,Apache Hadoop YARN已被提升为Apache软件基金会的子项目,这是一个值得庆祝的里程碑。这里我们也第一时间为各位献上Apache Hadoop YARN项目的系列介绍文章。YARN是一个普适的、分布式的应用管理框架,运行于Hadoop集群之上,用以替代传统的Apache Hadoop MapReduce框架。

MapReduce 模式

本质上来说,MapReduce模型包含两个部分:一是Map过程,将数据拆分成若干份,分别处理,彼此之间没有依赖关系;二是Reduce过程,将中间结果汇总计算成最终结果。这是一种简单而又条件苛刻的模型,但也促使它成为高效和极易扩展的并行计算方式。

Apache Hadoop MapReduce是当下最流行的开源MapReduce模型。

特别地,当MapReduce配合分布式文件系统,类似Apache Hadoop HDFS,就能在大集群上提供高吞吐量的计算,这一经济效应是Hadoop得以流行的重要原因。

这一模式成功的原因之一是,它使用的是“移动计算能力至数据节点”而非通过网络“移动数据至计算节点”的方式。具体来说,一个MapReduce任务会被调度到输入数据所在的HDFS节点执行,这会极大地减少I/O支出,因为大部分I/O会发生在本地磁盘或是同一机架中——这是核心优势。

阅读全文

Cascalog:基于 Clojure 的 Hadoop 查询语言

原文:http://nathanmarz.com/blog/introducing-cascalog-a-clojure-based-query-language-for-hado.html

我非常兴奋地告诉大家,Cascalog开源了!Cascalog受Datalog启发,是一种基于Clojure、运行于Hadoop平台上的查询语言。

特点

  • 简单 - 使用相同的语法编写函数、过滤规则、聚合运算;数据联合(join)变得简单而自然。
  • 表达能力强 - 强大的逻辑组合条件,你可以在查询语句中任意编写Clojure函数。
  • 交互性 - 可以在Clojure REPL中执行查询语句。
  • 可扩展 - Cascalog的查询语句是一组MapReduce脚本。
  • 任意数据源 - HDFS、数据库、本地数据、以及任何能够使用Cascading的Tap读取的数据。
  • 正确处理空值 - 空值往往让事情变得棘手。Cascalog提供了内置的“非空变量”来自动过滤空值。
  • 与Cascading结合 - 使用Cascalog定义的流程可以在Cascading中直接使用,反之亦然。
  • 与Clojure结合 - 能够使用普通的Clojure函数来编写操作流程、过滤规则,又因为Cascalog是一种Clojure DSL,因此也能在其他Clojure代码中使用。

阅读全文

Clojure 实战(5):Storm 实时计算框架

Storm 简介

上一章介绍的 Hadoop 工具能够对海量数据进行批量处理,采用分布式的并行计算架构,只需使用其提供的 MapReduce API 编写脚本即可。但随着人们对数据实时性的要求越来越高,如实时日志分析、实时推荐系统等,Hadoop 就无能为力了。

这时,Storm 诞生了。它的设计初衷就是提供一套分布式的实时计算框架,实现低延迟、高并发的海量数据处理,被誉为“Realtime Hadoop”。它提供了简单易用的 API 接口用于编写实时处理脚本;能够和现有各类消息系统整合;提供了 HA、容错、事务、RPC 等高级特性。

Storm 的官网是:storm-project.net,它的 Wiki 上有非常详尽的说明文档。

Storm 与 Clojure

Storm 的主要贡献者 Nathan Marz徐明明都是活跃的 Clojure 开发者,因此在 Storm 框架中也提供了原生的 Clojure DSL。本文就将介绍如何使用这套 DSL 来编写 Storm 处理脚本。

Storm 集群的安装配置这里不会讲述,具体请参考这篇文档。下文的脚本都运行在“本地模式”之下,因此即使不搭建集群也可以运行和调试。

阅读全文

Perl 入门实战:JVM 监控脚本(下)

套接字

使用套接字(Socket)进行网络通信的基本流程是:

  • 服务端:监听端口、等待连接、接收请求、发送应答;
  • 客户端:连接服务端、发送请求、接收应答。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
use IO::Socket::INET;

my $server = IO::Socket::INET->new(
LocalPort => 10060,
Type => SOCK_STREAM,
Reuse => 1,
Listen => SOMAXCONN
) || die "服务创建失败\n";

while (my $client = $server->accept()) {

my $line = <$client>;
chomp($line);

if ($line =~ /^JVMPORT ([0-9]+)$/) {
print "RECV $1\n";
print $client "OK\n";
} else {
print "ERROR $line\n";
print $client "ERROR\n";
}

close($client);
}

close($server);

阅读全文

fork() 与僵尸进程

使用fork()函数派生出多个子进程来并行执行程序的不同代码块,是一种常用的编程泛型。特别是在网络编程中,父进程初始化后派生出指定数量的子进程,共同监听网络端口并处理请求,从而达到扩容的目的。

但是,在使用fork()函数时若处理不当,很容易产生僵尸进程。根据UNIX系统的定义,僵尸进程是指子进程退出后,它的父进程没有“等待”该子进程,这样的子进程就会成为僵尸进程。何谓“等待”?僵尸进程的危害是什么?以及要如何避免?这就是本文将要阐述的内容。

fork()函数

下面这段C语言代码展示了fork()函数的使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// myfork.c

#include <unistd.h>
#include <stdio.h>

int main(int argc, char **argv) {
while (1) {
pid_t pid = fork();
if (pid > 0) {
// 主进程
sleep(5);
} else if (pid == 0) {
// 子进程
return 0;
} else {
fprintf(stderr, "fork error\n");
return 2;
}
}
}

阅读全文

Perl 入门实战:JVM 监控脚本(上)

由于最近在搭建Zabbix监控服务,需要制作各类监控的模板,如iostat、Nginx、MySQL等,因此会写一些脚本来完成数据采集的工作。又因为近期对Perl语言比较感兴趣,因此决定花些时间学一学,写一个脚本来练练手,于是就有了这样一份笔记。

需求描述

我们将编写一个获取JVM虚拟机状态信息的脚本:

  1. 启动一个服务进程,通过套接字接收形如“JVMPORT 2181”的请求;
  2. 执行netstat命令,根据端口获取进程号;
  3. 执行jstat命令获取JVM的GC信息;jstack获取线程信息;ps -o pcpu,rss获取CPU和内存使用情况;
  4. 将以上信息返回给客户端;

之所以需要这样一个服务是因为Zabbix Agent会运行在zabbix用户下,无法获取运行在其他用户下的JVM信息。

此外,Zabbix Agent也需要编写一个脚本来调用上述服务,这个在文章末尾会给出范例代码。

阅读全文

柯里化与偏应用(JavaScript 描述)

原文:http://raganwald.com/2013/03/07/currying-and-partial-application.html

上周末我参加了wroc_love.rb大会,其间Steve Klabnik的一张PPT中提到了偏应用(Partial Application)柯里化(Currying),并说这两者之间的区别如今已经不重要了。但是我不这么认为。

在这周发布的博文中,我用五种方式对this和闭包做了解释,但只有三到四种提到了柯里化。所以这篇博文就重点来谈谈这个。

函数参数的个数

在讲解之前,我们先明确一些术语。函数定义时会写明它所接收的参数个数(Arity)。“一元函数”(Unary)接收一个参数,“多元函数”(Polyadic)接收多个参数。还有一些特殊的名称,如“二元函数”(Binary)接收两个参数,“三元函数”(Ternary)接收三个参数等。你可以对照希腊语或拉丁语词汇来创造这些特殊的名称。

有些函数能够接收不定数量的参数,我们称之为“可变参数函数”(Variadic)。不过这类函数、以及不接收参数的函数并不是本文讨论的重点。

阅读全文