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

将ip对应城市数据导入redis并查询的更多相关文章

  1. 通过管道传输快速将MySQL的数据导入Redis

    通过管道传输pipe将MySQL数据批量导入Redis      自Redis 2.6以上版本起,Redis支持快速大批量导入数据,即官网的Redis Mass Insertion,即Pipe传输, ...

  2. Mysql百万数据量级数据快速导入Redis

    前言 随着系统的运行,数据量变得越来越大,单纯的将数据存储在mysql中,已然不能满足查询要求了,此时我们引入Redis作为查询的缓存层,将业务中的热数据保存到Redis,扩展传统关系型数据库的服务能 ...

  3. Redis数据导入工具优化过程总结

    Redis数据导入工具优化过程总结 背景 使用C++开发了一个Redis数据导入工具 从oracle中将所有表数据导入到redis中: 不是单纯的数据导入,每条oracle中的原有记录,需要经过业务逻 ...

  4. 如何将redis中的数据导入到本地MongoDB和MySQL数据库

    将redis中的数据导入到本地MongoDB数据库 创建一个process_items_mongodb.py文件(文件名自定义): #!/usr/bin/env python # -*- coding ...

  5. Redis 数据总结(1 数据导入)

    理论基础部分:http://www.redis.cn/topics/mass-insert.html 几百上千万的数据建议使用pipe来完成导入. 1.windows 下数据导入命令: type ou ...

  6. 日志收集之--将Kafka数据导入elasticsearch

    最近需要搭建一套日志监控平台,结合系统本身的特性总结一句话也就是:需要将Kafka中的数据导入到elasticsearch中.那么如何将Kafka中的数据导入到elasticsearch中去呢,总结起 ...

  7. C# DateTime的11种构造函数 [Abp 源码分析]十五、自动审计记录 .Net 登陆的时候添加验证码 使用Topshelf开发Windows服务、记录日志 日常杂记——C#验证码 c#_生成图片式验证码 C# 利用SharpZipLib生成压缩包 Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库

    C# DateTime的11种构造函数   别的也不多说没直接贴代码 using System; using System.Collections.Generic; using System.Glob ...

  8. Python 爬取 热词并进行分类数据分析-[云图制作+数据导入]

    日期:2020.01.28 博客期:136 星期二 [本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)] 所有相关跳转: a.[简单准备] b.[云图制作+数据导入](本期博客) ...

  9. 使用GO语言通过Stream Load实现Doris数据导入

    Doris github地址欢迎加Star apache/incubator-doris: Apache Doris(Incubating) is an MPP-based interactive S ...

随机推荐

  1. C++获取系统时间的方法

    //首先是了解这个结构体,_SYSTEMTIME ,然后通过系统函数GetLocalTime往这个结构体的变量中写入当前系统时间typedef struct _SYSTEMTIME { WORD wY ...

  2. Kill windows和linux 进程

    Windows

  3. 土司论坛nc反弹神器使用方法

    说明: PS:我本机是linux,因为没有服务器所以使用win7来演示.倘若你是windows可以在本机生成dll以后再放到服务器上面去执行dll即可反弹shell物理机ip:192.168.1.12 ...

  4. 在64位linux下编译32位程序

    在64位linux下编译32位程序 http://blog.csdn.net/xsckernel/article/details/38045783

  5. vue知识点(1)

    处理用户输入 v-on指令添加一个事件监听器 div id="app-5"> <p>{{ message }}</p> <button v-on ...

  6. SQL利用Case When Then多条件判断SQL 语句

    http://www.cnblogs.com/kevin2013/archive/2010/07/02/1769682.html SQL利用Case When Then多条件判断SQL ,用于sele ...

  7. Ruby-Clamp

    require "clamp" class ClampTest < Clamp::Command # 1.命令行的参数使用主要分两类,一种是参数名称后面带参数值的方式, #我 ...

  8. MUI 页面刷新及页面传值问题

    一.页面刷新问题 1.父页面A跳转到子页面B,B页面修改数据后再跳回A页面,刷新A页面数据 (1).父页面A代码 window.addEventListener("pageflowrefre ...

  9. powershell常用操作

    创建文件 New-Item -path $file_path -itemtype file 创建目录 New-Item -path $dir_path -type directory 删除目录 Rem ...

  10. .net 多播委托的使用方法以及场景,更简单的观察者模式

    首先来说一下什么是多播委托 多播委托就是在委托里定义一个或者多个方法的一个集合 使用方法: public Action actList; //添加方法 public void AddActionMet ...