<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg> <p>lab2应该是824的四个lab中最简单的一集,提前看了下后面两个,包括lab1的MapReduce,只有lab2的两个task全都是easy。</p>
讯享网
实现一个简单的KV Server键/值服务器,主要包含以下三个操作:
- Get (key)
- 根据给定的key,去查询key对应的value并返回给客户端。
- 如果不存在key,则返回空字符串。
- Put (key, value)
- 如不存在,则创建key,并将对应的值设置为value。
(注:实验手册并没有指明Put操作返回新值还是旧值,根据lab提供的测试来看,对Put操作的返回值也 没有要求,这里和Append操作保持一致) - Append (key, arg)
- 如已经存在key,将key对应的值后面加上arg,返回旧值。
- 如果不存在,创建key,并将对应的值设置为value。(即:假装已经有这个key了,这个key对应的value是长度为0的空串。)
如果有网络不稳定等情况导致有消息丢失,要保证每次请求要返回正确的结果。我们需要做的操作有如下三个:
重复请求
如果一次请求并没有收到服务端的确认消息,我们认为这次请求出现了消息丢失的情况,要重新发送请求,直到收到了服务端的确认消息。
缓存结果
出现请求丢失的情况,重复请求后得到的结果应当和第一次请求应当得到的结果保持一致,这就需要定义一个数据结构来缓存每次请求的结果。
释放内存
对于前一个步骤中的缓存结果,要定期释放,不能占用太多内存。
示例
下面这张图的流程就说明了一种可能出现问题的情况
- client1向server发送Get请求,假设键为k1,对应的值为v1。
- server接收到请求并回复,但回复丢失。
- 在client1重新发送请求前,client2发送Put请求,键为k1,对应的值为v2。
- server接收到请求并更新k1对应的值为v2,回复client2。
- 此时server接受到了client1发送的重复请求,此时k1对应的值已被修改成v2,但正确的回复应该是v1。
在Server中维护一个map即可,Get、Put、Append操作都比较直观,不细说了。

以Get为例,
讯享网
没有ok一直循环就好
对每次消息使用nrand()方法生成一个id,服务端每次收到请求,将返回的结果和对应请求的id缓存。
采用的方法是每次请求后增加一个确认请求。即增加一个bool参数Confirm,如果Confirm为false则按正常流程走;如果为true代表这是一个确认请求,server收到确认请求后删除对应请求id的缓存。
讯享网
讯享网
释放内存这一步,看实验手册里面这样写:

以为是对于每个client,第二次请求时释放第一次请求的缓存,这样对于每个client,server同时最多只保留一个请求的缓存。然而这样还是过不了测试用例,看了测试用例的源码发现好像server里一点缓存都不能有的感觉。于是按照2.4里面所说的方法增加了一个confirm请求。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/202671.html