大家好,我是讯享网,大家多多关注。
一、开源项目简介
Ip 2 region——离线IP地址位置数据库,准确率99.9%,0.0x毫秒级查询。ip2region.db的数据库只有MB,提供了Java、PHP、C、Python、Nodejs、Golang、C #等查询绑定和二进制、B树、内存等三种查询算法。
二、开源协议
使用Apache-2.0开源协议
三、界面展示
四、功能概述Ip2region特性99.9%准确率
数据聚合了一些知名的ip到地名查询提供商的数据。这些是他们官方的准确率。经过测试,比经典的纯IP定位更准确。
IP2Region的数据聚合自开放API或以下服务提供商的数据(对升级程序的请求次数为每秒2到4次):
01,> 80%,淘宝IP地址库
02,≈ 10%,GeoIP
03,≈ 2%,纯IP库
备注:如果上述开放API或数据未给予开放数据,IP 2 region将停止数据更新服务。
标准化的数据格式
每个ip段都有固定的格式:
_ City Id | Country | Region | Province | City | ISP _只有中国的数据精确到城市,其他国家的一些数据只能定位到国家。前后所有选项都是0,已经包含了你能找到的所有国家(请忽略前面的城市Id和个人项目要求)。
体积小
包括所有IP,生成的数据库文件ip2region.db只有几MB,最小的版本也只有1.5MB,随着数据细节的增加,数据库的大小也逐渐增大,目前还没有超过8MB。
查询速度快
所有查询客户端都有一个0.x毫秒的单个查询,并且内置了三个查询算法。
memory算法:整个数据库全部载入内存,单次查询都在0.1x毫秒内,C语言的客户端单次查询在0.00x毫秒级别。binary算法:基于二分查找,基于ip2region.db文件,不需要载入内存,单次查询在0.x毫秒级别。b-tree算法:基于btree算法,基于ip2region.db文件,不需要载入内存,单词查询在0.x毫秒级别,比binary算法更快。
任何客户端b树都比二进制算法快,当然内存算法最快!
五、技术选型多查询客户端的支持
集成的客户端有:java,C#,php,C,python,nodejs,php扩展(php5和php7),golang,rust,lua,lua_c,nginx。
有约束力的
形容
发展状况
二进制查询需要时间
-b树查询需要时间。
内存查询耗时
c
ANSC c装订
脱销
0.0x
0.0x
0.00x毫秒
c#
c#绑定
脱销
0.x毫秒
0.x毫秒
0.1毫秒
戈朗
戈朗装订
脱销
0.x毫秒
0.x毫秒
0.1毫秒
Java语言(一种计算机语言,尤用于创建网站)
java绑定
脱销
0.x毫秒
0.x毫秒
0.1毫秒
左上臂
Lua实现的绑定
脱销
0.x毫秒
0.x毫秒
0.x毫秒
lua_c
lua的扩展
脱销
0.0x
0.0x
0.00x毫秒
nginx
nginx的扩展
脱销
0.0x
0.0x
0.00x毫秒
nodejs
nodejs
脱销
0.x毫秒
0.x毫秒
0.1毫秒
服务器端编程语言(Professional Hypertext Preprocessor的缩写)
php实现的绑定
脱销
0.x毫秒
0.1毫秒
0.1毫秒
php5_ext
php5的扩展
脱销
0.0x
0.0x
0.00x毫秒
php7_ext
php7的c扩展
脱销
0.0毫秒
0.0x
0.00x毫秒
大蟒
python绑定
脱销
0.x毫秒
0.x毫秒
0.x毫秒
锈
生锈粘合
脱销
0.x毫秒
0.x毫秒
0.x毫秒
2快速测试ip2region,请参考每个绑定下的README说明来运行cli测试程序。例如,C语言中的demo运行如下:
CD binding/c/gcc-g-O2 test searcher . c ip2 region . c ./a . out../../data/ip2region.db将看到以下cli界面:
正在初始化B树…+ – +| ip2region测试脚本||作者:chenxin619315@gmail.com | |类型& # 39;辞职& # 39;要退出程序|+-+p2 region >;& gt01.105.35.572163 |中国|华南|广东|深圳|彭博士0.02295毫秒输入IP地址开始测试,第一次会有点慢。运行命令后,访问二进制,内存尝试其他算法。建议使用b树算法。内存算法可用于速度和并发性要求。具体集成请参考不同绑定下的测试。
ip2region安装
请参考自述文件和每个绑定下的测试演示。以下是一些可用的快捷安装方法:
maven仓库地址
& lt依赖性& gt& ltgroupId & gtorg.lionsoul & lt/groupId & gt;& ltartifactId & gtip2region<。/artifact id & gt;& lt版本& gt1 . 7 . 2 & lt;/version & gt;& lt/dependency & gt;点头安装节点-ip2region-savenuget安装包ip2region PHP composer #插件来自:2Region Composer要求邹/IP2Region IP2Region所有绑定搜索接口的并发使用都不是线程安全的实现,不同的线程可以通过创建不同的查询对象来使用。在并发量较大的情况下,二叉树和b树算法可能会打开过多文件的错误。请修改内核中允许打开的文件的最大数量(fs.file-max=一个更大的值),或者使用持久性内存算法。MemorySearch接口在发布对象之前执行预查询(本质上,它将ip2region.db文件加载到内存中),可以安全地在多线程环境中使用。2Region.db的生成是从1.8版本开始的。ip2region.db生成器的java实现在ip2region中是开源的,并且提供了ant编译支持。编译后,dbMaker-{version}。将获得下面提到的罐子。需要研究生成器或者更改自定义生成配置的,可以参考${ip2region_root}/maker/java中的java源代码。
从IP2Region的1.2.2版开始,dbMaker-{version}的可执行jar文件。jar已提交。用它来完成这项工作:
确保你安装好了java环境(不玩Java的童鞋就自己谷歌找找拉,临时用一用,几分钟的事情)cd到${ip2region_root}/maker/java,然后运行如下命令:
Java-jar dbmaker-{version}。jar-src文本数据文件-region csv文件[-ip2region.db文件的目录由[-dst]生成# text数据文件:db文件的原始文本数据文件路径,自带的ip2region . db文件由/data/ip.merge.txt生成,你可以用自己的替换或者更改/data/ip.merge.txt重新生成# region CSV文件:这个文件的目的是方便IP 2 region进行数据关系存储的配置,得到的数据包含一个city_id,这个/data/origin/global_region.csv文件可以直接使用。# ip2region.db文件的目录:是可选参数,如果不指定,将在当前目录下生成一个./data/ip2region.db文件。获取生成的ip2region.db文件并覆盖原始的ip2region.db文件。默认的ip2region.db文件生成命令:CD $ { IP 2 region _ root }/Java/Java-JAR DB Maker-1 . 2 . 2 . JAR-src。/data/ip.merge.txt-region。/data/global _ region.csv #会看到大输出架构原理布局。
标题
日期
种类
标签
状态
类型
出版
作者
邮政
Ip2region数据库的文件结构和原理
2016-08-18
工具
Ip定位
ip2区域
出版
邮政
真实的
注册
电子邮件
显示名称
凶手
dongyado@gmail.com
凶手
Ip2region是一个Ip地址定位数据库,准确率99.9%。0.0x毫秒级查询,数据库文件大小仅为1.5M java、php、c、python查询客户端并提供二进制、B树和内存查询算法。
本文将分为三个部分:
源数据转变成ip2region db 文件的过程ip2region 的结构搜索方法(一). 源数据如何存储到ip2region.db1. 源数据来源与结构
ip2region的ip数据来自于无罪和淘宝的ip数据库。每次抓取后都会生成ip.merge.txt,然后通过程序根据这个源文件生成ip2region.db文件。
ip.merge.txt中的每一行对应一条完整的记录,每条记录由ip段和数据组成,格式如下:
0 . 0 . 0 | 0 . 255 . 255 . 255 . 255 |未分配或内网IP | 0 | 0 | 0 IP | 0 | 0 | 1 . 0 . 0 . 0 . 255 |澳大利亚| 0 |0|0|0|01 . 0 . 1 . 0 | 1 . 0 . 15 . 255 |中国|华南|广东|广州|电信1.0.16.0|1.0.31.255|日本| 0 | 0 | 0 | 01无数据区默认为0。
最新的ip.merge.txt有122474条记录,按照起始ip地址升序排列。
2. 如何生成ip2region.db
给定一个ip,如何从ip.merge.txt中快速找到该ip所属的记录?最简单的方法是顺序遍历。当ip在记录的开始和结束ip之间时,它被命中。
这是低效的。如何提高查询性能?任何使用过mysql和其他数据库的人都知道,使用索引。所以ip2region.db使用内置索引,直接将性能提升到0.0x级别。
根据ip.merge.txt,为所有数据生成索引,用数据地址形成索引块。然后,索引按起始ip的升序排列,并存储在数据文件的末尾。最终生成的ip2region.db文件大小只有3.5M
此时,数据库文件中的每个索引都指向一条相应的数据,也就是说,如
|中国|华南|广东|广州|电信|这样的数据在档案中重复存储了很多次。经过重复数据删除和优化后,ip2region.db此时只有1.5M,将所有数据库文件读入内存然后进行搜索是非常可行的。
(二). ip2region.db 结构
生成的ip2region.db文件包含以下四个部分:
1、超级块
2、标题索引
3、数据
4、索引
生成ip2region.db时,头中将预留8个字节的超级块和8k的头索引。
然后根据ip.merge.txt,根据每条记录的起始ip和结束ip以及数据,生成索引块。前四个字节存储起始ip,中间四个字节存储结束ip,最后四个字节存储计算出的数据地址并临时存储在索引区。
索引区和数据区确定后,索引的起始位置存储在超级块的前四个字节,结束位置存储在超级块的后四个字节。
然后将索引划分为4K索引分区,将索引在每个分区起始位置的起始ip和索引的位置存储在一个头索引块中,形成头索引区,最后写入ip2region.db
特定功能:
INDEX索引区域,索引元素为 index block (12 字节), 分成三个部分,起始ip, 结束ip, 数据信息, 每一条 index block 对应 ip.merge.txt 中的一条记录。数据信息: 前三个字节保存数据地址(DATA中),后一个字节保存数据长度。每个index block 表示一个ip段的索引。当指定ip 在某个 index block 的起始ip和结束ip中间,即表示命中索引。再通过 index block 中的数据地址和数据长度,就能从ip2region.db读取对应的地址。SUPER BLOCK用来保存 INDEX 的起始地址和结束地址,first index ptr 指向INDEX起始位置的index block, last index ptr 指向最后一个index block的地址。这样查询的时候直接读取superblock 8个字节,就能快速获取 INDEX 索引区域的地址。HEADER INDEXHEADER INDEX 区是对 INDEX 区的二级索引, INDEX总长度除以 4K 就是 HEADER INDEX 的实际索引数。该区域长度为8k, 由 8 bytes 的 header index block 组成。header index block 前四个字节存储每个4K分区起始位置的index block 的起始ip值,后四个字节指向该index block的地址。把HEADER INDEX 区定义为8k,可以通过一次磁盘读取读取整个HEADER INDEX 区,然后在内存中进行查询,查询的结果可以确定该ip在INDEX区的某个4k分区内,然后再根据地址一次读取4k index 到内存,再在内存中查询,从而减少磁盘读取的次数。DATA保存的数据,数据格式如下: 2163|中国|华南|广东省|深圳市|鹏博士分别表示 城市ip,国家,区域,省份,城市,运营商(三). 搜索方法binary搜索
不介绍二分法。步骤:
把ip值通过ip2long方法转为长整型通过 SUPER BLOCK 拿到INDEX的起始位置和结束位置相减+1得出index block 总数采用二分法直接求解,比较 index block 和当前ip的大小,即可找到该ip属于的 index block拿到该 index block 的后面四个字节, 分别得到数据长度和数据地址从数据地址读取拿到的所得长度的字节,即是搜索结果
以php客户端为例说明:
& lt?PHP fseek($ this-& gt;dbFileHandler,0);$ super block = fread($ this-& gt;dbFileHandler,8);//从文件0位置读回8个字节,即超级块$ this->:firstIndexPtr = self::getLong($ super block,0);//获取索引$ this–>的起始位置;lastIndexPtr = self::getLong($ super block,4);//获取索引结束位置$ this->;total blocks =($ this-& gt;lastIndexPtr-$ this-& gt;first INDEX ptr)/INDEX _ BLOCK _ LENGTH+1;//计算索引总数,即索引块总数。//二分法搜索$ l = 0;//低阶$ h = $ this->;总块数;//高阶$ data ptr = 0;while($l & lt;= $h ) { $m = (($l + $h)>& gt1);//中位数$ p = $ m * INDEX _ BLOCK _ LENGTHfseek($ this-& gt;dbFileHandler,$ this-& gt;firstIndexPtr+$ p);//移动读取位置$ buffer = fread($ this->;dbFileHandler,INDEX _ BLOCK _ LENGTH);//读取INDEX_BLOCK_LENGTH字节(12字节),即读取一个索引块$ sip = self:: getlong ($ buffer,0);//获取起始ip //比较if($ IP ;& gt24)& 0x ff);//数据长度$ dataPtr =($ dataPtr & 0x 00 ffffff);//数据位置返回数组(& # 39;city _ id & # 39= & gtself::getLong($ this-& gt;DbBinStr,$dataPtr),//获取城市id & # 39区域& # 39;= & gtsubstr($ this-& gt;Dbbinstr,$ dataptr+4,$ datalen-4)//获取其他数据);?& gt源代码请参考ip2region php客户端的binarySearch方法。
b-tree 搜索
-标题索引用于b树搜索。第一步是在标题索引中搜索,然后在索引中定位一个4K索引分区进行搜索。
步骤:
把ip值通过ip2long 转为长整型使用二分法在 HEADER INDEX 中搜索,比较得到对应的 header index blockheader index block 指向 INDEX 中的一个 4K 分区,所以直接把搜索范围降低到 4K采用二分法在获取到的 4K 分区搜索,得到对应的 index block拿到该 index block 的后面四个字节, 分别得到数据长度和数据地址从数据地址读取拿到的所得长度的字节,即是搜索结果
具体源代码见ip2region php客户端中的btreeSearch方法。
六、源码地址
访问飞行开源:https://code.exmay.com/
本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://51itzy.com/32063.html