sofa-registry icon indicating copy to clipboard operation
sofa-registry copied to clipboard

ServiceStateMachine在snapshot的过程中没有加锁,是否安全

Open tsgmq opened this issue 4 years ago • 2 comments

Your question

例如:DataConfirmStatusService.copy方法中,是对集合生成了新对象,但是value是引用类型,在snapshot的过程中如果还有LogEntry对引用类型做修改了,是不是会导致snapshot中包含了未来的信息。 假如 logIndex=1000的时候DataNode的值Map<String/ipAddress/, DataNode>只有一个元素,但是snapshot的过程中又来了logIndex-1001的日志,应用到状态机中时将Map中添加了元素,导致最终snapshot的logIndex=1000,可是map内容却又2个元素了,这样在系统重启的时候,先从snapshot中恢复出来的logIndex=1000的包含了2条记录,然后应用1001的LogEntry后,第二条日志会被重复执行,请指点下是不是会存在这个问题

return new DataConfirmStatusService(new ConcurrentHashMap<>(expectNodes), new LinkedBlockingQueue<>(expectNodesOrders));

describe your question clearly

Your scenes

describe your use scenes (why need this feature)

Your advice

describe the advice or solution you'd like

Environment

  • SOFARegistry version:
  • JVM version (e.g. java -version):
  • OS version (e.g. uname -a):
  • Maven version:
  • IDE version:

tsgmq avatar Jul 17 '21 13:07 tsgmq

看了下源码,snapshot也是往taskQueue的ringBuffer中提交了Task,由于状态机中的Task是顺序onApply的,这样的话如果是单线程执行,就不会出现snapshot的过程中有其他logEntry处理,就不会改变状态机中的其他对象的值了吧
@Override public boolean onSnapshotSave(final SaveSnapshotClosure done) { return enqueueTask((task, sequence) -> { task.type = TaskType.SNAPSHOT_SAVE; task.done = done; }); }

tsgmq avatar Jul 17 '21 15:07 tsgmq

这个是由raft框架保证了顺序性 最新的6.x版本,我们去除了raft依赖,因为raft的强一致特性,对于可用性其实是不很友好的,另外raft这种强一致的算法,也无法强管控介入去运维,例如我们想人工指定meta leader,其实是在raft下很难做到的。 @tsgmq

NickNYU avatar Jul 21 '21 06:07 NickNYU