使用redis存储全球IP库
将本文以行表形式存储于关系型数据库中的IP信息库,通过转换,存储到key-value型的Redis库中,以加快查询的速度。本文通过使用Redis的散列类型和有序集合类型来实现这种需求。
在工程中常有这样的需求,即给定IP(本文一律考虑将点分十进制的ip转为无符号整型),从(全球)IP库中查找相关信息。若将IP库存储于关系型数据库中(本文仅截取部分字段用于阐明),其形式大概如下:
TAGID | FROMIP | TOIP | INFO1 | INFO2 |
---|---|---|---|---|
TAG01 | 1779830784 | 1779831039 | 湖南省 | 电信 |
TAG02 | 987332096 | 987332351 | 江苏省镇江市 | 电信 |
TAG03 | 2026831104 | 2026831359 | 江西省南昌市 | 移动 |
TAG04 | 2059661056 | 2059661311 | 江苏省淮安市 | 联通 |
TAG05 | 832214272 | 832214527 | 江苏省南京市 | 广电网 |
假设要查询给定IP的INFO1和INFO2信息,SQL语句如下:
SELECT INFO1,INFO2 WHERE IP >= FROMIP AND IP <= TOIP;
这样的语句查询关系型是数据库是比较耗时的。下面设法将上述数据存储到Redis中,主要借助Redis的散列类型和有序集合类型。
建表过程:
1. 将表中的每一个行以TAGID作为key,其余值作为value,以散列类型作为value的数据结构进行存储;
2. 将FROMIP和TAGID的映射关系(以FROMIP作为score),以有序集合的形式进行存储,这样所有的FROMIP将从小到大的顺序存储在Redis中;
查询过程(以java客户端jedis为例):
1. 将ip转换为无符号整型
2. 从redis有序集合类型中查找全球库中小于该ip的最大fromip,即确定该IP所在的起始区间;
jedis.zrevrangeByScore(key, max, min, offset, count);
key:有序集合类型的key值,目前为"fromipscore"
max:待查询的无符号整型IP
min:置为-1
offset:置为0,返回结果集的起始偏移量
count:置为1,只返回符合条件的第一条
如果查找不到,则直接返回,即该IP在库中查找不到;否则进行步骤3操作
3. 将步骤2返回的结果,作为新的key,查找redis散列类型的数据结构,并进行比较以确定该IP是否在上一步确定的区间内
Map<String, String> val = jedis.hgetAll(key);
val中包含的示例如下:
{INFO2=联通, INFO1=江苏省南京市, TOIP=1910858495, FROMIP=1910858240}
从val中取出toip的值,转换为整型,并与待查找的ip进行比较;
如果待查询ip <= toip;则 val即为查询的结果集;否则查找不到
由于有序集合使用散列表和跳跃表实现,因此确定IP所在的起始区间时间复杂度不超过O(lgn);其次查找散列表的时间复杂度,在不发生冲突时是常数。下面在shell端,对上面过程进行演示,加深理解。
- 将每行数据以散列表形式存储
127.0.0.1:6379> hmset TAG01 FROMIP 1779830784 TOIP 1779831039 INFO1 湖南省 INFO2 电信
OK
127.0.0.1:6379> hmset TAG02 FROMIP 987332096 TOIP 987332351 INFO1 江苏省镇江市 INFO2 电信
OK
127.0.0.1:6379> hmset TAG03 FROMIP 2026831104 TOIP 2026831359 INFO1 江西省南昌市 INFO2 移动
OK
127.0.0.1:6379> hmset TAG04 FROMIP 2059661056 TOIP 2059661311 INFO1 江苏省淮安市 INFO2 联通
OK
127.0.0.1:6379> hmset TAG05 FROMIP 832214272 TOIP 832214527 INFO1 江苏省南京市 INFO2 广电网
OK
- 把FROMIP作为SCORE,将TAGID以有序集合进行存储,key为fromip:score
127.0.0.1:6379> zadd fromip:score 1779830784 TAG01
(integer) 1
127.0.0.1:6379> zadd fromip:score 987332096 TAG02
(integer) 1
127.0.0.1:6379> zadd fromip:score 2026831104 TAG03
(integer) 1
127.0.0.1:6379> zadd fromip:score 2059661056 TAG04
(integer) 1
127.0.0.1:6379> zadd fromip:score 832214272 TAG05
(integer) 1
- 查询
IP为1779830785,该IP的tagid为TAG01
127.0.0.1:6379> zrevrangebyscore fromip:score 1779830785 -1 limit 0 1
1) "TAG01"
127.0.0.1:6379> hgetall TAG01
1) "FROMIP"
2) "1779830784"
3) "TOIP"
4) "1779831039"
5) "INFO1"
6) "\xe6\xb9\x96\xe5\x8d\x97\xe7\x9c\x81"
7) "INFO2"
8) "\xe7\x94\xb5\xe4\xbf\xa1"
127.0.0.1:6379>
比较1779830785和结果集中的TOIP即可判断
使用redis存储全球IP库相关推荐
- [喵咪开源软件推荐(3)]全球IP库-GeoLite2-City
[喵咪开源软件推荐(3)]全球IP库-GeoLite2-City 哈喽大家好啊!喵咪开源软件推荐(3)终于和大家见面了,这次我们来说说什么呢?大家有没有遇到过这样一个场景,当你出国游玩的时候到了一个国 ...
- redis缓存原理与实现_基于Redis实现范围查询的IP库缓存设计方案
点击上方"码农沉思录" 发现更多精彩我先说下结果.我现在还不敢放线上去测,这是本地测的数据,我4g内存的电脑本地开redis,一次都没写完过全部数据,都是写一半后不是redis挂 ...
- Google全球IP地址库
Google提供了大量基于互联网的产品与服务,为全世界访问量最高的站点,Google搜索集成了全球范围的信息,是互联网上规模最大.使用率最高.影响最广泛的搜索引擎,使人人皆可访问并从中受益.但是,20 ...
- 通过Ip查询对应地址,Ip2location全球IP地址网段
通过Ip查询对应地址,Ip2location全球IP地址网段 1. Ip2location介绍 Ip2location IP 库 是比较准确的 在 免费查询IP 行列, 有很多的地址段, 有 Ip 详 ...
- redis存储图片_一不小心肝出了4W字的Redis面试教程
本文脑图 redis基本数据结构 本文脑图 前言 Redis是基于c语言编写的开源非关系型内存数据库,可以用作数据库.缓存.消息中间件,这么优秀的东西客定要一点一点的吃透它. 这是关于Redis五种数 ...
- 每秒1w+分布式事务--dtm的Redis存储性能测试分析
概述 之前dtm给出了Mysql作为存储引擎的性能测试报告,在一个普通配置的机器上,2.68w IOPS,4核8G机器上,能够支持大约每秒900+分布式事务,能够满足大部分公司的业务需求. 此次带来的 ...
- Redis 存储字符串和对象
今天用redis存储,发现客户端jedis提供的存储方法中存储的类型只有String和byte数据,没有能够存储对象的,网上发现可以序列化存储对象.这就开始了我第一次序列化之旅. 1 测试类 impo ...
- 纯真IP库的结构分析及一个查询类
个人网站上有个功能,记录访问者的IP及其归属地.最初我偷懒通过一个WebService来查询IP归属地,后来觉得通过这种方法响应时间长,资源耗费大,而且对那个WebSerice的依赖度太高,如果它挂了 ...
- Redis 存储分片之代理服务Twemproxy 测试
Redis 存储分片之代理服务Twemproxy 测试 转载自:http://blog.jpush.cn/redis-twemproxy-benchmark/ 概述 实际业务场景中单点 Redis 容 ...
最新文章
- firefly如何安装mysql_CentOS7 安装Firefly及测试
- Netty之Channel的继承关系
- 光纤转CAN总线在消防报警主机联网中的应用
- Windows 10 下基于WSL的开源飞控开发环境配置(Ardupilot/PX4)
- 08TensorFlow2.0基础--8.1TensorFlow2.0特性
- 马哥 mysql教学笔记_【马哥linux学员学习笔记】MySQL多实例详解
- 【C语言】整人小程序
- 迅为IMX6ULL开发板Linux RS232/485驱动实验(上)
- Redis 过期策略+conf 记录
- 【渝粤题库】广东开放大学物业管理基本制度与政策 形成性考核
- SLA、BFD、NQA、ACl 笔记
- 二补数 (2's complement)
- 网站优化关键词密度多少才是最合适的?
- Exception】Chrome浏览器提示:此网页正试图从未经验证的来源加载脚本
- Retina、非Retina、点、像素、iPhone分辨率
- 职场必备两款高效率管理工具,大有用处!
- 安卓开发——安卓界面布局笔记
- PHPWord的使用
- javaScript实现登录(简陋)
- 科达4k摄像机获创新产品特等奖
热门文章
- Bachelor's song
- 树形动态规划之树的最大独立集
- Window Server 2012许可证过期解决方法
- input标签 设置纯数字输入
- 如何做好跨境电商,先了解3个基本观念
- 7 展讯Sprd设置-电池-关联自启动-跟踪代码
- ssm在线教学质量评价系统毕业设计源码141550
- jQuery Easyui 源码分析之combo组件
- YOLOv5改进之十三:主干网络C3替换为轻量化网络EfficientNetv2
- c语言计算输入20个有符号整数,统计正整数,零,负整数的个数.操作,输入20个有符号整数,统计正整数.零.负整数的个数.并分别计算之和...