Advacned Puppet: Puppet Master性能调优

本文是Advanced Puppet系列的第一篇:Puppet master性能调优,谈一谈如何优化和提高C/S架构下master端的性能。

故事情节往往惊人地类似:你是一名使用Puppet管理线上业务的DevOps工程师,随着公司的业务发展,你所管理的集群规模日益扩大。终于某一天,你突然发现执行一次puppet agent -vt的时间长得不可接受,多台agent并发运行时竟然会有节点运行失败,往日从来没有考虑过Puppet的性能居然成为了瓶颈……首先要恭喜你,因为Puppet Master端的性能瓶颈只有在集群发展到一定规模时才会遇到。

图1 性能调优

笼统地去谈系统的性能调优,是一个泛泛的话题,陈皓在他的《性能调优攻略》中介绍了系统性能的定义和如何定位性能瓶颈。因此,本篇把讨论范围缩小:只关注master端的性能调优,而不涉及Puppet代码的执行效率调优,部署逻辑的调优等等。

我们要对Puppet进行优化前,首先要清楚它有哪些瓶颈。对Puppet的C/S架构所有了解后,我们把它归类到Web服务: puppet agent端向puppet master发送请求,puppet master端处理请求并返回结果。web服务常见的性能度量指标是响应时间,系统吞吐量,系统资源利用率,并发用户数等。那么在这里我们主要关注两个指标:响应时间和并发用户数。因此,在对Puppet Master进行调优前,需要了解agent端和master端是如何交互的。

图2 Puppet C/S架构下的处理流程图

从图2可以看到一次完整的agent请求catalog的具体流程,Agent和Master之间的交互可以分为三步:

1. agent先向master发送一个请求,希望获取自己的catalog;

2. Master端通过agent附带的fqdn,environment等facts信息判断节点的分类,随后对其所属的class,define等资源进行编译;处理完成后把catalog以json格式返回给agent端;

3. Agent端拿到catalog后先做一个本地的状态查询,然后进行收敛达到预期的状态,完成后发送一个本次执行概况的report给Master端

ok,那我们来看一下实际的运行结果是如何的:以一台RabbitMQ节点向PuppetMaster发起一次执行操作为例,先分析Server端的访问日志有哪些操作:

10.0.1.45 - - [15/Aug/2014:23:31:50 -0400] "GET /production/node/server-45.1.test.ustack.in? HTTP/1.1" 200 4473 "-" "-" 0
10.0.1.45 - - [15/Aug/2014:23:31:50 -0400] "GET /production/file_metadatas/plugins?links=manage&recurse=true&checksum_type=md5&ignore=.svn&ignore=CVS&ignore=.git HTTP/1.1" 200 149510 "-" "-" 0
10.0.1.45 - - [15/Aug/2014:23:31:52 -0400] "POST /production/catalog/server-45.1.test.ustack.in HTTP/1.1" 200 305052 "-" "-" 7
10.0.1.45 - - [15/Aug/2014:23:32:03 -0400] "GET /production/file_metadata/modules/rsyslog/rsyslog_default?links=manage HTTP/1.1" 200 317 "-" "-" 0
10.0.1.45 - - [15/Aug/2014:23:32:03 -0400] "GET /production/file_metadata/modules/ssh/sshd_config?links=manage HTTP/1.1" 200 309 "-" "-" 0
10.0.1.45 - - [15/Aug/2014:23:32:04 -0400] "GET /production/file_metadata/modules/ssh/ssh_config?links=manage HTTP/1.1" 200 308 "-" "-" 0
10.0.1.45 - - [15/Aug/2014:23:32:04 -0400] "GET /production/file_metadatas/modules/mcollective/site_libdir?links=manage&recurse=true&checksum_type=md5 HTTP/1.1" 200 650 "-" "-" 0
10.0.1.45 - - [15/Aug/2014:23:32:04 -0400] "GET /production/file_metadatas/modules/mcollective/plugins/actionpolicy?links=manage&recurse=true&checksum_type=md5 HTTP/1.1" 200 1740 "-" "-" 0
10.0.1.45 - - [15/Aug/2014:23:32:07 -0400] "GET /production/file_metadata/modules/logrotate/etc/logrotate.conf?links=manage HTTP/1.1" 200 322 "-" "-" 0
10.0.1.45 - - [15/Aug/2014:23:32:07 -0400] "GET /production/file_metadata/modules/logrotate/etc/cron.hourly/logrotate?links=manage HTTP/1.1" 200 329 "-" "-" 0
10.0.1.45 - - [15/Aug/2014:23:32:07 -0400] "GET /production/file_metadata/modules/logrotate/etc/cron.daily/logrotate?links=manage HTTP/1.1" 200 328 "-" "-" 0
10.0.1.45 - - [15/Aug/2014:23:32:07 -0400] "PUT /production/report/server-45.1.test.ustack.in HTTP/1.1" 200 11 "-" "-" 0

再来看agent端的输出日志:

time puppet agent -vt 

Info: Retrieving plugin
Info: Caching catalog for server-45.1.test.ustack.in
Info: Applying configuration version ‘1408154486‘
Notice: Finished catalog run in 4.57 seconds

real    0m17.579s 

所谓catalog的编译,实质上是生成一个资源执行的有向状态图,是一个消耗CPU和磁盘IO资源的计算操作。在一次没有任何变更操作的情况,Puppet在分类和编译catalog上花费了整整11秒的时间,而作为文件服务器向agent端提供文件下载只花费了4秒,那么我们能从哪些方面来缩短master的响应时间?首先我们要分析慢在哪里,有哪些可能的原因会导致运行速度慢?

1. 升级软件版本

根据我的交流发现有不少公司仍在使用2.x版本的puppet,尤其以2.7.x居多。因为在Ubuntu/CentOS下,使用默认源安装的puppet版本就是2.7(6).x。根据官方的3.x Release Note,3.x的性能相比2.x相比有非常显著的提升,尤其是与2.7.x相比有50%的提升,我们目前使用的Puppet版本是3.3.1,实测结果是:相比2.7.14,整体的执行速度约提升了30%(与具体的部署逻辑相关)。

升级带来另外一个重要的问题:兼容性。我们知道把一个项目从Python2.7升级到Python3.4是一个非常困难的事情,某些语法的变更,最让人头疼的是大量的第三方库并不支持3.x。但是从Puppet 2.7(6).x升级到3.x你不需要太担心兼容性问题,因为绝大多数的puppet modules支持3.x的puppet语法规范。可能需要变动的是你自己编写的模块,例如模板,变量的命令空间等一些变动,并且这些兼容性问题只是以warning的形式提醒你进行修改。

2. 设置客户端合理的运行间隔

常常有不少同学喜欢把puppet agent端的运行间隔runinterval参数设置得很短,例如180s甚至60s。他们希望通过这种不停运行agent的方式,一是能够替代主动推送的需求,二是可以做到当服务意外停止,配置文件被人为修改后,可以尽快地恢复。这些想法并不能满足上述需求。

首先,推和拉是两个不同的操作模式,若以频繁的被动拉取节点配置来替代主动推送带来了几个问题:

1. 无意义地浪费server端的性能,从前面的数据中可以得知编译catalog是一个非常耗资源的操作;

2. 线上的一切变更均属于严肃的变更流程,需要主动地控制升级策略,例如两个web服务节点的升级流程,先得把web-01从lb背后摘下,进行变更,然后再重新上线,接着对web-02做同样的操作,拉模型明显不符合这样的部署需求;

3. 服务监控属于监控体系来管理,让puppet来做,心有余而力不足;

一个合理的runinterval值应该根据集群的规模来进行调整,官方的推荐值是1800s。

3.设置Splay避免惊群效应

举个简单的例子,当你往一群鸽子中间扔一块食物,虽然最终只有一个鸽子抢到食物,但所有鸽子都会被惊动来争夺,没有抢到食物的鸽子只好回去继续睡觉, 等待下一块食物到来。这样,每扔一块食物,都会惊动所有的鸽子,称为惊群。对于PuppetMaster来说,多个puppetmaster进程在等待CPU和IO资源时也会产生类似的情况。

在搭建内部开发环境的初期,我对puppet agent的运行间隔设置随意设置了一个较短的值:300s。本以为大功告成,但是当集群规模增加了一倍后,我发现agent从Puppet Master获取一次catalog的时间超过了我的预期。通过分析apache日志我才发现,所有节点几乎在同个时间段向这台可怜的PuppetMaster发出了请求,瞬间把这台运行在hypervisor上的master的CPU资源跑满。解决这个问题的办法就是设法错开Agent的拉取时间点,puppet默认提供了splay参数来满足这个需求。

你需要在每台agent节点的puppet配置文件中,添加:

splay = true

还有一个splaylimit参数,若不设置则默认会取runinterval的值。Puppet agent每次会在runinterval的基础上,增加0~splaylimit(秒)间的随机值后再运行,大大降低了agent同一时刻运行的概率。

4.弃用Webrick

很多同学喜欢使用ruby自带的webrick webserver来启动puppetmaster服务,因为简单方便。例如:

service puppetmaster start

首先,你要明白一点的是这些语言的内置webserver目的仅是为了方便调试代码,是根本不能放到生产环境去使用。

使用WebRick运行的Puppetmaster性能有多差?

仅9个并发请求就能把它拖垮。

我在在一台E5 2620的服务器上试验:只要9个puppet agent同时向运行在webrick上的puppet master发送请求,就处理不过来了,你会发现总有某台agent会出现40x Error的错误。

要提高单台Puppetmaster的性能很简单,只要使用常见的Web Server软件就可以显著地提高Puppet master的性能,例如Apache,Nginx等。这类文档很多,这里就不再详细说明配置的步骤了。

5.禁止使用activerecord + SQL作为Storeconfigs Backend

当你在开启了storeconfigs来使用Puppet的一些高级特性时,请注意不要使用activerecord + SQL的组合作为其后端存储。这对组合常常在2.x版本中出现得比较多,因为那时它的替代品PuppetDB还没有成熟,我们也曾经使用了近一年的ActiveRecord + MySQL的方式来做后端存储,它的目的就是把生成的catalog,facts等等都存到数据库中,其性能就是慢,慢,慢。去年我们在做私有云项目时,起初部署一台控制节点,竟然要30分钟!慢到老大一度想要用shell脚本去取代puppet,一度让我想把代码中所有高级特性全部禁用。我不得不寻求其他替代技术来改善storeconfigs的运行效率。

Puppet 3.x升级的另一个特性就是把这些老古董标记为弃用,当时社区推出了PuppetDB + PostgreSQL的新组合,其目的就是为了替代它们的。在执行存储和查询操作时,性能上提升不止快了一倍,最终交付给用户的时候,部署时间下降到了18分钟。不过,我已经忘记把测试对比数据丢哪了,可能是随ActiveRecord + MySQL一起丢了 :D。

6. 横向扩展Puppet集群

经过上述的优化后,你通过观察CPU负载发现单台Puppet已无法管理当前的集群规模时,可以对Puppet进行横向扩展。web服务的性能扩展较为容易,通过简单地增加puppet master节点的数量就能轻松地提高处理能力。在前端放置七层负载均衡,用于处理SSL认证和转发请求。如何搭建Puppet集群,如何在前端设置七层负载均衡的配置过程,我之前已写过相关的文章,也可以通过网上找到相应的资料。

图3 Puppet集群的典型架构图

7. 纵向扩展与横向扩展PuppetDB服务

当你选择使用PuppetDB作为storeconfigs的组件时,那么PuppetDB将是Puppet部署中的重要组件,如果PuppetDB挂了,那么agent节点将无法得到catalog。PuppetDB节点是属于典型的耗CPU,耗内存,耗磁盘IO的资源使用大户。下面我们来看看实际使用中可能会遇到的瓶颈以及解决办法。

图4 PuppetDB性能监控面板

7.1 数据库的性能瓶颈

PuppetDB主要作用是存储和查询catalog,facts和reports,其主要瓶颈主要在于后端PostgreSQL的读写性能,我们不可能花费精力去做PG的性能调优,需要找一种廉价的方式来提高性能。我的老大常常教育我,如果钱能解决的问题,那都不是事儿。因此若通过纵向扩展就能解决问题,其实是一种非常经济的手段:D。因此在生产环境中,推荐使用企业级的SSD盘去替代SATA盘,否则随着集群规模的增加,大量的随机读写操作会让PostgreSQL慢如蜗牛。

7.2 Java Heap大小的瓶颈

在使用PostgreSQL的情况下,分配128MB内存作为基础,然后根据集群的规模来增加额外的内存配置,原则是为每一台puppet node分配1M内存。然后通过观察PuppetDB的性能检测面板再进行适当地调整。修改方式是编辑puppetdb的启动脚本,修改JAVA_ARGS参数,为其分配2G内存:

JAVA_ARGS="-Xmx2g"

7.3 PuppetDB worker进程数的瓶颈

PuppetDB可以有效利用多核来处理其队列中的请求,每个核可以运行一个worker进程,PuppetDB默认只会运行该台机器一半核数的worker。因此,当你发现PuppetDB的性能监控面板上queue depth值长时间不为0时,你就需要配置更多的worker数。

图5 Command Queue 监控图

那如果单台PuppetDB不能满足需求了,如何处理? 那就需要横向扩展PuppetDB,构建PostgreSQL集群,其实大可不必如此忧愁。Puppetlabs官方给出的数据是使用一台2012年的笔记本 (16 GB of RAM, consumer-grade SSD, and quad-core processor)运行PuppetDB和PostgreSQL足以支撑8000台Puppet nodes每30分钟一次的运行。

8 总结

本篇中,我们先后从软件版本的升级,相关参数的调整,选择Web服务器作为容器,横向扩展,纵向扩展,后端存储的替换等多个方面考虑去提高Puppetmaster端的性能,具体到生产环境中,实际情况会所有不同,但是方法都是相同的:分析问题本质,找出问题所在,确定合理的优化方案。

时间: 2024-07-30 10:04:36

Advacned Puppet: Puppet Master性能调优的相关文章

hbase性能调优(1)

hbase性能调优 标签: hbase 性能调优 | 发表时间:2014-05-17 15:10 | 作者:无尘道长 分享到: 出处:http://www.iteye.com 一.服务端调优 1.参数配置 1).hbase.regionserver.handler.count:该设置决定了处理RPC的线程数量,默认值是10,通常可以调大,比如:150,当请求内容很大(上MB,比如大的put.使用缓存的scans)的时候,如果该值设置过大则会占用过多的内存,导致频繁的GC,或者出现OutOfMem

Hadoop之MapReduce性能调优

基于对这些组件的深入理解,用户可以很容易通过调整一些关键参数使作业运行效率达到最优,本文将分别从Hadoop管理员和用户角度介绍如何对Hadoop进行性能调优以满足各自的需求. 1 概述 Hadoop性能调优是一项工程浩大的工作,它不仅涉及Hadoop本身的性能调优,还涉及更加底层的硬件.操作系统和Java虚拟机等系统的调优.对这几个系统适当地进行调优均有可能给Hadoop带来性能提升. Hadoop(JobTracker.TaskTracker) JVM OS Hardware(CPU Mem

MySQL性能调优与架构设计——第 18 章 高可用设计之 MySQL 监控

第 18 章 高可用设计之 MySQL 监控 前言: 一个经过高可用可扩展设计的 MySQL 数据库集群,如果没有一个足够精细足够强大的监控系统,同样可能会让之前在高可用设计方面所做的努力功亏一篑.一个系统,无论如何设计如何维护,都无法完全避免出现异常的可能,监控系统就是根据系统的各项状态的分析,让我们能够尽可能多的提前预知系统可能会出现的异常状况.即使没有及时发现将要发生的异常,也要在异常出现后的第一时间知道系统已经出现异常,否则之前的设计工作很可能就白费了. 18.1 监控系统设计 系统监控

MySQL性能调优与架构设计——第 17 章 高可用设计之思路及方案

第 17 章 高可用设计之思路及方案 前言: 数据库系统是一个应用系统的核心部分,要想系统整体可用性得到保证,数据库系统就不能出现任何问题.对于一个企业级的系统来说,数据库系统的可用性尤为重要.数据库系统一旦出现问题无法提供服务,所有系统都可能无法继续工作,而不像软件中部分系统出现问题可能影响的仅仅只是某个功能无法继续服务.所以,一个成功的数据库架构在高可用设计方面也是需要充分考虑的.本章内容将针对如何构建一个高可用的 MySQL 数据库系统来介绍各种解决方案以及方案之间的比较. 17.1 利用

Hadoop性能调优总结(一)

目的 随着企业要处理的数据量越来越大,Hadoop运行在越来越多的集群上,同时MapReduce由于具有高可扩展性和容错性,已经逐步广泛使用开来.因此也产生很多问题,尤其是性能方面的问题.这里从管理员角度和用户角度分别介绍Hadoop性能优化的一些体会. 本文是基于Hadoop 0.20.x(包括1x),cdh 3及以上版本做介绍.(Hadoop的版本比较杂乱,具体可以看参考部分链接介绍). 管理员角度 1.    硬件选择: Master机器配置的选择要高于slave机器配置的选择. 2.  

OpenStack的性能调优工具 - osprofiler

简介 osprofiler是专门针对OpenStack的性能调优工具,采集到的信息可以存入ceilometer.redis.mongodb.elasticsearch等后端,默认存储在ceilometer中. 安装 还是以devstack方式先安装个OpenStack出来,上个local.conf配置文件(性能信息存入ceilometer) [[email protected] devstack]$ cat local.conf [[local|localrc]] # use trystack 

MapReduce - 性能调优

Hadoop为用户作业提供了多种可配置的参数,以允许用户根据作业特点调整这些参数值使作业运行效率达到最优. 一 应用程序编写规范 1.设置Combiner 对于一大批MapReduce程序,如果可以设置一个Combiner,那么对于提高作业性能是十分有帮助的.Combiner可减少Map Task中间输出的结果,从而减少各个Reduce Task的远程拷贝数据量,最终表现为Map Task和Reduce Task执行时间缩短. 2. 选择合理的Writable类型 在MapReduce模型中,M

MySQL性能调优与架构设计——第13章 可扩展性设计之 MySQL Replication

第13章 可扩展性设计之 MySQL Replication 前言: MySQL Replication 是 MySQL 非常有特色的一个功能,他能够将一个 MySQL Server 的 Instance 中的数据完整的复制到另外一个 MySQL Server 的 Instance 中.虽然复制过程并不是实时而是异步进行的,但是由于其高效的性能设计,延时非常之少.MySQL 的Replication 功能在实际应用场景中被非常广泛的用于保证系统数据的安全性和系统可扩展设计中.本章将专门针对如何利

MySQL性能调优与架构设计——第10章 MySQL数据库Schema设计的性能优化

第10章 MySQL Server性能优化 前言: 本章主要通过针对MySQL Server(mysqld)相关实现机制的分析,得到一些相应的优化建议.主要涉及MySQL的安装以及相关参数设置的优化,但不包括mysqld之外的比如存储引擎相关的参数优化,存储引擎的相关参数设置建议将主要在下一章“常用存储引擎的优化”中进行说明. 10.1 MySQL 安装优化 选择合适的发行版本 1. 二进制发行版(包括RPM等包装好的特定二进制版本) 由于MySQL开源的特性,不仅仅MySQL AB提供了多个平