博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用redis存储全球IP库
阅读量:2425 次
发布时间:2019-05-10

本文共 2426 字,大约阅读时间需要 8 分钟。

将本文以行表形式存储于关系型数据库中的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:待查询的无符号整型IPmin:置为-1offset:置为0,返回结果集的起始偏移量count:置为1,只返回符合条件的第一条

如果查找不到,则直接返回,即该IP在库中查找不到;否则进行步骤3操作

3. 将步骤2返回的结果,作为新的key,查找redis散列类型的数据结构,并进行比较以确定该IP是否在上一步确定的区间内

Map
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 电信OK127.0.0.1:6379> hmset TAG02 FROMIP 987332096 TOIP 987332351 INFO1 江苏省镇江市 INFO2 电信OK127.0.0.1:6379> hmset TAG03 FROMIP 2026831104 TOIP 2026831359 INFO1 江西省南昌市 INFO2 移动OK127.0.0.1:6379> hmset TAG04 FROMIP 2059661056 TOIP 2059661311 INFO1 江苏省淮安市 INFO2 联通OK127.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) 1127.0.0.1:6379> zadd fromip:score 987332096 TAG02(integer) 1127.0.0.1:6379> zadd fromip:score 2026831104 TAG03(integer) 1127.0.0.1:6379> zadd fromip:score 2059661056 TAG04(integer) 1127.0.0.1:6379> zadd fromip:score 832214272 TAG05(integer) 1
  • 查询
IP为1779830785,该IP的tagid为TAG01127.0.0.1:6379> zrevrangebyscore fromip:score 1779830785 -1 limit 0 11) "TAG01"127.0.0.1:6379> hgetall TAG011) "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即可判断

转载地址:http://ykbmb.baihongyu.com/

你可能感兴趣的文章
三星计划替换所有日产半导体材料;美企过度响应“禁令”,华为被曝祭出数亿索赔;苹果iPhone 11发布日期刚刚泄露...
查看>>
帮助你驾驭 Kubernetes 的 4 个工具 | Linux 中国
查看>>
Storm精华问答 | storm与Hadoop区别?
查看>>
正式发布!鸿蒙,来了!
查看>>
项目是如何死掉的?太过真实!
查看>>
再见!微服务
查看>>
这!不是一点儿super,青云混合云!
查看>>
华为开发者大会上,鸿蒙问世、方舟编译器开源、还有 EMUI 10;壕置100万美元,苹果推出漏洞攻击报告赏金计划……...
查看>>
Spring精华问答 | 为什么要学习Spring?
查看>>
常见的Hadoop十大应用误解
查看>>
“Java跌落向下,Python奋斗向前”,程序员:看哭了...
查看>>
蜕变!网易轻舟微服务这波操作,始于异构融合、源于中台!
查看>>
Kafka精华问答 | kafka节点之间如何备份?
查看>>
来华30载,这些都是Oracle的神来之笔……
查看>>
Kubernetes要成为一个企业友好平台,到底还缺啥?
查看>>
云数据库精华问答 | 云数据库与其他数据库的关系
查看>>
美国专利机构榜单:华为、京东方进前20名;印度巨头信实与微软结盟;三星发布 1.08 亿像素传感器,小米参与合作……...
查看>>
5G基站功耗,到底有多大?
查看>>
行!这下 CSDN 玩大了!粉丝:太良心
查看>>
Spark精华问答 | 怎么运行Spark?
查看>>