在云端部署MongoDB:全面指南
在当今数字化时代,将数据库部署到云端已成为众多企业和开发者的选择。MongoDB作为一款流行的NoSQL数据库,在云端部署方面有多种方式。本文将详细介绍使用MongoLab、手动在Amazon EC2上部署以及使用Docker容器部署MongoDB的方法,同时探讨与Hadoop的集成。
1. MongoLab的REST API与使用场景
MongoLab提供了用于各种操作的REST API,可替代标准驱动程序执行CRUD操作。不过,建议使用MongoDB客户端库。当客户端通过公共网络连接到MongoDB服务器时,使用REST API是一个不错的选择。因为本地机器上连接到云端MongoDB服务器的shell会向服务器发送未加密的数据,存在安全风险;而使用REST API时,由于采用HTTPS,流量通过安全通道传输。虽然MongoLab计划未来支持客户端与服务器之间的安全通道,但目前尚未实现。
若应用程序和数据库位于云提供商的同一数据中心,可依赖云提供商为其本地网络提供的安全保障。但要确保数据不通过公共网络传输,以实现安全通信。此外,当希望实例在自己的虚拟机实例上运行,或者应用程序位于虚拟专用云中时,MongoLab就无法满足需求。云提供商如亚马逊提供的VPC服务,可将部分AWS云视为自己网络的一部分,此时就不能使用MongoLab进行MongoDB实例的部署。
2. 手动在Amazon EC2上设置MongoDB
如果想更好地控制实例或在自己的虚拟专用云中设置MongoDB,可以手动进行部署。这里以AWS为例,使用Amazon Machine Image (AMI) 来完成设置。AMI是一个模板,包含操作系统、启动虚拟机时可用的软件等详细信息,在云端启动新的虚拟机实例时会用到这些信息。
2.1 准备工作
- 注册AWS账户 :访问http://aws.amazon.com/ 并点击“Sign up”。若已有亚马逊账户,直接登录;否则,创建新账户。需提供信用卡信息,但本文的操作将使用免费的微实例,除非另有说明。
- 下载并安装Putty :用于连接云端实例,可从http://www.putty.org/ 下载。
- 选择合适的实例类型 :对于使用AMI进行安装的操作,不能使用微实例,需使用标准大型实例。可在https://aws.amazon.com/ec2/pricing/ 查看不同地区EC2实例的定价信息,根据地理位置和财务因素选择合适的区域。
-
创建密钥对
:
- 若尚未创建密钥对,需进行创建。该密钥对用于从Putty客户端登录云端启动的Unix实例。若已创建且拥有.pem文件,可跳过此步骤。
- 访问https://console.aws.amazon.com/ec2/ ,确保右上角选择的区域与计划设置实例的区域一致。
- 选择区域后,资源页面会显示该区域的所有实例、密钥对、IP地址等信息。点击“Key Pairs”链接,进入显示所有现有密钥对的页面,可在此创建新的密钥对。
- 点击“Create Key Pair”按钮,在弹出窗口中输入任意名称,如“EC2 Test Key Pair”,然后点击“Create”。
- 创建完成后,会生成一个.pem文件,务必保存该文件,后续访问机器时需要用到。
-
将.pem文件转换为.ppk文件
:
- 启动puttygen,若未安装,可从http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html 下载。
- 选择SSH - 2 RSA选项,点击“Load”按钮,在文件对话框中选择“All files”,然后选择在EC2控制台生成的密钥对下载的.pem文件。
- 导入.pem文件后,点击“Save private key”选项,将文件保存为任意名称的.ppk文件,用于后续从Putty登录EC2实例。
若使用Mac OS X或Linux系统,可使用ssh - keygen实用程序生成SSH密钥。
2.2 具体操作步骤
- 访问https://console.aws.amazon.com/ec2/ ,点击左侧的“Instances”选项,然后点击“Launch Instance”按钮。
- 若要启动免费的微实例,勾选左侧的“Free tier only”复选框。在右侧选择要设置的实例,这里选择Ubuntu服务器,点击“Select”进入下一个窗口。
- 选择微实例,点击“Review and Launch”,忽略安全警告,默认安全组将接受来自公共网络所有主机的端口22连接。
- 不编辑任何默认设置,点击“Launch”。启动时会弹出一个窗口,让你选择现有的密钥对。若没有密钥对,需要密码或创建新的密钥对。这里使用之前创建的密钥对。
- 点击“Launch Instance”启动新的微实例。
- 参考之前操作中的步骤9 - 12,使用Putty连接已启动的实例。注意,这次使用的是Ubuntu用户,而非之前的ec2 - user,因为这次使用的是Ubuntu系统而非Amazon Linux。
- 在添加MongoDB存储库之前,导入MongoDB公钥:
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
- 在操作系统shell中执行以下命令:
$ echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list
- 执行以下命令加载本地数据库:
$ sudo apt-get install mongodb-org
- 执行以下命令创建所需目录:
$ sudo mkdir /data /log
- 启动mongod进程:
$ sudo mongod --dbpath /data --logpath /log/mongodb.log --smallfiles --oplogsize 50 –fork
为确保服务器进程正常运行,在shell中执行以下命令,日志中应显示如下内容:
$ tail /log/mongodb.log
2015-05-04T13:41:16.533+0000 [initandlisten] journal dir=/data/journal
2015-05-04T13:41:16.534+0000 [initandlisten] recover : no journal files present, no recovery needed
2015-05-04T13:41:16.628+0000 [initandlisten] waiting for connections on port 27017
- 启动mongo shell并执行以下命令:
$ mongo
> db.ec2Test.insert({_id: 1, message: 'Hello World !'})
> db.ec2Test.findOne()
2.3 原理说明
安装过程中,选择了Ubuntu系统,不同操作系统的安装步骤不同。可参考http://docs.mongodb.org/manual/installation/ 获取在不同平台安装MongoDB的步骤。本文中的步骤7 - 9是在Ubuntu上安装MongoDB的特定步骤,可参考https://help.ubuntu.com/12.04/serverguide/apt - get.html 了解apt - get命令的更多详细信息。
在本次设置中,将数据、日志和日志文件夹放在同一个EBS卷上,因为这是一个开发实例。对于生产实例,为了获得最佳性能,会使用具有预配置IOPS的不同EBS卷。这种设置利用了不同卷有不同控制器的优势,从而可以进行并发写操作。具有预配置卷的EBS卷由SSD驱动器支持。根据http://docs.mongodb.org/manual/administration/production - notes/ 的说明,MongoDB部署应使用RAID - 10磁盘。在AWS上部署时,建议优先选择PIOPS而非RAID - 10。例如,若需要4000 IOPS,选择具有4000 IOPS的EBS卷,而不是2 X 2000 IOPS或4 X 1000 IOPS的RAID - 10设置。这样不仅消除了不必要的复杂性,还能对单个磁盘进行快照,而不是处理RAID - 10设置中的多个磁盘。在大多数生产部署中,日志和数据会写入不同的卷,此时快照操作需要先刷新数据库写入,锁定数据直到备份完成,然后释放锁定。可参考http://docs.mongodb.org/manual/tutorial/backup - with - filesystem - snapshots/ 了解更多关于快照和备份的详细信息。
3. 使用Docker容器设置MongoDB
容器技术已经影响了信息技术的各个方面,Docker作为首选工具,在创建和管理容器方面起着重要作用。下面将介绍在Ubuntu (14.04) 服务器上安装Docker并在容器中运行MongoDB的方法。
3.1 准备工作
- 安装Docker :在Ubuntu服务器上执行以下命令:
$ wget -qO- https://get.docker.com/ | sh
- 启动Docker服务 :
$ service docker start
> docker start/running, process 24369
- 确认Docker正在运行 :
$ docker info
> Containers: 40
> Images: 311
> Storage Driver: aufs
> Root Dir: /var/lib/docker/aufs
> Dirs: 395
> Execution Driver: native-0.2
> Kernel Version: 3.13.0-37-generic
> Operating System: Ubuntu 14.04.2 LTS
> WARNING: No swap limit support
3.2 具体操作步骤
- 从Docker Hub获取默认的MongoDB镜像:
$ docker pull mongo
- 确认镜像已安装:
$ docker images | grep mongo
- 启动MongoDB服务器:
$ docker run -d --name mongo-server-1 mongo
> dfe7684dbc057f2d075450e3c6c96871dea98ff6b78abe72944360f4c239a72e
也可以运行
docker ps
命令检查正在运行的容器列表。
4. 获取容器的IP地址:
$ docker inspect mongo-server-1 | grep IPAddress
> "IPAddress": "172.17.0.3",
- 使用mongo客户端连接到新容器:
$ mongo 172.17.0.3
>MongoDB shell version: 3.0.4
> connecting to: 172.17.0.3/test
>
- 在服务器上创建目录:
$ mkdir –p /data/db2
- 启动新的MongoDB容器:
$ docker run -d --name mongo-server-2 -v /data/db1:/data/db mongo
- 获取新容器的IP地址并使用Mongo客户端连接:
$ docker inspect mongo-server-2 | grep IPAddress
> "IPAddress": "172.17.0.4",
$ mongo 172.17.0.4
>MongoDB shell version: 3.0.4
> connecting to: 172.17.0.4/test
>
- 为最后一个容器创建另一个目录并启动容器:
$ mkdir –p /data/db3
$ docker run -d --name mongo-server-3 -v /data/db3:/data/db -p 9999:27017 mongo
- 通过本地主机连接到该容器:
$ mongo localhost:9999
> MongoDB shell version: 3.0.4
> connecting to: localhost:9999/test
3.3 原理说明
首先从DockerHub (https://hub.docker.com/_/mongo/) 下载默认的MongoDB镜像。Docker镜像是一个自包含的操作系统镜像,针对要运行的应用程序进行了定制。所有Docker容器都是这些镜像的隔离执行。这类似于使用操作系统模板创建虚拟机。
镜像下载操作默认获取最新的稳定MongoDB镜像,也可以通过指定标签来选择特定版本,例如
docker pull mongo:2.8
。通过运行
docker images
命令验证镜像是否下载成功,该命令会列出服务器上安装的所有镜像。在步骤3中,使用
-d
参数以分离模式启动一个名为
mongo - server - 1
的容器。每个Docker容器默认会从docker服务器分配一个RFC 1918(不可路由)的IP地址空间,通过步骤4获取IP地址,然后在步骤5中连接到MongoDB实例。
由于每个Docker容器是临时的,销毁容器会导致数据丢失。因此在步骤6中创建一个本地目录来存储Mongo数据库。步骤7中启动的新容器与之前的命令类似,增加了
-v
参数,将本地目录
/data/db2
暴露给Mongo容器命名空间作为
/data/db
,类似于NFS文件挂载,但在内核命名空间内。最后,若希望外部系统连接到容器,在步骤9中使用
-p
参数将Ubuntu服务器的TCP 9999端口绑定到容器的TCP 27017端口,这样连接到服务器端口9999的任何外部系统都会被路由到该特定容器。
4. 与Hadoop集成
Hadoop是一款用于处理大型数据集的开源软件,拥有广泛使用的MapReduce编程模型API。几乎所有的大数据解决方案都支持与Hadoop集成,以利用其MapReduce框架。MongoDB也有与Hadoop集成的连接器,可使用Hadoop MapReduce API编写MapReduce作业,处理MongoDB/MongoDB转储中的数据,并将结果写入MongoDB/MongoDB转储文件。后续将介绍一些基本的MongoDB与Hadoop集成的方法,包括执行第一个使用mongo - hadoop连接器的MapReduce示例作业、编写第一个Hadoop MapReduce作业、使用流式处理在Hadoop上运行MapReduce作业以及在Amazon EMR上运行MapReduce作业等。
综上所述,在云端部署MongoDB有多种方式可供选择,开发者可以根据自己的需求和场景选择合适的方法。同时,与Hadoop的集成也为大数据处理提供了更多的可能性。
在云端部署MongoDB:全面指南
4. 与Hadoop集成(续)
4.1 执行首个使用mongo - hadoop连接器的MapReduce示例作业
借助mongo - hadoop连接器,我们能够轻松地执行MapReduce作业。这个连接器就像是一座桥梁,让MongoDB与Hadoop之间的数据交互变得顺畅。以下是执行首个示例作业的大致流程:
1.
配置环境
:确保mongo - hadoop连接器已正确安装并配置到Hadoop环境中。这一步就像是为一场演出搭建好舞台,只有舞台搭建好了,后续的表演才能顺利进行。
2.
准备数据
:将需要处理的数据存储在MongoDB中。这些数据就是演出的“演员”,是整个作业的核心内容。
3.
编写MapReduce代码
:使用Hadoop MapReduce API编写具体的Map和Reduce函数。这就像是为“演员”们编写剧本,告诉它们在不同的场景下该如何表现。
4.
运行作业
:将编写好的代码提交到Hadoop集群上运行。此时,就像是演出正式开始,各个“演员”按照剧本开始行动。
通过以上步骤,我们可以让MongoDB的数据在Hadoop的MapReduce框架下得到高效处理。
4.2 编写首个Hadoop MapReduce作业
编写Hadoop MapReduce作业需要对MapReduce的原理有一定的理解。MapReduce主要分为两个阶段:Map阶段和Reduce阶段。
-
Map阶段
:这个阶段就像是一个数据的“分拣员”,它会读取输入数据,并将其转换为键值对的形式。例如,对于一段文本数据,Map阶段可能会将每个单词作为键,出现的次数初始化为1作为值。
-
Reduce阶段
:这个阶段则像是一个数据的“统计员”,它会接收Map阶段输出的键值对,并对相同键的值进行合并和统计。比如,将所有相同单词的出现次数相加,得到最终的统计结果。
以下是一个简单的示例代码,展示了如何编写一个基本的Hadoop MapReduce作业:
import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class WordCount {
public static class TokenizerMapper
extends Mapper<Object, Text, Text, IntWritable>{
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context
) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
public static class IntSumReducer
extends Reducer<Text,IntWritable,Text,IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values,
Context context
) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
在这个示例中,
TokenizerMapper
类实现了Map阶段的功能,
IntSumReducer
类实现了Reduce阶段的功能。通过运行这个作业,我们可以统计输入文本中每个单词的出现次数。
4.3 使用流式处理在Hadoop上运行MapReduce作业
流式处理是一种在Hadoop上运行MapReduce作业的灵活方式。它允许我们使用任何编程语言编写Map和Reduce函数,只要这些函数能够通过标准输入和输出进行数据交互。以下是使用流式处理运行MapReduce作业的步骤:
1.
编写Map和Reduce脚本
:可以使用Python、Perl等脚本语言编写Map和Reduce函数。例如,以下是一个简单的Python Map脚本:
import sys
for line in sys.stdin:
line = line.strip()
words = line.split()
for word in words:
print('%s\t%s' % (word, 1))
- 配置Hadoop作业 :在Hadoop作业中配置使用流式处理,并指定Map和Reduce脚本的路径。
- 运行作业 :将作业提交到Hadoop集群上运行。
通过流式处理,我们可以充分利用各种编程语言的优势,更加灵活地处理数据。
4.4 在Amazon EMR上运行MapReduce作业
Amazon EMR(Elastic MapReduce)是亚马逊提供的一种托管式Hadoop服务,它可以让我们轻松地在云端运行MapReduce作业。以下是在Amazon EMR上运行作业的步骤:
1.
创建EMR集群
:在AWS控制台中创建一个EMR集群,并选择合适的配置。这就像是为我们的作业搭建一个专属的“工作场所”。
2.
上传数据和代码
:将需要处理的数据和编写好的MapReduce代码上传到Amazon S3存储桶中。S3就像是一个巨大的“仓库”,可以安全地存储我们的数据和代码。
3.
配置作业
:在EMR集群中配置作业,指定输入数据的位置、MapReduce代码的位置等参数。
4.
运行作业
:启动作业,让它在EMR集群上运行。
通过使用Amazon EMR,我们可以避免繁琐的集群管理工作,专注于数据处理和分析。
5. 总结与建议
在云端部署MongoDB并与Hadoop集成,为我们处理大数据提供了强大的工具和方法。以下是一些总结和建议:
-
选择合适的部署方式
:根据项目的需求和场景,选择使用MongoLab、手动在Amazon EC2上部署或使用Docker容器部署MongoDB。例如,如果需要快速部署且对安全要求不是特别高,可以考虑使用MongoLab;如果需要更多的控制权和定制化,可以选择手动部署;如果需要灵活的资源管理和隔离,可以使用Docker容器。
-
优化性能
:在生产环境中,合理配置EBS卷、选择合适的IOPS等,以确保MongoDB的性能。例如,对于高并发的写操作,选择具有预配置IOPS的EBS卷可以提高性能。
-
保障数据安全
:无论是在云端部署还是与Hadoop集成,都要重视数据的安全。例如,使用安全的通道传输数据、定期备份数据等。
-
深入学习与实践
:不断学习和实践MongoDB与Hadoop的相关知识和技术,探索更多的应用场景和优化方法。只有不断学习,才能跟上技术的发展步伐,更好地应对各种挑战。
总之,通过合理选择部署方式、优化性能、保障数据安全以及不断学习实践,我们可以充分发挥MongoDB和Hadoop的优势,为大数据处理和分析提供有力支持。
以下是一个简单的流程图,展示了在云端部署MongoDB并与Hadoop集成的主要步骤:
graph LR
A[选择部署方式] --> B[准备环境]
B --> C[部署MongoDB]
C --> D[与Hadoop集成]
D --> E[执行MapReduce作业]
同时,为了更直观地比较不同部署方式的特点,我们可以看下面的表格:
| 部署方式 | 优点 | 缺点 | 适用场景 |
| ---- | ---- | ---- | ---- |
| MongoLab | 快速部署、易于使用 | 功能受限、安全通道待完善 | 快速测试和开发 |
| 手动在Amazon EC2上部署 | 高度定制化、控制权强 | 配置复杂、管理成本高 | 对性能和安全要求高的生产环境 |
| Docker容器部署 | 资源隔离、灵活管理 | 数据持久化需额外配置 | 开发和测试环境 |
通过以上的介绍和分析,相信大家对在云端部署MongoDB以及与Hadoop集成有了更深入的了解。希望大家能够根据自己的实际需求,选择合适的方法和技术,实现高效的数据处理和分析。