<Redis实战>5.3.1 加载地址表

原文:https://redislabs.com/ebook/redis-in-action/part-2-core-concepts-2/chapter-5-using-redis-for-application-support/5-3-ip-to-city-and-country-lookup/5-3-1-loading-the-location-tables

对于开发数据,我从http://dev.maxmind.com/geoip/geolite下载了一个免费的IP地址对应城市数据库。这个数据库包含了两个重要的文件:包含了IP地址范围和城市ID范围信息的Geo- LiteCity-Blocks.csv,以及包含了城市ID对应的名称、地区、国家以及一些我们不需要的信息的GeoLiteCity-Location.csv

我们首先构造一个允许我们使用一个IP地址并将它转换为城市ID的查找表,然后构造第二个允许我们使用一个城市ID并将它转换成它实际的城市信息(也包含了地区和国家信息)的查找表。

这个使用一个IP地址并将它转换为城市ID的查找表将被构造成单个ZSET,这个ZSET使用城市ID作为成员,IP地址作为得分。为了允许我们从IP地址映射到城市ID,我们将点分形式的IP地址转换成整形得分,采用32位无符号整数中每八位为一个字节,第一个字节为作为最高位。执行这些操作的代码看这里

#代码https://github.com/huangz1990/riacn-code/blob/master/ch05_listing_source.py#L318def ip_to_score(ip_address):
    score = 0
    for v in ip_address.split(‘.‘):
        score = score * 256 + int(v, 10)
    return score

当我们有了得分,我们首先添加将IP地址映射到城市ID,为了从一般城市ID构造一个唯一城市ID(因为多个IP地址可以映射到同一个城市ID),我们将添加一个_字符随后接着一件添加到ZSET中的数量,我们可以看如下代码:

#https://github.com/huangz1990/riacn-code/blob/master/ch05_listing_source.py#L316def import_ips_to_redis(conn, filename):
    csv_file = csv.reader(open(filename, ‘rb‘))
    for count, row in enumerate(csv_file):
        # 按需将IP地址转换为分值。
        start_ip = row[0] if row else ‘‘
        if ‘i‘ in start_ip.lower():
            continue
        if ‘.‘ in start_ip:
            start_ip = ip_to_score(start_ip)
        elif start_ip.isdigit():
            start_ip = int(start_ip, 10)
        else:
            # 略过文件的第一行以及格式不正确的条目。
            continue                                  

        # 构建唯一城市ID。
        city_id = row[2] + ‘_‘ + str(count)
        # 将城市ID及其对应的IP地址分值添加到有序集合里面。
        conn.zadd(‘ip2cityid:‘, city_id, start_ip) 

执行完该函数,效果如下图所示:

当IP地址通过import_ips_to_redis()全部加载,我们将创建一个ZSET用来映射城市ID到城市信息,如下代码所示。我们将使用json格式来存储城市信息,因为我们的数据是不会随着时间而改变的固定格式。

#https://github.com/huangz1990/riacn-code/blob/master/ch05_listing_source.py#L354def import_cities_to_redis(conn, filename):
    for row in csv.reader(open(filename, ‘rb‘)):
        if len(row) < 4 or not row[0].isdigit():
            continue
        row = [i.decode(‘latin-1‘) for i in row]
        # 准备好需要添加到散列里面的信息。
        city_id = row[0]
        country = row[1]
        region = row[2]
        city = row[3]
        # 将城市信息添加到Redis里面。
        conn.hset(‘cityid2city:‘, city_id,
            json.dumps([city, region, country])) 

执行完该代码后,效果如图所示:

现在我们已经在Redis中有了全部的信息,可以开始查找IP地址了。

http://dev.maxmind.com/geoip/geolite#sthash.Y0BjekhR.dpuf

http://dev.maxmind.com/geoip/geolite#sthash.Y0BjekhR.dpuf

时间: 2024-11-15 12:58:52

<Redis实战>5.3.1 加载地址表的相关文章

Unity开发实战探讨-资源的加载释放最佳策略简要心得

Unity开发实战探讨-资源的加载释放最佳策略简要心得 看过我另外一篇关于Unity资源释放随笔<Unity开发实战探讨-资源的加载释放最佳策略>如果觉得略微复杂,那么下面是一些比较简要的心得体会: 概括 常用资源加载的方法有三种:静态,Resources内部资源,AssetBundle外部资源 资源释放的方式 有二种:立刻释放和统一释放. 静态 静态就是资源直接放场景,静态资源无法立刻释放,但场景关闭由引擎统一释放,开发者无法干预,所以最为无脑. 但静态过于死板,除了整个场景生命周期中必须使

[Ext JS 4] 实战之Load Mask(加载遮罩)的显示与隐藏

前言 Load Mask(遮罩)效果,就是在页面还没有完全显示出来之前, 加上一个转装转的效果. 类似: 添加这样的效果有两个好处: 1. 在页面没完全show出来之前, 把后面的页面给遮罩起来, 防止进行一些非法的操作. 2. 如果页面show出来的时间比较长的话, 可以暂时吸引用户的注意力(也就是提高 User Experience). 在Extjs 中, Ext js 的使用方式有多种. 你有可能会发现为什么有的状况下load mask 不出现?  且听下面一一道来... JsonStor

Uboot 引导内核时加载地址与入口地址问题

如果使用 mkimage 生成内核镜像文件的话,会在内核的前头加上了 64 bytes 的信息头,供建立 tag 之用.bootm 命令会首先判断 bootm xxx 这个指定的地址 xxx 与 -a 指定的加载地址是否相同. 如果不同的话会从这个地址开始提取出这个 64 bytes 的头部,对其进行分析,然后把去掉头部的内核复制到 -a 指定的加载地址去运行; 如果相同的话那就让其原封不同的放在那,但 -e 指定的入口地址会推后 64 bytes,以跳过这 64 bytes 的头部. 我们来看

linux内核镜像的加载地址和入口地址

copy from :https://blog.csdn.net/whahu1989/article/details/85255538  https://wenku.baidu.com/view/2670021c195f312b3069a532.html linux内核启动时几个关键地址  1.名词解释ZTEXTADDR  解压代码运行的开始地址.没有物理地址和虚拟地址之分,因为此时MMU处于关闭状态.这个地址不一定时RAM的地址,可以是支持读写寻址的flash等存储中介. ZRELADDR 

Oracle Bigdata Connector实战2: 使用Oracle Loader for Hadoop加载Hive表到Oracle数据库

部署Hadoop/Hive/OraLoader软件 [[email protected] ~]$ tree -L 1 ├── hadoop-2.6.2 ├── hbase-1.1.2 ├── hive-1.1.1 ├── jdk1.8.0_65 ├── oraloader-3.4.0 配置hive metastore 我们采用MySQL作为hive的metastore,创建MySQL数据库 mysql> create database metastore DEFAULT CHARACTER SE

【EF学习笔记08】----------加载关联表的数据 显式加载

显式加载 讲解之前,先来看一下我们的数据库结构:班级表 学生表 加载从表集合类型 //显示加载 Console.WriteLine("=========查询集合==========="); using (var db = new Entities()) { var query = from v in db.Classes where v.ClassName == "机电10501" select v; var cls = query.Single(); db.Ent

【JAVAWEB学习笔记】网上商城实战2:异步加载分类、Redis缓存分类和显示商品

网上商城实战2 今日任务 完成分类模块的功能 完成商品模块的功能 1.1      分类模块的功能: 1.1.1    查询分类的功能: 1.1.2    查询分类的代码实现: 1.1.2.1  创建表: CREATE TABLE `category` ( `cid` varchar(32) NOT NULL, `cname` varchar(20) DEFAULT NULL, PRIMARY KEY (`cid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 1

【java】itoo项目实战之hibernate 懒加载优化性能

在做itoo 3.0 的时候,考评系统想要上线,就开始导入数据了,只导入学生2万条数据,但是导入的速度特别的慢,这个慢的原因是因为导入的时候进行了过多的IO操作.但是导入成功之后,查询学生的速度更加慢,因为底层用了hibernate的hql语句进行查询的,学习过hibernate的人都知道,如果hibernate不设置懒加载的话,只有是有关联的数据都会一次性全部都查询出来,我试了试,查询2万条数据,最深的级联查询是有5层,然后发出来的语句是460条,时间大概是10s.然后就考虑使用lazy进行优

IDA 与VC 加载符号表

将Windbg路径下的symsrv.yes 拷贝到ida 的安装目录,重新分析ntoskrnl.exe, 加载本地的符号表 添加环境变量  变量名:_NT_SYMBOL_PATH变量值:SRV*{$Path}*http://msdl.microsoft.com/download/symbols/将“{$Path}”替换为要存储pdb符号表文件的路径,比如:C:\PDB,在线的符号下载. 于是用IDA,或者在VC里写程序调试时,都会从网上自动下载符号表……msvcrt.pdb,ole32.pdb,