码迷,mamicode.com
首页 > 其他好文 > 详细

<Redis实战>5.3.1 加载地址表

时间:2016-05-11 13:09:37      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:

原文: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#L318
def
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#L316
def
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#L354
def
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

<Redis实战>5.3.1 加载地址表

标签:

原文地址:http://www.cnblogs.com/hjyang2012/p/5479704.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!