文章分类 - Distributed
1
并行编程与分布式计算
摘要:本文讲一些常见的分布式应用层面的技术,其中大部分都依赖于Zookeeper,所以对zookeeper不熟悉的同学可以先看我之前写的两往篇博客Zookeeper编程(二)、Zookeeper编程(一) 锁 我们的推荐程序部署在多台服务器上,每天凌晨会去重建信息索引(索引存在Redis上)。建索引这件事
阅读全文
摘要:方法一第一阶段的Map,对每一数据项 $(i,j,v)$,若来自矩阵 A ,则输出 $(j,(A,i,v))$,若来自矩阵 B ,则输出$(i,(B,j,v))$,这 样 矩 阵 A 的 第j 列 和 矩 阵 B 的 第 i 行 会被同一个 reduce 节点处理;在 Reduce 端,将来自 A ...
阅读全文
摘要:两年前写过ZooKeeper编程(一),那时候还在实习。近期组内做了个zookeeper编程的分享,就又把各种问题整理了一下。以下只是简单地copy了幻灯片中的内容,写得不够连贯,读者见谅。 ZooKeeper的轮廓 / root | \ child1 | \ child2 | \ child3 |
阅读全文
摘要:一、客户端向JobTracker提交作业这个阶段要完成以下工作:向JobTracker申请 一下新的JobID检查是否指定了output dir,并且确认output dir不存在根据InputPath计算input split。这里的input split并不是MapReduce输入数据的完整拷贝,只是记录了每个split在什么地方存放着。split和block一样都是逻辑概念,一个split可能跨越不同的磁盘。把运行作业所需的resource复制到jobtracker的文件系统上去,保存在一个包含jobID的目录下。这些resource包括:jar文件、配置文件、计算好的input spl
阅读全文
摘要:HDFS适合做:存储大文件。上G、T甚至P。一次写入,多次读取。并且每次作业都要读取大部分的数据。搭建在普通商业机群上就可以了。虽然会经常宕机,但HDFS有良好的容错机制。HDFS不适合做:实时数据获取。如果有这个需求可以用HBase。很多小文件。因为namenode要存储HDFS的metadata(比如目录的树状结构,每个文件的文件名、ACL、长度、owner、文件内容存放的位置等等信息),所以HDFS上文件的数目受到namenode内存的限制。并发环境下的写入和修改。Block一个磁盘的block通常是512B,内核一次读写磁盘不能少于这个数目。在HDFS上一个Block的默认大小是64M
阅读全文
摘要:在Hadoop集群中,数据在网络上传输,保证数据完整性的通常做法使用checksum,比如常用的CRC-32 (cyclic redundancy check)。Hadoop上支持的文件压缩格式有:gzip ZIP bzip2 LZO。例如在UNIX上可以使用命令:gzip -1 file,会生成file.gz,但是原来的file就没有了。压缩算法都要在执行速度和压缩比上做一个权衡,-1表示只注意速度,-9表示只注重压缩比。CompressionOutputStream和CompressionInputStream很类似于java.util.zip.DeflaterOutputStream 和
阅读全文
摘要:配置Configuration一条configuration的名称可以是任意字符串,值可以是任意数据类型。conf.set("name", "orisun");conf.setInt("age",24);在代码中设置只对本次代码运行有效,而在配置文件中设置则长久有效。configuration-1.xml<?xml version="1.0"?><configuration><property><name>color</name><value>
阅读全文
摘要:InputFormatInputFormat类用来产生InputSplit,并把它切分成record。public interface InputFormat { InputSplit[] getSplits(JobConf job, int numSplits) throws IOE...
阅读全文
摘要:CountersBuilt-in Counters这些counters你在Web UI中,或是job结束后在控制台生成的统计报告中都看得到,根据名字你也能猜到这些counter是什么意思。分为3个Group:Map-Reduce FramewordMap input records,Map skip...
阅读全文
摘要:从理论上来讲用MapReduce技术实现KMeans算法是很Natural的想法:在Mapper中逐个计算样本点离哪个中心最近,然后Emit(样本点所属的簇编号,样本点);在Reducer中属于同一个质心的样本点在一个链表中,方便我们计算新的中心,然后Emit(质心编号,质心)。但是技术上的事并没有理论层面那么简单。Mapper和Reducer都要用到K个中心(我习惯称之为质心),Mapper要读这些质心,Reducer要写这些质心。另外Mapper还要读存储样本点的数据文件。我先后尝试以下3种方法,只有第3种是可行的,如果你不想被我误导,请直接跳过前两种。一、用一个共享变量在存储K个质心由于
阅读全文
摘要:word-doc矩阵在进行文件分类或文档检索的时候,我们通常需要建立一个word-doc矩阵,来记录每个词在每篇文档中出现的次数。class Mapper method map(docid id,doc d) foreach term in d Emit(pair(term,id),1)一种更高效的方法是在mapper侧进行聚合。class Mapper method map(docid id,doc d) H := new AssociativeArray foreach term in d H{term} := H{term}+1 foreach term in H E...
阅读全文
摘要:本文介绍几种MapReduce算法设计的技巧,全部内容翻译自《Data-Intensive Text Processingwith MapReduce》。Local Aggregation说到Local Aggregation,你可能会想不就是Combiner吗。实际上在mapper中进行combining比使用真正的combiner高效得多。首先combiner只是作为MapReduce的可选优化方案(就像inline对于C++编译器是一种可选优化方案一样),不一定会被执行。其次在mapper中进行combining可以减少很多的I/O操作,提高效率,毕竟mapper的每个结果都个结果都要被
阅读全文
摘要:杂记 ZooKeeper的用途:distributed coordination;maintaining configuration information, naming, providing distributed synchronization, and providing group ser
阅读全文
摘要:实际上,GDB 没有对多进程程序调试提供直接支持。例如,使用GDB调试某个进程,如果该进程fork了子进程,GDB会继续调试该进程,子进程会不受干扰地运行下去。如果你事先在子进程代码里设定了断点,子进程会收到SIGTRAP信号并终止。那么该如何调试子进程呢?其实我们可以利用GDB的特点或者其他一些辅助手段来达到目的。此外,GDB 也在较新内核上加入一些多进程调试支持。本文介绍的方法能让你把断点设在子进程中,单步查看子进程的运行情况。但问题,如果我想在一次调试中同时在父子进程中设置断点,单步执行该怎么做呢? 1 #include<stdio.h> 2 #include<stri
阅读全文
摘要:第一个性能当然是速度,还有两个:延时:完成指定工作所需要的时间吞吐率:单位时间内完成的工作量开发并行性通常能改进吞吐率。开发并行可以隐藏延时,当然并没有真正的减少延时,只是隐藏了延时的代价,因为它“与其等待,不如去计算其余部分”。并行计算比串行计算要建立更多线程而带来额外开销,建立进程的开销远大于线程,这是因为存储器的分配和初始化非常昂贵。线程(或进程)间的通信是开销的主要部分。存储器的带宽也限制了并行计算的速度,比如当CPU读DRAM时可能出现延时(当要加载的数据量很大,cache容不下时,CPU就不得不读取DRAM)。存储器带宽约束不多核计算中的特别问题,这通常受限于芯片的边界。避免过早的
阅读全文
摘要:现在一个芯片上可以构造多指令的执行引擎,俗称核。cache一般分三级,L1、L2、L3,L1离CPU最近,容量最小。Intel Core Duo处理器中,每个处理器各有一个32KB的私有1级指令cache和数据cache,它们共享一个2M的2级cache。cache一致性保证仅在处理器单独使用cache行的情况下,处理器才可以写入私有的高速缓存行单元----这样多处理器就引入了额外的开销。其次,当两个处理器处理同一问题时,它们对处理器带宽的要求是单个处理器需求的两倍,这意味着要把CPU的周长做长,以接入更多的I/O引脚,主要的节省来自于共享指令。AMD的Dual Core Operation芯
阅读全文
摘要:要统计一个整型数组中3出现的次数,写一个并行程序:#include<time.h>#include<assert.h>#include<stdlib.h>#include<stdio.h>#include<string.h>#include<sys/types.h>#include<pthread.h>#define ARRLEN 200000000 //int型数组的长度,我们的程序就是要统计这个数组中元素3出现了多少次struct padded_int{ int value; //4个字节 char pad
阅读全文
摘要:新版的GCC编译器都支持OpenMP。在程序中需要引入omp.h头文件,另外在编译时需要指定-fopenmp选项。#include<stdio.h>#include<omp.h>#include<time.h>void test(){ int a=0; clock_t t1=clock(); for(int i=0;i<10000000;i++){ a=i+1; } clock_t t2=clock(); printf("Test Time=%ld\n",t2-t1);}int main(int argc,char *argv[])
阅读全文
摘要:看到这个题目,俗了,大家都在计算圆周率。不过咱们的目的是看一下并行计算的基本流程。书上计算PI用的是精确的数值计算方法,我这里再给出一种概率计算方法。OpenMP和MPI将同时亮相。计算PI的方法1.tan(PI/4)=1 => PI=4arctan1。知道arctan1转化为定积分的形式是什么吧。利用arctan(x)的幂级数展开式,可以手工地计算PI另外也可以采用正式手工计算PI#include<stdio.h>#include<time.h>#define N 1000000main(){ double local,pi=0.0,w; long i; w=1
阅读全文
摘要:现代的线程库允许不同的线程运行在不同的处理器芯片上,从而实现真正意义上的并行。换句话说,如果你的机子是单核的,用多线程也没不会提高执行效率。我的电脑是多核的,并行计算耗时0.56秒,但按照常规的串行计算方法只需要0.07秒。分析一下原因,在我的程序里计算200×300和300×200的两个矩阵的乘积,分了300个子线程去分头完成。线程数太多,每个线程的工作量太小,CPU把时间都花在线程调度上了,所以并行的结果反而还不如串行。并行程序代码:#include<stdio.h>#include<time.h>#include<pthread.h>
阅读全文
1