打车软件中司机数据系统设计

欢迎关注更多精彩
关注我,学习常用算法与数据结构,一题多解,降维打击。

Go, MySQL, Redis

功能:为基础业务(包括打车业务,单车业务,金融等)提供司乘数据维护接口,提供高效迭代能力。维护千万级数据,保证接口性能,与服务稳定性。

在项目中的职责:优化系统代码架构,优化接口性能,保证服务稳定性。提升支持基础业务开发效率。

关键成果:业务字段添加配置化,数据查询与存储优化,业务字段获取管控,数据历史追溯

解决的问题:

  • 业务发展快速,添加字段频繁,迭代周期长(以周为单位)。
  • 司乘信息字段非常多(几百个),查询和存储效率低。
  • 用户获取数据冗余,数据安全和接口性能无法保证。
  • 司乘数据变迁记录无法查询,客诉问题追查困难

解决方案:

  • 引入noSQL数据库Fushion, 将业务数据进行垂直切分,提高了业务数据扩展性。
  • 业务字段添加配置化,提升支持基础业务开发效率。
  • 对数据进行水平切分,加快查询效率。
  • 对数据进行redis缓存,提升查询效率。
  • 查询接口字段分租户管控。
  • 消费binlog生成数据流水。

收益:

  • 业务添加字段由原来周级别提升到天级别。
  • 查询与存储效率提升可以支持百万级qps。
  • 业务取数按需获取,提升数据安全和接口性能。
  • 生成用户数据流水,追查历史方便。

挑战与取舍

  • 数据字段分表的考量是什么

水平分表:用户数据有5000万之多,放一张表里查询与存储效率低,需要分成每张表100万以下比较好,我分成了101(质数)张表,每张表大概50万。

垂直分表:我把字段分成两类,1. 变化较少或基本不变的用户属性字段,如身份证,年龄,家庭住址,性别等;2. 经常变化的业务字段,如当前位置,接单状态,接单数量等。

  • 一条数据是如何被缓存到redis的,批量每件查询下如何优化
    2种查询模式:
  1. 按id查询,先把id按照hash分成101组,然后每组去库里查询,并合并mysql与fusion结果数据并缓存。这种经常用于在线实的场景。
  2. 条件查询,先用条件去es索引中查询id, 再通过id按方法1查询。这种用于离线场景。
  3. 缓存设计时间 5秒钟
  • 如何保证redis与mysql&fusion数据一致性
  1. 数据底表操作
    正常情况,有可能存在更新多张表时有1张表更新失败的情况。那就需要用到事务操作,但实际上一次更新只会涉及到1张表。
    有2种接口一个是创建或更新用户属性表,另一个是创建或更新用户业务字段表。
    在用户创建阶段,只会写用户属性,业务字段为空读取时用默认值。
    另一个接口用于更新用户业务字段。

  2. redis一致性

先更新mysql或fusion数据,若成则更新redis数据。如果redis(加重试)不成功则会由超时重新回表兜底,适合于对数据实时性要求不高的场景。

  • 强一致性需求如何保证

有些业务场景对数据一致性要求非常实时,比如用户刚创建,此时就要来查询是否创建成功。上述设计是无法保证的,原因是读的是从库。所以系统还提供了强制读主的选项,此选项只分配给特定业务使用。

  • 分租户管控为什么不用graphql
  1. 数据只有单层
    司机和用户数据结构都单层的数据,且都是单值数据结构。 graphql更适合于多层解析。

  2. 数据下游访问很少
    graphql 可解析多个下游访问,本系统已经是最下游中很少访问下游取数据。

  3. 实现简单,引入graphql使依赖加重
    取数逻辑简单,管理简单。引入graphql反而变复杂了。

你可能感兴趣的:(面试技巧,系统设计,系统设计)