最近遇到一个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: ,
        生产环境线上一般是不允许开启conntrack的,因为默认的连接跟踪表也就万级别,不小心打满后,容易导致很难排查的网络问题。(iptables -t nat只查看也会不知不觉启用conntrack)所以很多团队是规定禁止线上运行iptables的。        但是某些设备上,conntrack是必备的一项功能,比如网关,用来做防火墙、包转发等。        今天就遇到了一个很特殊的场景。。表现特征是iptables配的MASQUERADE看起来并不生效。有时不知怎么回事生效以后,删掉规则居然仍然能转发。。明明删除了规则,居然还能ping通,新增了规则,居然还转发到老的地方。。

后来研究了一下,发现原来对于iptables的nat表来讲,只有连接新建时,才会查表进行一次匹配。当连接被conntrack后,就不再走nat表匹配了。
对于icmp来讲,默认conntrack会保留30s,所以如果添加规则前30s如果ping了一下。那么添加完并不会生效已有的。。。。反之亦然。
可以使用conntrack -E作为验证手段。该命令会打印conntrack模块对连接的跟踪情况。

如果想手动移除映射关系,可以使用conntrack -D
分页: 1/1 第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]