1、将纯真版ip数据  xxx.data 导入至 redis(整个过程只花费了几秒)

引入nuget包 CSRedisCore,使用方法见:https://github.com/2881099/csredis

/// <summary>
/// 更新ip库,请先将ip库上传至 /data/qqwry.dat,gb2312格式
/// </summary>
/// <returns></returns>
[HttpPost("update_ip")]
public APIReturn 更新ip库() {
RedisHelper.Remove("iplib");
var lines = Encoding.GetEncoding("GB2312").GetString(System.IO.File.ReadAllBytes("/data/qqwry.dat")).Split(new string[] { "\r\n" }, StringSplitOptions.None);
var lines_index = 0;
while(lines_index < lines.Length) {
var members = new List<(double, string)>();
for (var b = 0; b < 50000; b++) {
try {
var ipstart = Lib.Ip2Long(lines[lines_index].Substring(0, 15).Trim());
var ipend = Lib.Ip2Long(lines[lines_index].Substring(16, 15).Trim());
var location = lines[lines_index].Substring(32).Replace("CZ88.NET", "").Trim(); members.Add((ipend, $"{ipstart}-{ipend} {location}"));
} catch { }
if (++lines_index >= lines.Length) break;
}
if (members.Count > 0)
RedisHelper.ZAdd("iplib", members.ToArray());
} return AR.成功;
}
public static long Ip2Long(string ip) {
char[] separator = new char[] { '.' };
string[] items = ip.Split(separator);
return long.Parse(items[0]) << 24
| long.Parse(items[1]) << 16
| long.Parse(items[2]) << 8
| long.Parse(items[3]);
}
public static string Long2Ip(long ipInt) {
StringBuilder sb = new StringBuilder();
sb.Append((ipInt >> 24) & 0xFF).Append(".");
sb.Append((ipInt >> 16) & 0xFF).Append(".");
sb.Append((ipInt >> 8) & 0xFF).Append(".");
sb.Append(ipInt & 0xFF);
return sb.ToString();
}

2、定义根据ip查询所在地的函数(单次查询效率在1ms以内)

public static string GetLocationByIpAddress(string ip) {
if (string.IsNullOrEmpty(ip)) return "未知";
var find = RedisHelper.ZRangeByScore("iplib", Lib.Ip2Long(ip), double.MaxValue, 1, 0);
if (find.Any()) return find.First().Substring(find.First().IndexOf(' '));
return "未知";
}

使用redis有序集合sorted set设计高效查询ip所在地的更多相关文章

  1. Redis 有序集合(sorted set),发布订阅,事务,脚本,连接,服务器(三)

    Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过 ...

  2. redis(十四):Redis 有序集合(sorted set)

    Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过 ...

  3. Redis 有序集合(sorted set)

    Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过分数来为集合中的成员进行从小到大的排序. 有序 ...

  4. Python 操作redis有序集合(sorted set)

    #coding:utf8 import redis r =redis.Redis(host=") 1.Zadd Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中.如果某个成员 ...

  5. (六)Redis有序集合Sorted set操作

     Sorted set全部命令如下: zadd key score1 member1 score2 member2 ... # 将一个或多个member元素及其score值加入到有序集合key当中 z ...

  6. redis(十五):Redis 有序集合(sorted set)(python)

    #coding:utf8 import redis r =redis.Redis(host="23.226.74.190",port=63279,password="66 ...

  7. redis有序集合的使用

    Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过 ...

  8. python 操作redis之——有序集合(sorted set) (七)

    #coding:utf8 import redis r =redis.Redis(host=") 1.Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中.如果某个成员已经是有序 ...

  9. (PHP)redis Zset(有序集合 sorted set)操作

    /** * * Zset操作 * sorted set操作 * 有序集合 * sorted set 它在set的基础上增加了一个顺序属性,这一属性在修改添加元素的时候可以指定,每次指定后,zset会自 ...

随机推荐

  1. 排序系列 之 快速排序算法 —— Java实现

    基本思想: 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变 ...

  2. Dubbo中编码和解码的解析

    (这里做的解析不是很详细,等到走完整个流程再来解析)Dubbo中编解码的工作由Codec2接口的实现来处理,回想一下第一次接触到Codec2相关的内容是在服务端暴露服务的时候,根据具体的协议去暴露服务 ...

  3. netty源码分析之揭开reactor线程的面纱(一)

    netty最核心的就是reactor线程,对应项目中使用广泛的NioEventLoop,那么NioEventLoop里面到底在干些什么事?netty是如何保证事件循环的高效轮询和任务的及时执行?又是如 ...

  4. linux内核参数注释与优化

    目录 1.linux内核参数注释 2.两种修改内核参数方法 3.内核优化参数生产配置 参数解释由网络上收集整理,常用优化参数对比了网上多个实际应用进行表格化整理,使查看更直观. 学习linux也有不少 ...

  5. volatile可见性的一些认识和论证

    一.前言 volatile的关键词的使用在JVM内存模型中已是老生常谈了,这篇文章主要结合自己对可见性的一些认识和一些直观的例子来谈谈volatile.文章正文大致分为三部分,首先会介绍一下happe ...

  6. 干货,不小心执行了rm -f,除了跑路,如何恢复?

    前言 每当我们在生产环境服务器上执行rm命令时,总是提心吊胆的,因为一不小心执行了误删,然后就要准备跑路了,毕竟人不是机器,更何况机器也有bug,呵呵. 那么如果真的删除了不该删除的文件,比如数据库. ...

  7. java~springcloud微服务目录索引

    回到占占推荐博客索引 最近写了不过关于java,spring,微服务的相关文章,今天把它整理一下,方便大家学习与参考. java~springcloud微服务~目录索引 springcloud~服务注 ...

  8. 深度解密Go语言之关于 interface 的10个问题

    目录 1. Go 语言与鸭子类型的关系 2. 值接收者和指针接收者的区别 方法 值接收者和指针接收者 两者分别在何时使用 3. iface 和 eface 的区别是什么 4. 接口的动态类型和动态值 ...

  9. Go:学习笔记兼吐槽(1)

      Go:学习笔记兼吐槽(1) Go:学习笔记兼吐槽(2) Go:学习笔记兼吐槽(3) 自动添加分号 在很多其他的编程语言中,每一行代码的结尾都必须有分号(假设一行中只有一句代码),Golang 的开 ...

  10. netcore服务程序暴力退出导致的业务数据不一致的一种解决方案(优雅退出)

    一: 问题提出 现如今大家写的netcore程序大多部署在linux平台上,而且服务程序里面可能会做各种复杂的操作,涉及到多数据源(mysql,redis,kafka).成功部署成后台 进程之后,你以 ...