puppet-memcached模块

  1. 先睹为快
  2. 代码讲解
  3. 推荐阅读
  4. 动手练习

Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载,最初由LiveJournal的Brad Fitzpatrick开发,目前得到了广泛的使用。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。

puppet-memcached是由Steffen Zieger(saz)维护的一个模块。同时,他还维护了puppet-sudo,puppet-ssh等模块。

puppet-memcached项目地址:https://github.com/saz/puppet-memcached

1.先睹为快

不想看下面大段的代码解析,已经跃跃欲试了?

OK,我们开始吧!

打开虚拟机终端并输入以下命令:

  1. $ puppet apply -e "class { 'memcached': }"

在看到赏心悦目的绿字后,Puppet已经完成了Memcached服务的安装,配置和启动。这是如何做到的呢?

我们打开puppet-memcached模块下manifests/init.pp文件来一探究竟吧。

2.代码解析

puppet-memcached模块的代码结构非常简洁,所有的工作都在Class memcached中完成:

2.1 Class memcached

1.以下代码完成了对Memcached软件包管理:

  1. package { $memcached::params::package_name:
  2. ensure => $package_ensure,
  3. provider => $memcached::params::package_provider
  4. }
  5. if $install_dev {
  6. package { $memcached::params::dev_package_name:
  7. ensure => $package_ensure,
  8. require => Package[$memcached::params::package_name]
  9. }
  10. }

此处,值得一提的是:在package资源类型中,需要重写参数provider默认值的情况并不常见,该参数用于设置管理软件包的后端,常见的可选项有:yum,apt,pip等。

2.下述代码完成了对Memcached服务的管理:

  1. if $service_manage {
  2. service { $memcached::params::service_name:
  3. ensure => $service_ensure,
  4. enable => $service_enable,
  5. hasrestart => true,
  6. hasstatus => $memcached::params::service_hasstatus,
  7. }
  8. }

service资源类型中,需要设置参数hasstatus的情况也并不多见,该参数用于设置目标服务是否具有查看服务状态的脚本,默认为true。如果该服务的软件包中并没有提供查看服务运行状态的脚本,可以添加status参数,来用于指定一个手动运行的命令:若返回值为0,则认为服务是运行状态;若返回值非0,则认为服务是非运行状态。

2.2 memcached_sysconfig.erb模板

class memcached中使用了file资源对Memcached配置文件进行管理:

  1. if ( $memcached::params::config_file ) {
  2. file { $memcached::params::config_file:
  3. owner => 'root',
  4. group => 'root',
  5. mode => '0644',
  6. content => template($memcached::params::config_tmpl),
  7. require => Package[$memcached::params::package_name],
  8. notify => $service_notify_real,
  9. }
  10. }

2.2.1 什么是模板

第一次见到了模板(template),这是Puppet用于管理配置文件的常用方法。

模板是指含有可执行代码和数据的特殊文本格式文件,通过渲染最终生成纯文本文件。使用模板的目标就是通过一些简单的输入(传递几个参数)就可以产生复杂的文本输出。

memcached::params中查询到RHEL下的$memcached::params::config_tmpl值为${module_name}/memcached_sysconfig.erb

.erb又称为Embedded Ruby模板语言,Puppet可以通过函数templateinline_template来渲染模板文件。

下面取自templates/memcached_sysconfig.erb文件的部分代码片段。

  1. <%-
  2. result = []
  3. if @verbosity
  4. result << '-' + @verbosity.to_s
  5. end
  6. ...
  7. if @extended_opts
  8. result << '-o ' + @extended_opts.join(',')
  9. end
  10. result << '-t ' + @processorcount.to_s
  11. # log to syslog via logger
  12. if @syslog && @logfile.empty?
  13. result << '2>&1 |/bin/logger &'
  14. # log to log file
  15. elsif !@logfile.empty? && !@syslog
  16. result << '>> ' + @logfile + ' 2>&1'
  17. end
  18. -%>
  19. <%- if scope['osfamily'] != 'Suse' -%>
  20. PORT="<%= @tcp_port %>"
  21. USER="<%= @user %>"
  22. MAXCONN="<%= @max_connections %>"
  23. <% Puppet::Parser::Functions.function('memcached_max_memory') -%>
  24. CACHESIZE="<%= scope.function_memcached_max_memory([@max_memory]) %>"
  25. OPTIONS="<%= result.join(' ') %>"
  26. <%- else -%>
  27. MEMCACHED_PARAMS="<%= result.join(' ') %>"
  28. ...
  29. MEMCACHED_USER="<%= @user %>"
  30. ...
  31. <%- end -%>

2.2.2 模板标签

首先,在ERB模板中,标签(tag)是一个重要的概念。例如:

  • <% CODE %>以成对出现,表示这是一段可执行代码
  • <%= EXPRESSION %>以成对出现,表示是插入值的表达式
  • <%# COMMENT %>成对出现,表示为一段注释
  • <%%%%>,表示<%%>字符

如果在标签中加入-符,则会移除缩进和换行。

memcached_sysconfig.erb代码片段中,以下为插入值的表达式,最终会将$tcp_port,$user,$max_connections变量的值插入到Memcached的配置文件中:

  1. PORT="<%= @tcp_port %>"
  2. USER="<%= @user %>"
  3. MAXCONN="<%= @max_connections %>"

而下述代码则为一段可执行代码,用于判断$osfamily的值是否为’Suse’:

  1. <%- if scope['osfamily'] != 'Suse' -%>

2.2.3 模板变量

模板可以访问Puppet中的变量,在模板中访问变量时会有一个范围(scope)的概念,调用该模板的class或define中的变量为该模板的局部变量,可以直接使用变量名进行调用。

在ERB模板中有两种方式来访问变量:

@variable方式是ERB模板中变量的命名规范,以@开头,用于访问当前范围内的变量。如下述代码片段中,在渲染该模板文件时,Puppet会在class memcached中去搜寻与@tcp_port对应的$tcp_port变量,查询到该变量的默认值是11211,最终在/etc/sysconfig/memcached中得到配置PORT=11211

  1. PORT="<%= @tcp_port %>"

scope['variable']方式则可以访问所有的变量(包括当前范围以外的),使用哈希风格的表达式用于指定需要访问的变量,例如scope[foo::bar]
如下述代码片段中,Puppet将从Facter中获取到变量$osfamily的值。

  1. <%- if scope['osfamily'] != 'Suse' -%>

本节对于模板的介绍就到这里,后续会再次谈到模板。

推荐阅读

动手练习

  1. Memcached服务的默认进程数为服务器核数的一半
  2. 关闭puppet-memcached对防火墙规则的管理