范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

开源仅数MB,准确率99。9的离线IP地址定位库,0。0x毫秒级查询

  一、开源项目简介
  Ip2region - 准确率99.9%的离线IP地址定位库,0.0x毫秒级查询,ip2region.db数据库只有数MB,提供了java,php,c,python,nodejs,golang,c#等查询绑定和Binary,B树,内存三种查询算法。二、开源协议
  使用Apache-2.0开源协议三、界面展示
  四、功能概述Ip2region特性99.9%准确率
  数据聚合了一些知名ip到地名查询提供商的数据,这些是他们官方的的准确率,经测试着实比经典的纯真IP定位准确一些。
  ip2region的数据聚合自以下服务商的开放API或者数据(升级程序每秒请求次数2到4次):
  01, >80%, 淘宝IP地址库
  02,  10%, GeoIP
  03,  2%, 纯真IP库
  备注: 如果上述开放API或者数据都不给开放数据时ip2region将停止数据的更新服务。 标准化的数据格式
  每条ip数据段都固定了格式: _城市Id|国家|区域|省份|城市|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-tree都比binary算法快,当然memory算法固然是最快的! 五、技术选型多查询客户端的支持
  已经集成的客户端有:java、C#、php、c、python、nodejs、php扩展(php5和php7)、golang、rust、lua、lua_c, nginx。
  binding
  描述
  开发状态
  binary查询耗时
  b-tree查询耗时
  memory查询耗时
  c
  ANSC c binding
  已完成
  0.0x毫秒
  0.0x毫秒
  0.00x毫秒
  c#
  c# binding
  已完成
  0.x毫秒
  0.x毫秒
  0.1x毫秒
  golang
  golang binding
  已完成
  0.x毫秒
  0.x毫秒
  0.1x毫秒
  java
  java binding
  已完成
  0.x毫秒
  0.x毫秒
  0.1x毫秒
  lua
  lua实现的binding
  已完成
  0.x毫秒
  0.x毫秒
  0.x毫秒
  lua_c
  lua的c扩展
  已完成
  0.0x毫秒
  0.0x毫秒
  0.00x毫秒
  nginx
  nginx的c扩展
  已完成
  0.0x毫秒
  0.0x毫秒
  0.00x毫秒
  nodejs
  nodejs
  已完成
  0.x毫秒
  0.x毫秒
  0.1x毫秒
  php
  php实现的binding
  已完成
  0.x毫秒
  0.1x毫秒
  0.1x毫秒
  php5_ext
  php5的c扩展
  已完成
  0.0x毫秒
  0.0x毫秒
  0.00x毫秒
  php7_ext
  php7的c扩展
  已完成
  0.0毫秒
  0.0x毫秒
  0.00x毫秒
  python
  python bindng
  已完成
  0.x毫秒
  0.x毫秒
  0.x毫秒
  rust
  rust binding
  已完成
  0.x毫秒
  0.x毫秒
  0.x毫秒 ip2region快速测试
  请参考每个binding下的README说明去运行cli测试程序,例如C语言的demo运行如下: cd binding/c/ gcc -g -O2 testSearcher.c ip2region.c ./a.out ../../data/ip2region.db
  会看到如下cli界面: initializing  B-tree ...  +----------------------------------+ | ip2region test script            | | Author: chenxin619315@gmail.com  | | Type "quit" to exit program      | +----------------------------------+ p2region>> 101.105.35.57 2163|中国|华南|广东省|深圳市|鹏博士 in 0.02295 millseconds
  输入IP地址开始测试,第一次会稍微有点慢,在运行命令后面接入binary,memory来尝试其他算法,建议使用b-tree算法,速度和并发需求的可以使用memory算法,具体集成请参考不同binding下的测试源码。 ip2region安装
  具体请参考每个binding下的README文档和测试demo,以下是一些可用的快捷安装方式: maven仓库地址     org.lionsoul     ip2region     1.7.2 nodejsnpm install node-ip2region --savenuget安装Install-Package IP2Regionphp composer# 插件来自:https://github.com/zoujingli/ip2region composer require zoujingli/ip2regionip2region 并发使用全部binding的各个search接口都 不是 线程安全的实现,不同线程可以通过创建不同的查询对象来使用,并发量很大的情况下,binary和b-tree算法可能会打开文件数过多的错误,请修改内核的最大允许打开文件数(fs.file-max=一个更高的值),或者使用持久化的memory算法。 memorySearch接口,在发布对象前进行一次预查询(本质上是把ip2region.db文件加载到内存),可以安全用于多线程环境。 ip2region.db的生成
  从1.8版本开始,ip2region开源了ip2region.db生成程序的java实现,提供了ant编译支持,编译后会得到以下提到的dbMaker-{version}.jar,对于需要研究生成程序的或者更改自定义生成配置的请参考${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文件 [-dst 生成的ip2region.db文件的目录]  # 文本数据文件:db文件的原始文本数据文件路径,自带的ip2region.db文件就是/data/ip.merge.txt生成而来的,你可以换成自己的或者更改/data/ip.merge.txt重新生成 # 地域csv文件:该文件目的是方便配置ip2region进行数据关系的存储,得到的数据包含一个city_id,这个直接使用/data/origin/global_region.csv文件即可 # ip2region.db文件的目录:是可选参数,没有指定的话会在当前目录生成一份./data/ip2region.db文件获取生成的ip2region.db文件覆盖原来的ip2region.db文件即可 默认的ip2region.db文件生成命令: cd ${ip2region_root}/java/ java -jar dbMaker-1.2.2.jar -src ./data/ip.merge.txt -region ./data/global_region.csv  # 会看到一大片的输出架构原理
  layout
  title
  date
  categories
  tags
  status
  type
  published
  author
  post
  Ip2region 数据库文件结构及原理
  2016-08-18
  tool
  ip定位
  ip2region
  publish
  post
  true
  login
  email
  display_name
  slayer
  dongyado@gmail.com
  slayer
  ip2region 是一个准确率99.9%的ip地址定位库。 0.0x毫秒级查询,数据库文件大小只有1.5M,提供了java, php, c, python查询客户端和Binary,B树,内存三种查询算法。
  本文将分三个部分: 源数据转变成ip2region db 文件的过程 ip2region 的结构 搜索方法 (一). 源数据如何存储到ip2region.db1. 源数据来源与结构
  ip2region 的ip数据来自纯真和淘宝的ip数据库,每次抓取完成之后会生成 ip.merge.txt, 再通过程序根据这个源文件生成ip2region.db 文件。
  ip.merge.txt 中每一行对应一条完整记录,每一条记录由ip段和数据组成,格式如下: 0.0.0.0|0.255.255.255|未分配或者内网IP|0|0|0|0 1.0.0.0|1.0.0.255|澳大利亚|0|0|0|0 1.0.1.0|1.0.3.255|中国|华东|福建省|福州市|电信 1.0.4.0|1.0.7.255|澳大利亚|0|0|0|0 1.0.8.0|1.0.15.255|中国|华南|广东省|广州市|电信 1.0.16.0|1.0.31.255|日本|0|0|0|0 1.0.32.0|1.0.63.255|中国|华南|广东省|广州市|电信 1.0.64.0|1.0.127.255|日本|0|0|0|0 1.0.128.0|1.0.255.255|泰国|0|0|0|0 1.1.0.0|1.1.0.255|中国|华东|福建省|福州市|电信
  从左到右分别表示: 起始ip,结束ip,国家,区域,省份,市,运营商。无数据区域默认为0。
  最新的ip.merge.txt 有122474条记录,并且根据开始ip地址升序排列。 2. 如何生成ip2region.db
  给定一个ip,如何快速从ip.merge.txt中找到该ip所属记录?最简单的办法就是顺序遍历,当该ip在某条记录起始和结束ip之间时,即命中。
  这是低效的做法,如何提高查询性能?用过mysql和其他数据库的的都知道,使用索引。所以ip2region.db使用了内建索引,直接将性能提升到0.0x毫秒级别。
  根据ip.merge.txt,为所有数据生成一份索引,并和数据地址组成一个索引项(index block), 然后按起始ip升序排列组成索引,并存储到数据文件的末尾,最终生成的ip2region.db文件大小只有3.5M。
  此时的数据库文件中的每一条索引都指向一条对应的数据,也就是说如 |中国|华南|广东省|广州市|电信
  这样的数据在文件中被重复存储了很多次,再经过去重优化之后,ip2region.db只有1.5M了,此时把数据库文件全部读取到内存再查找都是非常可行的。 (二). ip2region.db 结构
  生成的ip2region.db文件包含以下四个部分:
  1, SUPER BLOCK
  2, HEADER INDEX
  3, DATA
  4, INDEX
  生成 ip2region.db 的时候,首先会在首部预留 8 bytes 的SUPER BLOCK 和 8k 的 HEADER INDEX。
  再根据ip.merge.txt,依据每一条记录的起始ip, 结束ip和数据,生成一个index block, 前四个字节存储起始ip, 中间四个字节存储结束ip, 后四个字节存储已经计算出的数据地址,并暂存到INDEX区。
  当 INDEX 索引区和 DATA 数据区确定下来之后,再把 INDEX 的起始位置存储到 SUPER BLOCK 的前四个字节,结束位置存储到 SUPER BLOCK 的后四个字节。
  再把 INDEX 分成大小为 4K 的索引分区,把每个分区起始位置的索引的起始ip和该索引的位置存入一个 header index block, 组成 HEADER INDEX 区域, 最后写入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 INDEX HEADER 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客户端作为例子注释: <?php     fseek($this->dbFileHandler, 0);      $superBlock = fread($this->dbFileHandler, 8); // 从文件0位置往后读取8字节,即 super block     $this->firstIndexPtr = self::getLong($superBlock, 0); // 获取INDEX起始位置     $this->lastIndexPtr  = self::getLong($superBlock, 4); // 获取INDEX结束位置     $this->totalBlocks   = ($this->lastIndexPtr-$this->firstIndexPtr)/INDEX_BLOCK_LENGTH + 1; // 计算总索引数,即 index block 总数      // 二分法搜索     $l = 0; // 低位     $h = $this->totalBlocks; // 高位     $dataPtr = 0;     while ( $l <= $h  ) {         $m = (($l + $h) >> 1); // 中位         $p = $m * INDEX_BLOCK_LENGTH;         fseek($this->dbFileHandler, $this->firstIndexPtr + $p); // 移动读取位置         $buffer = fread($this->dbFileHandler, INDEX_BLOCK_LENGTH); // 读取 INDEX_BLOCK_LENGTH 个字节 (12 字节), 即读取一个index block         $sip    = self::getLong($buffer, 0); // 获取开始 ip                  // 进行比较         if ( $ip < $sip  ) {             $h = $m - 1; // 比中位index block 开始ip小         } else {             $eip = self::getLong($buffer, 4);             if ( $ip > $eip  ) {                 $l = $m + 1; // 比中位index block 的结束ip小             } else { // 命中数据                 $dataPtr = self::getLong($buffer, 8); // getLong 函数将字节的顺序反过来了                 break;             }         }     }      // 下面这段代码看起来似乎是,第一个字节存储的长度,后三个字节存储的数据位置     // 其实是上文的 getLong 函数在获取数据的时候对字节顺序做了一下反转,具体参考 getLong 函数的代码     // 读取数据      $dataLen = (($dataPtr >> 24) & 0xFF); // 数据长度     $dataPtr = ($dataPtr & 0x00FFFFFF);   // 数据位置      return array(             "city_id" => self::getLong($this->dbBinStr, $dataPtr),  // 获取城市id             "region"  => substr($this->dbBinStr, $dataPtr + 4, $dataLen - 4) // 获取其他数据     ); ?>
  源码请查阅 ip2region php client 的 binarySearch 方法。 b-tree 搜索
  b-tree 搜索用到了 HEADER INDEX,第一步先在 HEADER INDEX 中搜索,再定位到 INDEX 中的某个 4k index分区搜索。
  步骤: 把ip值通过ip2long 转为长整型 使用二分法在 HEADER INDEX 中搜索,比较得到对应的 header index block header index block 指向 INDEX 中的一个 4K 分区,所以直接把搜索范围降低到 4K 采用二分法在获取到的 4K 分区搜索,得到对应的 index block 拿到该 index block 的后面四个字节, 分别得到数据长度和数据地址 从数据地址读取拿到的所得长度的字节,即是搜索结果
  具体源码请查阅 ip2region php client 中的 btreeSearch 方法。 六、源码地址
  访问一飞开源:https://code.exmay.com/

一个男人,主动在这三个时候联系你,说明是真爱文森屿鹿林感情里,一个人的爱在哪,联系就在哪。心里住进了某个人,就会忍不住惦记着对方,心心念念,牵挂不已。或许,他平时并不是喜欢主动联系别人的人,但是却会频繁联系你,在你需要的时候叛逆的性感10叛逆的性感,性感中夹带寂寞的野蛮,挣脱糜烂,她需要蜕变也需要勇敢才如此诠释一番。叛逆的性感,性感里携带忧郁的慵懒,摆脱纠缠,她需要嫉妒也需要危险,才因此拒绝一般。叛逆的性感,性感内我将初心安放于俗世,喧嚣过处依旧如画如诗人生总是奇妙的,一旦你努力去做一件事,如果结果不是你想象的那样,那么老天一定会给你一个更好的结果。刘同坚持去做一件事情,让它成为你生活里面的内核,不管遇到怎样的风雨都不会放弃,始终世界上最大的监狱,是人的思维引言叔本华说世界上最大的监狱,是人的思维。我们每个人都被自己的认知牢牢禁锢其中。如果仔细检查我们过往犯过的那些错误,或者失去的各种机会,你会发现绝大多数过失都是我们自己的认知局限带人生感悟这人活一辈子真的不容易,有的是风花雪月,快活逍遥,可有些人过着底层的的生活,只要能吃饱饭,养活家人就可以了,这就是人生,你的什么命老天已经给你安排好了,只能靠你后天的努力也许生活能当代散文老家的院落文张化纪提起老家,总有一份温暖和幸福荡漾心间。她见证了我的顽皮淘气快乐年华,她一直就是我温暖的港湾,深切的牵挂。老家的院落虽然不算很大,她的建筑虽然是土木结构不算豪华,但她是我一直琥珀中的史前蚂蚁,隐藏着生物进化的密码琥珀,由中生代白垩纪至新生代第三纪时期各种松柏科植物分泌树脂形成,是一种透明的生物化石。当树脂滴落后,在地下埋藏千万年,在压力与热力的作用下发生石化,随后经冲刷搬运沉积以及成岩作用天宫已建成,阿尔忒弥斯I任务还在路上两个重量都超20吨的庞然大物在高速飞行中对接,被形容为万里穿针今天凌晨4点,梦天实验舱经过13小时的飞行,终于追上了天宫组合体并成功对接至此,我国的国家太空实验室天宫空间站仅用时1梦天实验舱成功发射升空,你知道它有多牛吗?你知道梦天实验舱有多牛吗?10月31日15时37分,搭载空间站梦天实验舱的长征五号B遥四运载火箭也就是我们称为胖五的运载火箭,在我国文昌航天发射场点火发射,梦天实验舱与火箭成功分离告别纠结!今年双十一客厅选购智慧屏不妨看看这几款爆款产品随着人们生活水平的提高,消费者对家庭装修的理念也在发生变化,大屏化电竞化智能化成为当下客厅美学的主流消费趋势,所以其实如今对于大部分用户来说,智慧屏产品是相当重要的,智慧屏产品拥有双十一电脑怎么配?老司机教你合理搭配出高性价比配置一前言一年一度的双十一从本人写这篇文章(31号)开始,算是正式拉开了帷幕。其实严格来说,从20号左右付定金算起,双十一就已经开始了,只是比起往年,三哥今年买的东西不算多,就一颗U一
又涉童装!家长警惕最新检测不合格率16。4!这一项曾造成2名儿童死亡儿童衣服上的蝴蝶结绳带非常普遍,但一旦某些东西被缠住卡住,给孩子的安全不可想像!最近几年的童装国家监督抽查,像重金属增塑剂等项目超标的情况已经比较少见了,但是过长的绳带不牢固的小装没有语言的自闭症孩子,原因出在哪儿?常见的有这几个我们有很多自闭症孩子被发现异常是因为到了该说话的年纪还不会说话,才被家长带去就诊发现的。有的自闭症孩子会有语言,但是具备的语言能力也不能进行无障碍的沟通交流。还有一部分自闭症孩子是明年起儿童化妆品禁止标注可食用来源经济日报无论是商场还是电商平台,儿童口红儿童眼影儿童粉饼等广告随处可见。这些儿童化妆品在安全问题上给家长带来困扰,也给监管部门带来新挑战。儿童的皮肤与成人相比,具有不同的生理特孩子不爱吃蔬菜?做一份这样的蔬菜卷饼,好吃到停不下来让我家孩子吃蔬菜真的是太难了,但是为了孩子的健康着想还是没办法,绞尽脑汁给来给孩子做不一样的美食,虽然孩子不喜欢吃蔬菜,但是很喜欢吃鸡肉,在食材的搭配上面,食物就是要多元化才能营养张老师绘本分享爸爸系列绘本我爸爸我爸爸与我妈妈一样,都是安东尼布朗的家庭系列绘本。朗朗上口的短句,是低幼儿语言模仿的最佳选择同时也是小学生学习写作的好素材。不同年龄段阅读会有不一样的收获比心爸爸带我看宇宙一生命教育的绝佳蓝本楼上的外婆和楼下的外婆最近有朋友的孩子正在经历死亡敏感期,天天追问关于生死的事情。朋友不知道该如何作答,让羽佳推荐几本跟生命(包括死亡)相关的绘本。我随便翻了翻公号,猛然发现,我居然这么喜欢这个主题,分童声颂祖国童心感党恩来源阳泉日报9月27日,上站幼儿园萌娃迎国庆童声颂祖国系列活动在榴园大舞台举行,全园近400名幼儿参加了活动。活动中,小朋友盛装出席,脸上洋溢着灿烂的笑容,用一个个精彩的节目表达着春天奢侈的十件小事时间,不知不觉进入春天的地界已有一段时日。关于春天,有太多美好的词汇了春山春水,春风春雨,春草春花,春日春泥,春夜春心,春社春耕今天和你分享春天奢侈的十件小事。这个代言生命希望与爱酒店到底有多脏?你知道你住的酒店有多脏吗?那些看似干净卫生的酒店实则满屋细菌与病毒在房间的某个角落甚至还遗留着上位住户的毛发特别是非一次性用品,是藏污纳垢的好地方而本篇作品将带大家重新认识一下酒店民风淳朴歌声悠扬来源人民网人民日报美德村,鼓楼晨曦。田健摄(影像中国)占里村,青山绿禾。粟勇主摄(人民视觉)占里村,丰收归来。粟勇主摄(人民视觉)欣赏侗寨景色品尝特色美食,向村里的歌队学习侗歌侗族迪士尼人偶又被打,童话世界不是装傻犯浑的理由上海迪士尼乐园中憨态可掬的人偶为游客带去不少欢乐。然而,有些游客总是管不住自己的手。最近,达菲玲娜贝儿就接连被拍头,甚至影响了巡游表演。在那些动手的游客看来,玩偶服看着软绵绵的,拍