如何在django中有效地提供大量站点地图

时间:2010-05-11 02:08:59

标签: django caching memcached sitemap

我的网站地图中有一个大约150K页面的网站。我正在使用站点地图索引生成器制作站点地图,但实际上,我需要一种缓存方式,因为在我的服务器上构建每个1000个链接的150个站点地图是残酷的。[1]

我可以用memcached缓存每个站点地图页面,这就是我在网站上的其他地方使用的...但是,这是很多站点地图,它会完全填充memcached ....所以这不是工作

我认为我需要的是一种使用数据库作为缓存的方法,并且只在它们发生变化时生成它们(由于站点地图索引意味着只更改最新的几个站点地图页面,因为其余部分总是相同的。)[2]但是,尽管我可以说,我只能使用一个缓存后端与django。

如何在不杀死我的数据库或memcached的情况下让这些站点地图准备就绪吗?

有什么想法吗?

[1]我将其限制为每个站点地图页面的1,000个链接,因为生成最多50,000个链接,就是没有发生。

[2]例如,如果我有sitemap.xml?page = 1,page = 2 ... sitemap.xml?page = 50,我只需要更改sitemap.xml?page = 50,直到它为止完整的1000个链接,然后我可以永远这么做,并专注于第51页,直到它已满,永远缓存等等。

编辑,2012-05-12:这仍然是一个问题,我终于在使用文件缓存大约一年后放弃了Django的站点地图框架。相反,我现在使用Solr在一个非常简单的视图中生成我需要的链接,然后我将它们传递给Django模板。这个极大简化了我的站点地图,使它们表现得很好,截至目前我已经达到了大约2,250,000个链接。如果你想这样做,只需查看站点地图模板 - 从那里开始就非常明显。您可以在此处查看此代码:https://bitbucket.org/mlissner/search-and-awareness-platform-courtlistener/src/tip/alert/casepage/sitemap.py

4 个答案:

答案 0 :(得分:9)

我遇到了类似的问题,并决定使用django将静态媒体中的站点地图文件写入磁盘,并让网络服务器为它们提供服务。我打电话每隔几个小时重新生成一次站点地图,因为我的内容没有经常变化。但这取决于您的内容,您需要多久写一次文件。

我使用django自定义命令和cron作业,但使用cron作业卷曲更容易。

以下是我使用curl的方法,我有apache将/sitemap.xml作为静态文件发送,而不是通过django:

curl -o /path/sitemap.xml http://example.com/generate/sitemap.xml

答案 1 :(得分:9)

好的 - 我已经找到了更多关于这方面的信息以及亚马逊在600万左右的URL中做了什么。

亚马逊只需为每一天制作地图并添加到地图中:

  1. new urls
  2. 更新了网址
  3. 所以这意味着他们最终得到了大量的站点地图 - 但搜索机器人只会查看最新的 - 因为更新日期是最近的。我理解人们应该刷新一张地图 - 而不是不止一次包含一个网址。我认为这是真的。但是,亚马逊绕过这个,因为站点地图更像是一个日志。一个网址可能会出现在后来的网站地图中 - 因为它可能会更新 - 但是谷歌不会看旧版地图,因为它们已经过时了 - 除非它确实是一个重要的重新索引。这种方法很有意义,因为你所做的只是建立一个新的地图 - 比如新的和更新的内容的每一天,并在谷歌ping它 - 因此谷歌只需要索引这些新的网址。

    此日志方法与代码同步 - 因为您只需要一个静态数据存储模型,该模型存储每个映射的XML数据。你的cron作业可以构建一个地图 - 每天或每周,然后将原始XML页面存储在blob字段中或者你有什么。然后,您可以直接从处理程序和索引图中提供页面。

    我不确定别人的想法,但这听起来像一个非常可行的方法和一个负载关闭的服务器 - 相比重建大型地图只是因为几页可能已经改变。

    我还认为,有可能将一周价值的地图压缩成一周的地图,将4周的地图压缩成一个月 - 所以你最终会得到月度地图,当月的每周地图然后是过去7天的地图。假设所有日期都保持不变,这将减少整理过程的地图数量 - 我想的是将一年中每天的365张地图减少到12个。

    以下是网站地图上的pdf以及亚马逊和CNN使用的方法。

    http://www.wwwconference.org/www2009/proceedings/pdf/p991.pdf

答案 2 :(得分:3)

我正在使用django-staticgenerator应用程序将sitemap.xml缓存到文件系统,并在数据更新时更新该文件。

settings.py:

STATIC_GENERATOR_URLS = (
    r'^/sitemap',
)
WEB_ROOT = os.path.join(SITE_ROOT, 'cache')

models.py:

from staticgenerator import quick_publish, quick_delete
from django.dispatch import receiver
from django.db.models.signals import post_save, post_delete
from django.contrib.sitemaps import ping_google

@receiver(post_delete)
@receiver(post_save)
def delete_cache(sender, **kwargs):
    # Check if a Page model changed
    if sender == Page:
        quick_delete('/sitemap.xml')
        # You may republish sitemap file now
        # quick_publish('/', '/sitemap.xml')
        ping_google()

在nginx配置中,我将sitemap.xml重定向到缓存文件夹,并将django实例重定向到后备:

location /sitemap.xml {
    root /var/www/django_project/cache;

    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;

    if (-f $request_filename/index.html) {
        rewrite (.*) $1/index.html break;
    }
    # If file doesn't exist redirect to django
    if (!-f $request_filename) {
        proxy_pass http://127.0.0.1:8000;
        break;
    }    
}

使用此方法,将始终更新sitemap.xml,并且客户端(如google)始终静态获取xml文件。我觉得这很酷! :)

答案 3 :(得分:0)

对于那些(无论出于何种原因)更愿意动态生成站点地图的人(例如新鲜,懒惰)。试试django-sitemaps。它是标准站点地图的流媒体版本。直接替换。更快的响应时间,并使用更少的内存。