More Related Content
Similar to 美团点评沙龙12-LBS空间搜索架构的优化历程 (20)
美团点评沙龙12-LBS空间搜索架构的优化历程
- 2. 2
关于. 我
2009.01 2011.01 2015.11 现在
MIM Software 爱奇艺 新美大
云平台
1:云推送
2:Passport
3:爱奇艺泡泡
技术研发部
1:医疗软件开发
配送事业部
1:LBS
2:动态定价
3:动态预测
- 3. 3
目录
l 关于 . 我
l LBS与O2O
l 主要业务场景
l LBS服务演化
l MongoDB方案
l MySQL+GeoHash方案
l Redis+GeoHash方案
- 5. 5
配
送
系
统
如何将用户的订单交给合适的骑手配送?
主要业务场景
商家在哪里?
入驻时确定
坐标固定
用户在哪里?
下单时确定
坐标固定
骑手在哪里?
实时变化
坐标不固定
- 10. 10
当配送小的时候 – LBS1.0
MongoDB
Slave
MongoDB
Slave
MongoDB
Slave
MongoDB
Master
开发部署简单
• 原生支持空间索引
• 实时更新支持较好
• 开发成本低
扩展性较好
• 读写分离
• 负载均衡
- 11. 11
MongoDB as LBS
API接入层
位置上报服务
Master MongoDB Slave MongoDB
派
单
抢
单
人
工
派
单
推
单
- 19. 19
GeoHash
10111 00011 11010 01011
11100 11101 00100 01111
以北海公园为例
• 经纬度:116.389550,39.928167
纬度:39.928167 经度:116.389550
- 21. 21
LBS2.0: MySQL + GeoHash
API接入层
LBS
GeoHash
Master MySQL Slave MySQL
派
单
抢
单
人
工
派
单
推
单
- 22. 22
LBS2.0: MySQL + GeoHash
数据库查找 内存过滤
§ 选择合适的GeoHash位数
§ 选择当前坐标的格子以及
周边若干个格子
§ 拼成SQL语句
§ 内存过滤SQL
语句返回的结
果,刨除不符
合半径限制的
记录
如何进行空间搜索?
- 23. 23
LBS2.0: MySQL + GeoHash
标准的GeoHash缺陷
Base32编码,每一个字符代表5个bit位
wx4g0s8代表面积比Wx4g0s8q大32倍
GeoHash块可选范围小
纯二进制的GeoHash字符串缺陷
字符串太长、浪费空间
前缀匹配效率低
60Bit GeoHash优点
可选访问宽
节省存储空间
搜索效率高
如何选择合适GeoHash格式?
- 24. 24
LBS2.0: MySQL + GeoHash
Base32格式
GeoHash
左对齐转成64
位整形
右移4位
列名 字段类型 描述
bm_user_id bigint 骑手ID
bm_user_lat int 骑手纬度
bm_user_lng int 骑手经度
geohash_long bigint 60bit GEOHASH值
bm_org_id int 组织ID
utime int 上传时间
- 25. 25
LBS2.0: MySQL + GeoHash
方案优点
研发经验丰富
运维比较成熟
方案缺点
性能存在瓶颈
扩展困难
单数据库写压力须控制在2000以内
仅支持万级别的骑手数
分库分表方案
- 26. 26
LBS2.0: MySQL + GeoHash
方 案 复 杂
资 源 浪 费
未 予 实 施
分库分表
• Sharding Key: 21Bit GeoHash值
• 可表示19.5KM * 19.5KM的矩形
• 绝大部分查询可在一个表中完成
• 极端情况需要查询四个库(表)
资源评估
• 写多、读少、数据量少
• 支撑1.5W上报QPS需分片8个主库
分库分表方案?
- 28. 28
LBS2.0: Redis + GeoHash
数据冗余
如何解决多维度查询问题?
l 如何查询当前骑手的实时位置?
l 派单:如何查询一个组织内的所有骑手的实时位置?
l 众包抢单:如何查询一定范围内的所有骑手?
• 3公里半径内
• 多边形范围内
- 29. 29
LBS2.0: Redis + GeoHash
KEY VALUE
PREFIX:{riderId} (lat, lng, timestamp, …)
KEY FIELD VALUE
PREFIX:
{orgId}
RiderId (lat, lng,
timestamp, …)
KEY-MAP
结构
KEY FIELD VALUE
PREFIX:
{geohash}
RiderId (lat, lng,
timestamp, …)
l 如何查询当前骑手的实
时位置?
l 骑手到骑手坐标的映射
l 如何查询一定范围内所
有骑手?
l GeoHash到骑手坐标映射
l 如何查询组织内骑手实时
位置?
l 组织到骑手坐标映射
- 30. 30
LBS2.0: Redis + GeoHash
GeoHash位数选择
27bit,代表的格子大小约为4.5Km2
每次取9个GeoHash格子,可以过滤出周围3Km范围内所有骑手
Key-Map大小控制
hGetAll获取Map所有内容
Map大小不宜超过1000
- 31. 31
LBS2.0: Redis + GeoHash
骑手在格子间漂移的问题?
骑手坐标上传时
l 取出上一次骑手实时坐标
l 比较GeoHash格子是否有变化
• 有变化:删除上一次格子中的信
l 存储当前骑手经纬对应的GeoHash格子
每次上传大约操作Redis 3~4次
- 32. 32
LBS2.0: Redis + GeoHash
效果评估
资源消耗
l 10GB Redis主内存
QPS最高支持
l 写:10W,是当前峰值流量的6倍
l 读:20W,是当前峰值流量的16倍
接口性能
l 位置上报接口:TP99 约4ms
l 查询接口:TP99 小于10ms