大规模无监督学习与分布式环境:Gensim、Hadoop和Spark的应用
1. 大规模LDA扩展
Gensim是一个灵活的库,可用于处理大型文本语料库,并且无需修改或额外下载即可进行扩展:
-
CPU数量扩展
:允许在单节点上进行并行处理,借助相关类实现,如第一个示例所示。
-
观测数量扩展
:支持基于小批量的在线学习,可通过LdaModel和LdaMulticore中的update方法实现,如之前示例。
-
集群扩展
:借助Python库Pyro4以及Gensim提供的models.lda_dispatcher(作为调度器)和models.lda_worker(作为工作进程)对象,可将工作负载分布到集群节点上。
除了经典的LDA算法,Gensim还提供了其分层版本——Hierarchical Dirichlet Processing(HDP)。该算法的主题遵循多级结构,能让用户更好地理解复杂语料库,不过截至2015年底,其可扩展性不如经典LDA。
常见的可扩展无监督学习方法如下表所示:
| 方法 | 功能 |
| — | — |
| PCA | 通过创建包含大部分方差的特征来减少特征数量 |
| K - means | 聚类算法,将相似点分组并关联到一个质心 |
| LDA | 对文本数据进行主题建模,联合建模每个文档的主题和主题中出现的单词 |
2. 从单机到集群:分布式环境的需求
如今,全球存储的数据量呈指数级增长,数据科学家每天处理数TB数据已不罕见。而且数据来源多样,业务期望在短时间内生成模型。处理大数据不仅关乎数据大小,实际上是一个三维现象,根据3V模型,处理大数据的系统可按以下三个正交标准分类:
1.
速度(Velocity)
:几年前,速度指系统处理一批数据的快慢;如今,指系统能否对流式数据提供实时输出。
2.
容量(Volume)
:即待处理的信息量,可用行数、特征数或字节数表示。对于流式数据,指进入系统的数据吞吐量。
3.
多样性(Variety)
:几年前,数据多样性局限于结构化数据集;如今,数据可以是结构化(如表格、图像等)、半结构化(如JSON、XML等)和非结构化(如网页、社交数据等)。通常,大数据系统会尝试处理尽可能多的相关数据源。
此外,近年来还出现了其他一些“V”来解释大数据的其他特征,例如:
-
准确性(Veracity)
:指示数据中包含的异常、偏差和噪声情况,最终体现数据的准确性。
-
时效性(Volatility)
:表示数据可用于提取有意义信息的时长。
-
有效性(Validity)
:数据的正确性。
-
价值(Value)
:指示数据的投资回报率。
当前计算机,即使是最新、最昂贵的,其磁盘、内存和CPU资源也有限,难以每天处理TB甚至PB级信息并快速生成模型。而且,包含数据和处理软件的单机服务器需要复制,否则可能成为系统的单点故障。因此,大数据领域转向了集群,集群由多个价格不高的节点组成,通过高速互联网连接。通常,一些集群用于存储数据(大硬盘、低CPU和少量内存),另一些用于处理数据(强大的CPU、中到大量内存和小硬盘)。如果集群设置得当,可确保可靠性(无单点故障)和高可用性。
在分布式环境(如集群)中存储数据时,还需考虑CAP定理的限制,系统只能保证以下三个属性中的两个:
| 属性 | 含义 | 放弃该属性的后果及示例 |
| — | — | — |
| 一致性(Consistency) | 所有节点能同时向客户端提供相同数据 | 创建数据分布在节点上的环境,即使网络出现问题,系统仍能响应请求,但同一问题的响应可能不一致,如DynamoDB、CouchDB和Cassandra |
| 可用性(Availability) | 客户端请求数据时,无论请求成功或失败,都保证能收到响应 | 创建的分布式系统可能无法响应查询,如Redis、MongoDb和MemcacheDb等分布式缓存数据库 |
| 分区容错性(Partition tolerance) | 若网络出现故障,节点无法通信,系统仍能继续工作 | 陷入不允许网络分割的关系数据库的严格模式,如MySQL、Oracle和SQL Server |
以下是CAP定理的mermaid流程图:
graph LR
A[分布式系统] -->|选择两个属性| B[一致性+可用性]
A -->|选择两个属性| C[一致性+分区容错性]
A -->|选择两个属性| D[可用性+分区容错性]
B -->|示例| E[部分传统数据库]
C -->|示例| F[MySQL、Oracle等]
D -->|示例| G[DynamoDB、CouchDB等]
3. 分布式框架的必要性
构建集群最简单的方法是使用一些节点作为存储节点,另一些作为处理节点。这种配置看似简单,许多小型集群就是这样构建的,但由于以下原因,这种方法并不常用:
- 仅适用于易于并行的算法,若算法需要处理服务器之间共享公共内存区域,则无法使用。
- 若一个或多个存储节点故障,无法保证数据的一致性。例如,节点及其副本同时故障,或节点在写入操作后还未复制就故障。
- 若处理节点故障,无法跟踪其正在执行的进程,难以在其他节点上恢复处理。
- 若网络出现故障,很难预测网络恢复正常后的情况。
假设一个100节点的集群,每个节点在第一年的故障概率(硬件和软件崩溃的累积概率)为1%,在每个服务器相互独立的假设下,所有100个节点在第一年都正常运行的概率是通过简单乘法计算得出。结果表明,节点故障事件很可能发生,企业在处理大数据时必须采取足够的对策来应对节点故障,以确保数据操作的连续性。
目前,绝大多数集群框架采用“分而治之”的方法:
- 有专门用于数据节点的模块和专门用于数据处理节点(也称为工作节点)的模块。
- 数据在数据节点之间复制,一个节点作为主节点,确保读写操作成功。
- 处理步骤分布在工作节点上,它们不共享任何状态(除非存储在数据节点中),主节点确保所有任务都能正确执行并按正确顺序完成。
4. 搭建虚拟环境
搭建集群是一项漫长而困难的操作,数据工程师在构建集群前需要了解节点、数据、操作和网络的每一个细节。为了方便读者尝试集群操作,我们提供一个包含所需一切的虚拟机镜像。运行虚拟机需要两个免费开源软件:VirtualBox和Vagrant。
4.1 VirtualBox
VirtualBox是一款开源软件,可在Windows、macOS和Linux主机上虚拟化一个或多个客户操作系统。从用户角度看,虚拟化的机器就像在窗口中运行的另一台计算机,具备所有功能。它性能高、操作简单且图形用户界面(GUI)简洁,启动、停止、导入和终止虚拟机只需点击一下。
技术上,VirtualBox是一个管理程序,支持创建和管理多个虚拟机,包括多种版本的Windows、Linux和类BSD发行版。运行VirtualBox的机器称为主机,虚拟化的机器称为客户机,主机和客户机之间没有限制。例如,Windows主机可以运行Windows(相同版本、旧版本或最新版本)以及任何与VirtualBox兼容的Linux和BSD发行版。
VirtualBox常用于运行特定操作系统的软件,也可用于在克隆的生产环境中模拟新功能。由于客户机与主机隔离,若客户机出现问题(如格式化硬盘),不会影响主机。要恢复,只需在进行危险操作前克隆机器即可。对于想从头开始的用户,VirtualBox支持虚拟硬盘(包括硬盘、CD、DVD和软盘),安装新操作系统非常简单。例如,要安装Linux Ubuntu 14.04的纯净版本,先下载.iso文件,然后将其作为虚拟驱动器添加到VirtualBox,通过简单的逐步界面选择硬盘大小和客户机的特征(如RAM、CPU数量、视频内存和网络连接),在操作真实BIOS时选择启动顺序,将CD/DVD设为更高优先级,即可在开启客户机时开始安装Ubuntu。
下载并安装VirtualBox,需选择适合自己操作系统的版本,安装说明见:https://www.virtualbox.org/wiki/Downloads 。
4.2 Vagrant
Vagrant是一款高级配置虚拟环境的软件,其核心是脚本功能,常用于以编程方式自动创建特定虚拟环境。Vagrant使用VirtualBox(也可使用其他虚拟化工具)来构建和配置虚拟机。安装说明见:https://www.vagrantup.com/downloads.html 。
4.3 使用虚拟机
安装Vagrant和VirtualBox后,可按以下步骤运行集群环境的节点:
1. 创建一个空目录,并在新文件Vagrantfile中插入以下Vagrant命令:
Vagrant.configure("2") do |config|
config.vm.box = "sparkpy/sparkbox_test_1"
config.vm.hostname = "sparkbox"
config.ssh.insert_key = false
# Hadoop ResourceManager
config.vm.network :forwarded_port, guest: 8088, host: 8088, auto_correct: true
# Hadoop NameNode
config.vm.network :forwarded_port, guest: 50070, host: 50070, auto_correct: true
# Hadoop DataNode
config.vm.network :forwarded_port, guest: 50075, host: 50075, auto_correct: true
# Ipython notebooks (yarn and standalone)
config.vm.network :forwarded_port, guest: 8888, host: 8888, auto_correct: true
# Spark UI (standalone)
config.vm.network :forwarded_port, guest: 4040, host: 4040, auto_correct: true
config.vm.provider "virtualbox" do |v|
v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
v.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
v.customize ["modifyvm", :id, "--nictype1", "virtio"]
v.name = "sparkbox_test"
v.memory = "4096"
v.cpus = "2"
end
end
上述代码从顶部到底部,首先下载正确的虚拟机,然后设置一些端口转发到客户机,以便访问虚拟机的一些Web服务,最后设置节点的硬件。配置默认是使用4GB RAM和两个核心的虚拟机,若系统无法满足这些要求,可修改
v.memory
和
v.cpus
的值,但需注意设置不当可能导致后续代码示例失败。
2. 打开终端,导航到包含Vagrantfile的目录,使用以下命令启动虚拟机:
$ vagrant up
首次运行该命令需要一段时间,因为它会下载(约2GB)并构建虚拟机的正确结构。后续运行该命令所需时间较短,因为无需再次下载。
3. 启动虚拟机后,使用以下命令访问它:
$ vagrant ssh
在Windows机器上,此命令可能因缺少SSH可执行文件而失败,可下载并安装Windows的SSH客户端,如Putty(http://www.putty.org/ )、Cygwin openssh(http://www.cygwin.com/ )或Openssh for Windows(http://sshwindows.sourceforge.net/ )。Unix系统不受此问题影响。
4. 关闭虚拟机时,先从虚拟机内部使用
exit
命令退出SSH连接,然后使用以下命令关闭虚拟机:
$ vagrant halt
若要删除虚拟机并删除其所有内容,使用
vagrant destroy
命令,但需谨慎使用,因为删除后无法恢复其中的文件。
在虚拟机中使用IPython(Jupyter)Notebook的步骤如下:
1. 在包含Vagrantfile的文件夹中运行
vagrant up
和
vagrant ssh
,进入虚拟机。
2. 运行脚本:
vagrant@sparkbox:~$ ./start_hadoop.sh
- 运行以下shell脚本:
vagrant@sparkbox:~$ ./start_jupyter_yarn.sh
-
在本地机器上打开浏览器,访问
http://localhost:8888,即可看到由集群节点支持的Notebook。
关闭Notebook和虚拟机的步骤如下:
1. 终止Jupyter控制台,按
Ctrl + C
,然后输入
Y
确认。
2. 终止Hadoop框架:
vagrant@sparkbox:~$ ./stop_hadoop.sh
- 退出虚拟机:
vagrant@sparkbox:~$ exit
-
使用
vagrant halt关闭VirtualBox机器。
5. Hadoop框架介绍
在分布式环境中,Hadoop是一个重要的框架,它能帮助我们更好地处理大数据。下面将详细介绍Hadoop的主要组件。
5.1 HDFS(Hadoop Distributed File System)
HDFS是Hadoop的分布式文件系统,它旨在存储大规模数据,并提供高吞吐量的数据访问。其主要特点包括:
-
数据冗余
:数据会被复制到多个节点,以提高数据的可靠性和可用性。
-
流式数据访问
:适合批量处理数据,而不是随机访问。
-
可扩展性
:可以轻松地添加更多的节点来扩展存储容量。
HDFS的基本架构包括一个NameNode和多个DataNode:
| 节点类型 | 功能 |
| — | — |
| NameNode | 管理文件系统的命名空间和客户端对文件的访问,存储文件的元数据。 |
| DataNode | 存储实际的数据块,根据NameNode的指令进行数据的读写操作。 |
下面是HDFS的mermaid流程图,展示了数据读写的基本流程:
graph LR
A[客户端] -->|写请求| B[NameNode]
B -->|分配DataNode| C[DataNode1]
B -->|分配DataNode| D[DataNode2]
B -->|分配DataNode| E[DataNode3]
A -->|写入数据| C
A -->|写入数据| D
A -->|写入数据| E
A -->|读请求| B
B -->|返回DataNode信息| A
A -->|读取数据| C
A -->|读取数据| D
A -->|读取数据| E
5.2 MapReduce
MapReduce是一种用于大规模数据处理的编程模型,它将数据处理任务分解为两个主要阶段:Map阶段和Reduce阶段。
-
Map阶段
:将输入数据分割成多个小块,并对每个小块进行独立的处理,生成中间键值对。
-
Reduce阶段
:对Map阶段生成的中间键值对进行合并和汇总,生成最终的结果。
MapReduce的优点包括:
-
并行处理
:可以在多个节点上并行执行,提高处理效率。
-
容错性
:如果某个节点出现故障,任务可以在其他节点上重新执行。
以下是一个简单的MapReduce示例,用于统计文本文件中每个单词的出现次数:
# Map函数
def mapper(key, value):
words = value.split()
for word in words:
yield (word, 1)
# Reduce函数
def reducer(key, values):
total = sum(values)
yield (key, total)
5.3 YARN(Yet Another Resource Negotiator)
YARN是Hadoop的资源管理系统,它负责集群资源的分配和任务的调度。YARN的主要组件包括:
| 组件 | 功能 |
| — | — |
| ResourceManager | 全局资源管理器,负责整个集群的资源分配和调度。 |
| NodeManager | 每个节点上的代理,负责管理该节点上的资源和容器。 |
| ApplicationMaster | 每个应用程序的管理者,负责与ResourceManager和NodeManager通信,请求资源并监控任务的执行。 |
YARN的工作流程如下:
1. 客户端向ResourceManager提交应用程序。
2. ResourceManager为应用程序分配一个ApplicationMaster。
3. ApplicationMaster向ResourceManager请求资源,并与NodeManager通信,启动容器来执行任务。
4. 任务执行完成后,ApplicationMaster向ResourceManager报告任务状态。
6. Spark框架介绍
Spark是一个快速通用的集群计算系统,它提供了高级的API,支持Java、Scala、Python和R等多种编程语言。Spark的主要特点包括:
-
内存计算
:将数据存储在内存中,减少了磁盘I/O,提高了处理速度。
-
灵活性
:支持多种数据处理任务,如批处理、流处理、机器学习和图计算等。
-
可扩展性
:可以轻松地扩展到大规模集群。
6.1 pySpark
pySpark是Spark的Python接口,它允许Python开发者使用Spark的功能。以下是一个简单的pySpark示例,用于统计文本文件中每个单词的出现次数:
from pyspark import SparkContext
# 创建SparkContext对象
sc = SparkContext("local", "WordCount")
# 读取文本文件
text_file = sc.textFile("path/to/your/file.txt")
# 进行MapReduce操作
counts = text_file.flatMap(lambda line: line.split(" ")) \
.map(lambda word: (word, 1)) \
.reduceByKey(lambda a, b: a + b)
# 输出结果
counts.collect()
# 停止SparkContext
sc.stop()
6.2 Spark的工作模式
Spark支持多种工作模式,包括本地模式、Standalone模式、YARN模式和Mesos模式:
| 工作模式 | 特点 |
| — | — |
| 本地模式 | 在单台机器上运行,用于开发和测试。 |
| Standalone模式 | 独立的集群模式,Spark自己管理集群资源。 |
| YARN模式 | 集成到Hadoop的YARN中,使用YARN进行资源管理和调度。 |
| Mesos模式 | 集成到Apache Mesos中,使用Mesos进行资源管理和调度。 |
以下是Spark在YARN模式下的mermaid流程图,展示了任务的提交和执行过程:
graph LR
A[客户端] -->|提交应用程序| B[ResourceManager]
B -->|分配ApplicationMaster| C[ApplicationMaster]
C -->|请求资源| B
B -->|分配容器| D[NodeManager1]
B -->|分配容器| E[NodeManager2]
C -->|启动任务| D
C -->|启动任务| E
D -->|执行任务| F[任务1]
E -->|执行任务| G[任务2]
F -->|返回结果| C
G -->|返回结果| C
C -->|返回结果| A
通过以上对Hadoop和Spark框架的介绍,我们可以看到它们在处理大规模数据方面具有强大的功能和优势。无论是存储、处理还是资源管理,这些框架都提供了有效的解决方案,帮助我们更好地应对大数据的挑战。同时,通过搭建虚拟环境,我们可以方便地在本地进行实验和开发,为实际的大数据项目做好准备。
超级会员免费看
988

被折叠的 条评论
为什么被折叠?



