首页

第8章 MongoDB的优化和安全建议

关灯 护眼    字体:

上一章 章节列表 下一页


无论SQL数据库还是NoSQL数据库,都有一些通用的技巧可以大大提高读写性能。作为NoSQL的MongoDB有自己的一些特性。将这些特性应用到生产环境中时,需要提高警惕,以防导致不必要的麻烦。

MongoDB默认没有密码,且只允许本地访问。如果开放外网访问,就一定要设置密码,否则会有安全隐患。



8.1 提高MongoDB读写性能


使用一些简单的技巧,就可以大大提高 MongoDB 的读写性能。本节将介绍其中几种常见的技巧。



8.1.1 实例26:“批量插入”与“逐条插入”数据,比较性能差异


实例描述

在 MongoDB 中,分别用“逐条插入”与“批量插入”两种方式插入相同的数据,比较两者的时间差。

使用Python向MongoDB中插入一条数据,只需要3行代码,见代码8-1。

代码8-1 插入一条数据到MongoDB

从Python执行完成第3行代码,到数据存到数据库中,这个过程可能只需要几毫秒。但是在这几毫秒中,网络传输的时间占了非常大的比例。

I/O(Input/Ouput,输入/输出)操作总是最耗费时间的,无论是硬盘的I/O操作还是网络I/O操作。

● 如果写到本地的MongoDB,数据会在网卡中转一圈再存入硬盘。

● 如果写到远程的MongoDB,数据会先从本地网卡出去,然后经过网线,在电磁波、光信号、电信号之间进行转换,中间通过一层一层的交换机路由器,甚至海底光缆,绕地球一圈再进入目标服务器的网卡最后存入数据库。

这就像是扔砖头,分10次,每次只扔一块砖头的时间,肯定远远大于把10块砖一次扔出去的时间。如果你能够一次扔10块砖头,为什么你要一块一块地扔呢。

现在的宽带技术,上下行速度动辄每秒几百兆字节。如果使用 MongoDB 插入数据还在逐条插入,每一条几个字节,那可真是白白浪费了网络带宽。

下面通过实际数据来对比逐条插入数据和批量插入数据的性能差异。

1.生成初始数据

为了对比结果的公平性,首先生成一个CSV文件,这个文件中的数据将用于测试逐条插入与批量插入功能。

运行generate_people_info.py,会在当前文件夹下面生成一个people_info.csv文件,如图8-1所示。

图8-1 生成初始数据

people_info.csv一共有119 810行,除去第1行标题行和最后1行空白行,一共有119 808条数据将会被插入MongoDB中。

提示:

由于“age”“salary”“phone”这3个字段使用了随机数,所以每一次重新生成的数据都不同。读者自行生成的people_info.csv应该和图中有所差异,这是正常情况。读者只需要保证逐条插入和批量插入使用的数据相同即可。

2.逐行插入数据

编写一段Python代码,读取CSV文件并逐条插入到MongoDB中。代码如下:

代码8-2 计算逐条插入数据的时间

其中,主要代码说明如下。

● 第5~7行代码:使用Python自带的CSV模块读取CSV文件,并将其转换为包含字典的列表。其中每一个字典为CSV中的一行数据。

● 第9行代码:初始化MongoDB并连接到chatper_8库下面的one_by_one集合。

● 第11行代码:记录开始时间戳。

● 第12、13行代码:使用for循环把数据逐条插入到MongoDB中。

● 第14、15行代码:记录结束时间戳,并打印出时间差。

运行效果如图8-2所示。插入119 808条数据,共耗时44秒。

图8-2 逐条插入119808条数据,耗时44秒

3.批量插入数据

编写一段Python代码,测试批量插入数据的性能,见代码8-3。

代码8-3 计算批量插入数据的时间

其中,主要代码说明如下。

● 第5~7行代码:使用Python自带的CSV模块读取CSV文件,并将其转换为包含字典的列表。其中每一个字典为CSV中的一行数据。

● 第9行代码:初始化MongoDB,并连接到chatper_8库下面的batch集合。

● 第11行代码:记录开始时间戳。

● 第12行代码:使用insert_many()方法直接把包含字典的列表插入数据库。

● 第13、14行代码:记录结束时间戳,并打印时间差。

运行效果如图8-3所示。批量插入119 808条数据,只用了不到2.7秒。

图8-3 批量插入119808条数据,耗时2.7秒

4.如何正确批量插入数据

仅仅是使用本地的MongoDB数据库,批量插入数据的性能就远远超过逐条插入数据性能。如果使用的是远程数据库,那么网络I/O导致的时间消耗会比这个差异大很多倍。

既然批量插入数据库的性能这么好,那如何正确地使用批量插入功能?下面这一段代码想实现的功能是:从Redis里面读数据,再插入到MongoDB中。请读者看看这段代码有什么问题。

代码8-4 一段有多种崩溃可能的批量插入数据的示例代码

其中,主要代码说明如下。

● 第6行代码:初始化Redis连接。

● 第7行代码:初始化MongoDB连接。

● 第10行代码:开启一个永远运行的循环。

● 第11行代码:在Redis中名为people_info的列表左侧获取一条数据,并将数据赋值给people_info_json变量。

● 第12~14行代码:如果people_info_json不为空,则使用JSON模块把它转换为字典,然后将其添加到people_info_list列表中。


m.qiduwx.com提示您,本章没有阅读完,点击下一页进入下一页阅读!

上一章 章节列表 下一页