【问题标题】:Puppet 3 file recurse terribly slowPuppet 3 文件递归非常慢
【发布时间】:2013-04-10 11:07:05
【问题描述】:

我在 Amazon Linux 2012.09 上使用 Puppet 3,我的清单之一设置并重新配置了一些目录。其中一项任务是将文件夹所有者和组 recursivelt 更改为另一个用户 - 但是,这需要 60 秒才能完成,并且目录中几乎没有任何内容 - 终端中的 chown myuser:myuser /var/lib/jenkins不到一秒钟。

我的问题是:有没有更好/更快的方法在 Puppet 中递归更改目录所有权?

谢谢

 file {'/var/lib/jenkins':
   ensure  => 'directory',
   owner   => myuser,
   group   => myuser,
   recurse => true,
   require => Package['jenkins'],
 }

【问题讨论】:

    标签: jenkins puppet


    【解决方案1】:

    我也看到了这种缓慢,这似乎是由于 Puppet 单独检查/var/lib/jenkins 下的每个文件以确保它具有正确的所有者权限,这需要时间,因为$JENKINS_HOME 下有很多文件。

    只要顶层目录不属于所需用户,我就会在我们的 Jenkins 服务器上解决这个问题,而是运行一个简单的 chown -R 命令(使用 exec):

    define modify_owner() {
      exec { "modify_owner_${title}" :
        command => "/bin/chown -R ${user}:${user} '${title}'",
        onlyif => "/usr/bin/stat -c %U '${title}' | grep '^${default_user}$'"
      }
    }
    
    modify_owner { ['/var/lib/jenkins', '/var/log/jenkins', '/var/cache/jenkins']: }
    

    $user/$user 是我想要拥有这些目录的所有者/组组合。这使我的 Puppet 时间恢复到正常水平。

    注意:我使用了stat -c %U,但您可能需要根据您的操作系统调整确切的格式选项。此命令打印所有者的文本名称并在 Linux 上为我工作。)

    【讨论】:

      【解决方案2】:

      @stuart-m 的解决方法是正确的基本结构。如果您需要深入,请使用 find 和 xargs。我没有幸运地拥有他的简化用例!

      请注意,Puppet 的缓慢不仅仅是因为它必须检查的文件数量。这是 Puppet 在某些任务上的速度非常慢。

      我在 wordpress 目录树 (Debian 10) 上对此进行了测试。

      # time find /var/www/*/wordpress/wp-content/ -type f | wc -l
      50661
      
      real    0m0.148s
      user    0m0.048s
      sys     0m0.107s
      

      所以那里有五万个文件 - 这需要大约七分之一秒才能确定。现在我们检查实际的文件所有权属性:

      # time find /var/www/*/wordpress/wp-content/ -not -group www-data | wc -l
      38603
      
      real    0m0.236s
      user    0m0.056s
      sys     0m0.188s
      

      更深入一点 - 这大约需要四分之一秒。

      让我们全部更改:

      time find /var/www/*/wordpress/wp-content/ -type f -exec chmod 0640 {} \; 
      
      
      real    0m44.392s
      user    0m29.520s
      sys     0m14.729s
      
      # time find /var/www/*/wordpress/wp-content/ -type d -exec chmod 2750 {} \; 
      
      real    0m4.935s
      user    0m3.288s
      sys     0m1.666s
      

      好的,五十秒。其中有多少是 shell 调用?

      # time bash -c "find /var/www/*/wordpress/wp-content/ -type f -print0 | xargs -0 chmod 0640"
      
      real    0m0.452s
      user    0m0.148s
      sys     0m0.513s
      
      # time bash -c "find /var/www/*/wordpress/wp-content/ -type d -print0 |xargs -0 chmod 2750 "
      
      real    0m0.149s
      user    0m0.024s
      sys     0m0.158s
      

      很好,天哪,几乎所有的都是shell forks - 实际上只花了大约一秒钟。

      我在这里结束是因为同一棵树上的directory : recurse=>true 需要大约 800 秒。这对于 shell 命令可以在一两秒内完成的事情来说太慢了。

      我不喜欢浪费 I/O,但考虑到这方面的时间安排,如果您的文件系统是本地的(这只是一台 7 美元/月的主机,带有 spin-rust 驱动器),您可能有能力执行在每次运行时查找/xargs/ch[own/mod]。

      编辑:我编写了一个 puppet 函数来“完成它”,它在 2 秒内运行 18 个单独的实例,涵盖 50,000 个文件。让 Puppet 处理它的速度大约提高了 400 倍。第一部分,定义类型:

      define my_class::permissions_tree (
                                          String $owner = 'root',
                                          String $group = 'root',
                                          String $fmode = '0644',
                                          String $dmode = '0755',
                                         ) {
      
        $path = $title
      
        case $os_family {
          'Debian' : {
            $find  = '/usr/bin/find'
            $xargs = '/usr/bin/xargs'
            $chmod = '/bin/chmod'
            $chown = '/bin/chown'
          }
        }
      
        $permissions_command_owner = "${find} $path \( -not -user ${owner} -or -not -group ${group} \) -print0 | $xargs -0 --replace=found $chown ${owner}:${group} found"
        $permissions_command_dirs  = "${find} $path \( -type d -and -not -perm ${dmode} \) -print0 | $xargs -0 --replace=found $chmod ${dmode} found"
        $permissions_command_files = "${find} $path \( -type f -and -not -perm ${fmode} \) -print0 | $xargs -0 --replace=found $chmod ${fmode} found"
        $permissions_command = join([$permissions_command_owner,$permissions_command_dirs,$permissions_command_files], ";")
      
        exec { "permissions_tree_${path}" :
          path     => [ '/sbin', '/bin', '/usr/sbin', '/usr/bin' ],
          command  => $permissions_command,
          provider => shell,
        }
      
      } # permissions_tree
      

      第 2 部分,使用它,例如:

        my_class::permissions_tree { "$some_dir/subdir" :
          owner   => $my_owner,
          group   => $my_group,
          dmode   => '2750', 
          fmode   => '0640',
          require => File[$some_dir],
        }
      

      require 只是一个元参数,在那里使用你需要的任何东西。如果不是 Debian,请添加您的操作系统路径。

      编辑 2:为带有 print0 的布尔值添加了所需的括号

      【讨论】:

        猜你喜欢
        • 2019-02-12
        • 2016-04-15
        • 2014-06-03
        • 1970-01-01
        • 2022-10-06
        • 1970-01-01
        • 2019-10-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多