精华帖 (16) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-12-04
引用 双写其实很容易,直接在客户端或者通过写请求往中央节点发送,中央节点负责双写 双写理论上不太会带来太大性能负担,因为可以不阻塞执行,但是client得到的响应会稍微慢些,是两节点里面最长的写入时间。一个后果是无法避免的,就是server端维护client的结构消耗的内存相对之前会高不少,消耗数目会和client写的平均时间成正比,如果是简单多线处理,堆积的线程数也会和client写的平均时间至少成正比 双写最大的问题还是解决一个当机了怎么办的问题,在我们系统我们为下级的网元做同步主备集群,方式就是双写失败采取将失败节点操作在正常节点上序列化,一旦失败节点恢复,则序列化的没同步的操作会在该节点全部执行。 其实可以看到这就是双写+主备的变种方案,这种方案实现不难,相对效果也还行但实际上也有局限性: 1.备用节点恢复后,追上主节点可能要花很长时间,这段时间如果发生二次故障比如主节点失败则备用节点此时到底是切换成主节点还是停止服务。 2.如果数据不断往系统灌,主节点还原成双写状态需要在某个接近完全同步的时间点阻塞client的请求处理等备节点,可能瞬间造成大量请求堆积 双写本身比较简单。但是要注意的是如果要绝对保证数据一致性,采取双写策略最安全的方式只有双写不成功立即停止业务,解除故障后才能继续,即单点故障会导致服务中断,这可以保证主备节点数据的绝对可靠性,但代价就是有服务中断的时间窗口,这实际是牺牲了可用性换取了数据的可靠性和容灾,它是将可靠的可恢复放在第一位,而不是快速可恢复。 数据主备同步也是一样的,不过如果依赖数据库主备同步并阻塞client的write返回来保证数据一致性,则明显问题也还有两个: 1.性能,客户端的响应速度比双写会慢很多,这导致响应时间从max(n1,n2)变成了n1+n2 2.备当机了,则服务同样中断,还是失去了可用性 如果同时要保证服务高可用、高性能和数据可靠,可能1对主控节点+3存储节点处理灾难会容易些,空想中的一个结构: client--主控-----a | | c |__b 主控对a,b双写,c与a或b组成主备的异步同步,一旦a当机则b阻塞请求处理,等待c完全同步后b、c重新构成双写,b当机情况类似,c当机则a,b同时保存当机时间窗口的本地log历史操作,使得c节点恢复后能追上a,b,主控则可以采取双击同步主备维护a,b,c状态 即使有更经济的方案,但低成本(低节点数)、高可用(多点复制快速切换)、高可靠(一致性)难以兼得这是一定的 没有人为干预能够保一次性单点故障的方案不难,但是要设计无过多人为干预的能自动处理连续单点故障的系统就比较头疼 最简单的系统就是无阻塞的主备异步log同步,但是结果就是结合auto fail over来提供高可用则必然导致的数据丢失,区区几秒的异步数据丢失在满载的高性能系统中损失的可能至少是好几w的记录 谢谢 ppgunjack 的回复。 的确,对于数据存储,想要获得高可靠性,需要牺牲一定的性能甚至可用。 或许已经可以结合这样的讨论来理解CAP理论了? |
|
返回顶楼 | |