当前位置: 首页 > Linux

radosgwRestful并发读写的一致性实现机制

时间:2023-04-06 05:27:25 Linux

radosgwRestful并发读写的一致性实现机制原子PUT并发写问题:当多个客户端同时写入同一个对象时,如何保证一致性写入一致性后的对象?AtomicGET并发读写问题:当一个客户端读取一个对象时,另一个客户端正在写入同一个对象,如何保证读取对象的一致性(即读取的内容要么在写入之前,要么在写入之后)?根本原因:radosgw在读写一个对象时,需要对rados存储集群进行多次读写操作。考虑到读写并发的问题,最容易想到的就是增加读写锁处理,但是会破坏radosgw的水平扩展能力,增加radosgw的实现难度。(cephfs分布式文件系统在元数据服务器中实现锁定作为POSIX文件锁定支持的一部分。如果在网关中引入锁定机制,则需要在每个对象上维护状态并同步不同网关实例之间的状态。)PUT并发写入问题在写入一个对象时,先将该对象写入一个临时对象,当所有的临时对象都写入完毕后,再原子地把整个临时对象复制到目标对象中(类似于重命名),最后删除临时对象。由于RADOS底层存储是分布式的,为保证原子复制,需要临时对象和目标对象存储在同一个PG上;通常我们根据对象的名称,通过哈希算法计算出具体的后端存储位置;所以我们使用目标对象的名称来计算临时对象的存储位置,以确保它们最终在同一个PG上。具体步骤:将对象写入一个临时对象,但是这个临时对象需要和目标对象在同一个PG上;原子地复制临时对象到目标对象;删除临时对象;atomicGET并发读写问题RADOS底层存储支持原子批操作,类似于数据库事务操作,即一系列下发的操作,要么全部执行成功,要么都不执行。它可以保证在PUT对象时元数据和数据的原子更新。为了保证在开始读取对象后,正在读取的对象不会被改写。每次PUT写入对象时,都会生成一个随机值标记并保存在对象属性中。写对象时,需要检查对象是否已经存在,获取其tag值;如果已经存在,则克隆该对象,新克隆的对象名称为“objectname_tag”(原子操作)。具体的写原子操作过程如下:查看对象标签属性是否为cloneto_同样,客户端在读取一个对象之前,也需要获取其标签值。每个读取操作都需要检查其标记值。如果标签值相同,则正常读取对象;如果tag值不同,说明对象被改写了,需要读取“objectname_tag”的对象。具体读取过程如下:读取objectfootag->123verifyobjectfootag为“123”;readobjectfoo(offset=0,size=512K)->ok,read512Kcheckobjectfootagis“123”;readobjectfoo(offset=512K,size=512K)->notok,objectwasreplacedreadobjectfoo_123(offset=512K,size=512K)->ok,read512K至此并发读写问题解决,但细心的读者会发现一个问题,就是同一个对象可能有多个不同名称的实例,占用空间。因此,我们需要一种机制在合理的时间后清理冗余对象。我们添加了一个日志对象来记录每一个需要删除的对象;一段时间后,清理进程会清理掉这些多余的对象。相关信息官方文档