大纲:
一致性问题的痛点
分布式架构中的数据一致性问题
- 系统间的数据一致性(分布式事务)
- 数据库实例之间的数据一致性
graph TD
A-1(应用A-实例1)
A-2(应用A-实例2)
DB-A-1((应用A-数据库实例1))
DB-A-2((应用A-数据库实例2))
B-1(应用B-实例1)
B-2(应用B-实例2)
DB-B-1((应用B-数据库实例1))
DB-B-2((应用B-数据库实例2))
subgraph 应用B
B-1-->|w/r|DB-B-1
B-2-->|w/r|DB-B-1
B-1-->|r|DB-B-2
B-2-->|r|DB-B-2
end
subgraph 应用A
A-1-->|w/r|DB-A-1
A-2-->|w/r|DB-A-1
A-1-->|r|DB-A-2
A-2-->|r|DB-A-2
end
- 什么是数据一致性问题
- 一致性问题是怎么产生(网络、硬件、程序)
同城主备
graph TD
A-1(server1)
A-2(server2)
DB1((master))
DB2((slave))
B-1(server3)
B-2(server4)
DB3((slave))
DB4((slave))
NG(nginx)
NG-->B-1
NG-->B-2
NG-.-|x|A-1
NG-.-|x|A-2
subgraph SJQ
B-1-->|w/r|DB1
B-2-->|w/r|DB1
B-1-->|r|DB2
B-2-->|r|DB2
end
subgraph YZ
A-1-->|r|DB3
A-2-->|r|DB3
A-1-->|r|DB4
A-2-->|r|DB4
end
A-1-->|w/r|DB1
A-2-->|w/r|DB1
南北双活
graph TD
A-1(server1)
A-2(server2)
DB1((master))
DB2((slave))
B-1(server3)
B-2(server4)
DB3((master))
DB4((slave))
LL(流量)
LL-->B-1
LL-->B-2
LL-->A-1
LL-->A-2
subgraph 北方机房
A-1-->|w/r|DB1
A-2-->|w/r|DB1
A-1-->|r|DB2
A-2-->|r|DB2
end
subgraph 南方机房
B-1-->|w/r|DB3
B-2-->|w/r|DB3
B-1-->|r|DB4
B-2-->|r|DB4
end
otter(otter)
DB1---|sync|otter
DB3---|sync|otter
解决方案:最终一致性,2PC,多数派协议(paxos,raft)
最终一致的常见解决方案
- 幂等
- 重试
sequenceDiagram
participant A as 寻宝业务
participant B as 订单服务
participant C as 消费服务
participant E as 抽奖服务
participant D as 仓库服务
A->>B:下单
activate B
B->>C:扣费
activate C
C-->>B:扣费成功
deactivate C
B->>E:抽奖
activate E
E-->>B:返回中奖结果
deactivate E
B-->>A:返回中奖结果
deactivate B
loop 幂等重试
B->>D:发放操作礼物
end
点歌券业务
graph LR
A(点歌业务)
B(消费服务)
C(点歌券服务)
A-->|扣减|B
A-->|扣减|C
sequenceDiagram
participant A as Coordinator
participant B as participants A
participant C as participants B
A->>B:voting phase
B-->>A:OK
A->>C:voting phase
C-->>A:OK
A->>B:commit phase
B-->>A:commited
A->>C:commit phase
C-->>A:commited
sequenceDiagram
participant D as 用户
participant A as 点歌业务
participant B as 消费服务
participant C as 点歌券
D->>A:点歌请求
activate A
A->>A:业务下单
A->>B:冻结星币
activate B
B-->>A:OK
deactivate B
A->>C:冻结点歌券
activate C
C-->>A:OK
deactivate C
A->>A:扣费成功,更新订单状态
deactivate A
A-->>D:返回点歌成功
loop 幂等重试
A->>B:调用星币结算接口
activate B
B-->>A:返回成功
deactivate B
end
loop 幂等重试
A->>C:点歌券使用确认(confirm)
activate C
C-->>A:返回成功
deactivate C
end
graph LR
subgraph 业务
E(游戏类业务)
F(活动类业务)
G(送礼)
F(开通类)
E-.-F
F---G
end
H(订单服务)
I(送礼后分成)
J(送礼后资产发放)
K(充值后资产发放)
A((星币星豆))
B((仓库服务))
C((虚拟资产))
D((券服务))
两段提交
分布式事务
- 点歌券/塔防
- fescar
sequenceDiagram
participant D as TC
participant A as TM
participant B as RM 1
participant C as RM 2
A->>D:开启事务
D-->>A:xid
opt 第一阶段提交
A->>B:begin
activate B
B->>D:开启子事务
D-->>B:branch id
B->>D:report branch status
B-->>A:OK
deactivate B
end
opt 第一阶段提交
A->>C:begin
activate C
C->>D:开启子事务
D-->>C:branch id
C->>D:report branch status
C-->>A:OK
deactivate C
end
opt 第二阶段提交
A->>B:commit
A->>C:commit
A->>D:commit
end
(paxos、raft等)多数派协议
-
双写会带来数据的不一致(重点讲下之前的那次故障)
- 脑裂(split-brain问题)
- mha架构如何解决脑裂问题