连麦、PK和语音房的实现设计思路

implementation of linkmic pk and voice room

作者:ypingcn 首次发布时间:2023年12月31日 最后更新时间:2024年11月17日
[AD] -- 下方为内容广告,点击支持作者,想过滤广告? -- [AD]

连麦 PK 是秀场直播中的一个重要核心玩法。而语音房同样包含众多的连麦操作。这三类都是不同的角色在自己位置上的行为。

本文意在对已有功能实现的总结和思考,对比中思考改进点

故在此,对这三类场景的数据管理实现上,总结一下相同点与不同点。

存储位置状态数据

首先,PK 可以理解成是连麦上再次叠加的一层玩法,按照这种逻辑,双人 PK 则是需要双人连麦成功后才有的玩法。按照不同的连麦类型可以分成双人连麦和多人连麦,这两种分法,核心的本质在于一场连麦中的人数是2还是N,这个具体数字只需要在发起时确认即可。为统一讨论实现方案,后续仅讨论多人连麦。

其次,语音房是一种包含 8 个人或者 10 个人的位置状态管理,与连麦相比,这个位置信息不需要包含画面相关的信息,取而代之的是说话中的“声纹”。所以连麦和语音房的位置状态数据共同点,至少包含是否有人上座、用户ID的两个基础信息。

再者可以按以下逻辑,抽象出相关的信息存储——

用户->场次的索引、场次->所有位置信息的数据

那么,第一个实现上的差别就产生了,如何存储所有的位置信息并保证其准确性?以下是两个做法

文档型存储

这里的文档型存储,是类比“文档型数据库”的一种说法。将所有位置数据都抽象到同一个 json 或者其他序列化后的文本中,数据库辅以版本号进行管理。每次位置更新,只需要取出对应的版本号和位置数据,更新位置数据后用乐观锁同步到数据库中,同步失败则有限次地重复之前步骤重试。

连麦会话中的位置信息管理使用了本思路来处理,这样做的好处在于后续可扩展性高,有需要新增的字段数据只需要直接添加,不需要额外的改动。

数据结构设计

  1. 位置信息文档

    • 用户ID (user_id)
    • 场次ID (session_id)
    • 是否有人上座 (is_occupied)
    • 其他相关信息(如声纹信息、时间戳等)
    • 版本号 (version):用于乐观锁同步
  2. 场次文档

    • 场次ID (session_id)
    • 场次名称 (session_name)
    • 开始时间 (start_time)
    • 结束时间 (end_time)
    • 当前版本号 (version):用于记录场次的最新版本

操作流程

  1. 创建场次

    • 在场次文档中插入一条新的记录,并初始化版本号。
  2. 用户加入场次

    • 在位置信息文档中插入一条新的记录,关联用户ID和场次ID,并初始化版本号。
  3. 更新位置信息

    • 读取位置信息文档的当前版本号。
    • 更新位置信息文档中的数据。
    • 使用乐观锁同步更新到数据库中,即比较版本号是否一致。如果不一致,则重试有限次数。
  4. 查询位置信息

    • 直接读取位置信息文档中的数据,并根据需要关联其他相关信息(如用户信息、场次信息等)。

优点

  • 可扩展性高:新增字段数据只需要直接添加到位置信息文档中,不需要额外的改动。
  • 实现简单:相对于关系型存储,文档型存储的实现更为简单直观。
  • 性能较好:对于读多写少的场景,文档型存储的性能表现较好。

缺点

  • 数据一致性:由于使用乐观锁进行同步更新,可能存在一定的数据不一致风险。
  • 查询效率:对于复杂查询和数据分析,文档型存储的效率可能不如关系型存储。
  • 存储空间:由于存储的是序列化后的 JSON 数据,相对于关系型存储可能会占用更多的存储空间。

关系型存储

关系型存储则更侧重于结构化数据的存储和管理。在关系型数据库中,可以将位置信息拆分为多个表,例如用户表、场次表和位置信息表,通过外键关联这些表。每次位置更新,需要执行 SQL 语句来更新相关表中的数据,并通过事务来保证数据的一致性。

关系型存储的优点在于数据结构清晰,查询效率高,适合复杂查询和数据分析。但是,关系型存储的可扩展性相对较差,新增字段可能需要修改表结构。

以下是关系型存储在语音房中的技术细节实现文档:

关系型存储表结构设计

  1. 用户表(users)
    • user_id (主键)
    • username
    • email
  2. 场次表(sessions)
    • session_id (主键)
    • session_name
    • start_time
    • end_time
  3. 位置信息表(positions)
    • position_id (主键)
    • user_id (外键,关联用户表)
    • session_id (外键,关联场次表)
    • is_occupied (是否有人上座)
    • voiceprint (声纹信息)

关系型存储操作流程

  1. 创建场次:插入一条新的记录到场次表中。
  2. 用户加入场次:插入一条新的记录到位置信息表中,并关联用户表和场次表。
  3. 更新位置信息:执行 SQL 语句更新位置信息表中的数据。
  4. 查询位置信息:执行 SQL 语句查询位置信息表中的数据,并关联用户表和场次表。

关系型存储优缺点

优点:

  • 数据结构清晰,易于理解和维护。
  • 查询效率高,适合复杂查询和数据分析。
  • 数据一致性好,通过事务保证数据的一致性。

缺点:

  • 可扩展性较差,新增字段可能需要修改表结构。
  • 相对于文档型存储,关系型存储的性能较低。
[AD] -- 下方为内容广告,点击支持作者,想过滤广告? -- [AD]