拼车服务使用移动应用程序将乘客与司机联系起来,设计这样的系统系统有几个关键目标,其中包括:
提供高效可靠的服务,满足市场需求。
帮助司机找到最有效的路线。
检测和防止欺诈,确保所有用户的安全。
实时更新数据,提供高效服务。
在这里,我们将探讨设计这样一个系统的各个组成部分。
要使用拼车服务,乘客只需从出发地叫车到目的地。 一旦提出乘车请求,附近的司机将收到通知,其中一名司机将确认乘车。
为了确保高效的服务,司机需要经常更新他们当前的位置和可用性,以便服务能够将他们与附近的乘客相匹配。
确认行程后,司机和乘客都可以跟踪对方的当前位置,直到行程完成。 登机后,乘客将收到一张收据,其中包含路线图和**等行程信息。
为确保乘客了解他们的上车情况,该服务会在安排行程时显示乘客的预计到达时间。
假设我们有 1 亿客户和 100 万名司机,其中 100 万名日活跃客户和 100,000 名日活跃司机。
我们还假设每天有 100 万次乘车请求,并且所有活跃的司机每 4 秒更新一次其当前位置。
为确保流畅的体验,当客户叫车时,系统必须能够立即联系附近的司机。
该应用程序使用移动设备将乘客与司机联系起来。 一旦乘客通过应用程序叫车,司机就会被引导到他们的位置上车。 在幕后,该服务由大量服务器提供支持,这些服务器在每次骑行期间都会处理大量数据。
随着时间的推移,系统设计已经从更简单的单体架构发展到更复杂的面向服务的架构。 该架构由两个主要组件组成:服务(管理汽车和司机的可用性)和需求服务(处理乘客请求)。
因此,乘客和司机的实时匹配是服务的一个重要方面。 这是通过调度系统实现的,该系统使用来自供需服务的数据将乘客与最接近、最合适的司机相匹配。
通常,在系统的早期,传统的关系数据库管理系统 (RDBMS) 用于存储用户配置文件、GPS 位置和其他信息等数据。 然而,随着用户数量的增加,系统很难实时处理大量数据。 要解决此问题,请改用 NoSQL 数据库,它提供了更好的可伸缩性和性能。
通过切换到 NoSQL,数据库变得可水平扩展,也就是说,它们可以在不影响性能的情况下处理越来越多的数据和用户。 此外,NoSQL 数据库提供更好的写入和读取可用性,从而实现更快、更高效的数据处理。 这场技术革命正在为越来越多的用户提供服务。
在本节中,我们将深入探讨系统中涉及的组件的设计。
该系统中的需求服务负责管理乘客通过应用程序提出的请求。 当乘客叫车时,需求服务会通过网络套接字接收请求,并开始监控乘客的 GPS 位置。 它还处理其他类型的请求,例如所需的座位数、首选的汽车类型以及乘客是否要求拼车。
使用这些信息,需求服务将乘客与适当的司机和车辆相匹配,同时考虑到乘客的位置和其他偏好。 它还跟踪特定地理区域内的行程**和需求,以优化匹配过程。
该系统使用多种技术来确保为客户提供高效的服务。 当司机在路上时,他们的出租车位置会不断更新,并每 4 秒与服务器通信一次。 此信息通过 Web 应用程序防火墙和负载均衡器发送,这有助于确保数据安全且正确分发。
一旦位置数据到达服务器,它就会通过 Kafka 的 REST API 传递。 该技术可以有效地传输大量数据,并确保服务器始终拥有每辆出租车的最新位置信息。
位置数据现在存储在相关工作节点的主内存中。 这样可以快速轻松地访问信息,这对于为客户提供准确和及时的服务至关重要。 此外,位置数据的副本被传输到数据库以进行调度优化。 这有助于确保客户始终与最接近、最方便的司机相匹配。
系统的调度机制基于地图和位置数据,需要适当的建模和映射。 使用纬度和经度数据来汇总和估计位置是很棘手的。 但是,使用纬度和经度数据汇总和估计位置可能具有挑战性。 注意:DISCO必须满足几个目标,例如减少额外的驾驶,最大限度地减少等待时间,以及最大限度地减少总体预计到达时间。
让我们看看调度服务是如何工作的:
调度系统首先将地图数据划分为小单元,并使用 S2 库为每个单元分配一个唯一的 ID。 这是一种简单的技术,可以在分布式系统中有效地存储和分发数据。
S2 库还允许您根据给定位置创建特定区域或“覆盖范围”。 例如,如果要查找城市半径 5 公里内的所有驾驶员,则可以使用 S2 库创建一个半径为 5 公里的圆,它将过滤掉 ID 在该半径内的所有像元。
接下来,将可用出租车列表提供给 ETA(预计到达时间)算法,该算法使用道路系统来计算出租车与乘客之间的距离。 然后,分拣后的预计到达时间被传输回系统并提供给驾驶员。
此过程有助于最大限度地减少额外的驾驶,减少等待时间,并准确**客户的总预计到达时间。
预计到达时间 (ETA) 是应用程序中的一项功能,可让乘客在行程开始前知道司机需要多长时间才能到达上车地点。 该应用程序还会显示旅行开始后到达目的地的预计时间。
为了计算预计到达时间,使用附近司机的位置数据来估计他们到达乘客上车地点所需的时间。 旅行开始后,该应用程序会定期更新目的地的预计到达时间。 这让乘客更好地了解他们何时可以到达目的地。 ETA 计算还考虑了实时交通、天气和其他可能影响行程持续时间的因素。
当用户请求叫车时,该请求将通过 Web 套接字发送到需求服务。 需求服务意识到需要乘车,并向**服务提交带有乘车信息的请求。 要考虑的关键问题是:为什么系统使用 Web 套接字?
*服务使用需求服务提供的信息,例如乘客的位置,以确定哪些司机离乘客最近。 然后,它将请求发送到服务器环中的一台服务器。 这些服务器使用 ETA 值来找出离乘客最近的出租车。
*一旦服务计算出 ETA 值,它就会通过 Web 套接字通知驱动程序。 如果合作车主接受请求,行程将分配给乘客和合作车主。 然后,司机将接载乘客并将他们带到目的地。
使用分析来深入了解客户和驾驶员的需求和行为,优化运营成本,并提高客户满意度。 为了实现这一目标,采用了一系列技术和框架。
驾驶员和乘客位置数据存储在 NoSQL、RDBMS 或 HDFS 等数据库中进行分析。 对于实时分析,Hadoop平台提供了各种与分析相关的工具。
借助 HDFS,可以从 NoSQL 数据库中提取原始数据,并使用 Hive 等查询工具进行访问,以分析和解释数据以增强其服务和操作。
高峰定价是网约车公司采用的一种动态定价策略,用于在需求旺盛时增加乘车成本。 高峰时段定价的目的是激励更多的司机上路,提供更多的乘车服务,以满足不断增长的需求。
用于确定高峰时段定价的算法基于供需原则。 该系统使用给定区域内驾驶员和乘客数量的实时数据,以及交通和天气等其他因素来确定乘车需求水平。
当需求激增且没有足够的司机时,该算法会提高乘车次数,以鼓励更多司机上路。 **也可能因一天中的时间、星期几和其他因素而异。
以下是该算法背后的一些常规步骤和见解:
定义基本:根据距离、时间和任何其他相关因素设置骑行的基本情况**。
确定需求水平:该系统分析历史或实时数据,以估计特定区域的游乐需求。
确定级别:现在,系统会估计当时同一区域中可用的驱动程序数量。
计算浪涌倍数:现在,系统通过将需求除以供应来计算浪涌乘数。 例如,如果需求是两倍,则浪涌乘数可能为 20x。
调整**:最后,系统通过将基数乘以浪涌倍数来调整行驶。
为了提高系统的效率,有必要减少它在后台搜索的位置数量。 为了实现这一点,我们可以实现一个网格系统,其中每个网格的最大位置限制为 1000 个位置(或其他数字)。 当网格超过此限制时,将使用 4 个叉树数据结构将其划分为四个大小相似的较小网格。
四叉树是一种基于树的结构,用于存储有关其相应网格内所有位置的数据。 当四叉树中的节点达到 1000 个位置限制时,它将被分成四个子节点,每个子节点存储一个位置子集。 重复此过程,直到到达叶节点,该节点表示无法进一步分割的网格。 通过这种方式,我们可以有效地搜索位置,同时将每个网格中的位置数量保持在可管理的限制范围内。
为了确保所有当前驾驶员的位置准确反映在我们的数据结构中,我们需要在驾驶员移动时实时更新它们。 但是,这可能非常耗时且耗费资源。 为了实现这一点,我们必须首先根据驾驶员之前的位置找到正确的网格,然后用新位置对其进行更新。 如果驱动程序的新位置不在同一网格中,我们必须将其从旧网格中删除并将其添加到新网格中。 如果新网格在此传输后达到其最大驱动程序限制,则必须对其进行重新分区以保持网格的大小限制。
我们的系统需要一种快速有效的方法,将周围所有驾驶员的当前位置传达给特定区域的任何活跃客户。 此外,在乘车过程中,系统必须让驾驶员和乘客知道车辆的当前位置。
为确保信息是最新的,我们必须不断使用最新的驱动程序位置更新四叉树。 由于所有驱动程序每 4 秒报告一次他们的位置,因此我们将收到来自树的许多更新。 因此,一旦服务器收到有关驱动程序位置的更新,它将通知相应的四叉树服务器和所有感兴趣的客户端。
为了有效地与客户共享驾驶员的位置,我们使用推送模型,其中服务器将位置更新推送给所有相关用户。 当客户在手机上打开应用程序并请求附近的驱动程序时,我们会在服务器端订阅这些驱动程序的所有更新,然后再将可用驱动程序列表发送到客户端。 这样,我们可以在任何给定时间跟踪所有有兴趣了解驾驶员位置的客户。
每当驱动程序在四叉树中的位置有更新时,我们都会将其当前位置广播给所有订阅客户端。 这可确保客户始终看到有关驾驶员位置的最新信息,并有助于更高效、更快速地搜索附近的驾驶员。
为了确保高可用性,我们需要一个副本,以便在主服务器发生故障时,备用服务器可以接管。 此外,我们可以将这些关键数据存储在永久存储中,例如具有快速 IO 速度的 SSD,这样如果主服务器和辅助服务器都出现故障,我们仍然可以从永久存储中恢复数据。
虽然数据中心故障很少见,但通常会维护第二个数据中心以确保顺利运行。 但是,尽管现有数据具有所有必需的组件,但不会将其复制到备份数据中心。 为了减轻数据中心故障的影响,请使用驾驶员的手机作为行程数据**。 当驾驶员的移动应用程序和调度系统之间进行API调用时,调度系统将加密数据传输到驾驶员的移动应用程序,驾驶员移动应用程序每次都会接收数据。
如果数据中心发生故障,备份数据中心将没有关于正在进行的行程的信息,因此它将从驾驶员的手机应用程序请求数据。 然后,从驾驶员的手机应用程序获取的数据将用于更新备份数据中心。
优质作者名单