go-redis使用redis geo必须严格遵循经度在前、纬度在后顺序,采用wgs84坐标系,georadius单位仅认小写m/km/ft/mi,geosearch半径单位固定为米;高德/百度坐标须纠偏转wgs84,集群需用newclusterclient初始化并验证拓扑。

go-redis 作为 Go 微服务中接入 Redis GEO 的事实标准客户端,不是“能不能用”,而是“怎么避免踩坑用对”。它本身不解决坐标系、单位、顺序这些底层语义问题,只负责把参数原样发给 Redis——错一点,位置就飞到南美洲。
GeoAdd 参数顺序写反是最常导致线上事故的硬伤
Redis GEOADD 要求严格按「经度、纬度」顺序传参,go-redis/v9 完全不校验,也不会报错。传成 lat, lng 后数据能存进去,但所有查询都失效,且日志里看不出异常。
- 错误写法:
client.GeoAdd(ctx, "user:geo", 31.205593, 121.446617, "u123")(上海纬度当经度) - 正确写法:
client.GeoAdd(ctx, "user:geo", 121.446617, 31.205593, "u123") - 更推荐批量写法:
client.GeoAdd(ctx, "user:geo", &redis.GeoLocation{Longitude: 121.446617, Latitude: 31.205593, Name: "u123"}),字段名明确,不易混淆 - 注意边界:
Longitude必须 ∈ [-180, 180],Latitude∈ [-85.05112878, 85.05112878],超限会返回ERR invalid longitude, latitude
GEORADIUS 和 GEOSEARCH 单位处理差异极大
GEORADIUS 和 GEOSEARCH 在 go-redis/v9 中封装方式不同,单位逻辑完全不兼容,混用必出错。
Colly 是一个用于 Go 语言的快速开源爬取和爬虫框架。它适用于从简单的页面提取到异步爬虫处理大量页面集合,支持请求回调和结构化解析。
-
GEORADIUS:必须显式指定Unit字段,只认小写"m"、"km"、"ft"、"mi";漏写或写成"KM"直接返回空结果 -
GEOSEARCH:Radius字段单位固定为米,Unit参数已被废弃,传了也无效 - 调试时务必加
WithCoord: true和WithDist: true,否则只返回 member 名,无法验证是否真在范围内 - 若用
FROMMEMBER模式(比如查某个用户附近的其他用户),优先选GEOSEARCH,省去先调GEOPOS再拼坐标两步
坐标系偏差比代码 bug 更难排查
前端 Geolocation API 返回的是 WGS84,可直存;但高德、百度 SDK 默认返回 GCJ-02,未经纠偏直接进 Redis,会导致位置系统性偏移 200–500 米——这不是精度问题,是整个坐标系错位。
- 国内地图 SDK 获取坐标后,必须调用纠偏函数转成 WGS84,例如用
github.com/tidwall/gjson配合开源纠偏表,或走轻量级 HTTP 转换服务 - 别信“误差在可接受范围”——附近搜索半径设 500 米,偏移 300 米意味着近半用户查不到
- Redis GEO 底层用 Haversine 公式,只支持球面模型,跨大洲场景误差可达百米级,业务要求高精度时需自行补偿
- 测试阶段务必用
redis-cli手动验证:GEORADIUS user:geo 121.446617 31.205593 1 km WITHDIST,确认结果符合预期再上业务逻辑
微服务部署下集群连接初始化容易静默失败
用 redis.NewClient 连 Redis Cluster 是常见误区:它不会报错,只会 fallback 到第一个节点,后续 GEO 命令因 slot 路由失败而静默返回空结果。
- 必须用
redis.NewClusterClient,且Addrs至少传 2–3 个可连通 master 地址(不能只填一个) - Docker 环境下地址别写
localhost,改用host.docker.internal或服务名 - 初始化后立即执行
client.Ping(ctx).Err(),仅靠err == nil不代表集群 ready,要结合CLUSTER NODES状态判断 - 集群不支持
KEYS、SCAN等跨 slot 命令,GEO 查询没问题,但运维类操作需切到单节点模式
float64 ——它们是不是真的代表地球上那个点。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










