MIT6.824 Lab 3: Fault-tolerant Key/Value Service (1)

本文详细介绍了如何使用Raft库实现容错key-value服务的Part A,包括Put(), Append()和Get()的RPC调用处理,以及客户端与服务器之间的交互。实验中,服务端通过Raft共识处理操作,客户端通过并发RPC调用来测试系统的正确性。关键在于服务端的execOp函数,它根据操作类型提交到Raft并处理结果。" 106721827,8078799,理解BFS与DFS遍历方法,"['算法', '数据结构', '二叉树']
摘要由CSDN通过智能技术生成

Introduction
  在这次实验中,我们将使用Lab2的Raft库来实现容错的key-value存储服务。
  存储系统将由客户端和key/value服务器,每个key/value服务器使用Raft节点。客户端发送Put(), Append()和Get()的RPCs 到key/value服务器(kvraft),然后将这些RPC调用存入Raft的log中并按序执行。客户端可以向任何kvraft服务器发送RPC请求,但是如果该服务器不是Raft领导者或者请求失败超时,则需要重新发送给另外一个。假如操作被committed到Raft的log中并应用到状态机中,那么它的结果需要反馈到客户端。假如commit操作失败(比如领导者被替换),客户端必须重新发送请求。
  本次实验分为2部分。在Part A,我们要实现key/value服务,无需考虑日志长度。在Part B,我们需要考虑日志长度,实现Snapshot。

Part A: Key/value service without log compaction
  该服务支持3种RPC调用:Put(key, value),Append(key, arg)和Get(key)。Put()函数替换key对应的value,Append(key, arg)函数将arg增加到key对应的value,Get()函数获取key对应的value。Append值到不存在的key,就理解为Put函数。

具体实现
  与前面博客一样,我们先从测试代码出发,一步步实现具体函数。
  首先是TestBasic测试函数,该测试函数检查在无Fault情况下单客户端操作的正确性。其中涉及到了1个重要的测试函数GenericTest。

func GenericTest(t *testing.T, tag string, nclients int, unreliable bool, crash bool, partitions bool, maxraftstate int) {
    const nservers = 5
    cfg := make_config(t, tag, nservers, unreliable, maxraftstate)
    defer cfg.cleanup()

    ck := cfg.makeClient(cfg.All())

    done_partitioner := int32(0)
    done_clients := int32(0)
    ch_partitioner := make(chan bool)
    clnts := make([]chan int, nclients)
    for i := 0; i < nclients; i++ {
        clnts[i] = make(chan int)
    }
    for i := 0; i < 3; i++ {
        // log.Printf("Iteration %v\n", i)
        atomic.StoreInt32(&done_clients, 0)
        atomic.StoreInt32(&done_partitioner, 0)
        go spawn_clients_and_wait(t, cfg, nclients, func(cli int, myck *Clerk, t *testing.T) {
            j := 0
            defer func() {
                clnts[cli] <- j
            }()
            last := ""
            key := strconv.Itoa(cli)
            myck.Put(key, last)
            for atomic.LoadInt32(&done_clients) == 0 {
                if (rand.Int() % 1000) < 500 {
                    nv := "x " + strconv.Itoa(cli) + " " + strconv.Itoa(j) + " y"
                    // log.Printf("%d: client new append %v\n", cli, nv)
                    myck.Append(key, nv)
                    last = NextValue(last, nv)
                    j++
                } else {
                    // log.Printf("%d: client new get %v\n", cli, key)
                    v := myck.Get(key)
                    if v != last {
                        log.Fatalf("get wrong value, key %v, wanted:\n%v\n, got\n%v\n", key, last, v)
                    }
                }
            }
        })

        if partitions {
            // Allow the clients to perform some operations without interrup
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值