目录
摘要
本文主要介绍使用MongoDB集群搭建whois web查询系统,其中用到MongoDB集群化存储,XAMPP一站式web搭建工具,具体实现使用基于PHP的Laravel框架。
一.MongoDB 集群搭建配置
二.Whois数据的导入
1.数据预处理
- 原始数据编码格式比较混乱,测试时使用如下类型转换能够处理各种字符串
content=re.sub("\\\N", "\\\\\N", content) #如果用decode('unicode-escape'),那么content不能存在\N或\U或\u这种转义符,
content=re.sub("\\\u", "\\\\\u", content) #如果存在这些符号,后面跟的内容必须是正确的转义规则所指的内容
content=re.sub("\\\U", "\\\\\U", content) #如果使用sub("\N", "\\N", content),并不仅仅匹配\N,还会匹配所有的N
content=content.decode('unicode-escape')
- IP地址转数字
import struct
import socket
import chardet
import netaddr
ip_number=socket.ntohl(struct.unpack("I",socket.inet_aton(ip))[0])
2.IP前缀查询
- sql中,where查询的效率远低于单一值查询,尤其是where选择命中行数过大,会带来很大的I/O、内存读取负载,因此查询效率极低,之前在mysql部署时遇到这个问题,但是在monodb进行查询测试时,查询速度很快,explain不显示查询时间,暂时不管。
- 在实际查询时,是指定IP进行查询,因此最容易的方法是where范围查询,命中范围内的数据。但是基于上一条的原因速度很慢。在老师的启发下,参考路由表查询算法,改成前缀查询法。即对32位IP地址,依次逻辑左移并进行查询匹配,直到匹配到结果,取结果中范围最小的数据。因此还需要将IP范围转化成cidr形式进行存储。
import netaddr
cidrs = netaddr.iprange_to_cidrs(ip1, ip2)
3.插入数据
- 开启分片
- 创建索引
conn=MongoClient('127.0.0.1',27118)
db=conn.whois
apnic=db.apnic
apnic.drop()
apnic_cidr=db.apnic_cidr
apnic_cidr.drop()
#设置分片
admin_db= conn['admin']
try:
admin_db.command('enablesharding', 'whois')
except Exception as e:
print "whois:",e
try:
admin_db.command('shardCollection', 'whois.apnic', key = {'_id': 'hashed'})
except Exception as e:
print "apnic:",e
try:
admin_db.command('shardCollection', 'whois.apnic_cidr', key = {'_id': 'hashed'})
except Exception as e:
print "apnic_cidr:",e
try:
apnic.create_index({'id':1})
except Exception as e:
print e
try:
apnic_cidr.create_index({'ip_range_predix':1})
except Exception as e:
print e
三.Web服务搭建
1.Liunx下搭建XAMPP
- 即Apache服务器+Mysql+PHP+Perl,虽然用不到Mysql,但是后续使用基于PHP的Laravel框架,而且XMAPP一键部署一劳永逸,因此还是比较便捷的,尤其是搭建简单的PHP项目推荐使用。
2.使用Laravel框架搭建whois查询服务
数据已经导入MongoDB数据库,现在若要在Laravel框架下做Mongodb查询,需要引入针对Laravel框架的mongodb插件,可以参考这篇文章,引入mongodb插件时,主要需要做以下工作。
- 首先需要先安装PHP的mongodb扩展,亲测好使。
- 安装Laravel mongodb扩展。使用composer方式下载Laravel mongodb扩展遇到问题,主要是网络问题,理论上直接下载扩展文件复制到相关目录也可以。
3.前后台编码工作。
- 后台查询逻辑,核心就是前缀查询的实现。
- 前台页面使用个表格JS插件将数据进行展示。
最终效果如下图所示。
参考文献