Welcome to Snooda's Blog
    最近遇到一个bug,定位了非常久,感觉有必要分享出来。。。避免后人掉坑。

    前段时间发现了一个raft主从间内存不一致的场景,导致切主后数据异常。。当时费了很大的力气排除掉其他模块逻辑问题。后来问题缩小到raft state machine里。由于raft高度依赖state machine幂等性(重启、切主都会导致状态机重做,如果逻辑不是严格幂等,就会出现状态不一致问题),一般要求日志中必须记录绝对操作,尽量不记相对操作。但有一个round-robin分配资源的场景,还是依赖了一下资源节点的排序问题。

    最早是使用std::map来存,使用迭代器遍历。由于map本身是有序的,所以三副本之间是一致的。
    后来有不熟悉的同学为了优化map的lg(n)性能,改用了基于哈希的unorderedmap,那么问题就来了。逻辑上map和unorderedmap都支持迭代器遍历。所以只修改数据类型,不修改逻辑是可以兼容的。简单执行也没有问题。

    已知unorderedmap肯定不能保证遍历结果的有序,但是目前场景也并不要求结果有序,只要每次遍历结果顺序不变就行,那么unorderedmap能否保证遍历顺序幂等性?目前看答案是“不能”。

    简单来想,hash表就是对元素做哈希,然后选定桶,对于桶内的元素就串到list上。那么只要按同样的顺序插入,似乎也是可以保序的。因为unorderedmap内部存在自动rehash过程。。一旦rehash,节点的遍历顺序就会变化。。。

    所以一定要重视“unordered”关键字。。。任何情况下unorderedmap都不保证任何顺序。。。。
Tags: ,
分页: 1/1 第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]