我在Appengine上使用Python,正在查找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以上,所以不大。
答案 0 :(得分:3)
从dat文件加载数据库需要花费时间。一旦你有了内存,查找时间并不重要。所以,如果你可以将gi变量保留在内存中,这似乎是最好的解决方案。
如果你不能,你可能也不能使用memcached。
答案 1 :(得分:3)
如果你需要跨多个进程进行查找(你几乎肯定会在AppEngine上进行查找),并且你可能会在很短的时间内(你可能会)多次遇到相同的ip地址,然后使用memcache对速度来说可能是一个好主意。
更多细节,因为你说你对编码比较陌生:
正如Lennart Regebro所说的那样,缓慢的是从磁盘读取geoip文件并解析它。然后个别查询会很快。但是,如果任何给定的进程只提供一个请求(从您的角度来看,在AppEngine上,它是),那么这个价格将在每个请求上得到支付。缓存最近在memcache中使用的查找将允许您跨进程共享此信息...但仅适用于最近遇到的数据点。但是,由于任何给定的ip都可能以突发方式显示(因为它是一个用户与您的网站进行交互),这正是您想要的。
其他替代方法是将所有数据点预先加载到内存缓存中。您可能不想这样做,因为您的可用内存有限,并且您最终不会使用大部分内存。 (另外,如果你达到内存限制,memcache会把它的一部分扔掉,这意味着你需要编写备份代码来实时读取geoip数据库。)一般来说,做懒惰的缓存 - 查找一个值当你第一次需要它然后保留它以便重复使用时,这是一种非常有效的机制。 Memcache专门用于此,因为它会丢弃最近遇到内存压力时尚未使用的数据。
另一种替代方案(尽管不在AppEngine中)是运行一个单独的进程来处理位置查询,并让所有前端进程与之对话(例如通过thrift)。然后你可以使用在该过程中加载geoip数据库的建议,并为每个请求实时查询。
希望有所帮助。
答案 2 :(得分:1)
对于您已经从数据库中获取的个人IP地址,我肯定会将它们放在内存缓存中。我假设数据库文件相对较大,而且每次需要查找一个地址时都不想从memcache加载。
我知道人们用来帮助跟踪API调用速度的一个工具是AppStats。它可以帮助您了解对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