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. Python 下调用C动态链接库 -- (转)

    在linux开发的动态链接库需要被python调用,首先需要生成.so文件. 生成动态链接库的方法网上有很多,主要就是首先根据源文件编译生成.o,然后链接这些.o文件-shared生成.so.需要注意 ...

  2. 【DeepLearning学习笔记】Coursera课程《Neural Networks and Deep Learning》——Week1 Introduction to deep learning课堂笔记

    Coursera课程<Neural Networks and Deep Learning> deeplearning.ai Week1 Introduction to deep learn ...

  3. linux percpu机制解析【转】

    转自:http://blog.csdn.net/wh8_2011/article/details/53138377 一.概述 每cpu变量是最简单也是最重要的同步技术.每cpu变量主要是数据结构数组, ...

  4. Linux的SMP,UMA,NUMA

    SMP 是Symmetric Multi-Processing的意思,对称多处理器,一种多核结构,认为这些核是完全同构的,任务可以随便在任一个核上跑. UMA是Uniform Memory Acces ...

  5. Shell脚本中引用、调用另一个脚本文件的2种方法

    Shell脚本中引用.调用另一个脚本文件的2种方法 http://www.jb51.net/article/67903.htm

  6. Oracle 内存管理

    --内存分配建库时可以先分配系统内存的50%-80%给Oracle,后期根据业务再进行调整.SGA.PGA分配比例:OLTP:SGA %80 , PGA %20OLAP:SGA %50 , PGA % ...

  7. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 动态树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 题意:加边,删边,查询到根的距离. #include <bits/stdc++ ...

  8. linux命令--head

    head 与 tail 就像它的名字一样的浅显易懂,它是用来显示开头或结尾某个数量的文字区块,head 用来显示档案的开头至标准输出中,而 tail 想当然尔就是看档案的结尾. 具体使用参考链接: h ...

  9. ajax登录请求,无法跳转

    没有用form提交数据,用的ajax提交.服务器显示已经登录成功,并且返回了成功代码OK.却无法进行跳转: js代码: $("input[type='submit']").on(& ...

  10. windows下github 出现Permission denied (publickey)

    github教科书传送门:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 再学习到 ...