Whip,关于IP地址数据的谁、什么、哪里和何时
项目描述
概述
Whip,关于IP地址数据的谁、什么、哪里和何时。
Whip提供了一个快速的IP信息查询服务,可扩展到大型数据集。Whip可以高效地回答关于特定IP地址的查询,可选地通过时间戳进行细化。
功能摘要
对IP地址的快速查询,可选地限制在特定的时间戳内。这意味着随着时间的推移而(缓慢)变化的数据可以在任何已知的历史时刻进行查询。
透明支持IPv4和IPv6地址和范围
支持增量加载。这意味着可以将新数据添加到现有数据库中。这对于摄取每周数据集快照非常有用。
高效的存储格式(数据存储为范围,历史记录为差异)
透明支持以.gz结尾的gzip压缩输入数据
Whip可以处理几乎任何包含关于IP地址范围信息的数据集。Whip不对与IP地址或IP地址范围关联的数据类型进行限制,因此可以用于各种数据集,例如IP地理定位数据集。请注意,Whip自身不附带任何数据集。
源文件应被视为在特定时间点演变的数据集的“快照”。在加载阶段,Whip将所有快照(具有不同的时间戳)合并,并以一种可以高效查询的方式构建所有记录的历史记录。它通过构建IP范围的索引并将数据关联到每个范围(例如地理位置标签)来实现,并为每个不同的范围保留历史记录。
安装
使用virtualenv安装Whip及其依赖项。从源树安装:
$ pip install -r requirements.txt
这些是当前依赖项:
Python 3.3+(不支持Python 2!)
Plyvel 从Python访问LevelDB
Flask 用于REST API
Aaargh 用于命令行工具
UltraJSON (ujson) 用于快速JSON编码和解码
Msgpack 用于Msgpack编码和解码
用法
命令行界面
大多数功能都由whip-cli命令行工具提供。详细用法信息
$ whip-cli --help
将输入数据加载到my.db中(如有必要则创建它)
$ whip-cli --db my.db load input-file-1.json.gz input-file-2.json.gz
通过REST API提供数据库服务
$ whip-cli --db my.db serve
REST API也可以使用WSGI部署,例如使用gunicorn/nginx。
REST API
REST API支持以下查询:
获取IP地址的最新记录
GET /ip/1.2.3.4
获取IP地址的特定记录
GET /ip/1.2.3.4?datetime=2013-05-15
获取IP地址的完整历史记录
GET /ip/1.2.3.4?datetime=all
在每种情况下,响应将是一个< span class="docutils literal">application/json编码的文档,即使没有找到匹配项,此时结果将是一个空的JSON文档。HTTP状态码仅用于表示错误。
输入数据格式
源文件格式很简单:它只是一个包含每行一个JSON格式文档的文本文件。每个文档可以包含关于一组IP地址的任意信息。
Whip本身需要三个字段
begin:IP地址范围的起始(包含),例如1.0.0.0
end:IP地址范围的结束(包含),例如1.0.255.255
datetime:记录的时间戳,例如2013-02-28
除了这些字段外,每个文档还可以包含任意键/值对,例如"country"。
输入数据文件必须遵循以下规则:
文件中的每个范围必须至少跨越1个IP地址,但可以跨越任意数量的连续IP地址(不受网络块/CIDR限制),由begin和end字段指定。
单个输入文件中的范围不得重叠,但范围之间可以有间隙(在没有任何信息可用的情况下)。
单个输入文件中的范围必须按IP地址排序。IPv4范围必须在IPv6范围之前排序,因为Whip在内部使用RFC3493 IPv4映射IPv6地址。
在datetime字段中指定的时间戳应采用ISO8601格式,因为Whip依赖于输入字符串的字典序。
单个输入文件中的所有时间戳必须相同。是的,这增加了冗余,但避免了需要标题行或带外元数据的需求。
一个示例输入文档如下(为了清晰起见,格式化在多行中)
{ "begin": "1.0.0.0", "end": "1.255.255.255", "datetime": "2013-02-28", "location": "Amsterdam", "some-other-data": "anything-you-like" }
包含许多此类文档的单个输入文件如下所示
{"begin": "1.0.0.0", "end": "1.255.255.255", "datetime": "2013-02-28", "...": "..."} {"begin": "2.0.0.0", "end": "2.255.255.255", "datetime": "2013-02-28", "...": "..."} {"begin": "11.0.0.0", "end": "11.0.255.255", "datetime": "2013-02-28", "...": "..."}
Whip可以在单个加载过程中加载许多此类输入文件(例如,更长时期的每周快照)。
想法/待办事项
在内存结构上执行范围扫描,而不是在数据库迭代器上查找。这意味着Whip必须在启动时将所有键加载到内存中(在一个array.array数组中);使用bisect.bisect_right查找正确的条目,然后只需简单地调用db.get()来获取实际值。为了避免在启动时扫描整个数据库,应该使用键前缀来分割键空间:一部分同时保留键和值(完整数据库),另一部分只保留键。后者将在启动时扫描并加载到内存中。对于约2500万个IPv4地址,仅将索引保留在内存中只需要100MB的RAM,并且查找将仅对已知存在的键调用db.get()。
更新:在包含大多数使用IP范围的大数据库上进行的实验表明,这种方法并不比实际查找更快,因为it.seek()所需的时间与db.get()相同。这意味着将大量内存用于提高非命中(在这种情况下不进行数据库调用)的性能。
尝试使用LMDB而不是LevelDB
可插拔存储后端(例如HBase)
项目详情
whip-0.1.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | b1938b7da96616ffcc7ff08b6322f7461feceaf3abbb6d83075841d1c0ba55b2 |
|
MD5 | 03fe9650cad2bb0ddee78bedf0f12065 |
|
BLAKE2b-256 | 1aa6a4cf9dbe303f317a020b9b6b6cf7aebbf773926cd970be6cffc21e00c88c |