零零散散开始记录自己学习大数据的相关知识,力争做到从完全小白的角度记录如何入门大数据机器学习的相关知识点与框架操作。如果有将来从事互联网类的机器学习方向的,肯定少不了学,可以参考。
先说下大致认识,大数据的底层架构知识非常多,以前分享过一个非常全的系列学习视频,详细请关注公众号AInewworld。
可以看出,大数据,从hadoop到文件系统,到存储,到处理框架等等很多。但是没必要都需要学通,因为这些对应了不同的职业,毕竟从事大数据可划分的职业非常多,有专门底层架构搭建的,有专门研究存储的,有专门研究大数据数据库等等的,而我想介绍的也是属于数据分析类,大数据挖掘,机器学习类的内容。这样子你只需要了解基本的大数据底层结构,数据库操作等等知识,更多的是学习处理大数据的api,以及机器学习知识。
基于这个细分方向,我这里主要涉及框架为spark,企业中多数使用的也是spark。
话不多说,今天介绍的主题是大数据的核心方法之一,并行化的处理函数:map方法。没听过或者不懂不要紧,往下看。
我们知道大数据处理和普通处理的核心区别在哪?大数据的存储与处理都是分布式的。什么意思,分布式就是有n台电脑并在一起去执行某项任务,而我们的普通处理通常就是一台电脑来执行,所以显而易见,分布式说白了就是无脑增加机器达到时间与效率上快、达到存储量上的大(当然不止于此)。先说效率,举个例子,有一个txt文件有1亿行数据,每行都包含一个字符串,如“asdasdsfsdfas”,现在想让你统计每行字符串包含字母a的个数。那么单机怎么处理,写个for循环,每行每行统计计算a的个数,再来看看分布式处理怎么处理,先看看有多少台机器,比如10000台,那么把这个文本切分1万份,注意是切分,不是复制,然后每一份用一台机器去for循环,10000台机器同时for循环,最后把结果合并起来,结束。可想而之,这速度和效率的提升,直白的认为就有10000倍吧,这是效率上的优势。再来看存储优势,假设这个txt不是1亿行数据,是1亿亿行数据,这个数据量有多大呢,随便假设一下100G的数据量吧,这么大的数据量,单机怎么处理,基本没有办法,那么分布式呢,可以,首先100G的数据会分散分布在前面假设的10000台电脑上,假设都不重复的话,每台电脑只有0.01G也就是10M左右吧,这个数据量那简直太简单了,处理时也非常容易加载到内存中毫无压力。
所以可以看出分布式处理的两个核心优势:分布式处理-速度快,分布式存储-存海量数据。
理解了这点再来看看分布式处理的核心函数之一map方法。
map方法是一个通类方法,就是表明我处理时是以分布式的方式进行处理的。举个例子,假设我有一个test.txt文件如下:
a;b;c
d;e;f
q;w;e
z;x;c
现在要对每一行进行“;”分割,不采用分布式的方法是什么?先读进去,然后一行一行的分割。这里采用python进行处理,很简单:
def fun(x):
return x.split(";")
if __name__ == "__main__":
data = "test.txt"
with open(data) as f:
for line in f.readlines():
print fun(line)
显示结果就是(换行符也出来了):
['a', 'b', 'c\n']
['d', 'e', 'f\n']
['q', 'w', 'e\n']
['z', 'x', 'c']
下面看看分布式的map处理是什么样子的。这里如果在python下面操作,需要安装pyspark,安装的过程可以google,很多,这里先略过,如果使用scala语言,也需要安装spark,说一下spark官方语言就是scala,这个语言很优美,后续会介绍一点。
假设已经安装了pyspark,这里以单机模拟分布式,那么分布式的代码就是:
from pyspark import SparkContext
def fun(x):
return x.split(";")
if __name__ == "__main__":
sc = SparkContext(appName="wordsCount")
lines = sc.textFile('test.txt')
lines_0 = lines.map(fun)
res = lines_0.collect()
for t in res:
print(t)
sc.stop()
结果如下:
[u'a', u'b', u'c']
[u'd', u'e', u'f']
[u'q', u'w', u'e']
[u'z', u'x', u'c']
多了个u是文件处理格式显示的,可以先不管,整体结果是一样的。
代码里面,首先声明一个spark处理空间sc,然后采用分布式的数据读取方法sc.textFile,这个函数可以读取分布式存储的数据(虽然我们的数据是单机存储的,我们想象它是分布式的,没有影响),然后一个map方法传入一个我想要处理的函数fun进行处理,其实这个过程就相当于把fun函数拷贝到了n台分布式联合的电脑上,然后每台电脑上进行与单机一样的处理操作。最后的结果显然也是一个分布式存储的结果,每台电脑上都有一部分结果,我们采用collect方法把所有结果收集到一台电脑上,这样数据就不是分布式的了,最后在显示出来。其实收集所有结果的过程也是一个非常核心的过程:reduce过程,这个后面再说。
整个过程的大致流程就是这样的,这么来看,我们可以发现,map方法其实就好比一个函数复制器一样,告诉机器我是分布式处理的,可以把里面的函数应用到所有的机器上同时处理,前提是我的数据必须是分布式的。
假设你不想分布式处理,那你可以在分布式读取数据以后,把数据都收集到一台机器上,然后单机处理,好比下面这样:
from pyspark import SparkContext
def fun(x):
return x.split(";")
if __name__ == "__main__":
sc = SparkContext(appName="wordsCount")
lines = sc.textFile('test.txt')
lines_single = lines.collect()
for t in lines_single:
print(t)
sc.stop()
那么这个过程就是分布式读数据,单机处理数据,显然当数据量大的时候,这种方式速度是非常慢的。这是我刚开始不会map方法时常使用的模式,太蠢了。
总结一点分布式方法map的特点,map里面使用的函数基本一定是单机可独立的(也有例外),什么意思呢,就是你这个函数里面不应该出现全局变量之类的东西,a机器运行这个函数与b机器运行这个函数是完全相互独立的,这样才满足分布式处理的特点。那么可能会问,加入碰到map里面需要一个函数,这个函数有些参数是必须共享的怎么办呢?这个后面也有一些办法解决,但总的来说,分布式之所以分布式,就是基本满足可复制不相互干扰的条件,如果破坏了这个条件,势必引起速度的下降,从分布式变成单机就是这样。
map方法是理解分布式处理机制的一个非常重要的方法,与之对应的是reduce方法,即将map处理的结果合并起来,下节介绍。
也可关注公号第一时间获取。