分布式与一致性协议之Gossip协议

news2024/12/26 11:30:32

Gossip协议

概述

有些人的业务需求具有一定的敏感性,比如监控主机和业务运行的告警系统,大家都希望自己的系统在极端情况下(比如集群中只有一个节点在运行)也能运行。在会以了二阶段提交协议和Raft算法之后,你会发现它们都需要全部节点或者大多数节点正常运行才能稳定运行,并不适合此类场景。而如果采用Base理论,则需要实现最终一致性,那么,怎样才能实现最终一致性呢?
在我看来,可以通过Gossip协议来实现这个目标。
Gossip协议,顾名思义,就像流言蜚语一样,是指利用一种随机、带有传染性的方式将信息传播到整个网络中,并在一定时间内使得系统内的所有节点数据一致。掌握这个协议不仅能帮助我们很好地理解这种最常用的、实现最终一致性的算法,也能让我们在后续工作中得心应手地实现数据的最终一致性。

Gossip的三板斧

Gossip的三板斧分别是直接邮寄(Direct Mail)、反熵(Anti-entropy)和谣言传播(Rumor Mongering)。

直接邮寄

是指直接发送更新数据,当数据发送失败时,将数据缓存下来,然后重传。如图所示,节点A直接将更新数据发送给了节点B、D.
在这里补充一点,直接邮寄虽然实现起来比较容易,数据同步也很及时,但可能会因为缓存队列满了而丢失数据。也就是说,只采用直接邮寄是无法实现最终一致性的。
在这里插入图片描述

反熵

那如何实现最终一致性呢?答案就是反熵。本质上,反熵是一种通过异步修复实现最终一致性的方法。常见的最终一致性系统(比如Cassandra)都实现了反熵功能.反熵是指集群中的节点每隔一段时间就随机选择一个其他节点,然后通过互相交换自己的所有数据来消除两者之间的差异,实现数据的最终一致性。如图所示,从图中可以看到,节点A通过反熵的方式修复了节点D中缺失的数据。那具体如何实现呢?
反熵的实现方式主要有推、拉和推拉3种,将以上面图中两个数据副本的不一致问题为例来详细分析。

也许有人会觉得反熵是一个很奇怪的明此。其实,你可以这么来理解,反熵中的熵是指混乱程度,而反熵是指消除不同节点中数据的差异,以提升节点间数据的相似度,降低熵值。
另外需要注意的是,因为反熵需要节点两两交换和比对自己所有的数据,通信成本会很高,所以不建议在实际场景中频繁执行反熵操作,可以通过引入校验和(Checksum)等机制降低需要比对的数据量和通信消息等。
虽然反熵很实用,但是执行反熵操作时,相关的节点都是已知的,而且节点数不能太多。如果是一个动态变化或节点数比较多的分布式环境(比如在DevOps环境中检测节点故障并动态维护集群节点状态),这时反熵就不适用了。此时,我们应该怎样实现最终一致性呢?答案就是谣言传播。在这里插入图片描述
在这里插入图片描述

  • 推方式是指将自己的所有副本数据推给对方,以修复对方的数据副本中的熵,如图所示
    在这里插入图片描述
  • 拉方式是指拉取对方的所有副本数据,以修复自己的数据副本中的熵,如图所示在这里插入图片描述
  • 理解了推方式和拉方式之后,推拉方式就很好理解了,它是指同时修复自己和对方的数据副本中的熵。如图所示在这里插入图片描述

谣言传播

即广泛地散播谣言,是指当一个节点有了新数据后,这个节点就会变成活跃状态,并周期性地联系其他节点向其发送新数据,直到所有的节点都存储了该新数据。如图所示。节点A向节点B、D发送新数据,节点B收到新数据后变成活跃节点,然后节点B向节点C、D发送新数据。其实,谣言传播非常具有传染性,它适合动态变化的分布式系统。在这里插入图片描述

如何使用反熵实现最终一致性

在这里插入图片描述

在分布式存储系统中,实现数据副本最终一致性的最常用的方法是反熵。为了帮助我们沉底理解和掌握在实际环境中实现反熵的方法,以InfluxDB的反熵实现为例具体分析一下。
在InfluxDB中,一份数据副本是由多个分片组成的,也就是实现了数据分片。3节点3副本的InfluxDB集群如图所示。
反熵的目标是确保每个DATA节点拥有元信息指定的分片,而且在不同节点上,同一分片组中的分片都没有差异。比如,节点A要拥有分片Shard1和Shard2,而且节点A的Shard1和Shard2与节点B、C中的Shard1和Shard2是一样的。那么,DATA节点熵存在哪些数据缺失的情况呢?换句话说,我们需要解决哪些问题呢?

我们将数据缺失分为这样两种情况。
1.缺失分片:某个节点上的整个分片都丢失了
2.节点之间的分片不一致:节点上的分片都存在,但里面的数据不一样,有数据丢失的情况发生。
第一种情况修复起来很简单,我们只需要通过RPC通信将分片数据从其他节点上复制过来就可以了,如图所示
第二种情况修复起来要复杂一些,我们需要设计一个闭环流程,按照一定的顺序来修复,这样执行完整个流程后也就实现了一致性。具体要怎样设计呢?
它是按照一定顺序来修复节点的数据差异,先随机选择一个节点,该节点生成自己节点有而下一个节点没有的差异数据,并发送给下一个节点,修复下一个节点的数据缺失,然后按照顺序,各节点循环修复,如图所示,从图中可以看到,数据修复的起始节点为节点A,数据修复是按照顺时针顺序循环进行。需要注意的是,最后节点A又对节点B的数据执行了一次数据修复,因为只有这样,节点C、节点B缺失的差异数据才会同步到节点B上。

看到这里,在实现反熵时,实现细节和最初算法的约定有些不同。比如,不是一个节点不断随机选择另一个节点来修复副本上的熵,而是设计了一个闭环的流程,一次修复所有的副本数据不一致问题。
为什么这样设计呢?因为我们希望能在一个确定的时间范围内实现数据副本的最终一致性,而不是基于随机性的概率,在一个不确定的时间范围内实现数据副本的最终一致性。这样做能减少数据不一致对监控试图影响的时长。但是,需要注意的是,技术是要活学活用的,我们要能根据场景特点权衡妥协,设计出最适合这个场景的系统功能。最后需要注意的是,因为反熵需要做一致性对比,很消耗系统资源,所以建议将是否启用反熵功能、执行一致性检测的时间间隔等做成可配置的,以方便在不同场景中按需使用
在这里插入图片描述
在这里插入图片描述

思维拓展

既然使用反熵实现最终一致性时需要通过一致性检测发现数据副本的差异,如果每次做一致性检测时都要做数据对比,必然会消耗一部分资源,那么,有什么办法可以降低一致性检测时的性能损失呢?
答案是:我们期望最好的做法是花费更少的时间、花费更少的通信资源,如果我们将每个节点上的数据都进行传输,必然会消耗很多网络资源,反过来,如果我们将每条数据都进行传输,也会很消耗时间,所以使用对数据进行Hash计算,将得到的hash值进行比对,这样就无须再逐个进行比对,我们只要保证,同一数据源可以得到同一个Hash值,而且一个hash值所占用的网络资源也是相当少的

重点总结

  • 1.Gossip协议作为一种异步修复、实现最终一致性的协议,反熵再存储组件中应用广泛,比如Dynamo、InfluxDB、Cassandra,在需要实现最终一致性的实际工作场景中,优先考虑反熵
  • 2.因为谣言传播具有传染性,如一个节点传给了另一个节点,另一个节点又将充当传播者,传给其他节点,所以非常适合动态比那花的分布式系统,比如Cassandra
  • 3.一般而言,在实际场景中实现数据副本的最终一致性时,直接邮寄的方式是一定要实现的,因为不需要做一致性对比,只需要通过发送更细年数据或重传缓存来修复数据,新跟那个损耗低。在存储组件中,节点都是已知的,一般采用反熵修复数据副本的一致性。当集群节点是变化的,或者集群节点数比较多时,这时要采用谣言传播的方式更新数据,实现最终一致性。

如果我们在实际场景中涉及了一套AP型分布式系统,并通过反熵实现了各数据副本的最终一致性,且系统也在线上稳定地运行着,此时突然有同时提出希望数据写入成功后,能立即读取到新数据需求,也就是要实现强一致性,这时我们该怎么呢?难道我们必须推倒架构,一切从头再来?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1657358.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何开启深色模式【攻略】

如何开启深色模式【攻略】 前言版权推荐如何开启深色模式介绍手机系统手机微信手机QQ手机快手手机抖音 电脑系统电脑微信电脑QQ电脑WPS电脑浏览器 最后 前言 2024-5-9 20:48:21 深色模式给人以一种高级感。 本文介绍一些常用软件深色模式的开启 以下内容源自《【攻略】》 仅…

7-37 整数分解为若干项之和

题目链接&#xff1a;7-37 整数分解为若干项之和 一. 题目 1. 题目 2. 输入输出格式 3. 输入输出样例 4. 限制 二、代码 1. 代码实现 #include <iostream> #include <vector> using namespace std;// 打印整数分解序列式子的右边内容 void print_combinations(…

JavaScript初了解

JS的三种书写位置&#xff1a;行内&#xff0c;内嵌&#xff0c;外部 JS的注释的书写&#xff1a;单行注释&#xff1a;// ctrl/ 多行注释&#xff1a;/**/ ShiftAltA JavaScript输入输出语句

分布式事务Seata使用

我们要学习seata&#xff0c;首先需要具备如下技术储备&#xff1a; 数据库事务的基本知识&#xff1b;maven工具的使用&#xff1b;熟悉SpringCloudAlibaba技术栈&#xff1b;掌握SpringDataJPA简单使用&#xff1b; 一. Seata基本概念 1.seata是什么 Seata是阿里巴巴中间…

路由模块封装

目录 一、问题引入 二、步骤 一、问题引入 随着项目内容的不断扩大&#xff0c;路由也会越来越多&#xff0c;把所有的路由配置都堆在main.js中就不太合适了&#xff0c;所以需要将路由模块抽离出来。其好处是&#xff1a;拆分模块&#xff0c;利于维护。 二、步骤 将路由相…

【java.io.IOException: java.lang.IllegalArgumentException: db.num is null】

默认用户名&#xff1a;nacos 密码&#xff1a;nacos解决方法&#xff1a; a)在conf目录下将nacos-mysql.sql脚本创建完成&#xff1b; b)修改application.properties&#xff0c;在内容里添加如下内容 spring.datasource.platformmysql db.num1 db.url.0jdbc:mysql://localho…

videosapi开发微信管理系统

获取登录二维码&#xff1a; export interface Request {/*** 设备ID&#xff0c;首次登录传空&#xff0c;之后传接口返回的appId*/appId?: string;/*** 代理IP 格式&#xff1a;socks5://username:password123.2.2.2*/proxyIp?: string;/*** 地区*/regionId: string;[prop…

加速科技突破2.7G高速数据接口测试技术

随着显示面板分辨率的不断提升&#xff0c;显示驱动芯片&#xff08;DDIC&#xff09;的数据接口传输速率越来越高&#xff0c;MIPI、LVDS/mLVDS、HDMI等高速数据接口在DDIC上广泛应用。为满足高速数据接口的ATE测试需求&#xff0c;作为国内少数拥有完全自研的LCD Driver测试解…

Android GPU渲染屏幕绘制显示基础概念(1)

Android GPU渲染屏幕绘制显示基础概念&#xff08;1&#xff09; Android中的图像生产者OpenGL&#xff0c;Skia&#xff0c;Vulkan将绘制的数据存放在图像缓冲区中&#xff0c;Android中的图像消费SurfaceFlinger从图像缓冲区将数据取出&#xff0c;进行加工及合成。 Surface…

Tensorflow2.0笔记 - 循环神经网络RNN做IMDB评价分析

本笔记记录使用SimpleRNNCell做一个IMDB评价系统情感二分类问题的例子。 import os import time import numpy as np import tensorflow as tf from tensorflow import keras from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics, Inputos.envir…

模拟实现链表的功能

1.什么是链表&#xff1f; 链表是一种物理存储结构上非连续存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。 实际中链表的结构非常多样&#xff0c;以下情况组合起来就有8种链表结构&#xff1a; 单向或者双向 带头或者不带头 …

机器学习:基于线性回归、岭回归、xgboost回归、Lasso回归、随机森林回归预测卡路里消耗

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

小丑的身份证和复印件 (BFS + Floyd)

本题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 题目&#xff1a; 样例&#xff1a; 输入 2 10 (JOKERjoke #####asdr) 输出 12 思路&#xff1a; 根据题意&#xff0c;要求最短时间&#xff0c;实际上也可以理解为最短距离。 所以应该联想到有关最短距离的算法&…

【图文教程】PyCharm安装配置PyQt5+QtDesigner+PyUic+PyRcc

这里写目录标题 PyQt5、Qt Designer、PyUic、PyRcc简介&#xff08;1&#xff09;下载安装PyQt5&#xff08;2&#xff09;打开designer.exe所在位置&#xff08;3&#xff09;在PyCharm中配置QtDesigner&#xff08;4&#xff09;验证QtDesigner是否配置成功&#xff08;5&…

重学java 34.API 5.工具类

有失才有悟&#xff0c;崩塌后的重建只会更牢固 —— 24.5.9 一、System类 1.概述: 系统相关类,是一个工具类 2.特点: a.构造私有,不能利用构造方法new对象 b.方法都是静态的 3.使用: 类名直接调用 4.方法 方法 …

Linux系统入侵排查(二)

前言 为什么要做系统入侵排查 入侵排查1 1.排查历史命令记录 2.可疑端口排查 3.可疑进程排查 4.开机启动项 4.1系统运行级别示意图&#xff1a; 4.2查看运行级别命令 4.3系统默认允许级别 4.4.开机启动配置文件 入侵排查2&#xff1a; 1.启动项文件排查&#xff1…

Python从0到POC编写--实用小脚本

UrlCheck&#xff1a; 假设我们要对一份 url 列表进行访问是不是 200 &#xff0c; 量多的话肯定不能一个一个去点开看&#xff0c; 这个时候我们可以借助脚本去判断&#xff0c; 假如有一份这样的列表&#xff0c; 这份列表呢&#xff0c;奇奇怪怪&#xff0c;有些写错了…

基于Spring Boot的公司OA系统设计与实现

基于Spring Boot的银行OA系统设计与实现 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 用户登录界面&#xff0c;在银行OA系统运行后&#x…

刷题第3天(中等题):LeetCode24--两两交换链表中的节点--递归法

LeetCode24&#xff1a; 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4…

FastDFS - 无法获取服务端连接资源:can‘t create connection to/xx.xx.xx.xx:0

问题描述 根据官方文档 安装完FastDFS服务器后&#xff0c; 服务正常启动&#xff0c;但是在 SpringBoot 项目使用 fastdfs-client 客户端报错无法获取服务端连接资源&#xff1a;cant create connection to/xx.xx.xx.xx:0, 一系列排查发现是获取到的 tracker 端口为 0 。 co…