将ip对应城市数据导入redis并查询
1.GeoLite免费数据库
先去地址http://dev.maxmind.com/zh-hans/geoip/legacy/geolite/#i-5下载GeoLiteCity-latest .zip压缩包,数据库包包含两个重要的文件:一个是GeoLiteCity-Blocks.csv,它记录了多个IP地址段以及这些地址所属城市的ID,另一个GeoLiteCity-Location.csv,它记录了对应城市与城市名,地区/州名/省名、国家名一级一些不会用到的其他信息直接的映射。先通过ip查找ip所属城市的id,然后根据城市id查找对应的城市的实际信息
2.编写java程序将CSV导入redis
city类:
public class City { //城市id private String cityId; //国家 private String country; //区域 private String region; //城市名 private String city; //邮政编码 private String postalCode; //纬度 private String latitude; //经度 private String longitude; //都市号 private String metroCode; //区号 private String areaCode; public String getCityId() { return cityId; } public void setCityId(String cityId) { this.cityId = cityId; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getRegion() { return region; } public void setRegion(String region) { this.region = region; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getPostalCode() { return postalCode; } public void setPostalCode(String postalCode) { this.postalCode = postalCode; } public String getLatitude() { return latitude; } public void setLatitude(String latitude) { this.latitude = latitude; } public String getLongitude() { return longitude; } public void setLongitude(String longitude) { this.longitude = longitude; } public String getMetroCode() { return metroCode; } public void setMetroCode(String metroCode) { this.metroCode = metroCode; } public String getAreaCode() { return areaCode; } public void setAreaCode(String areaCode) { this.areaCode = areaCode; } }
config类:
public class Config { public static final String GEOLITECITY_LOCATION="E://ip/GeoLiteCity-Location.csv"; public static final String GEOLITECITY_BLOCKS="E://ip/GeoLiteCity-Blocks.csv"; public static final String IP2CITYID="ip2cityid:"; public static final String CITYID2CITY="cityid2city:"; }
data2redis类:
public class Data2Redis { public long toSore(String ipAddress){ long score=0; for(String str:ipAddress.split("\\.")) score= score*256 + Integer.parseInt(str, 10); return score; } public void ipToRedis(Jedis jedis,File file){ Pipeline pipeline=jedis.pipelined(); try { System.out.println("导入ip地址开始"); long startTime=System.currentTimeMillis(); Reader reader=new FileReader(file); CSVParser parser=new CSVParser(reader,CSVFormat.newFormat(',') ); List<CSVRecord> list=parser.getRecords(); for(CSVRecord record : list ){ long num=record.getRecordNumber(); if(num<3) continue; pipeline.zadd(Config.IP2CITYID,Long.valueOf(replaceSprit(record.get(0))),replaceSprit(record.get(2))+"_0"); pipeline.zadd(Config.IP2CITYID,Long.valueOf(replaceSprit(record.get(1))),replaceSprit(record.get(2))+"_1"); } pipeline.syncAndReturnAll(); parser.close(); reader.close(); long endTime=System.currentTimeMillis(); System.out.println("------------"); System.out.println("导入ip地址完成"); System.out.println("耗时:"+(endTime-startTime)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void citiesToRedis(Jedis jedis,File file){ Gson gson=new Gson(); Pipeline pipeline=jedis.pipelined(); try { System.out.println("导入城市地址开始"); long startTime=System.currentTimeMillis(); Reader reader =new FileReader(file); CSVParser parser=new CSVParser(reader,CSVFormat.newFormat(',') ); List<CSVRecord> list=parser.getRecords(); City city=new City(); for(CSVRecord record : list){ long num=record.getRecordNumber(); if(num<3) continue; record2City(city, record); pipeline.hset( Config.CITYID2CITY, city.getCityId(), gson.toJson(city)); } pipeline.syncAndReturnAll(); parser.close(); reader.close(); long endTime=System.currentTimeMillis(); System.out.println("------------"); System.out.println("导入城市地址完成"); System.out.println("耗时:"+(endTime-startTime)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void record2City(City city, CSVRecord record){ city.setCityId(replaceSprit(record.get(0))); city.setCountry(replaceSprit(record.get(1))); city.setRegion(replaceSprit(record.get(2))); city.setCity(replaceSprit(record.get(3))); city.setPostalCode(replaceSprit(record.get(4))); city.setLatitude(replaceSprit(record.get(5))); city.setLongitude(replaceSprit(record.get(6))); city.setMetroCode(replaceSprit(record.get(7))); city.setAreaCode(replaceSprit(record.get(8))); } public City findByIp(Jedis jedis,String ip){ long score=toSore(ip); Set<String> results=jedis.zrangeByScore(Config.IP2CITYID, score,score); if(0 == results.size()) return null; String cityId = results.iterator().next(); cityId = cityId.substring(0, cityId.indexOf('_')); return new Gson().fromJson(jedis.hget(Config.CITYID2CITY, cityId), City.class); } private String replaceSprit(String str){ return str.replaceAll("\"", ""); } }
测试类:
public class MyTest { @Test public void test1(){ Jedis jedis = RedisClient.getResource(); Data2Redis data2Redis = new Data2Redis(); data2Redis.ipToRedis(jedis, new File(Config.GEOLITECITY_BLOCKS)); RedisClient.returnResource(jedis); } @Test public void test2(){ Jedis jedis = RedisClient.getResource(); Data2Redis data2Redis = new Data2Redis(); data2Redis.citiesToRedis(jedis, new File(Config.GEOLITECITY_LOCATION)); RedisClient.returnResource(jedis); } @Test public void test3(){ Jedis jedis = RedisClient.getResource(); Data2Redis data2Redis = new Data2Redis(); City city= data2Redis.findByIp(jedis, "115.192.111.140"); if(null == city){ System.out.println("没有找到对应的ip"); return; } System.out.println(city.getCity()); RedisClient.returnResource(jedis); } }
参考《redis实战》p100-p102
博客链接:http://blog.csdn.net/michaeljy1991/article/details/50387644