Django下5000万量级商品sitemap.xml高效生成方案咨询
Django千万级数据量sitemap最优实现方案
你现在手动拆分Sitemap子类、逐一配置路由的实现方式完全是重复造轮子,Django自带的sitemap框架原生支持大规模数据的分页索引能力,不需要写任何重复代码,配合少量优化就能轻松支撑5000万级商品的sitemap生成。
基础配置:零重复代码实现自动分页
Django django.contrib.sitemaps 内置了sitemap分页、索引文件自动生成逻辑,你只需要定义1个Sitemap类、配置2条路由即可,框架会自动按照你设置的单文件URL上限拆分页面、生成索引入口,不需要手动切片、手动加路由。
1. 编写sitemaps.py
from django.contrib.sitemaps import Sitemap from .models import Book class BookSitemap(Sitemap): protocol = 'https' changefreq = 'weekly' priority = 0.9 limit = 50000 # 单文件最大URL数,符合sitemap协议上限,不需要调更小 def items(self): # 只查询生成URL需要的字段,避免拉取大字段浪费内存 return Book.objects.all().order_by('id').only('id', 'updated_at') def lastmod(self, obj): # 返回商品最后更新时间,搜索引擎会优先抓取更新过的页面,提升收录效率 return obj.updated_at
2. 配置urls.py
from django.contrib.sitemaps.views import sitemap, index from django.urls import path from django.views.decorators.cache import cache_page from .sitemaps import BookSitemap sitemaps = { 'books': BookSitemap, # 后续要加其他页面的sitemap(比如分类页、文章页),直接往这个字典加即可 } urlpatterns = [ # sitemap总索引入口,访问/sitemap.xml会自动列出所有分页sitemap的地址 path('sitemap.xml', cache_page(3600)(index), {'sitemaps': sitemaps}, name='sitemap-index'), # 自动匹配所有分页sitemap,比如/books-sitemap1.xml、/books-sitemap2.xml,页码由框架自动计算 path('<section>-sitemap<int:page>.xml', cache_page(3600)(sitemap), {'sitemaps': sitemaps}, name='sitemap-page'), ]
配置完成后,框架会自动计算总页数:5000万商品/50000条每页=1000个分页sitemap,不需要你手动维护任何类和路由,商品新增、下架后总页数会自动适配,不需要改代码。上面代码里已经加了1小时的页面缓存,避免重复请求打库。
5000万量级性能优化
默认逻辑在百万级数据下可以直接跑,到5000万量级需要做几个小优化避免慢查询:
- 避免实时全表count:千万级数据表的
count()查询在关系型数据库里性能很差,你可以把商品总数放到缓存里,定时更新,不要每次请求都实时算总条数。示例代码:from django.core.cache import cache class BookSitemap(Sitemap): # 保留上面的基础属性 def _get_cached_total(self): total = cache.get('book_sitemap_total') if not total: total = Book.objects.count() # 缓存1小时,商品上下架时可以主动更新这个缓存值 cache.set('book_sitemap_total', total, 3600) return total def pagination(self, page): total = self._get_cached_total() limit = self.limit # 用主键游标分页代替大偏移量offset查询,千万级下性能提升10倍以上 start_id = (page - 1) * limit items = self.items().filter(id__gt=start_id)[:limit] return items, total - 静态化生成(可选,性能最高):如果流量很大、不想让sitemap请求占用应用服务资源,可以写个定时脚本,每天低峰期跑一次,把所有sitemap文件预先生成好存到Nginx对应的静态目录,或者存到对象存储,直接通过静态资源服务返回,完全不依赖Django和数据库,性能没有上限。
- 查询优化:
items()方法里一定不要查不需要的字段,大文本字段、详情字段全部排除,避免内存占用过高。
避坑提醒
- 单sitemap文件的URL数不能超过50000,文件大小不能超过50MB,这是Google、百度等主流搜索引擎的硬性要求,超出部分不会被收录。
- 不要用大偏移量的
[offset:offset+limit]切片做分页,千万级数据下offset到几百万的时候查询会非常慢,用主键范围过滤的方式分页效率高很多。 - sitemap不需要实时更新,缓存时间设1~6小时完全不影响收录,没必要每次请求都查最新数据。
内容的提问来源于stack exchange,提问作者djangodjames
相关产品推荐
相关产品推荐

