需要注意clarify什么
要实现哪些功能,先列出来,再让面试官去选他认为的核心功能。
场景
用户找车,
司机接单
Api
RequestPickUp(userId, lat, lon, destination) 也可以把lat + lon换成geohash
ReportLocation(driverId, lat, lon), Return Value(TripId, destination, passengerName) if there is trip assigned to the dirver
AcceptATrip(driverId, tripId)
Storage/Database Design
Location Driver Table:
GeoHash, Set<Driver(Id,)>
存三个level的geoHash
Trip Table:
TripId, from, to, createdAt, riderId, driverId, status(enum)
Driver Table:
DriverId, GeoHash,Status, tripId
Working Solution:
司机每几秒向服务器汇报一下自己的位置,服务器算出司机的GeoHash,同时调出来上次司机在哪个位置,去一次的位置把司机从Location Driver 删掉, 在新的位置添加上司机的位置。同时更新driver table。
用户发起请求后,系统也和用户建立起heartbeat联系, 系统根据乘客的位置去查询和他前缀相同并且available的司机,并在heartbeat返回值里面通知司机trip的信息, 司机收到后决定是否接收,如果接收则把trip状态改为 Started或者accepted,通知乘客司机的信息,同时在返回给乘客的heartbeat里,定期播报司机的信息。
如何加速
使用读和写都很多的数据库比如redis
Replica和sharding来提高访问速度.
如何Sharding
按location sharding, 可以接city进行sharding, 根据用户的位置看在哪个城市。然后根据去那个服务器上找。
如果司机在城市之间切换怎么办?
Driver Table可以用 DriverId Sharding, 这样就没有任何问题了。
另外一种办法是再存一个Driver City(Server) table. 这张表记录一下每个司机在哪个城市里。如果想查某个司机的信息。先去这张表里找一下这个司机在哪个服务器上 。当司机变换城市时,通过中心服务器司机变更城市 ,并且把数据转移服务器。 这样的变化应该比较小, 所以服务器压力不大。这个表只在司机上线或者变成城市时才会用。
Driver City Table
DriverId, LastSeenCity, TimeStamp