Bada系列- 副本策略


Bada系列 - 副本策略

Bada 是360开发的一套Nosql系统, 具备多机房架构, 低延迟, 结构化等特点.

今天我们聊聊Bada的多副本策略

我们知道常见的分布式系统的多副本策略主要分成两类

  1. 以cassandra, dynamo 为主的, 没有主从结构的设计, 读写的时候满足W + R > N, 因此写入的时候写入2个副本成功才能返回. 读的时候需要读副本然后返回最新的. 这里的最新可以是时间戳或者逻辑时间

  2. 以MongoDB, Bada为主的, 有主从结构的设计, 那么读写的时候, 客户端访问的都是主副本, 通过binlog/oplog 来将数据同步给从副本

两种设计都只能满足最终一致性. 那么我们再从CAP理论上看, 那么都是在哪些维度做了权衡

  • 从性能上来看

    有主从的设计很明显性能会由于无主从的, 因为有主从的设计只需要访问一个副本就可以返回, 而无主从的至少两个副本返回才可以.

  • 从一致性来看

    有主从的设计如果挂掉一个节点, 如果这个节点是主, 那么就会造成由于数据同步的不及时, 这段时间写入的数据丢失. 如果挂掉的是从节点, 那么则对数据没有任何的影响. 只要这个节点在接下来的时间内能够起来即可.

    无主从的设计如果挂掉一个节点, 理论上对结果是无影响的, 因为返回的时候会比较最新的结果.

    有主从的结构由于写入都在一个节点, 因此不存在冲突. 而无主从的结构由于写入的是任意的两个副本, 会存在对同一个key的修改在不同的副本, 导致客户端读取的时候是两个不一致的版本, 这个时候就需要去解决冲突, 常见的方案就涉及到vector clock, 时间戳等等.

    不过, 总体来看无主从的设计一致性应该优于有主从的设计.

  • 从分区容错来看

    两边都必须有一半以上的节点存活才能够对外提供服务, 因为有主从的设计中必须获得超过一半节点的投票才能成为主节点. 而无主从的结构, 常见在W = 2, R = 2的情况下, 必须2个副本以上才能对外提供服务

  • 从可靠性来看

    有主从的设计因为只访问一个副本, 性能优于无主从的设计. 而且无主从的设计中, 因为对单条数据必须有两次读取, 因此对系统的访问压力也会比无主从的来的多.

    当然有主从的设计容易造成主落在同一个机器上, 造成负载不均的情况, 但是这里只要将主平均到所有的机器, 就可以解决这个问题.

    但是有主从的设计在切换主从的时候, 必然有一段时间无法对外提供服务, 而无主从的设计则不存在这样的问题

    总体来说, 笔者认为从可靠性的角度来说, 有主从的设计应该比无主从来的可靠.

那Bada最后采取的是怎样的副本策略呢?

Bada采用的是有主从的设计, 主要考虑如下几个情况

  1. Bada主要的应用场景对性能的要求比较高, 大部分的请求需要在1ms左右的时间返回, 因此有主从的设计, 性能更满足需求
  2. 线上服务的可靠性是我们另外一个考虑的因素

那么数据的一致性如何解决?

有主从的设计最大的问题在于挂掉一个主副本, 就会造成数据的丢失. 因为后续从副本起来后, 之前主副本的未同步的数据就丢失了. MongoDB 就存在这样的问题. Bada在早期版本也是这样.

这里笔者一直觉得设计就是在做折衷, 比如这里就是一个一致性和性能,可靠性的一个折衷. 在牺牲少量可靠性和性能的情况下, 尽可能的提高数据的一致性.

因此后续我们又做了改进, 比如Binlog Merge等来提高数据的一致性, 只要机器挂了以后能够重启, 那么我们就可以将由于同步不及时的数据找回. 后续可以介绍Bada Binlog/Binlog Merge的实现