一种提高微服务架构的稳定性与数据一致性的方法(3)
- UID
- 1066743
|
一种提高微服务架构的稳定性与数据一致性的方法(3)
Write-Ahead-Queue 的 Offset 管理前面的事务方案的假设是整个处理过程,对于一个 Kafka 的Partition 是独占的。这也就意味着有多少个 RPC 的并发处理线程(或者协程)就需要有多少个对应的 Partition 来跟踪对应线程的处理状态。这样就会变得很不经济,需要开大量的 Kafka Partition。但是如果让多个 RPC 线程共享一个 Kafka Partition,那么由谁来移动 Offset 来标记事务的执行成功呢?这里就需要引入一个 Offset 管理者,来去协调多个 RPC 线程的 Offset 的移动。
- RPC 线程1,写入了 WAL1 (Write-Ahead-Log),其 Offset 为 1
- RPC 线程2,写入了 WAL2,其 Offset 为 2
- RPC 线程3,写入了 WAL3,其 Offset 为 3
- RPC 线程3执行完毕,欲把WAL3标记为执行成功,移动Offset到3。但是因为前面1和2,还没有执行成功,这个时候Offset不能被移动。
- RPC 线程1执行完毕,欲把WAL1标记为执行成功,移动Offset到1。因为前面没有尚未执行完成的WAL,所以这个时候Offset被移动到1成功。
- RPC 线程2执行完毕,欲把WAL2标记为执行成功,移动Offset到2。因为后面的3已经被执行完了,所以Offset被直接更新为3。
这个处理逻辑和 TCP 的窗口移动逻辑是非常类似的。用这种方式,大概就是一个RPC的进程,对应一个kafka的partition去跟踪它的处理流程。相当于给 RPC 框架,加了一个 WAL 的保护,用于保证 RPC 流量会被完整地跑完。
其他方案实现跨数据库和消息队列的事务一致性,还有两种做法:
- 去哪儿网,利用数据库作为队列,然后用数据库的多表事务来保障一致性:
- 淘宝 Notify,利用两阶段提交的消息 broker 来实现:
两种实现都需要用 mysql 来作为消息中间件,引入了比较高的运维成本。
总结前面给了三个独立的技术方案
- 使用同步转异步的方案,提高同步 RPC 的可用性,同时提高数据一致性。
- 引入本地队列作为兜底,提高消息队列的总体可用性,以及降低延迟。
- 通过引入两级队列,让 Write-Ahead-Queue 来保证 Business-Event-Queue 一定会在数据库事务成功之后被写入。
我们只需要把这三个独立的方案结合到一起,就可以把队列技术应用到纯 RPC 同步组合的微服务集群里,用于提高可用性和数据的一致性。同时可以保证这份消息数据是可靠的,从而给其他的业务逻辑把自己放在队列后面,建立了前提条件。 |
|
|
|
|
|