Ganglia是个很不错的工具,它的安装配置过程简单,采集的指标丰富,而且支持自定义,像Hadoop、HBase都对Ganglia进行了扩展。
在做系统设计和实现时必须充分考虑各种可能出错的情况(如数据延迟、丢数据、脏数据、网络断开等等)。
稳定性与准确性折中:建议不要在实时计算中过于追求计算结果的准确性,为了保证系统的稳定运行,可以牺牲一定的准确性,保证应用能够“活下去”更重要。
登录到问题机器上,也可使用top、free、sar、iostat、nmon等常用命令进一步查看、确认系统资源使用情况、问题之处。
同时,通过查看集群上的日志(包括集群级别、业务级别),确认是否有异常日志及对应的原因。
strace、jvm工具等方式追踪工作进程,从问题现场寻找原因。
系统的自动安装 kickstart cobbler
1. 服务器型号的区分,为以后的统一化和标准化作硬件上的准备,很多人忽视这一点,其实如果这一点做得好会使后面的运维工作轻松很多,根据应用我们主要把服务器分为3中,cpu密集型,主要用于大量计算应用,比如p2p;内存密集型,用于cache类应用,比如squid,varnish缓存服务器;磁盘密集型,用于大存储类应用,比如视频存储服务器,Hadoop日志存储集群。
2. 系统的的自动安装,主要有kickstart和cobbler
3. 统一的yum源和定制化的rpm包, 并集成至yum源站,为后续的环境初始化做软件上的准备
4. 构建专属于自己的内网DNS
5. 标准化的统一的命名方式(标准化基础),便于使用puppet管理,并且减少操作的错误,如果每个机器的hostname都为localhost,那将是一个多么可怕的事。。。在我们的生产环境中主要使用下面这种命名方式
机房-主业务-应用程序-IP后两位-公司域名,这样一眼就可以看出是哪台服务器,应用于什么业务,报警也可以直接定位。
6.自动化的配置管理和环境部署工具:puppet,puppet的模块编写要尽量减少模块直接的耦合度,并使用class继承的方式来减少运维的工作量,定制化的facter变量会使软件的配置环境更加灵活,由于puppet暂时不支持群集,所以在实际应用中需要部署多套,根据经验,1500台左右的server时puppet会出现性能问题。
7. 强大有效的监控系统,在生产环境中我们使用了zabbix proxy+zabbix master的群集结构,zabbix可以实现有效的系统和应用级别的监控,应用监控同时也使用了ppmon来实现多点监控。
选择zabbix有一个最大的好处,就是监控数据是存放在数据库中的,这样就可以利用数据库中的数据做很多操作,比如可以分析一段时间内服务器的各个性能指标,查看服务器的资源利用率,可以对数据进行聚合操作,从而分析全网的指标,比如总的流量,总的http code分布情况。
8. 日志收集服务器群集 和qos分析系统,构建 有效的日志收集系统可以有效地对用户的访问数据进行整合和分析,可以快速的分析qos,对应重要的节点我们采用本地分析并导入mongodb,最后导入zabbix的方式,非重要节点则直接将日志打包压缩,通过ftp上传至hadoop数据仓库集群中。
9. 构建冗余的结构,消除单点,在生成环境中对于一些重要节点都采用keepalived-ha的方案来提高冗余度。对于resin,php等应用服务器则在前端使用nginx做反向代理,同时nginx使用keepalived-ha
10. 自动化的代码分发系统,主要是controltier + svn的使用,可以方便快速地部署代码。
任务实例并行化:可以并行化的直接采用多shard,多进程/多线程的方式;复杂的任务则可以考虑先进行拆解,然后进行并行化。
不同类型的任务:CPU密集型考虑利用多核,将CPU尽可能跑满;内存密集型则考虑选择合适的数据结构、数据在内存中压缩(压缩算法的选择)、数据持久化等。
缓存Cache:选择将频繁使用、访问时间开销大的环节做成Cache;通过Cache减少网络/磁盘的访问开销;合理控制Cache的大小;避免Cache带来的性能颠簸,等等。
1)安装、部署过程要尽可能自动化。
将集群搭建的步骤脚本化,可以做到批量部署多个节点、快速上线/下线一个节点。集群的节点多,或者不断有节点上下线的话,都能省出不少的时间。
2)搭建并充分利用好集群的监控系统。
首先,最重要的是集群自带的监控系统。例如,HBase的Master、Region Server监控页面;Hadoop的JobTracker/TaskTracker、NameNode/DataNode监控页面;Storm的Storm UI监控页面,等等。这类监控侧重集群上的作业、资源等,而且包含的信息很全,包括作业运行的异常日志等,这对于排查、定位问题是非常及时有效的。
其次,既然是集群,就需要有一个统一的监控地址负责收集、展示各个节点的工作状态,集群既不能太闲,也不能负载过高。因此,我们需要对集群内各节点的CPU、内存、磁盘、网络等进行监控。Ganglia是个很不错的工具,它的安装配置过程简单,采集的指标丰富,而且支持自定义,像Hadoop、HBase都对Ganglia进行了扩展。
3)为集群内节点添加必要的运维脚本。
删除过期的、无用的日志文件,否则磁盘占满会导致节点不工作甚至发生故障,如Storm集群的Supervisor进程日志、Nimbus进程日志,Hadoop集群的各个进程日志。
为集群上的守护进程添加开机自启动脚本,尽可能避免宕机重启后的人工干预。例如,CDH已经为Hadoop、Hive、HBase等添加了启动脚本,rpm安装后进程可在机器重启后自启动。
同时监控集群上的守护进程是否存在,不存在则直接重启。这种方式只适用于无状态的进程,像Storm的Nimbus、Supervisor进程,Zookeeper进程等,都应该加上这样的监控脚本,确保服务进程终止后可以尽快被重启恢复。例如,通过设置crontab每分钟检查一次。
4)根据业务特点添加应用层的监控和告警。
对于业务层的计算任务,可以监控每天产出数据的大小和时间,如果出现异常情况(如数据文件的大小骤变,计算结果产出延迟等)则进行报警。
对于实时计算的应用,最重要的是数据处理是否出现明显延迟(分钟延迟、秒级延迟等),基于此,可以定义一系列的规则,触发不同级别的报警,以便第一时间发现并解决问题。
5)使多个用户能够共享集群的计算和存储资源。
使用集群的Quota限制不同用户的资源配额,例如Hadoop就提供了这一机制;但是,Storm和HBase目前并没有发现有什么方式可以限制。
通过多用户队列的方式对集群的资源进行限制与隔离。例如Hadoop为了解决多用户争用计算资源的情况,使用Capacity Scheduler或Fair Scheduler的方式,对不同用户提交的作业进行排队,可以直接部署应用,也可以根据业务需求对其进行定制后使用,很方便。
对于Storm集群,其计算资源也是按照Slots划分的,因此可以考虑在Storm之上加上一层资源控制模块,记录每个用户最大可占用的Slots数、当前已占有的Slots数等,从而实现用户的资源配额(不过目前Storm无论从集群规模还是内部使用用户来看,都还不算多,这一需求并不是特别迫切)。
另外,不同用户对集群的访问控制权限十分必要。比如,是否可以提交作业、删除作业,查看集群各类资源等,这是保证集群安全运行的一道基本保障。
6)实时计算应用要想办法应对流量峰值压力。
真实压测:例如为了应对双11当天流量压力,模拟平时3~5倍流量进行压测,提前发现解决问题,保证系统稳定性。
运维开关:通过加上运维开关,避免流量峰值时刻对系统带来的冲击,例如,通过ZooKeeper对实时计算应用加上开关,在线调整处理速度,允许一定时间的延迟,将流量平滑处理掉。
容错机制:实时计算的场景随流量的变化而变化,可能遇到各种突发情况,为此在做系统设计和实现时必须充分考虑各种可能出错的情况(如数据延迟、丢数据、脏数据、网络断开等等)。
稳定性与准确性折中:建议不要在实时计算中过于追求计算结果的准确性,为了保证系统的稳定运行,可以牺牲一定的准确性,保证应用能够“活下去”更重要。
7)多种方式追踪、定位、解决集群中的问题。
借助于集群的监控系统,定位问题所在的具体机器。登录到问题机器上,也可使用top、free、sar、iostat、nmon等常用命令进一步查看、确认系统资源使用情况、问题之处。
同时,通过查看集群上的日志(包括集群级别、业务级别),确认是否有异常日志及对应的原因。
另外,也可通过strace、jvm工具等方式追踪工作进程,从问题现场寻找原因。
8)集群运行任务的一些调优思路。
综合考虑系统资源负载:结合集群监控,从各个节点上任务实例的运行情况(CPU、内存、磁盘、网络),定位系统瓶颈后再做优化,尽可能使得每个节点的系统资源得到最大利用,尤其是CPU和内存。
任务实例并行化:可以并行化的直接采用多shard,多进程/多线程的方式;复杂的任务则可以考虑先进行拆解,然后进行并行化。
不同类型的任务:CPU密集型考虑利用多核,将CPU尽可能跑满;内存密集型则考虑选择合适的数据结构、数据在内存中压缩(压缩算法的选择)、数据持久化等。
缓存Cache:选择将频繁使用、访问时间开销大的环节做成Cache;通过Cache减少网络/磁盘的访问开销;合理控制Cache的大小;避免Cache带来的性能颠簸,等等。