加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

带着问题学习分布式系统之数据分片

发布时间:2018-09-03 02:53:45 所属栏目:教程 来源:xybaby
导读:正文 在前文中,提出了分布式系统(尤其是分布式存储系统)需要解决的两个最主要的问题,即数据分片和数据冗余,下面这个图片(来源)形象生动的解释了其概念和区别: 其中数据即A、B属于数据分片,原始数据被拆分成两个正交子集分布在两个节点上。而数据集C属

MongoDB中,元数据服务器被称为config server。在MongoDB3.2中,已经不再建议使用三个镜像(Mirrored)MongoDB实例作为config server,而是推荐使用复制集(replica set)作为config server,此举的目的是增强config server的一致性,而且config sever中mongod的数目也能从3个达到replica set的上线(50个节点),从而提高了可靠性。

在MongoDB3.0及之前的版本中,元数据的读写按照下面的方式进行:

  • When writing to the three config servers, a coordinator dispatches the same write commands to the three config servers and collects the results. Differing results indicate an inconsistent writes to the config servers and may require manual intervention.

MongoDB的官方文档并没有详细解释这一过程,不过在stackexchange上,有人指出这个过程是两阶段提交。

MongoDB3.2及之后的版本,使用了replica set config server,在《CAP理论与MongoDB一致性、可用性的一些思考》文章中,详细介绍了replica set的write concern、read concern和read references,这三个选项会影响到复制集的一致性、可靠性与读取性能。在config server中,使用了WriteConcern:Majority;ReadConcern:Majority;ReadReferences:nearest。

元数据的缓存:

即使元数据服务器可以由一组物理机器组成,也保证了副本集之间的一致性问题。但是如果每次对数据的请求都经过元数据服务器的话,元数据服务器的压力也是非常大的。很多应用场景,元数据的变化并不是很频繁,因此可以在访问节点上做缓存,这样应用可以直接利用缓存数据进行数据读写,减轻元数据服务器压力。

在这个环境下,缓存的元数据必须与元数据服务器上的元数据一致,缓存的元数据必须是准确的,未过时的。相反的例子是DNS之类的缓存,即使使用了过期的DNS缓存也不会有太大的问题。

怎么达到缓存的强一致性呢?比较容易想到的办法是当metadata变化的时候立即通知所有的缓存服务器(mongos),但问题是通信有延时,不可靠。

解决不一致的问题,一个比较常见的思路是版本号,比如网络通信,通信协议可能会发生变化,通信双方为了达成一致,那么可以使用版本号。在缓存一致性的问题上,也可以使用版本号,基本思路是请求的时候带上缓存的版本号,路由到具体节点之后比较实际数据的版本号,如果版本号不一致,那么表示缓存信息过旧,此时需要从元数据服务器重新拉取元数据并缓存。在MongoDB中,mongos缓存上就是使用的这种办法。

另外一种解决办法,就是大名鼎鼎的lease机制 -- “An Efficient Fault-Tolerant Mechanism for Distributed File Cache Consistency”,lease机制在分布式系统中使用非常广泛,不仅仅用于分布式缓存,在很多需要达成某种约定的地方都大显身手,在《分布式系统原理介绍》中,对lease机制有较为详细的描述,下面对lease机制进行简单介绍。

Lease机制:

既然,Lease机制提出的时候是为了解决分布式存储系统中缓存一致性的问题,那么首先来看看Lease机制是怎么保证缓存的强一致性的。注意,为了方便后文描述,在本小节中,我们称元数据服务器为服务器,缓存服务器为客户端。

要点:

  • 服务器向所有客户端发送缓存数据的同时,颁发一个lease,lease包含一个有限期(即过期时间)
  • lease的含义是:在这个有效期内,服务器保证元数据不会发生变化
  • 因此客户端在这个有效期内可以放心大胆的使用缓存的元数据,如果超过了有效期,就不能使用数据了,就得去服务器请求。
  • 如果外部请求修改服务器上的元数据(元数据的修改一定在服务器上进行),那么服务器会阻塞修改请求,直到所有已颁发的lease过期,然后修改元数据,并将新的元数据和新的lease发送到客户端
  • 如果元数据没有发生变化,那么服务器也需要在之前已颁发的lease到期之间,重新给客户端颁发新的lease(只有lease,没有数据)

在Lease论文的标题中,提到了“Fault-Tolerant”,那么lease是怎么做到容错的呢。关键在于,只要服务器一旦发出数据和lease,不关心客户端是否收到数据,只要等待lease过期,就可以修改元数据;另外,lease的有效期通过过期时间(一个时间戳)来标识,因此即使从服务器到客户端的消息延时到达、或者重复发送都是没有关系的。

不难发现,容错的前提是服务器与客户端的时间要一致。如果服务器的时间比客户端的时间慢,那么客户端收到lease之后很快就过期了,lease机制就发挥不了作用;如果服务器的时间比客户端的时间快,那么就比较危险,因为客户端会在服务器已经开始更新元数据的时候继续使用缓存,工程中,通常将服务器的过期时间设置得比客户端的略大,来解决这个问题。为了保持时间的一致,最好的办法是使用NTP(Network Time Protocol)来保证时钟同步。

Lease机制的本质是颁发者授予的在某一有效期内的承诺,承诺的范围是非常广泛的:比如上面提到的cache;比如做权限控制,例如当需要做并发控制时,同一时刻只给某一个节点颁发lease,只有持有lease的节点才可以修改数据;比如身份验证,例如在primary-secondary架构中,给节点颁发lease,只有持有lease的节点才具有primary身份;比如节点的状态监测,例如在primary-secondary架构中监测primary是否正常,这个后文再详细介绍。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读