Chef中收敛与幂等的区别

时间:2015-06-03 09:08:38

标签: chef theory configuration-management

Chef的融合和幂等性之间的基本区别是什么?

3 个答案:

答案 0 :(得分:35)

融合和幂等不是特定于厨师的。它们通常归功于配置管理理论,但在其他领域也有用,尤其是数学。

让我们从更基本的,幂等的开始。我们将忽略幂等的数学用法,而是关注人们谈论它时的配置管理。那就是:“同一动作的多个应用程序对系统状态没有副作用。”幂等操作的一个简单示例是mkdir -p

mkdir -p /var/lib/statedir/myapp

无论我们运行此命令多少次,都会导致创建该树。另一种说明幂等操作的方法是,“一次又一次地运行工具不会在第一次之后改变系统。”

现在将其与收敛进行对比。通常,汇聚意味着将[人或者]事物聚集在一起。在配置管理中,收敛意味着使系统状态符合已定义的策略。也就是说,只有在需要制作时才对系统进行更改。收敛操作的一个简单示例是:

if [ ! -d /var/lib/statedir/myapp ]; then
  mkdir -p /var/lib/statedir/myapp
fi

这是收敛的,因为如果所需的目录不存在,我们只执行mkdir命令。我们还将其称为“测试和修复”操作。也就是说,我们测试我们正在管理的特定事物的当前状态,然后使用特定命令或操作修复它,如果它不在该状态。这就是Chef在幕后用这样的资源做的事情:

directory '/var/lib/statedir/myapp' do
  recursive true
end

我们(Chef)谈论这个问题的方式是,Chef采取幂等行动将系统融合到各种资源声明的状态。 Chef中的每个资源都是声明性的,并对资源的当前状态执行测试,然后修复系统以匹配该资源。

为了深入了解关于Chef如何工作的杂草,它在Chef运行中有一个“编译”阶段和一个“融合”阶段。在“编译”阶段,它评估节点上的Ruby配方,并且它正在寻找它添加到“资源集合”的资源对象。一旦它评估了所有的配方,它就进入“融合”阶段,在那里迭代资源集合,采取适当的行动将资源置于所需的状态,从而创建用户,编写文件,安装包,等等。

答案 1 :(得分:4)

免责声明:我是配置管理社区的局外人,花了我很多小时才能弄清楚接下来的内容。我在此答案中批评配置管理社区,因此您应该意识到它们的世界不是我的世界,在我目前的工作中我什至不使用任何配置管理工具,而我只是根据我能找到的东西来判断它们在Google上。

定义

要说一个操作是 convergent ,则意味着将其管理的系统任何部分置于指定状态。

当配置管理人员说某项操作是幂等时,通常意味着如果您在运行一次之后立即第二次运行该操作,则第二次运行将立即终止而不进行任何多余的工作。

特别是在 Chef 上下文中将资源描述为幂等时,这意味着在资源已进入所需状态后后续的Chef运行不会将其视为“已更新”运行结束时 x / y资源已更新消息中的“”。

请注意,默认情况下,大多数内置资源都满足对幂等性的最终,最严格定义,您可以使用only_if and not_if卫队和converge_if_changed在自己的配方和自定义资源中实现这一点。

一些评论,以及关于其他定义的注释

令人困惑的是,您在互联网上找到的大多数“幂等”定义将与我刚刚给出的任何定义相匹配。我不是相信专家所说的定义,而是通过观察他们实际上使用术语的方式来推断它。找到某人给出“幂等”的定义,然后以明显在随后的几段中与该定义不一致的方式来使用该词,这真是令人发指。

要对此进行探讨,让我们开始探讨配置管理领域之外存在的“幂等”定义。许多这样的定义在https://en.wikipedia.org/wiki/Idempotence的Wikipedia上列出。在配置管理上下文中最常(错误)给出幂等的含义如下:

  • 在数学中,对于 x的所有可能值,如果 f(f(x))= f(x),则称函数 f 是幂等的
  • 在数学中,如果满足其他形式定义或其他形式的定义,则称其他类型的数学对象为全幂的(通常具有“反复执行与一次执行相同的作用”这一共同主题) 。
  • 在编程中,说一个函数或过程是幂等的,意味着两件事之一:
    1. 对于带有参数并返回值的函数,与数学含义完全相同。
    2. 对于具有副作用的函数,在调用一次函数后,后续调用将使系统状态保持不变。

大量混乱的源给出了其中一个定义,即在配置管理上下文中的“幂等”的含义,然后立即继续使用该术语,以明确表明这并不是它们的真正定义。使用。一些例子:

  • Pace的competing answer to this very question。他在那里宣称:

      

    如果在系统上多次执行该步骤(其基础状态未更改)后,其结果与该步骤已执行一次相同,则该步骤是幂等的。

    ,然后继续以不等幂的步骤为例:

    rm -rf /var/log/myapp
    mkdir -p /var/log/myapp
    

    显然,此步骤确实符合Pace对幂等的定义,因为连续运行多次使我们进入与运行一次相同的最终状态(即/var/log/myapp存在且为空的状态) 。但是,它第二次运行时会做多余的工作,因此Pace将其描述为非幂等。

  • Mischa Taylor和Seth Vargo的书学习厨师:配置管理和自动化指南。他们在那里声称:

      

    当Chef代码为幂等时,它可以在同一系统上运行多次,结果将始终相同,而不会产生意外的副作用。

    但是后来,对他们的示例食谱之一进行了评论:

      

    我们的配方是否通过了幂等性检验?可悲的是没有。 ... Chef错误地认为仍有需要做的事情-在第二次运行中更新了2/3资源。如果配方确实是幂等的,我们将看到0/3资源已更新。 Chef将检查系统的状态,确认自上次运行以来没有任何更改(没有人触摸两次运行之间的节点),并且不执行任何资源更新

    同样,他们基于多次运行某个配方时系统状态不变而声明等幂的定义,但实际上使用表示避免不必要的工作。

    p>
  • 本·福特(Penpet)博客上的Idempotence: not just a big and scary word,他首先给出了幂等的定义...

      

    幂等是一个简单的词,描述的是无论您运行一次还是运行10001次都会产生相同效果的操作。加一不是幂等的,因为结果一直在递增,但乘以一是幂等的,因为无论你乘多少次,答案都是相同的!

    然后,他给出了幂等的示例,尽管与上面给出的定义 一致,但还是有点可疑-因为它专注于后续执行不做多余的工作,而不是对他们达到相同的结果

      

    想象一下,当您12岁时,您的妈妈要您取出垃圾。作为您的好孩子,您丢下了GameBoy,然后按照要求跳了起来,是吗?

         

    但是30分钟后,当她回到客厅,看到你ed缩在沙发上玩“超级马里奥大地”时,她再次告诉你取出垃圾。我强烈怀疑您没有跳起来去拿空的垃圾袋。相反,您说:“妈妈已经做到了!”那就是幂等。被告知一次将垃圾取出的效果与被告知两次的效果相同。您没有再做一次,因为它已经完成了。

    然后,他终于把自己的定义抛在了一边,并举了一个例子,尽管重复执行 会达到相同的结果,但他声称这不是幂等的:

      

    那时候您因编写非等幂执行程序而受到责难了吗? Puppet的新手通常会替换他们的shell脚本,他们编写的代码看起来像这样:

    exec { '/usr/bin/curl http: //server.net/packages/package.tar.gz -o /tmp/package.tar.gz ': }
    
    -> exec { 'tar -xf /tmp/package.tar.gz -C /tmp/package': }
    
    -> exec { '/tmp/package/installer.sh': }
    
    file { '/tmp/package':
        ensure  => absent,
        force   => true,
        require => Exec[ '/tmp/package/installer.sh'],
    }
    
    file { '/tmp/package.tar.gz':
        ensure  => absent,
        force   => true,
        require => Exec[ '/tmp/package/installer.sh'],
    }
    
         

    那是怎么回事?可以,对吧?下载压缩包,解压缩,安装东西,然后自己清理。假设没有拼写错误或网络问题,它看起来应该可以完美运行。而且会的。但是,每次Puppet运行时,它将完美运行。换句话说,它将每三十分钟下载并运行一次安装程序脚本!

    但是结果将是一样的,本!先前,这就是您告诉我们幂等性定义的细节了!

    很明显,尽管他主张了什么,但本还是真的运用幂等性的“避免重复工作”定义。

操作可以是幂等但不能收敛的吗?

是的。这样的操作不会使系统进入指定的最终状态,但是确实避免了连续运行时的多余工作。 Pace's answer提供了此类操作的示例,Thinking Like A Chef提供了另一种操作:

  

系统可以是幂等的,而不会收敛。例如,如果我们有伪代码if file X does not exist, write the current timestamp to file X,它是幂等的,但实际上不能说它收敛于特定的最终状态。

我能想到的一个最实用的例子是可以使用等幂但不收敛的操作,即使用典型的软件包管理器的install命令安装软件包:

  • 如果未安装软件包,则会安装最新版本
  • 如果已经安装了较旧的版本,则不会更新。

状态(获得的软件包的版本)不是由配方决定的,因此可以说它不是收敛的,但是可以成功避免不必要的工作。

操作可以收敛但不是幂等吗?

是的,绝对!一个简单的例子是上文已经引用的本·福特的例子,它无条件地将文件下载到某个本地路径。这是收敛的,因为最终状态始终是相同的(文件存在),但不是幂等的,因为它在每次运行时都会执行重新下载文件的不必要工作。


对于它的价值,我感到很沮丧的是,配置管理社区使用了在更广泛的编程世界中已经具有明确含义的术语,然后在相关但仍明显不同的中使用它。 >方式,而从未提供其世界含义的正式定义。搜索Chef文档(https://www.google.co.uk/search?q=site%3Ahttps%3A%2F%2Fdocs.chef.io+idempotent)会产生该术语的许多用法,但没有定义。当浮动术语的大多数定义与用法不匹配时,使这个主题引起人们的困惑也就不足为奇了。

我只能找到一个曾经给出过幂等定义的人,这些定义与该术语的使用方式一致,这就是coderanger(又名Noah Kantrowitz)。在我之前引用的Thinking Like A Chef中,他写道:

  

“幂等”……意味着演员为实现所需状态所做的尽可能少的事情。

他在an IRC conversation from 2015中写道:

  

幂等意味着在不需要时不采取行动,收敛意味着它在特定的最终状态下“解决”。

除了这个人以外,我从字面上找不到其他人提供过与整个配置管理社区使用它的方式相匹配的术语定义。

答案 2 :(得分:2)

@Mark Amery要求提供一个更令人满意的两者之间差异的例子,以便我努力提供。

如果步骤成功结束,系统已进入已知状态,则步骤收敛

步骤是幂等,如果在系统上多次执行步骤(其基础状态未发生变化)后,结果与步骤执行一次相同。

没有幂等的融合

收敛但不是幂等的步骤是:

rm -rf /var/log/myapp
mkdir -p /var/log/myapp

在步骤成功结束时,我们知道/var/log/myapp是一个存在的空目录。

它不是幂等的,因为它每次都会吹掉/var/log/myapp目录。幂等性是可取的,因为它减少了系统上不必要的流失。显然,任何写入/var/log/myapp目录的应用程序都不满意上述步骤。

无融合的幂等

幂等但不收敛的步骤是:

test "$(ls -A /home/foo 2>/dev/null)" || tempfile -d /home/foo

只有/home/foo中没有文件时,该脚本才会在/home/foo中创建一个随机名称的文件。这是幂等的,在第一次运行后,目录不会为空,因此将来的运行将不执行任何操作。

然而,它并不收敛。你不能说这一步将系统置于任何类型的已知状态,因为创建的文件将具有随机名称。

需要融合,因为它有助于生成处于相同状态的系统,因此更有可能表现出可预测性。

提醒

这些术语就像抽象,它们不准确,可以泄漏。例如,您可以声明操作不是幂等的,因为它耗尽了CPU周期。你可以说,进行昂贵测试的一个幂等测试和修复操作是不那么幂等的"比另一个进行廉价测试的操作,即使"不那么幂等"不是事实。

您可以尝试声明安装MySQL版本X的步骤不会收敛,因为当在不同的计算机上运行时,它会在文件上留下不同的时间戳。或者你可以说我在上面发布的步骤是收敛的,因为它使系统处于状态" / home / foo存在并且只包含一个文件"。

当数学逃离黑板时会发生这种情况。