资讯专栏INFORMATION COLUMN

建立一套IP查询系统,将IP对应到地区,实现每秒千次以上的查询。

TZLLOG / 1868人阅读

摘要:但是无论如何,我都达到不了想要的执行效率,最好的时候每秒查询的数据都超不过条。效率一下子提高了上来,每秒查询效率稳稳过次。

这两天接了个任务,描述如下:

建立一套IP查询系统,将IP对应到地区,实现每秒千次以上的查询。

1.MySQL+PHP的方式:

将网上的数据源扒下来,一条一条放到mysql中,然后使用sql语句查询,建立索引,
数据库结构
SET FOREIGN_KEY_CHECKS=0;


-- Table structure for ip_address


DROP TABLE IF EXISTS ip_address;
CREATE TABLE ip_address (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
start_ip int(10) unsigned NOT NULL,
end_ip int(10) unsigned NOT NULL,
region varchar(50) NOT NULL,
address varchar(100) NOT NULL,
PRIMARY KEY (id),
KEY start (start_ip) USING BTREE,
KEY end (end_ip)
) ENGINE=MyISAM AUTO_INCREMENT=405037 DEFAULT CHARSET=utf8;

INSERT INTO ip_address VALUES ("1", "0", "16777215", "IANA保留地址", "CZ88.NET");
INSERT INTO ip_address VALUES ("2", "16777216", "16777471", "澳大利亚", "CZ88.NET");
INSERT INTO ip_address VALUES ("3", "16777472", "16778239", "福建省", "电信");
INSERT INTO ip_address VALUES ("4", "16778240", "16779263", "澳大利亚", "CZ88.NET");
INSERT INTO ip_address VALUES ("5", "16779264", "16781311", "广东省", "电信");

.......

查询数据的时候使用SELECT * FROM ip_address WHERE ip_startip <= ip AND ip_endip >= ip。
但是无论如何,我都达到不了想要的执行效率,最好的时候每秒查询的数据都超不过30条。

完成不了任务,只好去问问度娘。

2.diszuz中的实现方式:

function convertip_tiny($ip, $ipdatafile) {

static $fp = NULL, $offset = array(), $index = NULL;

$ipdot = explode(".", $ip);
$ip    = pack("N", ip2long($ip));

$ipdot[0] = (int)$ipdot[0];
$ipdot[1] = (int)$ipdot[1];

if($fp === NULL && $fp = @fopen($ipdatafile, "rb")) {
    $offset = @unpack("Nlen", @fread($fp, 4));
    $index  = @fread($fp, $offset["len"] - 4);
} elseif($fp == FALSE) {
    return  "- Invalid IP data file";
}

$length = $offset["len"] - 1028;
$start  = @unpack("Vlen", $index[$ipdot[0] * 4] . $index[$ipdot[0] * 4 + 1] . $index[$ipdot[0] * 4 + 2] . $index[$ipdot[0] * 4 + 3]);

for ($start = $start["len"] * 8 + 1024; $start < $length; $start += 8) {

    if ($index{$start} . $index{$start + 1} . $index{$start + 2} . $index{$start + 3} >= $ip) {
        $index_offset = @unpack("Vlen", $index{$start + 4} . $index{$start + 5} . $index{$start + 6} . "x0");
        $index_length = @unpack("Clen", $index{$start + 7});
        break;
    }
}

@fseek($fp, $offset["len"] + $index_offset["len"] - 1024);
if($index_length["len"]) {
    return "- ".@fread($fp, $index_length["len"]);
} else {
    return "- Unknown";
}

}

用的是二进制的文件,然后使用快速查找法:(折半查找法)。效率一下子提高了上来,每秒查询效率稳稳过5000次。哈哈!

3.PHP扩展的方式:

方式和PHP一样的,不过使用了C语言,效率直接超过了50000(五万)次。效率那就不用说了,核心代码如下:
扩展地址:http://pecl.php.net/package/qqwry
下载后安装方式按照phpize的方式即可
计入安装目录:
./phpize
./configure
make && makeinstall
然后要确保qqwry.so放到扩展目录下,并添加php.ini:
extension=qqwry.so
OK,已经好了

static uint32_t search_index(const uint32_t ip,FILE *qqwry_file) {
uint32_t index_ip;
unsigned char head[8];
unsigned char index_bytes[7];
fread(head,8,1,qqwry_file);
uint32_t index_start,index_end,index_mid;
index_start = (uint32_t)LE_32(&head[0]);
index_end = (uint32_t)LE_32(&head[4]);
while (1) {
    if ((index_end-index_start)==7) {
        break;
    }
    //printf("index:%u:%u
",index_start,index_end);
    index_mid=index_end/7 - index_start/7;
    if (index_mid%2==0) {
        index_mid=index_mid/2;
    } else {
        index_mid=(index_mid+1)/2;
    }
    index_mid=index_start+index_mid*7;
    fseek(qqwry_file,index_mid,SEEK_SET);
    fread(index_bytes,7,1,qqwry_file);
    index_ip=(uint32_t)LE_32(&index_bytes[0]);
    if (index_ip==ip) {
        break;
    } else if (index_ipip) {
    fseek(qqwry_file,index_start,SEEK_SET);
    fread(index_bytes,7,1,qqwry_file);
}
return (uint32_t)LE_24(&index_bytes[4]);

}
这也是我目前为止找的效率最快的方式了,完全能够买足公司的需求了。如果有能够效率更高的方式,留个言哈。

所有需要的文件都可以从这里下载哈:
http://url.cn/QorZ2O
下载后把data.rar解压到当前目录,并执行index.php就可以查看后面的两种方式的执行效率了(前提是,有装qqwry扩展哈!)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/20727.html

相关文章

  • 建立一套IP查询系统IP对应地区实现每秒千次以上查询

    摘要:但是无论如何,我都达到不了想要的执行效率,最好的时候每秒查询的数据都超不过条。效率一下子提高了上来,每秒查询效率稳稳过次。 这两天接了个任务,描述如下: 建立一套IP查询系统,将IP对应到地区,实现每秒千次以上的查询。 1.MySQL+PHP的方式: 将网上的数据源扒下来,一条一条放到mysql中,然后使用sql语句查询,建立索引, 数据库结构 SET FOREIGN_KEY_C...

    haitiancoder 评论0 收藏0
  • 2017中国云计算评测报告

    摘要:当前国内云计算服务仍处于单打独斗,提供单向服务的阶段,完整生态模式尚未搭建完成。注特别说明的是,评测期间我们随机抽取了金山云位于北京区的机房用于验证评测,属传统扁平网络,此机房在本次报告发布时已不再售卖。 ➨ 报告电子版至听云官方博客下载:http://blog.tingyun.com/web/a... 评测说明 评测目标:同一应用(网站)在不同云上的用户访问体验,以及对云资源的使用洞...

    changfeng1050 评论0 收藏0
  • UCloud IP信息服务与IPIP.NET原厂合作,价格低至0.25元/千次

    摘要:信息服务产品页信息服务产品优势原厂合作与原厂合作,保证数据准确性实时性。价格弹性低至元千次,可按次购买,按需使用,按实际用量计费,精确到元。用量熔断接口有小时级别的次数限制,不用担心因误操作导致意外的大额费用。UCloud IP信息服务IP 库是一个互联网基础数据,在做 CDN、DNS 智能解析、广告定向投放、用户地域分析、用户定制化体验等等诸多场景,IP 库的准确与否对效果好坏有直接的影响...

    Tecode 评论0 收藏0
  • PHP面试常考之网络协议

    摘要:是为互联网服务的协议族,它是网络通信协议的统称,由和等协议组成。预告本周五更新面试常考题之会话控制和网络协议,敬请期待。以上内容摘自程序员面试笔试宝典书籍,该书已在天猫京东当当等电商平台销售。 你好,是我琉忆,欢迎您来到PHP面试专栏。本周(2019.2-25至3-1)的一三五更新的文章如下: 周一:PHP面试常考之会话控制周三:PHP面试常考之网络协议周五:PHP面试常考题之会话控...

    joywek 评论0 收藏0
  • CDN小结

    摘要:二目的是一个经策略性部署的整体系统,从技术上全面解决由于网络带宽小用户访问量大网点分布不均而产生的用户访问网站响应速度慢的根本原因。 一、CDN全称:  Content Delivery Network或Content Ddistribute Network,即内容分发网络。   二、目的:  CDN是一个经策略性部署的整体系统,从技术上全面解决由于网络带宽小、用户访问量大、网点分布不...

    cod7ce 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<