需要

通常咱们的做法是把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代表完结。数据如下:

valuescore
1:s0
1:e100
2:s200
3:e300

查问的时候,能够获取小于查问值的第一个成员,比方50,取到1:s,因为是s结尾,所以阐明在某个区间内,再通过1获取详细信息。如果传入的是150,则获取到1:e,因为是e结尾,所以不在任何区间内。如果是250,取到的是2:s,因为是s结尾,所以阐明在某个区间内,再通过2获取详细信息。
下面失去的1或者2获取的详细信息,是通过hash存的,1作为主键,内容寄存相应对象。

实际

@Testpublic 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);}@Testpublic 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);}