redis – 根据ip查询地址

微信扫一扫,分享到朋友圈

redis – 根据ip查询地址

需求

通常我们的做法是把ip起始地址和结束地址转为long型存放数据库,然后把需要查询的ip转long型,判断是否在某个ip区间内,如果在,则取出对应的地址信息,如果不在,则不存在ip地址信息。比如北京的ip范围是0-100,上海的ip地址是200-300,那所要查询的ip是50,就属于北京,如果是250,就是上海,如果是150,那就是没有对应的地址。这边为了方便,数字是瞎编的。

如果用sql的话,是这样写的:

select * from table where 50>start and 50<end

上面sql,start是ip初始值,end是结束值。

在redis中,可以通过有序集合对分值进行排序以及根据分数进行排序。我们可以这样设计,在有序集合中,member的值为id+ :
+s|e,s代表起始位置,e代表结束。数据如下:

value score
1:s 0
1:e 100
2:s 200
3:e 300

查询的时候,可以获取小于查询值的第一个成员,比如50,取到1:s,由于是s结尾,所以说明在某个区间内,再通过1获取详细信息。如果传入的是150,则获取到1:e,由于是e结尾,所以不在任何区间内。如果是250,取到的是2:s,由于是s结尾,所以说明在某个区间内,再通过2获取详细信息。

上面得到的1或者2获取的详细信息,是通过hash存的,1作为主键,内容存放相应对象。

实践

@Test
public void init() {
// 初始化有序集合
JedisUtils.zadd("ip:segment", 0, "1:s");
JedisUtils.zadd("ip:segment", 100, "1:e");
JedisUtils.zadd("ip:segment", 200, "2:s");
JedisUtils.zadd("ip:segment", 300, "2:e");
// 初始化hash
Map<String, String> map = new HashMap<>();
map.put("name", "北京");
JedisUtils.hmset("ip:info:1", map);
Map<String, String> map2 = new HashMap<>();
map2.put("name", "上海");
JedisUtils.hmset("ip:info:2", map2);
}
@Test
public void test() {
getInfo(-1);
getInfo(50);
getInfo(150);
getInfo(250);
}
public void getInfo(double num) {
Set<String> tuples = JedisUtils.zrevrangeByScore("ip:segment", num, Integer.MIN_VALUE, 0, 1);
if (tuples.size() == 0) {
System.out.println("暂无对应地址");
return;
}
String member = tuples.iterator().next();
if (member.endsWith(":e")) {
System.out.println("暂无对应地址");
return;
}
String id = member.replace(":s", "");
Map<String, String> map = JedisUtils.hgetAll("ip:info:" + id);
System.out.println(map);
}

微信扫一扫,分享到朋友圈

redis – 根据ip查询地址

研究:向美红十字会献血的人中只有约2%有新冠抗体

上一篇

《太鼓之达人 咚咔!二合一大冒险》11月26日发售 CM公开

下一篇

你也可能喜欢

redis – 根据ip查询地址

长按储存图像,分享给朋友