分布式问题

问题

  • 一致性问题

    • 主从延迟
      • 对于即时性高的接口,直接从主库中读取
    • 资源抢夺
      • 不进行读写分离,在主库中完成流程
  • 分片id冲突

    • 实现分布式ID
  • 事务不支持跨库原子性

    • 一个业务中可能包含多个库中的写操作,该业务需要具有原子性,但事务不具备跨库原子性
    • 解决办法
      • 将有关联的表放在一个数据库中
        • 同库操作可以使用一个事务
        • 如用户表&用户频道表,文章基本信息表&文章内容表 放在一起
      • 使用分布式事务
        • 核心是二阶段提交协议(简称2PC协议/XA协议)
        • 会出现事务等待的情况,增加死锁的产生几率,效率低
      • 实现基于消息的最终一致性方案
        • 通过消息队列执行异步任务,部分失败则不断重试或全部取消
        • 分布式中间件 mycat
          • 一般会提供一定程度的最终一致性方案,如任务分发,任务重试,消息幂等
          • 基于mysql进行了二次封装,学习/修改成本高
  • 不支持的跨库操作 join/分组/聚合/排序

    • 解决办法
      • 分两次查询进行,在应用端合并

项目中的处理

  • 复制
    • 采用主从架构,实现了“手动读写分离”,但没有对主从延迟进行特殊处理
  • 分片
    • 实现了垂直分表 用户表&文章表
    • 使用雪花算法生成了分布式ID, 为水平分表提供了准备(单表数据超过1000W)
    • 后续分库
      • 注意将相关的表放在同一个数据库节点中
      • 对于跨库操作, 先分别处理, 再合并, 并根据业务逻辑实现最终一致性方案
  • 应用层设计方案
    • 悲观锁
      • 开发者主动设置锁
    • 乐观锁
      • 先不加锁(假设不会有并发问题), 但是更新前校验数据一致性, 需要手动代码实现
      • Django项目中先判断库存, 再生成订单,就是乐观锁设计
      • 高级的乐观锁可能会采用版本号/时间戳来校验, 需要进行表设计
1.读取点赞数, 如like_count=10
3.每次更新表中的数据时,为了防止发生冲突,需要这样操作
update t_article set like_count = 11 where article_id=5 and like_count = 10;
posted @ 2019-08-25 09:54  太虚真人  阅读(187)  评论(0编辑  收藏  举报