哪个更快?Memcache还是文件查询?(使用maxmind geoip.dat文件)

2 投票
3 回答
1394 浏览
提问于 2025-04-16 09:14

我在使用Python和Appengine,想要查找一个IP地址的地理位置,方法是这样的:

import pygeoip
gi = pygeoip.GeoIP('GeoIP.dat')
Location = gi.country_code_by_addr(self.request.remote_addr)

(你可以在这里找到pygeoip: http://code.google.com/p/pygeoip/)

我想为每个用户的每个页面获取地理位置,所以我现在是查一次IP地址,然后把结果存到memcache里。

我想问的是,哪种方式更快?是每次从.dat文件中查找IP地址快,还是从memcache中获取快?还有其他我需要注意的优缺点吗?

对于像这样的常见问题,有没有好的指南可以教我如何优化我的代码和自己进行速度测试?我对Python和编程都很陌生,所以如果这是个基础概念,我先说声抱歉。

谢谢!

汤姆

编辑:感谢大家的回复,memcache似乎是正确的选择。我觉得Nick和Lennart在建议我把整个gi变量放到memcache里。我觉得这是可行的。顺便说一下,整个GeoIP.dat文件稍微超过1MB,所以并不算大。

3 个回答

1

对于你已经从数据库中获取的单个IP地址,我建议把它们放到memcache里。因为我假设你的数据库文件比较大,每次查找一个地址时,不想每次都从数据库中加载。

有一个工具叫做 AppStats,很多人用它来跟踪API调用的速度。这个工具可以帮助你查看各种API调用花了多长时间。

既然你刚开始接触编程,我想提一下,appstats是一个非常针对App Engine的工具。如果你只是写一个在自己电脑上运行的基本Python应用,你可以通过简单地减去两个时间戳来计算时间:

import time
t1 = time.time()
#do whatever it is you want to time here.
t2 = time.time()
elapsed_time = t2-t1
3

如果你需要在多个进程之间查找信息(在AppEngine上你几乎肯定会需要这样做),而且你可能会在短时间内遇到同一个IP地址很多次(这也是很有可能的),那么使用缓存(memcache)来加快速度是个不错的主意。

更详细地说,因为你提到你对编程还比较陌生:

正如Lennart Regebro所说,慢的地方在于从磁盘读取geoip文件并解析它。单个查询会很快。但是,如果某个进程只处理一个请求(从你的角度来看,在AppEngine上确实是这样),那么每个请求都会付出这个代价。把最近使用的查找结果缓存到memcache中,可以让你在不同的进程之间共享这些信息……但这只适用于最近遇到的数据。不过,由于同一个IP地址可能会在短时间内频繁出现(因为它是一个用户在与你的网站互动),这正是你所需要的。

另一种选择是把所有的数据点预先加载到memcache中。你可能不想这样做,因为你的内存有限,而且大部分内存可能都不会用到。(另外,如果你达到内存限制,memcache会丢弃一部分数据,这意味着你还是需要写备份代码来实时读取geoip数据库。)一般来说,懒惰缓存是一种非常有效的机制——当你第一次需要某个值时慢慢查找,然后把它保留以便后续使用。memcache特别适合这种情况,因为当内存紧张时,它会丢弃最近没有使用的数据。

还有一种选择(虽然在AppEngine上不适用)是运行一个单独的进程专门处理位置查询,让你所有的前端进程都与它通信(例如通过thrift)。这样你就可以在那个进程中加载geoip数据库,并实时查询每个请求。

希望这些信息对你有帮助。

3

这里花时间的主要是从 dat 文件加载数据库。一旦数据库加载到内存中,查找的时间就不会太长。所以如果你能把 gi 变量保存在内存中,那就是最好的解决办法。

如果你做不到这一点,可能也无法使用 memcached。

撰写回答