Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

美团点评沙龙12-LBS空间搜索架构的优化历程

867 views

Published on

LBS作为O2O行业的基础服务,在美团配送服务中扮演着连接用户、商家和配送员的重要角色。如何应对海量配送员的实时位置上报?如何为商家的订单找到附近合适的配送员?是配送调度的关键。随着美团配送业务的高速发展,LBS空间搜索服务经历过多次架构优化升级。本次分享将为大家介绍美团配送LBS空间搜索服务架构的优化历程。

Published in: Engineering
  • Be the first to comment

美团点评沙龙12-LBS空间搜索架构的优化历程

  1. 1. LBS空间搜索架构的优化历程   尹非凡@美团配送  20160925  
  2. 2. 2 关于.  我   2009.01 2011.01 2015.11   现在   MIM  Software   爱奇艺   新美大       云平台     1:云推送   2:Passport   3:爱奇艺泡泡   技术研发部     1:医疗软件开发   配送事业部     1:LBS   2:动态定价   3:动态预测  
  3. 3. 3 目录   l  关于  .  我   l  LBS与O2O   l  主要业务场景   l  LBS服务演化   l  MongoDB方案   l  MySQL+GeoHash方案   l  Redis+GeoHash方案  
  4. 4. 4 LBS与O2O   LBS   团购   打车   外卖配送   餐饮   商超   电影票  
  5. 5. 5 配   送   系   统   如何将用户的订单交给合适的骑手配送?   主要业务场景   商家在哪里?   入驻时确定   坐标固定   用户在哪里?   下单时确定   坐标固定   骑手在哪里?   实时变化   坐标不固定  
  6. 6. 6 主要业务场景   骑手实时坐标上传   骑手多,上报QPS高   峰值QPS:1.5W+  
  7. 7. 7 主要业务场景 订单找   骑手  派单   推单   抢单   人工派单   订单找   骑手  
  8. 8. 8 主要业务场景   空间搜索   订单找骑手   骑手找订单  
  9. 9. 9 业内解决方案   更新索引效率低   不适合实时更新场景   GeoHash   笛卡尔   层级   R树   MongoDB    Postgre/PostGIS   Lucene/Solr/ES  
  10. 10. 10 当配送小的时候  –  LBS1.0   MongoDB Slave   MongoDB   Slave       MongoDB   Slave   MongoDB Master 开发部署简单   •  原生支持空间索引   •  实时更新支持较好   •  开发成本低   扩展性较好   •  读写分离   •  负载均衡  
  11. 11. 11 MongoDB  as  LBS   API接入层   位置上报服务   Master  MongoDB   Slave  MongoDB   派 单   抢 单   人 工 派 单   推 单  
  12. 12. 12 MongoDB空间搜索原理   MongoDB内存过滤、合并   搜 索 结 果 空间搜索操作 为CPU密集型  
  13. 13. 13 MongoDB瓶颈   读写密集时出现问题   从服务器CPU负载急剧上升   查询性能急剧降低   查询吞吐量大幅降低   主从复制出现较大的延迟   原因分析   每一次LBS查询,会分解成许多次 单独的子查询   增大查询锁等待概率   结果合并、内存过滤消耗CPU  
  14. 14. 14 优化方案:MongoDB   库级锁问题   升级MongoDB(2.8+)   支持行级锁   CPU密集问题   分片   单库写控制在4000以内   支持目前的骑手数,至少需要 4个MongoDB实例   资源浪费严重  
  15. 15. 15 优化方案:自研LBS   GeoHash 存储系统   自研LBS 能否基于GeoHash算法,自己实现一个LBS空间搜索服务?
  16. 16. 16 GeoHash   定义:将一个经纬度信息,转换成一个可排序、可比较的字符串编码;   技术能力:负责子系统、技术规划、方法论沉淀、部⻔门级影响力;  
  17. 17. 17 GeoHash   (116.389550,39.928167) wx4g0s8q3jf9 降维   前缀包含   邻域相似  
  18. 18. 18 GeoHash   GeoHash原理  
  19. 19. 19 GeoHash   10111 00011 11010 01011 11100 11101 00100 01111 以北海公园为例   •  经纬度:116.389550,39.928167   纬度:39.928167     经度:116.389550  
  20. 20. 20 LBS2.0  -  存储系统选择   关系数据库   No-SQL   GeoHash 存储系统   自研LBS MySQL   Redis  
  21. 21. 21 LBS2.0:  MySQL  +  GeoHash   API接入层   LBS   GeoHash   Master  MySQL   Slave  MySQL   派 单   抢 单   人 工 派 单   推 单  
  22. 22. 22 LBS2.0:  MySQL  +  GeoHash   数据库查找   内存过滤   §   选择合适的GeoHash位数   §   选择当前坐标的格子以及 周边若干个格子   §   拼成SQL语句   § 内存过滤SQL 语句返回的结 果,刨除不符 合半径限制的 记录   如何进行空间搜索?  
  23. 23. 23 LBS2.0:  MySQL  +  GeoHash   标准的GeoHash缺陷   Base32编码,每一个字符代表5个bit位   wx4g0s8代表面积比Wx4g0s8q大32倍   GeoHash块可选范围小   纯二进制的GeoHash字符串缺陷   字符串太长、浪费空间   前缀匹配效率低   60Bit  GeoHash优点   可选访问宽   节省存储空间   搜索效率高   如何选择合适GeoHash格式?  
  24. 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. 25 LBS2.0:  MySQL  +  GeoHash   方案优点   研发经验丰富   运维比较成熟   方案缺点   性能存在瓶颈   扩展困难   单数据库写压力须控制在2000以内   仅支持万级别的骑手数   分库分表方案  
  26. 26. 26 LBS2.0:  MySQL  +  GeoHash   方 案 复 杂 资 源 浪 费 未 予 实 施 分库分表   •  Sharding  Key:  21Bit  GeoHash值   •  可表示19.5KM  *  19.5KM的矩形   •  绝大部分查询可在一个表中完成   •  极端情况需要查询四个库(表)   资源评估   •   写多、读少、数据量少   •  支撑1.5W上报QPS需分片8个主库   分库分表方案?  
  27. 27. 27 LBS2.0:  Redis  +  GeoHash   API接入层   LBS   GeoHash   Redis  Cluster   派 单   抢 单   人 工 派 单   推 单  
  28. 28. 28 LBS2.0:  Redis  +  GeoHash   数据冗余   如何解决多维度查询问题?   l  如何查询当前骑手的实时位置?   l  派单:如何查询一个组织内的所有骑手的实时位置?   l  众包抢单:如何查询一定范围内的所有骑手?   •   3公里半径内   •   多边形范围内  
  29. 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. 30 LBS2.0:  Redis  +  GeoHash   GeoHash位数选择   27bit,代表的格子大小约为4.5Km2   每次取9个GeoHash格子,可以过滤出周围3Km范围内所有骑手   Key-Map大小控制   hGetAll获取Map所有内容   Map大小不宜超过1000  
  31. 31. 31 LBS2.0:  Redis  +  GeoHash   骑手在格子间漂移的问题?    骑手坐标上传时   l  取出上一次骑手实时坐标   l  比较GeoHash格子是否有变化   •  有变化:删除上一次格子中的信   l  存储当前骑手经纬对应的GeoHash格子   每次上传大约操作Redis  3~4次  
  32. 32. 32 LBS2.0:  Redis  +  GeoHash   效果评估   资源消耗   l  10GB  Redis主内存   QPS最高支持   l  写:10W,是当前峰值流量的6倍   l  读:20W,是当前峰值流量的16倍   接口性能   l  位置上报接口:TP99  约4ms   l  查询接口:TP99  小于10ms  
  33. 33. 技术分享   谢谢!    

×