当数据库遇到分布式,你会怎么做?
本地索引 文档分区所以,在这种索引方法中,每个分区是完全独立的,每个分区维护自己的二级索引,仅覆盖该分区中的文档。当数据写入时(添加、删除、更新),只需要处理分区内数据的索引更新。数据查询时,则需要将查询发送到所有的分区,并合并所有返回的结果。 这种查询分区数据库的方法有时被称为分散/聚集(scatter/gather),并且可能会是二级索引上的读取查询相当昂贵。即使并行查询分区,已容易导致尾部延迟放大。MongoDB、Cassandra、ElasticSearch、SolrCloud都是使用这种文档分区二级索引。 全局索引 关键词分区,这种索引方法跟主键分区的方式是一样的。相对于文档分区索引,读取更有效率,不需要分散/聚集所有分区,客户端只需要向包含关键词的分区发出请求。缺点在于写入速度较慢且较为复杂,因为写入单个文档可能会影响索引的多个分区。 理想情况下,索引总是最新的。写入数据库的每个文档都会立即反映在索引中。在基于关键词的全局索引中,这需要跨分区的分布式事务,并不是所有的数据库都支持。在实践中,对全局二级索引的更新通常是异步的。 分区再平衡 随着数据集大小增加、查询吞吐量的增加,需要更多的机器来处理。这些都需要数据和请求从一个节点移动到另一个节点,这一过程称为再平衡(reblancing)。 再平衡通常要满足以下几点要求: 再平衡之后,负载(数据存储、读取和写入请求)应该在集群中的节点之间公平地共享 再平衡发生时,数据库应该继续接受读取和写入 节点之间只移动必须的数据,以便快速再平衡,并减少网络和磁盘I/O负载 平衡策略可以分为几种:固定数量的分区、动态数量的分区和按节点比例分区 固定数量的分区 创建比节点更多的分区,并为每个节点分配多个分区。如果一个节点被添加到集群中,新节点可以从当前每个节点中窃取一些分区,直到分区再次公平分配。ElasticSearch使用这种方式分区策略。 只有分区在节点间移动,分区的数量不会改变,键所对应的分区也不会改变,唯一改变的是分区所在的节点。这种变更不是实时的(网络上传输数据需要时间),传输过程中,原有分区仍然会接手读写请求。 分区的数量通常在数据库第一次建立时确定,之后不会改变。每个分区包含了总数据量固定比率的数据,因此每个分区的大小与集群中的数据总量成比例增长。如果数据集的总大小难以预估,选择正确的分区数是困难的。分区太大,再平衡和节点故障恢复变得昂贵;分区太小,则会产生太多的开销。 动态数量的分区 对于使用键范围进行分区的数据库,具有固定边界的固定数量的分区将非常不方便:如果出现边界错误,则可能会导致某些分区的没有数据。按键范围进行分区的数据库通常会动态创建分区。 当分区增长到超过配置的大小时,会被拆分成两个分区,每个分区约占一半的数据。动态分区的优点是分区数量适应总数据量,能够平衡各方面的开销。HBase和MongoDB采用的就是这种策略。 数据集开始时很小,直到达到第一个分区的分隔点,所有写入操作都必须由单个节点处理,而其他节点处于空闲状态。为了解决这个问题,HBase和MongoDB允许在一个空的数据库上配置一组初始分区(预分隔,pre-splitting)。在键范围分区的情况下,预分隔需要提前知道键时如何分配的。 按照节点比例分区 分区数与节点数量成正比,即每个节点具有固定数量的分区。每个分区的大小与数据集大小成比例的增长。当增加节点时,随机选择固定数量的现有分区进行拆分,然后占有这些拆分分区中的每个分区的一半。 请求路由 现在我们已经数据集分割到多个节点上运行的多个分片上,客户端发起请求时,如何知道连接哪个结点。随着分区再平衡,分区对节点的分配也发生变化。 不仅限于数据库,这个问题可以概括为服务发现(service discovery),通常有以下三种方案: 允许客户端连接任何节点,如果该节点恰巧拥有请求的分区,则直接处理该请求;否则将请求转发到适当的节点,接收结果并返回给客户端。 客户端发送请求到路由层,它决定了应该处理请求的节点,并相应的转发。 客户端知道分区和节点的分配,直接连接到适当的节点。 以上问题的关键在于:做出路由决策的组件如何了解分区-节点之间的分配关系变化?这是一个具有挑战性的问题,因为需要所有的参与者达成一致。 很多分布式系统都依赖于一个独立的协调服务,比如ZooKeeper来跟踪集群元数据。 每个节点在ZooKeeper上注册自己,ZooKeeper维护分区到节点的可靠映射 路由层可以在ZooKeeper订阅此信息,当分区分配发生变化能实时感知 复制 复制意味着在通过网络连接的多台机器上保留相同数据的副本,复制数据能带来以下的好处: 提高可用性,即使系统的一部分出现故障,系统也能继续工作 扩展可以接受读请求的机器数量,从而提高读取吞吐量 使得数据与用户再地理上接近,从而减少延迟 复制的困难之处在于处理复制数据的变更。目前流行有三种变更复制算法:单领导者(single leader),多领导(multi leader)和无领导者(leaderless),几乎所有的分布式数据库都使用这三种方法之一。 单领导者复制过程: 每一次向数据库的写入操作都需要传播到所有的副本上,否则副本就会包含不一样的数据。最常见的解决方案被称为基于领导者的复制 或 主从复制 副本之一被指定为领导者(或主库),当客户端要向数据库写入时,它必须发给领导者,领导者会将新数据写入其本地存储; 其他副本被称为追随者(只读副本、从库),会同步主库的变更日志,按照主库相同的顺序写入 当客户端从数据库读取数据时,可以向领导者或追随者查询 同步 or 异步 (编辑:应用网_阳江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |