滴滴打车派单系统思考 数据库设计与实现 - 每月投入6140元, 1天最多可盈利117亿 -_-!...

标签

PostgreSQL , 滴滴 , 派单


背景

打车类应用,如果完全按调度系统来派单,而非抢单的话,调度系统要非常的健硕。

比如滴滴打车,如何处理供给双方的需求,并高效的完成派单呢?

随着业务的需求增多,调度规则也会增加,比如拼车,预约,等。

下面是一个简单的派单系统的思考,如何使用PostgreSQL与空间数据库插件PostGIS来实现一个简单的距离优先派单、拼车撮合。

采用skip lock或advisory lock来避免锁冲突。应对高峰期问题。

《HTAP数据库 PostgreSQL 场景与性能测试之 30 - (OLTP) 秒杀 - 高并发单点更新》

《聊一聊双十一背后的技术 - 不一样的秒杀技术, 裸秒》

《PostgreSQL 秒杀场景优化》

PostgreSQL 设计

1、空间数据库插件PostGIS

在PostgreSQL中创建空间数据库

postgres=# create extension postgis;  
CREATE EXTENSION  

1、滴滴车辆位置表

记录车辆的实时位置,是否被下单,有无剩余座位(不拼单的订单直接把剩余座位设为0)

create table car (  
  id int primary key,                          -- 车辆ID,主键  
  pos geometry,                                -- 实时位置, 使用PostGIS,geometry类型  
  sites int2 not null default 4,               -- 总座位数  
  rest_sites int2,                             -- 剩余座位数 (因为有拼车业务)  
  mod_time timestamp,                          -- 位置修改时间  
  order_pos geometry[],                        -- 当前订单对应用户打车的目的地位置  
  check (rest_sites <= sites and rest_sites>=0 and sites>0)  
);  

2、用户表

create table users (  
  id int8 primary key,  -- ID  
  otherinfo jsonb       -- 其他信息,请允许我偷懒一下使用JSON,实际上我这里派单只需要记录ID  
);  

3、订单表

记录每一笔订单,以及订单的状态

create table orders (  
  id serial8 primary key,   -- 订单号  
  carid int,             -- 车辆ID  
  uid int8,              -- 用户ID  
  crt_time timestamp,    -- 订单创建时间  
  pos1 geometry,         -- 上车位置  
  pos2 geometry,         -- 目的地  
  sites int2,            -- 乘坐几人  
  status int2            -- 订单状态(进行中 2, 取消 1, 结束 0)  
);  

4、车辆位置实时更新

每N秒(比如5秒),上报并更新位置。

《HTAP数据库 PostgreSQL 场景与性能测试之 29 - (OLTP) 空间应用 - 高并发空间位置更新(含空间索引)》

假设这个城市一共有1000万量车

假定车辆的活动范围经纬度(110~120, 25~30)  
  
vi test.sql  
  
\set id random(1,10000000)  
insert into car(id, pos, mod_time) values (  
  :id,   
  ST_SetSRID(ST_Point(round((random()*(120-110)+110)::numeric,6), round((random()*(30-25)+25)::numeric,6)), 4326),  
  now()  
) on conflict (id) do update set pos=ST_SetSRID(ST_Point(ST_X(excluded.pos)+random()-0.5, ST_Y(excluded.pos)+random()-0.5), 4326), mod_time=excluded.mod_time  
where car.sites <> car.rest_sites or car.rest_sites is null;     -- 不能被叫的车辆不更新位置(例如他的座位满了)  

(含空间索引)压测如下:

pgbench -M prepared -n -r -P 1 -f ./test.sql -c 56 -j 56 -T 120  
  
  
progress: 4.0 s, 200614.4 tps, lat 0.279 ms stddev 0.357  
progress: 5.0 s, 202598.0 tps, lat 0.276 ms stddev 0.336  
progress: 6.0 s, 196562.4 tps, lat 0.285 ms stddev 0.785  
progress: 7.0 s, 200305.4 tps, lat 0.280 ms stddev 0.534  
progress: 8.0 s, 207505.2 tps, lat 0.270 ms stddev 0.270  
progress: 9.0 s, 204128.0 tps, lat 0.274 ms stddev 0.347  
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值