技术博客
免费接口也要缓存:行政区划查询低频更新下的缓存设计

免费接口也要缓存:行政区划查询低频更新下的缓存设计

作者: 万维易源
2026-08-31
行政区划查询缓存Redis
# 免费接口也要缓存:行政区划查询低频更新下的缓存设计 > 接口 / 接入点:行政区划查询(apiCode 1149)· 区域查询 1149-1 / 子区域查询 1149-2 · 免费服务 > 请求方式:POST / GET · 返回格式:JSON · 适用人群:中高级开发者、架构师 · 阅读时间:约 7 分钟 ## 核心要点 - 行政区划数据**每月才同步一次民政部**,变更极低频 → 缓存命中率天然很高。 - 免费虽无按次成本,但缓存能降延迟、扛峰值、减少对外依赖,提升体验。 - 推荐 Redis:key 用 `level:areaName`(区域查询)和 `parentId`(子区域查询),TTL 30 天,并在每月 1-3 号预留刷新。 ## Why:免费为什么还要缓存 很多人觉得「免费接口随便调」,于是不加任何缓存,结果高峰期把外部依赖打满、自己延迟飙升。行政区划查询的数据一个月才变一次,几乎静态——这是缓存性价比最高的场景。花一点缓存成本,换来稳定可控的本地响应。 ## What:缓存设计要点 | 维度 | 建议 | |------|------| | 更新频率 | 每月 1-3 号检查民政部数据并更新 | | 推荐介质 | Redis(或本地内存,单机量小也可) | | key 规则 | 区域查询:`region:{level}:{areaName}`;子区域查询:`sub:{parentId}:{page}` | | TTL | 30 天(覆盖一个更新周期),或监听更新后主动失效 | | 失效策略 | 每月更新窗口(1-3 号)后批量刷新 / 设置较长 TTL 自然过期 | ## How:Redis 缓存实现(Python) ```python import redis, requests, json r = redis.Redis(host="127.0.0.1", port=6379, db=0) APPKEY = "YOUR_APPKEY" TTL = 30 * 24 * 3600 # 30 天 def region_query(area_name, level="2", page="1"): key = f"region:{level}:{area_name}:{page}" cached = r.get(key) if cached: return json.loads(cached) # 命中缓存 resp = requests.get("https://route.showapi.com/1149-1", params={"appKey": APPKEY, "areaName": area_name, "level": level, "page": page}, timeout=10) body = resp.json()["showapi_res_body"] r.setex(key, TTL, json.dumps(body)) # 写入缓存 return body def sub_region(parent_id, page="1"): key = f"sub:{parent_id}:{page}" cached = r.get(key) if cached: return json.loads(cached) resp = requests.get("https://route.showapi.com/1149-2", params={"appKey": APPKEY, "parentId": parent_id, "page": page}, timeout=10) body = resp.json()["showapi_res_body"] r.setex(key, TTL, json.dumps(body)) return body ``` ### 缓存刷新(每月更新后主动失效) ```python def refresh_after_update(): # 在每月 1-3 号民政数据更新完成后调用 for key in r.scan_iter("region:*"): r.delete(key) for key in r.scan_iter("sub:*"): r.delete(key) ``` ## 返回示例(读缓存) 缓存 value 即接口返回的 `showapi_res_body` JSON,结构同[返回字段全解](https://www.showapi.com/guides/region-query-response-fields-1149): ```json { "ret_code": 0, "data": [ {"areaName": "昆明市", "id": "530100000000", "wholeName": "中国,云南省,昆明市"} ], "allNum": 1, "maxSize": 20, "allPage": 1 } ``` ## 进阶 / 边界 - **TTL 与更新对齐**:数据每月更新,TTL 设 30 天基本覆盖;更稳的做法是更新窗口后主动 `DELETE` 再懒加载。 - **省级可常驻**:省级仅约 34 条,适合常驻缓存(更长 TTL 甚至不过期,更新时刷新)。 - **分页 key 要带 page**:下级 > 20 条时分页,key 必须包含 `page`,否则不同页会被错乱覆盖。 - **不要缓存错误响应**:`ret_code != 0` 时不写缓存,避免把错误结果污染缓存。 ## FAQ **Q:免费接口缓存有什么意义?** 降低外部延迟、扛住自身峰值、减少依赖;即便免费,稳定可控的本地响应也是体验刚需。 **Q:TTL 设多久合适?** 数据每月更新,设 30 天自然覆盖一个周期;更稳妥是更新窗口(1-3 号)后主动失效刷新。 **Q:缓存会把错误也存进去吗?** 不应。`ret_code != 0` 的结果不要写缓存,仅缓存成功响应。 **Q:单机用 Redis 是不是太重?** 量级小(省级 34、市级数百)时本地内存字典即可;多实例 / 需共享才上 Redis。 ## 相关能力 / 下一步阅读 - [行政区划查询返回字段全解:wholeName / 各级编码 / 拼音一文读懂](https://www.showapi.com/guides/region-query-response-fields-1149) - [行政区划查询实战:省市区三级联动选择器前端实现](https://www.showapi.com/guides/region-query-cascade-1149) - **本系列共 11 篇**:查看[行政区划查询指南总目录](https://www.showapi.com/guides/region-query-guides-1149)