neverchanje / notes

1 stars 0 forks source link

pegaus 的写流程 #18

Open neverchanje opened 5 years ago

neverchanje commented 5 years ago

Pegasus 的写流程

每个 replica 收到 client 发来的写请求后都会进行 2PC(two phace commit) 写日志的过程。正常情况下,在日志提交后,数据会写入到 rocksdb,写入成功后 response 会返回给 client。为了简单,我们这里笼统的把 "multi_put","put","incr","check_and_mutate" 都称为 “写请求”。下面我们详细介绍具体流程。

第一步:2PC 的 Prepare Phase

整个写流程的的起点在 replica::on_client_write

3 副本 2 副本 1 副本 0 副本
full healthy unhealthy write unhealthy read unhealthy
可读/可写 可读/不可写 DDD 状态

如果一切正常,primary 将会把日志分发到 secondaries 上,同时将日志落盘。

第二步:2PC 的 Commit Phase

如果日志成功提交,那么它将写入 rocksdb,这个操作从 replica::execute_mutation 开始。 rDSN 作为一个分布式框架,它抽象了底层存储引擎的接口:replication_app_ base,抽象接口的好处在于可以做 mock test。当然对 Pegasus 来说,这个底层存储就是 RocksDB。

线程模型

在我们目前的实现下,PacificA 状态机以单线程运行,这是为了让状态转移的过程无需加锁,减少工程实现上的心智负担。可以这样理解:一个 pegasus server 持有多个 replica,每个 replica 会绑定一个线程,专门负责在进行状态机转移时执行相关逻辑。对每个 replica 而言,无论它进行 2PC,learn,还是任何涉及状态读写的操作,都会在单线程运行。

由于日志写使用 libaio,的线程池

PacificA 状态机

鉴于篇幅,关于 PacificA 的具体内容我们不做过多赘述。但