Page 240 - 《软件学报》2021年第10期
P. 240
3212 Journal of Software 软件学报 Vol.32, No.10, October 2021
2. while p p_ack do
3. i pick a batch of waiting ack from { }
p p p ack
i
4.
p _ ack p _ ack p
i
5. for each u in do
p p
u
u
6. add ack into /*receive an ack for u’s ack set */
p p
Input: Set of pth partition reply r p ;
1. Procedure ReplyProcess(r p )
2. while r p p_r do
3. p pick a batch of waiting reply from r p p_r
4. p_r p p_r
5. for each u’s reply obj u p in in do
p
u
u
6. fetch u’s ack set by
p
p
7. if | u p |≥ N / 2 1 do
8. send reply to client
LogStore 由如下 4 个子服务组成:tcpServer、replicationServer、replyServer、stateMachServer.tcpServer 负
责接收客户端请求并对其进行参数检查:如果请求合法,且该请求是修改操作,则将其放入对应分片的任务集合
M p 以及对应的复制集 R p (RequestDispatch,#3-#4).stateMachServer 从队列获取一批任务进行处理(ProcessTask,
#4),然后利用 applicator 改变系统的状态(ProcessTask,#7).当任务成功地在多数派备机上执行时,则主机会将该
状态持久化.为了追踪该任务可否回复给客户端,stateMachServer 针对每一个修改操作 u 都维护一个对象
u , 收集来自其他节点的 ack.接着,将该对象加入第 p 个分片的等待回复集合 r p .函数 ProcessTask 的最后一个步
p
骤是将操作 u 的本地 ack 加入到第 p 个分片复制通道.在 LogStore 中,复制任务(ReplicateSendStage)与收集回复
(ReplicateRecvAndAckStage)这两个函数运行在不同的通道,互不干扰.ReplicationServer 从复制任务队列获取一
u
批任务 R p ,发送给不同的备机(ReplicateSendStage,#3-#4).然后将每一个修改操作 u 的 ack 集合 加入对应分片
p
i
u
.
ack 集合 同时,ReplicationRecvAndAckStage 收集来自备机的回复,并将其加入对应操作 u 的 ack 集合
p
p
(ReplicationRecvAndAckStage,#6).replyServer 不停地检查函数 processTask 产生的回复对象(replyProcess,#5),如
果对应的 ack 集合的基数满足大于多数派要求,那么该操作可以成功回复客户端(replyProcess,#7-#8).
3 实 验
3.1 实验配置
实验在阿里云集群上进行,配置如下:3 台机器,每台机器有 16 个核心处理器,32GB 物理内存,600GB SSD 容
量,默认通过千兆以太网连接.但是由于阿里云允许的带宽,我们只能使用 1/3 网络带宽.从 github 下载的
LogBase(由 NUS 数据库团队开发)的源代码无法正常运行,我们修复了这些错误.问题如下.
1) LogBase 与 HDFS 以及客户端不匹配.在 NUS 发布的版本中,LogBase 使用 HDFS(v 0.20.2),这个配置
与客户端不兼容.尝试后,我们用版本 0.20.205 替换客户端和 HDFS;
2) CreateFileNum 函数的错误实现,代码片段 Int ret=(int) System.currentTimeMillis()/100 会导致溢出并
出现逻辑错误;
3) 每个操作都要咨询 meta,导致性能问题.我们将缓存添加到客户端以绕过此问题;
4) GET(byte [] key)API 将遍历大于 key 的所有键值,不符合语义;
5) LogBase 将其日志写入 HDFS,并再次写入 HLog(WAL for HBase),即写入两次日志.我们修复了这个问