| Subcribe via RSS

memcached 入门到理解

8月 28th, 2008 | No Comments | Posted in memcached < by Michael Field >

这是由 mixi 株式会社 开发部系统运营组的两位工程师所写,日常负责程序的运营。本文将针对最近在Web应用的可扩展性领域的热门话题memcached,说明其内部结构和使用。

文章分为5个章节、案例讲解,推荐大家阅读学习,中文版PDF文档下载地址见最下!

  • 第1章 memcached的基础
    • 1.1 memcached是什么?
      1.2 memcached的特征
      1.3 安装memcached
      1.4 用客户端连接
      1.5 使用Cache::Memcached
      1.6 总结
  • 第2章 理解memcached的内存存储
    • 2.1 Slab Allocation机制:整理内存以便重复使用
      2.2 在Slab中缓存记录的原理
      2.3 Slab Allocator的缺点
      2.4 使用Growth Factor进行调优
      2.5 查看memcached的内部状态
      2.6 查看slabs的使用状况
      2.7 总结
  • 第3章 memcached的删除机制和发展方向
    • 3.1 memcached在数据删除方面有效利用资源
      3.2 LRU:从缓存中有效删除数据的原理
      3.3 memcached的最新发展方向
      3.4 外部引擎支持
      3.5 总结
  • 第4章 memcached的分布式算法
    • 4.1 memcached的分布式
      4.2 Cache::Memcached的分布式方法
      4.3 Consistent Hashing
      4.4 总结
  • 第5章 memcached的应用和兼容程序
    • 5.1 mixi案例研究
      5.2 memcached应用经验
      5.3 兼容应用程序
      5.4 总结
      如今,越来越多的Web应用程序开始使用memcached这个高速的缓存服务器软件。然而,memcached的基础知识远远未能像其他Web技术那样普及,memcached在国内的大规模应用也鲜为人知。而日本的mixi(http://mixi.jp)则在这方面走在了前面,不仅大规模使用memcached作为缓存来加速Web应用,而且自行开发了Tokyo Cabinit、Tokyo Tyrant等一系列相关的软件。

      最近,日本的技术评论社的网站上刊登了mixi的两名工程师长野雅广、前坂徹撰写的一篇连载《memcachedを知り尽くす》。这篇连载语言简洁、通俗易懂,非常适合memcached入门的人阅读。

    PDF档下载地址

    阅读内文 Tags: , , , ,

    OP Cache大比拼: APC vs eAccelerator vs xcache, eAccelerator胜出

    8月 25th, 2008 | 5 Comments | Posted in PHP < by Johnny Woo >

    APC 3.0.19 (Alternative PHP Cache)
    配置

    extension=apc.so
    apc.enabled=1
    apc.shm_segments=1
    apc.shm_size=128
    apc.ttl=7200
    apc.user_ttl=7200
    apc.num_files_hint=1024
    apc.mmap_file_mask=/tmp/apc.XXXXXX
    apc.enable_cli=1

    结果

    7303 fetches, 50 max parallel, 1.67458e+07 bytes, in 300 seconds
    2293 mean bytes/connection
    24.3433 fetches/sec, 55819.3 bytes/sec
    msecs/connect: 3.27583 mean, 2999.74 max, 0.184 min
    msecs/first-response: 2043.52 mean, 7853.21 max, 325.513 min
    HTTP response codes:
      code 200 -- 7303

    eAccelerator 0.9.5.3
    配置

    [eaccelerator]
    extension=eaccelerator.so
    eaccelerator.shm_size="16"
    eaccelerator.cache_dir="/tmp/eaccelerator"
    eaccelerator.enable="1"
    eaccelerator.optimizer="1"
    eaccelerator.check_mtime="1"
    eaccelerator.debug="0"
    eaccelerator.log_file = "/var/log/httpd/eaccelerator_log"
    eaccelerator.filter=""
    eaccelerator.shm_max="0"
    eaccelerator.shm_ttl="0"
    eaccelerator.shm_prune_period="0"
    eaccelerator.shm_only="0"
    eaccelerator.compress="1"
    eaccelerator.compress_level="9"

    结果

    7568 fetches, 50 max parallel, 1.73534e+07 bytes, in 300.001 seconds
    2293 mean bytes/connection
    25.2266 fetches/sec, 57844.6 bytes/sec
    msecs/connect: 0.39873 mean, 1.01 max, 0.173 min
    msecs/first-response: 1972.44 mean, 5520.1 max, 635.565 min
    HTTP response codes:
      code 200 -- 7568

    XCache v1.2.2
    配置

    extension="xcache.so"
    [xcache.admin]
    ; Change xcache.admin.user to your preferred login name
    xcache.admin.user = "admin"
    ; Change xcache.admin.pass to the MD5 fingerprint of your password
    ; Use md5 -s "your_secret_password" to find the fingerprint
    xcache.admin.pass = "e10adc3949ba59abbe56e057f20f883e"
    [xcache]
    ; Change xcache.size to tune the size of the opcode cache
    xcache.size = 24M
    xcache.shm_scheme = "mmap"
    xcache.count = 2
    xcache.slots = 8K
    xcache.ttl = 0
    xcache.gc_interval = 0
    ; Change xcache.var_size to adjust the size of variable cache
    xcache.var_size = 8M
    xcache.var_count = 1
    xcache.var_slots = 8K
    xcache.var_ttl = 0
    xcache.var_maxttl = 0
    xcache.var_gc_interval = 300
    xcache.test = Off
    xcache.readonly_protection = On
    xcache.mmap_path = "/tmp/xcache"
    xcache.coredump_directory = ""
    xcache.cacher = On
    xcache.stat = On
    xcache.optimizer = On
    [xcache.coverager]
    xcache.coverager = Off
    xcache.coveragedump_directory = ""

    结果

    4539 fetches, 50 max parallel, 1.04079e+07 bytes, in 300 seconds
    2293 mean bytes/connection
    15.13 fetches/sec, 34693.1 bytes/sec
    msecs/connect: 0.405883 mean, 0.999 max, 0.182 min
    msecs/first-response: 3214.64 mean, 18691.3 max, 772.952 min
    HTTP response codes:
      code 200 -- 4539

    No OP-Cache
    结果

    1798 fetches, 50 max parallel, 3.9867e+06 bytes, in 300 seconds
    2217.3 mean bytes/connection
    5.99332 fetches/sec, 13289 bytes/sec
    msecs/connect: 12.0802 mean, 2999.48 max, 0.203 min
    msecs/first-response: 6966.64 mean, 59754 max, 381.002 min
    41 timeouts
    61 bad byte counts
    HTTP response codes:
      code 200 -- 1757

    结论:
    eAccelerator 0.9.5.3
    25.2266 fetches/sec

    APC 3.0.19
    24.3433 fetches/sec

    XCache v1.2.2
    15.13 fetches/sec

    No OP-Cache
    5.99332 fetches/sec

    eA的效果最好.APC紧随其后.两者的性能表现基本相同.xcache最差.

    阅读内文 Tags: , , , , ,

    Cacti实现短信报警

    8月 25th, 2008 | 6 Comments | Posted in Cacti < by John.Lv >

    一、 软件环境:cacti(需Threshold插件),飞信机器人(fetion)
    二、 安装过程:
    Cacti的Threshold插件下载及安装配置参见:Cacti配置e-mail报警
    飞信机器人(fetion)下载及安装配置参见:系统监控:linux命令行-飞信客户端发送免费报警短信
    三、 配置过程:
    1.按照Cacti配置e-mail报警配置并启用thold
    2.编辑cacti/plugins/thold/thold-functions.php
    在thold–functions.php查找thold_mail($global_alert_address, ”, $subject, $msg, $file_array);行在此行下面加入:

    exec("echo $subject >>/var/www/html/cacti/plugins/thold/alter.log");
    exec("/var/www/html/cacti/plugins/thold/sendsms.sh");

    查找 thold_mail($item["notify_extra"], ”, $subject,
    $msg, $file_array);行在此行下面加入:

    exec("echo $subject >>/var/www/html/cacti/plugins/thold/alter.log"); #将报警信息记录到alter.log
    exec("/var/www/html/cacti/plugins/thold/sendsms.sh"); #执行sendsms.sh

    备注:本人的thold安装在/var/www/html/cacti/plugins/thold/目录中,如果注释掉thold_mail,只通过短信发送报警。不注释掉thold_mail,会通过email和短信同时发送报警

    thold-functions.php生成的alter.log范例如下:

    192.168.1.207 - Used Space - G: Label: [hdd_percent] is still above threshold of 85 with 99

    编写脚本sendsms.sh自动调用飞信机器人发送报警

    #!/bin/sh
    #send sms by fetion
    #Write by John.Lv
    if [ ! -e "/var/www/html/cacti/plugins/thold/alert.log" ];then #判断alter.log是否存在
    echo "Usage:alert.log does not exist"
    exit
    fi
    if [ -n "`cat /var/www/html/cacti/plugins/thold/alert.log`" ]; then #判断alter.log是否有报警信息
    admin="135xxxxxxxx"  #短信接收人,需在你飞信的好友列表中
    echo "sms $admin "`cat /var/www/html/cacti/plugins/thold/alert.log` >>/var/www/html/cacti/plugins/thold/sms.txt #发送alter.log中的报警信息给admin
    echo "exit" >> /var/www/html/cacti/plugins/thold/sms.txt #退出飞信
    else
    echo "Usage:no alert"
    exit
    fi
    if [ -n "`cat /var/www/html/cacti/plugins/thold/sms.txt`" ] ; then
    /var/www/html/cacti/plugins/thold/install/fetion -u 13512345678 -p "123456" -b /var/www/html/cacti/plugins/thold/sms.txt  -EN
    #调用fetion发送短信,命令格式和参数说明参见:系统监控:linux命令行-飞信客户端发送免费报警短信
    rm -f /var/www/html/cacti/plugins/thold/sms.txt 1>/dev/null 2>&1
    rm -f /var/www/html/cacti/plugins/thold/alert.log 1>/dev/null 2>&1
    else
    echo "Usgae:no message to send"
    exit
    fi

    ok,配置完成了,现在就可以通过短信接收报警信息了

    阅读内文 Tags:

    测试JS引擎性能

    8月 24th, 2008 | 3 Comments | Posted in FireFox, JavaScript < by Johnny Woo >

    http://wd-testnet.world-direct.at/mozilla/dhtml/funo/jsTimeTest.htm
    FireFox 3.1pre里面如果打开了jit
    确实运行js如飞
    新的trace monkey引擎对于spider monkey来说
    在大多数项目上都有100~300%的增幅
    除了parseint以外
    希望FireFox 3.1可以快些到来
    因为pre版不支持任何FF插件
    还不能当作正式生产环境的工具来用.

    阅读内文

    Cacti实现MSN报警

    8月 22nd, 2008 | 6 Comments | Posted in Cacti < by John.Lv >

    一、 软件环境:cacti(需Threshold插件),MSN机器人(SendMsg)
    二、 安装过程:
    Cacti的Threshold插件参见:Cacti配置e-mail报警
    MSN机器人(SendMsg)参见:系统监控:msn在线机器人实时报警
    三、 配置过程:
    1.按照Cacti配置e-mail报警配置并启用thold
    2.编辑cacti/plugins/thold/thold-functions.php
    在thold–functions.php查找thold_mail($global_alert_address, ”, $subject, $msg, $file_array);行在此行下面加入:

    exec("echo $subject >>/var/www/html/cacti/plugins/thold/alter.log");
    exec("sh /var/www/html/cacti/plugins/thold/sendmessage.sh");

    查找 thold_mail($item["notify_extra"], ”, $subject,
    $msg, $file_array);行在此行下面加入:

    exec("echo $subject >>/var/www/html/cacti/plugins/thold/alter.log");
    exec("sh /var/www/html/cacti/plugins/thold/sendmessage.sh");

    备注:本人的thold安装在/var/www/html/cacti/plugins/thold/目录中,如果注释掉thold_mail,只通过MSN发送报警。不注释掉thold_mail,会通过email和MSN同时发送报警

    thold-functions.php生成的alter.log范例如下:

    192.168.1.207 - Used Space - G: Label: [hdd_percent] is still above threshold of 85 with 99

    编写脚本sendmessage.sh自动调用SendMsg发送报警

    #!/bin/sh
    echo `echo -n "date:"&&date +%Y-%m-%d-%H:%M` >> /var/www/html/sendMsg/msn.txt.1
    #得到当前的日期+时间
    cat /var/www/html/cacti/plugins/thold/alter.log >>/var/www/html/sendMsg/msn.txt.1
    #读取alter.log的报警信息
    now=`date +%Y-%m-%d-%H:%M`
    SA=(disk)
    msnaddr=(lvming104@hotmail.com) #报警接收人msn
    sendMsg()
    {
    num=0
    while [ $num -lt 1 ];
    do
    wget --post-data "sender=test@live.cn&password=12346&recipient=${1}&message=${2}" http://127.0.0.1/sendMsg/index.php -O /var/www/html/sendMsg/index.php.1 >/dev/null 2>&1
    #sender:发送人msn,password:密码。/var/www/html/sendMsg为sendMsn安装目录
    if [ -f /var/www/html/sendMsg/index.php.1 ]; then
    if cat /var/www/html/sendMsg/index.php.1 |grep -i successfully >/dev/null 2>&1;then
    num=1 #判断信息发送成功
    elif cat /var/www/html/sendMsg/index.php.1 |grep -i "The user appears to be offline" >/dev/null 2>&1;then
    num=1 #判断msn接受人为是否在线状态
    echo "The user is offline."
    exit 0
    elif cat /var/www/html/sendMsg/index.php.1 |grep -i "Something went wrong trying to connect to the server" >/dev/null 2>&1;then
    num=1 #判断msn 服务器存在连接问题
    echo "MSN server is wrong."
    exit 0
    else
    num=0 #除了以上三种情况退出循环外,其他情况重试。
    fi
    rm -f /var/www/html/sendMsg/index.php.1
    else
    num=0
    fi
    done
    }
     
    mv /var/www/html/sendMsg/msn.txt /var/www/html/sendMsg/bak/msn$now.txt -f 1>/dev/null 2>&1
    mv /var/www/html/sendMsg/msn.txt.1 /var/www/html/sendMsg/msn.txt -f 1>/dev/null 2>&1
    rm /var/www/html/cacti/plugins/thold/alter.log -f 1>/dev/null 2>&1

    for i in 0
    do
    if cat /var/www/html/sendMsg/msn.txt ; then
    messages=`cat /var/www/html/sendMsg/msn.txt ` #读取要发送的信息
    sendMsg "${msnaddr[$i]}" "$messages" #发送报警信息
    else
    continue
    fi
    done

    ok,配置完成了,现在就可以通过MSN接收报警信息了:如下所示

    下次更新Cacti实现短信报警,敬请期待

    阅读内文 Tags:

    IT流言终结者3:eaccelerator与xcache性能测试对比

    8月 22nd, 2008 | 6 Comments | Posted in PHP < by Johnny Woo >

    网上有一篇比较eAccelerator与xcache的性能的文章
    php缓冲器:eaccelerator与xcache性能测试对比
    里面最终的结果是Xcache胜出
    而这次由于生产环境调优的关系
    我们同样适用Xcache与EA进行对比
    选出能够提高生产环境效率的PHP OPCODE缓冲器
    这次我们直接使用的是网站程序中的登录模块
    整个网站基于SEAGULL 0.61框架.
    前端是
    APACHE 2.2.4
    PHP 5.2.4
    Xcache 1.1.2
    eAccelerator 0.9.5.3
    Zend Engine v2.2.0
    测试工具http_load
    参数

    ./http_load -p 50 -f 500 -s 300 phps

    eAccelerator配置

    extension="eaccelerator.so"
    eaccelerator.shm_size="16"
    eaccelerator.cache_dir="/tmp/eaccelerator"
    eaccelerator.enable="1"
    eaccelerator.optimizer="1"
    eaccelerator.check_mtime="1"
    eaccelerator.debug="0"
    eaccelerator.log_file = "/var/log/httpd/eaccelerator_log"
    eaccelerator.filter=""
    eaccelerator.shm_max="0"
    eaccelerator.shm_ttl="0"
    eaccelerator.shm_prune_period="0"
    eaccelerator.shm_only="0"
    eaccelerator.compress="1"
    eaccelerator.compress_level="9"

    xcache配置

    extension="xcache.so"
    [xcache.admin]
    ; Change xcache.admin.user to your preferred login name
    xcache.admin.user = "admin"
    ; Change xcache.admin.pass to the MD5 fingerprint of your password
    ; Use md5 -s "your_secret_password" to find the fingerprint
    xcache.admin.pass = "e10adc3949ba59abbe56e057f20f883e"
    [xcache]
    ; Change xcache.size to tune the size of the opcode cache
    xcache.size = 24M
    xcache.shm_scheme = "mmap"
    xcache.count = 2
    xcache.slots = 8K
    xcache.ttl = 0
    xcache.gc_interval = 0
    ; Change xcache.var_size to adjust the size of variable cache
    xcache.var_size = 8M
    xcache.var_count = 1
    xcache.var_slots = 8K
    xcache.var_ttl = 0
    xcache.var_maxttl = 0
    xcache.var_gc_interval = 300
    xcache.test = Off
    xcache.readonly_protection = On
    xcache.mmap_path = "/tmp/xcache"
    xcache.coredump_directory = ""
    xcache.cacher = On
    xcache.stat = On
    xcache.optimizer = Off
    [xcache.coverager]
    xcache.coverager = On
    xcache.coveragedump_directory = ""

    Zend配置

    [Zend]
    zend_extension_manager.optimizer=/usr/local/Zend/lib/Optimizer-3.3.0
    zend_extension_manager.optimizer_ts=/usr/local/Zend/lib/Optimizer_TS-3.3.0
    zend_optimizer.version=3.3.0a
    zend_extension=/usr/local/Zend/lib/ZendExtensionManager.so
    zend_extension_ts=/usr/local/Zend/lib/ZendExtensionManager_TS.so

    测试结果(几次测试中取样代表性数据)

    with nothing
    1798 fetches, 50 max parallel, 3.9867e+06 bytes, in 300 seconds
    2217.3 mean bytes/connection
    5.99332 fetches/sec, 13289 bytes/sec
    msecs/connect: 12.0802 mean, 2999.48 max, 0.203 min
    msecs/first-response: 6966.64 mean, 59754 max, 381.002 min
    41 timeouts
    61 bad byte counts
    HTTP response codes:
      code 200 -- 1757
    with eAccelerator v0.9.5.3
    作为php扩展模块
    7578 fetches, 50 max parallel, 1.73764e+07 bytes, in 300 seconds
    2293 mean bytes/connection
    25.26 fetches/sec, 57921.2 bytes/sec
    msecs/connect: 3.16951 mean, 3000.16 max, 0.141 min
    msecs/first-response: 1970.65 mean, 8268.16 max, 197.622 min
    HTTP response codes:
      code 200 -- 7578
    with Zend Extension Manager v1.2.2, Copyright (c) 2003-2007, by Zend Technologies
    with eAccelerator v0.9.5.3, Copyright (c) 2004-2006 eAccelerator, by eAccelerator
    作为zend扩展模块
    7640 fetches, 50 max parallel, 1.75185e+07 bytes, in 300 seconds
    2293 mean bytes/connection
    25.4667 fetches/sec, 58395.1 bytes/sec
    msecs/connect: 3.14855 mean, 2999.92 max, 0.165 min
    msecs/first-response: 1954.57 mean, 8446.03 max, 267.841 min
    HTTP response codes:
      code 200 -- 7640
    with eAccelerator v0.9.5.3
    with Zend Extension Manager v1.2.2
    with Zend Optimizer v3.3.0
    作为php扩展模块
    6732 fetches, 50 max parallel, 1.54365e+07 bytes, in 300 seconds
    2293 mean bytes/connection
    22.44 fetches/sec, 51454.9 bytes/sec
    msecs/connect: 0.40062 mean, 0.761 max, 0.177 min
    msecs/first-response: 2218.16 mean, 7707.3 max, 632.3 min
    HTTP response codes:
      code 200 -- 6732
    with XCache v1.2.2
    作为php扩展模块
    4371 fetches, 50 max parallel, 9.96732e+06 bytes, in 300.001 seconds
    2280.33 mean bytes/connection
    14.57 fetches/sec, 33224.4 bytes/sec
    msecs/connect: 0.402745 mean, 0.763 max, 0.196 min
    msecs/first-response: 3355.27 mean, 54504.3 max, 576.103 min
    2 timeouts
    25 bad byte counts
    HTTP response codes:
      code 200 -- 4369
    with XCache v1.2.2
    作为php扩展模块
    打开xcache.optimizer = On
    4871 fetches, 50 max parallel, 1.11603e+07 bytes, in 300.001 seconds
    2291.17 mean bytes/connection
    16.2366 fetches/sec, 37200.9 bytes/sec
    msecs/connect: 4.71709 mean, 3000.64 max, 0.152 min
    msecs/first-response: 3047.7 mean, 27066.9 max, 557.86 min
    4 bad byte counts
    HTTP response codes:
      code 200 -- 4871
    with Zend Extension Manager v1.2.2
    with XCache v1.2.2
    作为zend扩展模块
    1583 fetches, 50 max parallel, 3.5877e+06 bytes, in 300 seconds
    2266.39 mean bytes/connection
    5.27667 fetches/sec, 11959 bytes/sec
    msecs/connect: 0.39951 mean, 0.756 max, 0.163 min
    msecs/first-response: 9297.83 mean, 59294.4 max, 502.852 min
    19 bad byte counts
    HTTP response codes:
      code 200 -- 1583

    结果显示eAccelerator无论在速度还是稳定性上都大大超过xcache
    而且在稳定性上大大提高.使用eA基本上没有出现过bad byte counts
    而令人奇怪的就是Zend Optimizer加上eA后反而性能下降
    xcache使用zend扩展模式
    基本等于没有发挥任何作用.
    此次测试没有Optimizer与Xcache的组合
    是由于两者相互冲突.一旦加上Optimizer
    不论是将xcache作为zend扩展还是php扩展
    都会产生问题导致PHP无法执行.
    所以最优的环境是只安装eA,如果你的PHP代码是经过加密的
    很可惜,可能没有只使用EA性能这么好,不过下降的也不多.
    但是比加了Optimizer就无法加载的XCACHE要好

    国外有人也测试了一下eAccelerator和APC
    结果EA的内存占用以及加速效果都好过APC
    Benchmarking APC vs. eAccelerator using Drupal
    另外一篇讲述OP-CACHE的文章
    PHP op-code caches / accelerators: Drupal large site case study

    我们的wordpress博客

    with XCache v1.2.2
    作为zend模块加载
    329 fetches, 50 max parallel, 5.72335e+07 bytes, in 100 seconds
    173962 mean bytes/connection
    3.29 fetches/sec, 572334 bytes/sec
    msecs/connect: 1.09919 mean, 20.231 max, 0.184 min
    msecs/first-response: 13970.3 mean, 23204.4 max, 2489.5 min
    HTTP response codes:
      code 200 -- 329
    with eAccelerator v0.9.5.3
    作为php扩展模块
    366 fetches, 50 max parallel, 6.36701e+07 bytes, in 100.001 seconds
    173962 mean bytes/connection
    3.65997 fetches/sec, 636696 bytes/sec
    msecs/connect: 0.47335 mean, 4.758 max, 0.21 min
    msecs/first-response: 12670.6 mean, 23359.5 max, 1469.66 min
    HTTP response codes

    PS:
    所有的测试都会和参数调优有一定关系.
    不是所有的测试都是准确的
    测试始终会有局限性.
    本例也不例外

    阅读内文 Tags: , , ,

    MySQL优化

    8月 21st, 2008 | 3 Comments | Posted in MySQL < by Johnny Woo >

    thread_concurrency
    数量设置为CPU核心数量的两倍.
    thread_cache_size
    按照内存大小来设置, 1G=8, 2G=16, 3G=32, >3G=64
    wait_timeout
    超时时间,如果连接数比较大,可以减少此参数的值,我使用的是10
    max_connections
    最大连接数,mysql实际允许连接数的值是max_connections+1,按照系统库不同而有不同性能.一般是500~1000,MySQL AB提供的linux静态库可以达到4000.
    query_cache_size
    查询缓冲,默认是0,所以必须打开以提高mysql性能,其本身需要40K来保存结构数据.所以不能设置的太小,初期可以设置成32M,然后根据实际运行情况另行调整
    query_cache_type
    指定查询缓冲的类型,0是关闭,1是缓冲除了使用SELECT SQL_NO_CACHE语句指明了不需要缓冲的数据意外的所有查询,2是只缓冲SELECT SQL_CACHE指定的查询.一般设置为1.
    query_cache_limit
    允许进入查询缓冲区的最小数据大小,默认值是1MB,可以修改的小一点以满足更多查询的需求.但是如果设置的过于小,则会导致很多新的小查询的结果将原有的查询结果交换出去.增加系统的颠簸.

    相关命令
    查询mysql服务器相关状态数据
    >SHOW STATUS;

    查询mysql服务器相关配置选项
    >SHOW VARIABLES;

    整理查询缓冲区里的碎片
    >flush query cache;

    删除查询缓冲区里的所有内容
    >reset query cache;

    设置mysql参数
    >SET GLOBAL;

    查询mysql当前执行的sql语句
    >show processlist;

    变量 含义
    Qcache_queries_in_cache
    在缓存中已注册的查询数目
    Qcache_inserts
    被加入到缓存中的查询数目
    Qcache_hits
    缓存采样数数目
    Qcache_lowmem_prunes
    因为缺少内存而被从缓存中删除的查询数目
    Qcache_not_cached
    没有被缓存的查询数目 (不能被缓存的,或由于 QUERY_CACHE_TYPE)
    Qcache_free_memory
    查询缓存的空闲内存总数
    Qcache_free_blocks
    查询缓存中的空闲内存块的数目
    Qcache_total_blocks
    查询缓存中的块的总数目

    MySQL查询优化
    >SHOW STATUS LIKE ‘Qcache%’;
    查询出Cache状态
    如果Qcache_lowmem_prunes非常大,说明因为内存不足而被交换出cache的数据很多.如果增加内存.可以保证较小的交换次数以及较高的命中率
    例如现在我们查询的结果如下

    | Qcache_free_blocks      | 1234     |
    | Qcache_free_memory      | 25957504 |
    | Qcache_hits             | 55771119 |
    | Qcache_inserts          | 7441153  |
    | Qcache_lowmem_prunes    | 28332    |
    | Qcache_not_cached       | 1233788  |
    | Qcache_queries_in_cache | 4810     |
    | Qcache_total_blocks     | 11038    |

    设置为64M cache内存后
    >set global query_cache_size=67108864;

    | Qcache_free_blocks      | 1        |
    | Qcache_free_memory      | 66623616 |
    | Qcache_hits             | 55788258 |
    | Qcache_inserts          | 7445445  |
    | Qcache_lowmem_prunes    | 28332    |
    | Qcache_not_cached       | 1234057  |
    | Qcache_queries_in_cache | 183      |
    | Qcache_total_blocks     | 392      |

    自由内存块看起来变小了
    是因为现在自由内存块.是一个整块.而以前的内存块都是分散的小块
    而因为重建了cache区
    Qcache_queries_in_cache变量变小了.因为此操作重新建立了cache内存区.所有数据重新缓存
    在运行一两天后我们再看此数据.如果变大了.说明增大cache内存区域是有效的.如果和以前数据差不多
    说明增加的内存并没有实际起到多大的作用.

    有人会觉得如果我将cache内存设置的非常大
    然后将cache_limit设置成0
    那么所有查询都会被缓存了
    理论上是这样.但是一台数据库服务器的查询非常多.
    如果连查询单条数据都要缓存.
    那么内存再大也会不够的.到时候老的内容就会被交换出去
    当cache内存使用满的时候,就会不停的有新查询进来将老查询替换出去.
    这样导致两个结果.一个是内存颠簸.效率反而下降.
    第二个是cache内存的小碎块增多,内存利用率降低
    如果是只有内容很少的小库,并且查询率不高.是可以使用这种方法提高响应速度
    但是如果是实际生产环境,数据量会比较大.还是需要按照最佳比例来配置.
    而不同的应用不同的数据量会有不同的搭配,这点大家不要看网上的优化配置随便的填写
    还是要时时的查看mysql的状态进行调整.即便是这个月调整好的优化参数
    到了下个月业务不同,数据量增加,也会需要调整的.

    阅读内文

    Cacti配置e-mail报警

    8月 20th, 2008 | 10 Comments | Posted in Cacti < by John.Lv >

    一、 软件环境:cacti(需Threshold插件)
    二、 安装过程:
    Cacti的安装各位baidu一下,这里就不详细介绍了。
    安装Threshold插件
    V0.3.9下载地址:http://mirror.cactiusers.org/downloads/plugins/thold-0.3.9.tar.gzv
    安装Threshold插件,只需将解压出来的Thold目录拷贝到cacti/plugins/目录下,并修改cacti配置文件(cacti目录下的include/config.php)。在配置中查找$plugins = array();行,在此行下面加入:

    $plugins[] = 'thold';

    刷新cacti首页,你将看到多出来一个Threshld选项卡。如下所示

    三、 配置过程:
    1.设置Threshold插件:选中console选项卡,在左侧菜单中点击Settings,然后点击Alerting/Thold选项卡


    2.设置发送警报通知:在Default Alerting Options中选择Send notifications
    3.设置出现down机的情况时(即Monitor出现如图所示 )发送警报通知:选择Dead Hosts notifications
    报警邮件范例如下:

    Host Error : 192.168.1.220 (192.168.1.220) is DOWN
    Message : Host did not respond to SNMP           (down机报警)
    Host Notice : 192.168.1.207 (192.168.1.207) returned from DOWN state   (恢复)

    4.设置警报发送纯文本的电子邮件没有图(默认是HTML电子邮件与图表嵌入在电子邮件):选择Send alerts as text
    5.设置周末不执行报警检查:选择Weekend exemptions
    6.设置报警的门槛:Default Trigger Count
    7.设置Emailing Options

    Mail Services:SMTP。(可以选择PHP mail,sendmail,SMTP三种方式)
    From Email Address:按实际设置
    From Name:按需要设置(该处显示的name就是email的发件人姓名)

    8.设置Sendmail Options(Mail Services设置为sendmail需设置此项)

    Sendmail Path:/usr/sbin/sendmail(路径是服务器上Sendmail的,仅用于邮件服务选定为Sendmail)

    9.设置SMTP Options(Mail Services设置SMTP需设置此项)

    SMTP Hostname:SMTP服务器如:mail.test.com
    SMTP Port:25
    SMTP Username: 通过SMTP发送邮件用来验证的用户名,如果你不要求身份验证留空
    SMTP Password:通过SMTP发送邮件用来验证的密码,如果你不要求身份验证留空

    测试:点击Send a Test Email,测试成功如下所示:

    收到的测试邮件范例:

    This is a test message generated from Cacti. This message was sent to test the configuration of your Mail Settings.
    Your email settings are currently set as follows
    Method: SMTP
    Host: mail.ips.com.cn
    Port: 25
    Authenication: true
    Username: john.lv
    Password: (Not Shown for Security Reasons)

    配置完成后别忘记save。
    下面我以磁盘空间报警为例,来设置具体的报警信息(CPU,DISK,服务,网络等等)
    在console选项卡下左侧菜单中点击Threshold Templates 。

    在如下图所示中点击Add按钮来添加一个Threshold模板

    添加磁盘监控的模板,无论是linux还是windows都是使用的Host MIB

    设置按照百分比来监控的,在Data Field选择hdd_percent,可以选择hdd_total,hdd_used,hdd_percent三种

    设置以下信息(参照下图:)
    选择Enabled 激活检查和报警提醒
    High Threshold文本框中填入0.085,意思是当硬盘使用率超过85%时,发送邮件报警。
    Threshold CDEF下拉框选择Divide by 1024,
    Alert E-Mail填入报警的接收邮箱
    完成Threshold模板的添加。

    应用刚才创建的Threshold模板
    在console选项卡下点击Management ->Devices,选择要应用此模板的Host,点击最上面的Create Graphs for this Host链接,然后点击Auto-create thresholds链接来应用刚创建的Threshold模板。

    设置完成后在console选项卡下左侧菜单中点击Thresholds

    在此可以管理已创建的警报,如下:

    点击threshld选项卡可以查看警报的触发情况,如下:

    磁盘报警邮件范例:

    Host: 192.168.1.207 (192.168.1.207)
    URL: http://192.168.1.211/cacti//graph.php?local_graph_id=&rra_id=1
    Message: 192.168.1.207 - Used Space - D: Label:tool [hdd_percent] went
    above threshold of 0.085 with 0.0896

    Ok,磁盘空间的邮件报警就正式配置完成了。

    阅读内文 Tags:

    [转载]RRDTool 中文手册-简易入门(二)

    8月 19th, 2008 | No Comments | Posted in Cacti, RRDTool, 系统监控, 读书笔记 < by Michael Field >

    三、RRD数据库更新实例

      在简易入门(一)中已经介绍过update 命令:它使用1个或多个参数,其格式为: : . 如果你知道可以用一个 N 表示当前的时间,你一定会高兴的。或者你可以用Perl中的 time 函数来指定时间:
      perl: perl -e ‘print time, “\n” ‘
      shell: date +%s
      如何按照固定间隔运行某个程序各操作系统不同。不过可以用伪码来表示:
      - Get the value and put it in variable “$speed”
      - rrdtool update speed.rrd N:$speed

      就这些。每5分钟运行一次上面的脚本。在你想知道图像看起来是啥样时,运行上面的例子。你可以把他们放入一个脚本中。运行此脚本后,查看我们刚才创建的graph。

    四、SNMP相关知识

      我可以想像到只有少数的人能够每5分钟从他们的汽车中读取一次真实的数据。其他人不得不清算其他类型的计数器。你可以测量打印机打印的页数,咖啡机做的咖啡杯数,计算使用的电流的设备,都可以。递增的计数器可以被监视,并且用你已经学会的方法被绘制成图像。稍后我们就能够监视像温度计这样的值了。
      大多数对RRDtool感兴趣的人会使用一个跟踪网络设备传输数据量的计数器。这样我们下一步就来作这个。我们会从解释如何收集数据开始。

      有些人会说有些工具可以帮助你收集数据。他们是对的!不过,我感觉理解这些工具不是必须的非常重要。在你能够确定为什么事情发生了错误,你要知道他们是如何工作的。

      本例中使用的工具在本文档前面非常简短地提到过,它就是所谓的SNMP。它是与联网设备交谈的方式。

    下面用到的工具名为 snmpget ,以下是关于它是如何工作的说明:

    snmpget device password OID

    snmpget -v[version] -c[password] device OID
      对于device, 你要用设备的名称或者IP地址来替换。对于password, 你需要使用SNMP领域中称为 comunity read string 来替换。对于某些设备来说,缺省的 public 可以工作,但是该设置可能会被关闭,调整或者由于安全和机密的原因而被保护起来。请阅读你的设备或程序的文档。

      接下来有一个称为OID的参数,它用来表示 对象标识符 。

      刚开始学习SNMP时,它看起来有些令人困惑。在你看到MIB管理信息基时,就不会那么困难了。MIB是用来描述数据的倒状树,它有只有一个根结点,并且由根结点开始有多个分支。这些分支都以另一个结点终结,他们继续向下分支,如此继续。所以的分支都有一个名称,它们构成了一个我们能够沿着往下的路径。我们所沿着的这些分支都被命名了:iso, org, dod, internet, mgmt 和mib-2.这些名称也可以用数字方式记录,就像 1 3 6 1 2 1。
      iso.org.dod.internet.mgmt.mib-2 (1.3.6.1.2.1)

      有些程序会使用前导点 . , 令人感到许多困惑。在一个OID中并 没有前导点。为了显示OID缩记法和OID完整记法的区别,(通常约定)在使用OID的完整记法时使用前导点。通常这些程序在返回数据给你时,会省略却缺省的部分。这些程序有的有几个缺省前缀,这会让事情显得更加糟糕。
      Ok, lets continue to the start of our OID: we had 1.3.6.1.2.1 From there, we are especially interested in the branch interfaces which has number 2 (e.g., 1.3.6.1.2.1.2 or 1.3.6.1.2.1.interfaces).

      好了,我们继续OID的初步学习:我们有一个1.3.6.1.2.1的OID,我们对(其下面的) interface 分支特别感兴趣,其编号为2(例如:1.3.6.1.2.1.2 或 1.3.6.1.2.1.interface)。

      首先,我们得要有几个SNMP的程序。先看看你的OS平台上是否有已编译好的软件包。这是最便捷的方式。如果没有,你就得下载源代码、并编译。互联网上到处都是源代码、程序。你可以用你喜欢的任何方式、搜索引擎来找到相关的信息。

      假设你已经有了这些程序。先试着收集大多数系统都有的数据。记住:那些引起我们兴趣的树,它上面的部分都有一个简略名。

      在此我会给出一个在Fedora Core 3操作系统上可用的例子。如果对你的操作系统不可用,请查看snmp的手册,并作相应的调整让它能够运行。

    snmpget -v2c -c public myrouter system.sysDescr.0
      该设备应当回应其自身的描述,该描述可能是一个空的。只有在你从某个设备获得响应后,你才能够继续。其中可能需要使用不同的口令、或者不同的设备。
    snmpget -v2c -c public myrouter interfaces.ifNumber.0

      最好你得到的结果是一个数字。如果这样的话,你就可以继续往下,并试试另一个叫做 snmpwalk 的程序。

    snmpwalk -v2c -c public myrouter interfaces.ifTable.ifEntry.ifDescr
      如果该命令返回一系列的接口,这就对了。以下是该命令运行的返回结果的例子:
    [user@host /home/alex]$ snmpwalk -v2c -c public cisco 2.2.1.2
    interfaces.ifTable.ifEntry.ifDescr.1 = "BRI0: B-Channel 1"
    interfaces.ifTable.ifEntry.ifDescr.2 = "BRI0: B-Channel 2"
    interfaces.ifTable.ifEntry.ifDescr.3 = "BRI0" Hex: 42 52 49 30
    interfaces.ifTable.ifEntry.ifDescr.4 = "Ethernet0"
    interfaces.ifTable.ifEntry.ifDescr.5 = "Loopback0"
      对于cisco设备,我想监视 ‘Ethernet0` 接口,从上面的输出结果能够看到该接口的编号是 4。 我试着运行如下命令:
    [user@host /home/alex]$ snmpget -v2c -c public cisco 2.2.1.10.4 2.2.1.16.4

    interfaces.ifTable.ifEntry.ifInOctets.4 = 2290729126
    interfaces.ifTable.ifEntry.ifOutOctets.4 = 1256486519
      这样,我就有两个OID需要监视,他们是(这次使用完整记法):
      1.3.6.1.2.1.2.2.1.10

      1.3.6.1.2.1.2.2.1.16
      这两个OID都有接口编号4。
      别被糊弄了,我可不是试一次就搞定的。我花了一些数据来搞清这些数字都是什么意思。把这些编号转换成描述文字大有帮助… 至少在大家谈论MIB和OID时,你知道他们是什么东西。别忘了接口编号(如果它不是附属接口,就是0),如果用snmpget没有得到响应,试试 snmpwalk。

    五、应用RRDtool的实例

      实际运用的例子
      开始有趣的东东吧。首先,创建一个新的数据库。它包含输入和输出2个计数器的数据。该数据被放入能够进行平均的归档中。他们一次使用1、6、24、或 288个样本。他们同时被存入保存最大数字的归档中。稍后会解释。样本间隔时间为300秒,也就是5分钟,这是一个好的开始。:

      1个样本 “平均” 保留5分钟的周期
      6个样本 每30分钟进行一次平均
      24个样本 每2小时进行一次平均
      288个样本 每1天进行一次平均

      我们试着与MRTG互相兼容,MRTG存储以下数据::

      600 5分钟样本数: 2天和2小时
      600 30分钟样本数: 12.5天
      600 2小时样本数: 50天
      732 1天样本数: 732天

      这些范围被补充进去,因此在数据库中保存的数据总数大约797天。RRDtool存储不同的数据,它不会在 每日 归档停止的地方开始 每周 归档。对于这两个归档,最新的数据会是在 now 附近,因此我们需要比MRTG保存更多的数据!
      我们需要::

      600个5分钟的样本 (2天和2小时)
      700个30分钟的样本 (2天和2小时,加12.5天)
      775个2小时的样本 (上述+50天)
      797个1天的样本 (上述+732天,环型回绕最大797)

    rrdtool create myrouter.rrd \
    DS:input:COUNTER:600:U:U \
    DS:output:COUNTER:600:U:U \
    RRA:AVERAGE:0.5:1:600 \
    RRA:AVERAGE:0.5:6:700 \
    RRA:AVERAGE:0.5:24:775 \
    RRA:AVERAGE:0.5:288:797 \
    RRA:MAX:0.5:1:600 \
    RRA:MAX:0.5:6:700 \
    RRA:MAX:0.5:24:775 \
    RRA:MAX:0.5:288:797

    接下来要做的就是收集数据并把它保存起来。以下是一个例子。它是用伪码写的,你得根据OS调整后让它能够运行。:

    while not the end of the universe
    do
    get result of
    snmpget router community 2.2.1.10.4
    into variable $in
    get result of
    snmpget router community 2.2.1.16.4
    into variable $out

    rrdtool update myrouter.rrd N:$in:$out

    wait for 5 minutes
    done

    在收集了1天的数据后,试着用下面的命令创建图像::

    rrdtool graph myrouter-day.png --start -86400 \
    DEF:inoctets=myrouter.rrd:input:AVERAGE \
    DEF:outoctets=myrouter.rrd:output:AVERAGE \
    AREA:inoctets#00FF00:"In traffic" \
    LINE1:outoctets#0000FF:"Out traffic"

    这会产生一个具有1天流量值的图像。1天有24(小时)x60(分钟)x60(秒)。我们从当前时间-86400秒开始。我们用DEF把输入和输出字节数定义成myrouter.rrd数据库中的的平均值,并且绘制输入流量区和输出流量线。

    阅读内文 Tags: , , ,

    [转载]RRDTool 中文手册-简易入门(一)

    8月 18th, 2008 | No Comments | Posted in Cacti, RRDTool, 系统监控, 读书笔记 < by Michael Field >

    一、简介

      RRDtool是由Tobias Oetiker 编写并由全球各地的许多人贡献的工具。本篇文档的作者是Alex van den Bogaerdt 主要是帮助你理解RRDtool是什么,它能够帮助你作些什么。 RRDtool的文档对于有些人来说过于技术化。本教程帮助你理解RRDtool的基本概念。它为你自学RRDtool的文档做好准备。本文档还重点介绍了网络统计方面的知识。


    1、RRDtool是什么东西?

      RRDtool是指Round Robin Database 工具(环状数据库)。Round robin是一种处理定量数据、以及当前元素指针的技术。想象一个周边标有点的圆环--这些点就是时间存储的位置。从圆心画一条到圆周的某个点的箭头--这就是指针。就像我们在一个圆环上一样,没有起点和终点,你可以一直往下走下去。过来一段时间,所有可用的位置都会被用过,该循环过程会自动重用原来的位置。这样,数据集不会增大,并且不需要维护。RRDtool处理RRD数据库。它用向RRD数据库存储数据、从RRD数据库中提取数据。


    2、RRD中可以存放什么样的数据?

      可以适合时间序列的数据。就是说你必须能够在时间的几个点上度量某些值,并提供这些信息给RRDtool。如果你能够做到这一点,RRDtool就能够存储它们。这些数值必须是数字,但是不一定要是整数,在与MRTG合用时。(下一节会给出更详细的介绍)。
      下面的例子是关于SNMP的,SNMP是简单网络过来协议的缩写。简单是指协议简单--并不表示管理或监视网络简单。读完本篇文档后,你应当能够对人们谈论的SNMP的东西有更多的理解。现在,只要知道SNMP可以用来查询设备中保持的计数器的值就可以了。我们要存放到RRD数据库中的正是这些计数器中的数值。


    3、RRDtool可以用来干什么?

      RRDtool源自MRTG(多路由器流量绘图器)。MRTG是有一个大学连接到互联网链路的使用率的小脚本开始的。MRTG后来被当作绘制其他数据源的工具使用,包括温度、速度、电压、输出量等等。
      很可能你会从使用RRDtool来存储和处理通过SNMP收集到的数据开始。这些数据很可能是某个网络或计算机接收或发送的字节数(比特数)。它也可以用来显示潮水的波浪、阳光射线、电力消耗、展会的参观人员、机场附近的噪音等级、你喜欢的度假区的温度、电冰箱的温度、以及任何你可以想象的东西。
      你最需要一个度量数据,以及能够提供这些数据给RRDtool的感应器就可以了。RRDtool会让你创建数据库、存储数据、提取数据、创建用于在Web浏览器中显示的PNG格式的图像。这些PNG图像以来于你收集的数据,它可以是网络平均使用率、峰值。


    4、问题探讨

      首先:再读一遍!你可能漏了某些地方。如果你无法编译源代码,而且你的操作系统相当普遍,很可能不是RRDtool的错误。互联网上有已经编译好的版本。如果来自可信赖的网站,就下载一个。
      另一种情况是程序能够工作,但是没有得到预期的结果,可能是配置方面的问题。检查你的配置,与后面例子的配置比较一下。
      RRDtool有一个邮件列表及其归档。读一下几周的列表并搜索归档。没有搜索过归档就提问是很粗鲁的做法:你遇到的问题可能已经由其他人解决了!尽管不是全部,大多数问题都会这样,邮件列表不是经济为了某个参与者服务的。看看RRDtool的文档了解邮件列表的位置和使用方法。
      我建议你马上就花点时间订阅邮件列表,只要发送一封主题为 subscribe 的邮件到 rrd-user-request@list.ee.ethz.ch 就可以了。如果要退定该邮件列表,只需要发送主题为 unsubscribe 到同样的地址即可。


    二、学习实例
    1、第一个RRD数据库

      在我看来,学习某个东西的最好办法就是实践。为什么现在不开始呢?我们会创建一个数据库,放一些数值到它里面,然后提取这些数据。你的输出应当与本文档中的输出是一样的。
      我们会从一些简单的入手,然后把汽车与路由器比较,或者将公里和比特、字节数比较。他们都是一样的:都是某些时段的某些数值。
      假设我们有一个向互联网发送数据和接收数据的设备。该设备保留一个计数器,该计数器在开启设备时设置为0,并在每传送一个字节就加1。该计数器可能会有一个最大值。如果该值达到最大时,在加一个字节的计数,该计数器就会再次从0开始。这与世界上的许多计数器都是一样的,比如车辆上的里程计数器。
      关于网络的讨论通常用每秒比特数来衡量,因此我们要习惯这种用法。把一个字节看成是8个比特,并且开始用比特而不是字节来思考问题。不过,计数器仍然用字节数为单位来计量!在SNMP世界里,大部分的计数器都是32比特的。这就意味着他们计数范围是0-4294967。我们在例子里会用到这些数值。该设备在被查询时,会返回计数器的当前值。我们知道从上次查询设备开始到现在的时间,因此我们现在就知道每秒 平均传输了多少字节数。这不难计算。首先用文字来描述,然后计算:

    用当前查询到的计数器值,减去上一次查询的计数器值
    把当前查询时间和上次查询时间作上述同样操作(秒)
    将(1)的结果除以(2)的结果,得到的结果就是每秒的字节数。乘以8就得到每秒的比特数(bps)

  • 实例一
    • 你现在正在开车。12:05时你看了一下仪表盘上的里程计数器,它显示这俩车已经行驶了12345公里。12:10分时,你有看了一下里程计数器,它显示 12357公里。这表示你在5分钟内行驶了12公里。科技人员会把它转换成米/秒,这样可以更好的进行比较(每5分钟的字节数)和(每秒比特数)。
      我们行驶了12公里,也就是12000米。我们在5分钟内,或者说是300秒内完成。我们的速度是1200米/300秒,或者说是40米/秒。
      我们可以用公里/小时来计算速度:12乘以5分钟就是一个小时,因此我们必须把12公里乘以12得到144公里/小时。对于和我一样说英语的朋友来说,就是90英里/小时,因此不要在家里或我生活的地方尝试这个速度 :)
      记住:这些数值都仅仅是平均值。如果无法从数字中得到你是否以固定的速度在行驶。本教程后面有一个例子说明这个问题。我希望你理解在计算米/秒或者比特/秒。唯一的差别在于收集数据的方式。即使是K这个单位也是一样的,因为在网络术语中,K同样表示1000。
      我们现在要创建一个数据库,在此数据库中我们能够保存所有这些有趣的数字。启动这个程序的方法可能在各个操作系统上各不相同,但是我假设你可以搞清楚它是否与你的操作系统不同,键入下面的行作为一个长长的行(为了可读性,我得把他分成几行)并且用 \ 来分割。
    rrdtool create test.rrd \
    --start 920804400 \
    DS:speed:COUNTER:600:U:U \
    RRA:AVERAGE:0.5:1:24 \
    RRA:AVERAGE:0.5:6:10


    2、创建了什么东西?

      我们创建的rrd数据库名为test (test.rrd),它的起始时间是我写这篇文档的当天下午,也就是1999年3月7日(该日期转换成920804400秒)。我们的数据库存放一个名为 ’speed’ 的数据源(DS),它表示一个计数器。该计数器每5分钟(缺省)读取一次。在同一个数据库中,保存有2个环状归档(RRA),一个是每次读取时的平均数据(例如:没有东西进行平均)并保留24个样本(24乘以5分钟是2小时)。另一个RRA有6个平均值(半小时)并包含10个这样的平均值(例如5个小时)。

      RRDtool使用来源于UNIX世界的特殊时间戳。该时间戳是自1979年1月1日UTC时间开始到当前逝去的秒数。该时间戳的值被转换成本地时间,它在不同的时区会不一样。
      可能你不是和我在地球的同一个地方。这就是说时区不同。在所有的例子中,我所说的时间当中,小时可能对你来说是错误的。这对这些例子中的结果有一点影响,在阅读时,只需要修正时间中的小时即可。例如:我看到 12:05 的话,在英国的家伙看到的时间就是 11:05 。

    现在我们得向数据库中填入一些数字。我们希望读到以下数据:
    12:05 12345 KM
    12:10 12357 KM
    12:15 12363 KM
    12:20 12363 KM
    12:25 12363 KM
    12:30 12373 KM
    12:35 12383 KM
    12:40 12393 KM
    12:45 12399 KM
    12:50 12405 KM
    12:55 12411 KM
    13:00 12415 KM
    13:05 12420 KM
    13:10 12422 KM
    13:15 12423 KM

  • 我们用下面的命令把上述数据填入数据库:
  • rrdtool update test.rrd 920804700:12345 920805000:12357 920805300:12363
    rrdtool update test.rrd 920805600:12363 920805900:12363 920806200:12373
    rrdtool update test.rrd 920806500:12383 920806800:12393 920807100:12399
    rrdtool update test.rrd 920807400:12405 920807700:12411 920808000:12415
    rrdtool update test.rrd 920808300:12420 920808600:12422 920808900:12423

    正如你说看到的那样,可以在一个命令里向数据库中填入多个值。为了可读性,我得只用三个数据,实际一行里运行的最大数据与操作系统相关。
    我们可以使用 rrdtool fetch 命令从数据库中提取数据。

    rrdtool fetch test.rrd AVERAGE --start 920804400 --end 920809200
      该命令会返回如下输出结果:
      speed

      920804700: nan
      920805000: 4.0000000000e-02
      920805300: 2.0000000000e-02
      920805600: 0.0000000000e+00
      920805900: 0.0000000000e+00
      920806200: 3.3333333333e-02
      920806500: 3.3333333333e-02
      920806800: 3.3333333333e-02
      920807100: 2.0000000000e-02
      920807400: 2.0000000000e-02
      920807700: 2.0000000000e-02
      920808000: 1.3333333333e-02
      920808300: 1.6666666667e-02
      920808600: 6.6666666667e-03
      920808900: 3.3333333333e-03
      920809200: nan
      如果不是像上面的输出结果,可能哪里有错误。也许你的操作系统会打印出不同的格式 NaN 。 NaN 表示 非数字 。 如果你的操作系统输出 U 或 UNKN 或者其他类似东西都是正常的。如果其他地方错误,可能是因为你的过程中的那些步骤出错了(当然假设我的教程是完全正确的 :-))。这样的话,删除数据库文件然后再重新尝试。 有时事情就会变化。本例哟难道的数据像 0.04 而不是 4.0000e-02 。这些实际上是一样的数字,只是写法不同而已。如果rrdtool今后的版本显示略有不同是输出也不要大惊小怪。本文档中的例子对于RRDtool 1.2.0版本都是正确的。


    3、绘第一张图

    建几个图示的时候到了,试试下面的命令:

    rrdtool graph speed.png \
    --start 920804400 --end 920808000 \
    DEF:myspeed=test.rrd:speed:AVERAGE \
    LINE2:myspeed#FF0000

  • 如图一

    • 该命令会创建名为speed.png的图像文件,该图像从12:00开始,到13:00。有一个名为myspeed的变量定义,它使用来自 test.rrd数据库的 speed RRA中的数据。绘制的线条是2像素高,表示myspeed变量。颜色是红色的.
      你会注意到图像的起始不是12:00而是12:05。这是因为在此时间之前的数据不够计算出平均值。这只会在缺少某些样本的情况下发生,不会经常发生。
      颜色是由红、绿、蓝构成的。对每种颜色成分,你可以用16进制来表示使用多少,其中00表示不包含,FF表示完全包含。白色是由红、绿、蓝组成的:FFFFFF。黑色是全部不包含:000000。


    4、用几种数学方法来绘图

      查看图像时,你会注意到横轴下标为 12:10、12:20、12:30、12:40、12:59。有时某些下标不适合(可能是12:00和13:00)会被忽略掉。
      纵轴显示我们输入的范围。下面提供的公里数,以及除以300妙的结果,我们得到非常小的数值。为了更加精确,第一个值是12(12567-12456),除以300后得到0.04,RRDtool显示时为 40m 表示 40/1000 。 其中的 m 与米、公里、或者毫米都没有任何关系!RRDtool不知道我们的数据单位,它只处理没有单位的数据。
      如果我们用米来衡量我们的距离,就会是这样:(12′357′000-12′345′000)/300 = 12′000/300 = 40.
      因为许多人都对这样的数值范围感觉更好,我们就来修正一下。我们将重新创建数据库,并存储正确的数据。但是有更好的办法:在创建png文件时进行一些计算!
    rrdtool graph speed2.png \
    --start 920804400 --end 920808000 \
    --vertical-label m/s \
    DEF:myspeed=test.rrd:speed:AVERAGE \
    CDEF:realspeed=myspeed,1000,\* \
    LINE2:realspeed#FF0000

  • 如图二


  • 注意:不要忘记操作符 * 后面的 。这个反斜杆用来将*从操作系统可能解释的符号转义,而不是直接传递给rrdtool命令。
    在查看PNG文件后,你会注意到 m 不见了。正确的结果就是这样。同样,在图像中加入了一个标注。出了上面提到的几点外,PNG看起来应当是一样的。

      计算是在CDEF部分中指定的,使用逆波兰表达式( RPN )表示的。我们要求RRDtool所作的事情是:`取数据源myspeed, 以及数值1000;把他们相乘` 。在此不要被RPN表达式困扰了,后面会详细介绍。同时,你可能想读一读关于CDEF的教程。以及Steve Rader的RPN表达式的教程。不过哦首先看我这篇教程吧。
      如果我们用1000乘以这些数值,显示把同样的数据显示成公里/小时也是可以的。
      要修改米/秒为单位的值:
      计算米/小时: value * 3′600
      计算公里/小时: value / 1′000
      合起来: value * (3′600/1′000) 或者 value * 3.6

    下面我们来创建这个PNG文件,并加入更多的魔幻功能…

    rrdtool graph speed3.png \
    --start 920804400 --end 920808000 \
    --vertical-label km/h \
    DEF:myspeed=test.rrd:speed:AVERAGE \
    "CDEF:kmh=myspeed,3600,*" \
    CDEF:fast=kmh,100,GT,kmh,0,IF \
    CDEF:good=kmh,100,GT,0,kmh,IF \
    HRULE:100#0000FF:"Maximum allowed" \
    AREA:good#00FF00:"Good speed" \
    AREA:fast#FF0000:"Too fast"

  • 如图三


  • 这个图像看起来更好。速度用KM/H表示,有一个附加的线条表示最大允许的速度(在我行驶的道路上的最大限速)。我还修改了速度的显示颜色,把它从线条改为区块。


    5、一个更复杂的图例

      现在计算更加复杂一些。对于在限速内的速度衡量方法是:
      检查公里/小时是否大于100 ( kmh,100 ) GT
      如果是,返回0,否则返回公里/小时。 ((( kmh,100 ) GT ), 0, kmh) IF

      对于上述的限速值:
      检查公里/小时是否大于100 ( kmh,100 ) GT
      如果是,返回公里/小时,否则返回0。 ((( kmh,100) GT ), kmh, 0) IF

    我愿意相信RRDtool的绘图功能能够处理的数据没有任何虚拟的限制。我会解释他们是如何工作的,不过看看下面的PNG图像:

    rrdtool graph speed4.png \
    --start 920804400 --end 920808000 \
    --vertical-label km/h \
    DEF:myspeed=test.rrd:speed:AVERAGE \
    "CDEF:kmh=myspeed,3600,*" \
    CDEF:fast=kmh,100,GT,100,0,IF \
    CDEF:over=kmh,100,GT,kmh,100,-,0,IF \
    CDEF:good=kmh,100,GT,0,kmh,IF \
    HRULE:100#0000FF:"Maximum allowed" \
    AREA:good#00FF00:"Good speed" \
    AREA:fast#550000:"Too fast" \
    STACK:over#FF0000:"Over speed"

  • 如图四

  • 第一部分完
    本文从网上转载,本人重新整理和附图,出处未考证。

    阅读内文 Tags: , , ,

    大量连接数导致iptables报错ip_conntrack: table full, dropping packet.

    8月 15th, 2008 | 8 Comments | Posted in iptables < by Johnny Woo >

    这个问题更多出现在使用linux作为NAT服务器的环境中
    默认ip_conntrack模块默认的链接时间是5天
    导致大量链接后很容易超过记录表的大小

    /etc/sysctrl.conf
    net.ipv4.ip_conntrack_max = 81920
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 1500

    阅读内文

    RRDTool 快速学习-思维导图

    8月 14th, 2008 | 18 Comments | Posted in RRDTool, 思维导图 < by Michael Field >

    最近研究了RRDTool,边学边做了笔记;
    参考网址:
    RRD doc
    大作 rrdtool (像 mrtg 的東東) 完全攻略
    画了这张导图,虽然没有涵盖所有的内容,但基本常用的都加入进去了;
    学习rrdtool还是要靠多多实践,反复练习;
    这张图只能给大家一个快速记忆和简单介绍;

    如果需要导图源文件下载;请留言并留下邮箱地址我会发给大家。
    RRDTool 快速学习:

    阅读内文 Tags: , , , , , ,

    squid 2.6 round-robin分发后无法限制域名

    8月 14th, 2008 | No Comments | Posted in Squid < by Johnny Woo >

    原有的配置文件如下

    cache_peer 10.11.12.51 parent 80 0 no-query originserver round-robin name=web1
    cache_peer 10.11.12.52 parent 80 0 no-query originserver round-robin name=web2
    cache_peer 10.11.12.53 parent 80 0 no-query originserver round-robin name=web3
    cache_peer 10.11.12.54 parent 80 0 no-query originserver round-robin name=web4
    cache_peer 10.11.12.160 parent 80 0 no-query originserver name=content
    cache_peer 10.11.12.150 parent 80 0 no-query originserver name=bbs
    cache_peer 172.16.10.140 parent 80 0 no-query originserver round-robin name=game1
    cache_peer 172.16.10.141 parent 80 0 no-query originserver round-robin name=game2

    cache_peer_domain contentchina content.web.com
    cache_peer_domain bbs  bbs.web.com
    cache_peer_domain game1 game2 game.web.com
    cache_peer_domain web1 web2 web3 web4  .web.com
    cache_peer_domain web1 web2 web3 web4   web.com

    设定不同的二级域名分发到不同的服务器上.
    www.web.com能够正确访问.
    查看后台链接.每次访问时squid也会正常去连parent服务器,每次都轮询访问
    测试game.web.com
    返回有很多内容都是404
    但是单独访问140以及141都是没有问题
    然后发现很多链接分发到了其他web服务器上
    看了说明.里面提到round-robin参数会设置一组随机的访问
    感觉是写了round-robin的都是一个组
    所以将game的去掉round-robin参数

    cache_peer 172.16.10.140 parent 80 0 no-query originserver name=game1
    cache_peer 172.16.10.141 parent 80 0 no-query originserver name=game2

    访问后仍旧发现还是有分发错误的情况
    再次查看squid.conf.default
    里面的cache_peer_domain的语法如下

    #       cache_peer_domain cache-host domain [domain ...]
    #       cache_peer_domain cache-host !domain

    感觉是否是因为cache-host这里只能写一台服务器而非一组的关系
    随将配置文件修改

    cache_peer 10.11.12.51 parent 80 0 no-query originserver round-robin name=web1
    cache_peer 10.11.12.52 parent 80 0 no-query originserver round-robin name=web2
    cache_peer 10.11.12.53 parent 80 0 no-query originserver round-robin name=web3
    cache_peer 10.11.12.54 parent 80 0 no-query originserver round-robin name=web4
    cache_peer 10.11.12.160 parent 80 0 no-query originserver name=content
    cache_peer 10.11.12.150 parent 80 0 no-query originserver name=bbs
    cache_peer 172.16.10.140 parent 80 0 no-query originserver round-robin name=game1
    cache_peer 172.16.10.141 parent 80 0 no-query originserver round-robin name=game2

    cache_peer_domain contentchina content.web.com
    cache_peer_domain bbs  bbs.web.com
    cache_peer_domain game1 game.web.com
    cache_peer_domain game2 game.web.com
    cache_peer_domain web1 .web.com
    cache_peer_domain web2 .web.com
    cache_peer_domain web3 .web.com
    cache_peer_domain web4 .web.com
    cache_peer_domain web1 web.com
    cache_peer_domain web2 web.com
    cache_peer_domain web3 web.com
    cache_peer_domain web4 web.com

    修改后访问game.web.com
    问题解决.没有出现404
    后台的分发很正常
    可能由于cache-host这里写了一组
    导致squid并无法辨识进行针对性的分发
    随即将所有的分发都分发到所有round-robin服务器上.
    因为www.web.com后端的服务器较多.命中的概率较大.
    而命中后第二次取出文件即是squid中的缓存文件,所以访问www.web.com时没有发现问题
    而game.web.com因为真实服务器比例较小
    分发时很多链接分发到其他web服务器.
    导致反馈回很多404

    阅读内文 Tags: ,

    Solarwinds实现MSN报警

    8月 13th, 2008 | No Comments | Posted in 系统监控 < by John.Lv >

    一,软件环境
    Solarwinds+msn机器人(msn机器人安装在支持apache+php的环境)
    二,msn机器人下载地址及安装方法见
    系统监控:msn在线机器人实时报警
    三,配置过程
    1. Solarwinds报警配置磁盘空间监控
    1
    在上图中的Configure Alerts中新建报警DiskStatus,按照你的需要配置监控的服务器,报警的条件,监控的周期等,然后按照下图配置满足报警要求后的Action
    2

    按照上图添加2个Alert Action
    Alert Action 1:log the alert to a file将报警保存为alter.log(可随意指定文件名和目录)
    Alert Action 2:Execute an external VBScript指定要执行的VbScript,请将VbScript放在fetion的安装目录下,因为下面的VbScript指定的路径是相对路径
    备注:请一定要先设置报警保存的log,然后在设置要执行的VbScript,因为只有先生成log,然后在执行VbScript读取log中的短信报警信息,设置好后如下图:
    3
    配置生效后应该先生成log然后执行VBScript发送短信

    2.Log样本如下:

    Alert: Percent Space Used of 100.121-D:\ is now 84 %
    Alert: Percent Space Used of 100.102-C:\ is now 82 %

    3. VBScript如下:

    '本脚本有john.lv编写
    logfile="G:\LibFetion\install\alert.log"   '定义报警log请输入Solarwinds中的log设置
    sendmsn="lvming104@hotmail.com" '定义msn接收人信息,需在你MSN好友列表中
    Set objFS = CreateObject ("Scripting.FileSystemObject")
    Dim arrFileLines()
    i = 0
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFile = objFSO.OpenTextFile(logfile, 1)  '读取报警log全部信息
    Do Until objFile.AtEndOfStream
         Redim Preserve arrFileLines(i)
         arrFileLines(i) = objFile.ReadLine
         i = i + 1
    Loop
    objFile.Close
    l = Ubound(arrFileLines) '读取报警log最后一行,因为最近的报警信息永远是最后一行
    mess=arrFileLines(l) '定义要发送的信息

    Set objExplorer = CreateObject("InternetExplorer.Application")
    '通过sendMsg发送信息,本人的sendMsg是安装在另外一台server上sendMsg这个目录下,如果安装在本地把http://192.168.1.211/sendMsg/send.php?改为http://localhost/sendMsg/send.php?
    objExplorer.Navigate "http://192.168.1.211/sendMsg/send.php?msnaddr="&sendmsn&"&message="&chr(34)&mess&chr(34)

    4.编写http://192.168.1.211/sendMsg/send.php

    #!/usr/bin/php
    <?
    $msnaddr = $_GET['msnaddr'];
    $messages = $_GET['message'];
    include('sendMsg.php');
    $sendMsg = new sendMsg();
    #login sendMsg with user:test@live.cn and passwd:123456
    $sendMsg->login('test@live.cn', '123456');
    #who will receive message
    $sendMsg->createSession($msnaddr);
    #send message With a custom font and color
    $sendMsg->sendMessage($messages, 'Times New Roman', '008000');
    ?>

    保存为send.php
    备注:由于监控的机器不多,而且报警的条件也比较高,所有报警次数比较少,生成的log就比较小,如果每天生成的log很大,建议log每天生成,增加日期变量即可

    阅读内文 Tags:

    飞信机器人实现命令式互动(以Linux版本为例)

    8月 13th, 2008 | 2 Comments | Posted in 短信 < by John.Lv >

    使用软件:飞信机器人

    飞信机器人下载及安装方法详见

    http://www.hiadmin.com/%e7%b3%bb%e7%bb%9f%e7%9b%91%e6%8e%a7%ef%bc%9alinux%e5%91%bd%e4%bb%a4%e8%a1%8c-%e9%a3%9e%e4%bf%a1%e5%ae%a2%e6%88%b7%e7%ab%af%e5%8f%91%e9%80%81%e5%85%8d%e8%b4%b9%e6%8a%a5%e8%ad%a6%e7%9f%ad%e4%bf%a1/

    修改fetion安装目录下plugins中的plugin_message

    ?

    #!/bin/bash
    ?? # $1:? fetion_account
    ?? # $2:? message
    ?? # Plus Description:
    ?? # When a new message arrival, the system will call this plug-in:
    ?? buddy=$1
    ?? message=$2
    ?? admin="135xxxxxxxx"? #Only accept instructions sent admin
    ?? # message A Show disk space
    ?? if [[ "$message" = "A" && "$buddy" = "$admin" ]] ;then
    ??????? df -h
    ??????? sendback="you send command A"
    ?? # message B show network connections
    ?? elif [[ "$message" = "B" && "$buddy" = "$admin" ]];then
    ??????? netstat -an | wc -l
    ??????? sendback="you send command B"
    ?? # message C run shell script
    ?? elif [[ "$message" = "C" && "$buddy" = "$admin" ]];then
    ??????? /root/sendMsg/1.sh
    ??????? sendback="you send command C"
    ?? # message D only send message
    ?? elif [[ "$message" = "D" && "$buddy" = "$admin" ]];then
    ??????? sendback="you send command D"
    ?? # other send not accept
    ?? elif [ "$buddy" = "$admin" ];then
    ??????? sendbac="you send command $message。command does not accept"
    ?? else
    ??????? sendback="you can not send comman"
    ?? fi
    ?? #send message $sendback
    ?? cmd="sms $buddy $sendback"
    ?? echo $cmd

    ?保存退出

    下面进行测试
    测试帐号:13713718888
    密码:123456 (如果密码中含有特殊字符,请使用单引号)
    ./fetion -u 13713718888 -p 123456 -EN

    发送信息给135xxxxxxxx
    sms 135xxxxxxxx “show me the command”

    如果135xxxxxxxx回复短信,将自动调用插件plugin_message
    如果135xxxxxxxx 回复 A 执行查看磁盘空间的命令并回复message
    如果135xxxxxxxx 回复 B 执行统计网络连接数并回复message
    如果135xxxxxxxx 回复 C 执行一个shell脚本并回复message
    如果135xxxxxxxx 回复 D 只回复message
    如果135xxxxxxxx 回复 其它 回复错误指令的信息
    如果不是135xxxxxxxx 回复的信息即使是正确指令也不予执行
    其中A,B,C,D可以任意指定激活执行命令或者脚本的条件,通过短信回复可以使机器人执行命令,脚本,程序,回复信息等任意操作。

    阅读内文 Tags:

    Mysql数据库索引查询优化的分享

    8月 11th, 2008 | 10 Comments | Posted in MySQL < by Michael Field >

    问题描述:
    我们要访问的表是一个非常大的表,四千万条记录,id是主键,program_id上建了索引。
    执行一条SQL:

    select * from program_access_log where program_id between 1 and 4000

    这条SQL非常慢。
    我们原以为处理记录太多的原因,所以加了id限制,一次只读五十万条记录

    select * from program_access_log where id between 1 and 500000 and program_id between 1 and 4000

    但是这条SQL仍然很慢,速度比上面一条几乎没有提升。
    Mysql处理50万条记录的表,条件字段还建了索引,这条语句应该是瞬间完成的。

    问题分析:
    这张表大约容量30G,数据库服务器内存16G,无法一次载入。就是这个造成了问题。
    这条SQL有两个条件,ID一到五十万和Program_id一到四千,因为program_id范围小得多,mysql选择它做为主要索引。
    先通过索引文件找出了所有program_id在1到4000范围里所有的id,这个过程非常快。
    接下来要通过这些id找出表里的记录,由于这些id是离散的,所以mysql对这个表的访问不是顺序读取。
    而这个表又非常大,无法一次装入内存,所以每访问一条记录mysql都要重新在磁盘上定位并把附近的记录都载入内存,大量的IO操作导致了速度的下降。

    问题解决方案:
    1. 以program_id为条件对表进行分区
    2. 分表处理,每张表的大小不超过内存的大小
    然而,服务器用的是mysql5.0,不支持分区,而且这个表是公共表,无法在不影响其它项目的条件下修改表的结构。
    所以我们采取了第三种办法:

    select * from program_access_log where id between 1 and 500000 and program_id between 1 and 15000000

    现在program_id的范围远大于id的范围,id被当做主要索引进行查找,由于id是主键,所以查找的是连续50万条记录,速度和访问一个50万条记录的表基本一样

    总结:
    这是一个在千万笔记录表中由于使用了索引导致了数据查找变慢的问题,有一定的典型性和大家交流下!

    阅读内文 Tags: , , ,

    cacti数据备份与迁移

    8月 8th, 2008 | No Comments | Posted in 1.系统服务, Cacti < by Michael Field >

    原来的监控服务器因为是在电信机房的所以很多网通的被监控主机有很多timeout,而且随着被监控服务器的不断增加存在问题也越来越显著。

    一、工作流
    安装mysql;php;apache;rrdtool后;
    将cacti目录tarball后,复制到双线机房新监控服务器上解压;
    cactid目录tarball后,复制到双线机房新监控服务器上解压;
    mysql数据库dump或者tarball后,复制到双线机房新监控服务器上解压;

    #mysqldump -p cacti >cacti.sql

    重新赋予cactiuser对于数据库cacti所有权限;

    grant all on cacti.* to cactiuser@localhost identified by 'cactipassword';

    二、故障发生
    打开cacti可以正常登录和控制,检查graph management,打开所有的图无显示;于是打开debug模式:
    *Turn On Graph Debug Mode.

    RRDTool Says:
        ERROR: This RRD was created on other architecture

    三、解决方案
    google、baidu了一下,发生这个问题的原因是因为所有rrd库需要全部重新dump和restore一次;
    好了上脚本:
    从老的cacti服务器上dump所有的rrd文件为xml file,共计9K多张:

    #!/bin/sh

    rrddump="/usr/bin/rrdtool dump"
    xmldir=/tmp/rraxml

    for file in `find /var/www/html/cacti/rra/ -mtime -2 |awk -F\/ '{print $NF}'`
    #遍历rra目录,查找近2天修改过的rrd文件;
      do
        ${rrddump} ${file} > ${xmldir}/${file}.xml
      done

    tar走rraxml目录到新监控服务器上解压:restore脚本如下:

    #!/bin/sh
    rrdrestore="/usr/bin/rrdtool restore"
    xmldir=/tmp/rraxml/
    for file in `find ${xmldir} |awk -F\/ '{print $NF}' |sed s/.xml//g`
    #遍历xml目录,并去掉xml后缀,直接还原到rra目录下
      do
        ${rrdrestore} ${xmldir}${file}.xml /cacti/rra/${file}
      done
    chown cactiuser:cactiuser /cacti/rra -R

    完成后,再次打开cacti监控显示正常;迁移成功;
    用这个方法其实是用来备份rra的,这次正好顺便备份一下;

    阅读内文 Tags: , , ,

    cacti进阶应用三: IDC 质量监控-评估节点的网络品质

    8月 8th, 2008 | 2 Comments | Posted in 1.系统服务, Cacti < by Michael Field >

    一、实际需求
    公司租用多个idc机房,为了实时的和历史的查看idc网络状态,记录该节点的网络流量和做分析统计使用,都具有许多现实意义;
    比如:该机房的总出口带宽,当前总在线人数,平均每个客户端的下载速度(各地速度不同这里指的是平均速率),带宽使用率等等,依此来评估该机房是否能达到当初的预测效果。
    实际效果如下图所示:数据仅为举例使用;

    各个IDC数据如下图:

    其中:
    - tcp est connections是所有机房连接数总计;
    - download speed是每个连接的下载速度;
    - Total outbound是所有服务器对外提供服务器的带宽总计;
    - boundwidth used是总租用带宽除以当前流量的带宽使用率;
    - this node boundwidth是该节点租用的带宽数;
    目的:
    可以实时的掌握idc机房总体信息;
    可以历史的查询过去时间段内的局部信息;
    可以对机房的网络质量做出及时判断;
    可以针对每个机房的网络情况作出及时的调整;
    以下我来谈一下具体实现(方法各有不同,达到效果即可,欢迎提供技术交流):

    二、数据采集
    1、tcp est connections汇总方法:
    我提供的方法是在每台机器上部署snmp自定义脚本指定独立的oid传送给监控服务器:
    详细参考我之前写的:Cacti进阶引用二:使用cacti获取snmp发送的自定义信息后作图
    脚本原理:使用snmpwalk oid得到每个idc机房所有服务器的establish 连接数,进行汇总累加;
    2、total outbound汇总计算:
    方法一:使用rrdtool fetch(推荐使用)
    指令如下:

    #rrdtool fetch xxhost_traffic.rrd -s -10m AVERAGE |sed -n 3p |awk '{printf "traffic_out: %.f KB tarffic_in: %.f KB\n", $2/1024,$3/1024}'
    traffic_out: 13569 KB tarffic_in: 354 KB

    说明:我这里取得数值是10分钟前的流量,这是为了避免和cacti每5分钟取值产生冲突,也能保证取值准确;
    fetch取值都是科学计数,这里用printf进行来还原为可读的数值。(要和谐一下!)
    方法二:使用snmpwalk取流量值(不推荐使用,大家了解一下)
    指令如下:

    #snmpwalk -v2c -c public 127.0.0.1 .1.3.6.1.2.1.31.1.1.1.10
    说明:oid指的是ifHCOutOctets = Counter64的数值(snmp v2c 64bit解决溢出问题),需要在5分钟之后再取一次,然后将后一次的数据减去5分钟前的数据,得出的就是这5分钟内的流量;

    方法三:本地ifconfig取流量,方法与snmpwalk有相似之处:

    #ifconfig eth0 |grep "TX bytes" |awk '{print $6}' |cut -c 7-
    说明:其中RX为接受bytes数,TX为发送bytes数,如果取traffic out数据(即提供服务的数据),就上面的指令;同时也需要每5分钟取值一次然后相减,得出每5分钟的流量;可以在本地写脚本,用snmp传送到监控服务器;

    3、带宽使用率和下载速度(即每个连接的平均速度)计算
    带宽使用率=当前使用带宽 / 租用总带宽
    下载速度=当前使用带宽 / 总连接数

    4、汇总数据到文本:
    文本的内容和格式如下:

    xiantao,links: 3087,speed: 349.6262,bw: 1054,bound: 2048,bw_percent: 51%
    datong,links: 2332,speed: 968.2333,bw: 2205,bound: 4096,bw_percent: 53%
    nantong,links: 4279,speed: 598.0313,bw: 2499,bound: 4096,bw_percent: 61%
    Total,links: 153610.0,speed: 607.8250,bw: 87278.0,bound: 112640.0,bw_percent: 76%
    说明:以上数据为举例,total行中的数据应该为全部idc的总和(当前流量和总租用带宽)或者平均(下载速度、带宽使用率),%符号和单位都可以不用添加我们可以在cacti中设定;

    5、cacti取值脚本
    内容如下:

    #!/bin/sh
    workfile=result.txt #汇总数据的文本
    node=$1
    if [ -f $workfile ] && [ ! -z $node ];then
      echo -n `cat $workfile |grep -i $node |awk -F, '{print $2" "$3" "$4" "$6" "$5}' |sed s/": "/:/g |sed s/"%"//g`
    else
      echo -n "links:0 speed:0 bw:0 bw_percent:0 bound: 0"
    fi

    输出格式:

    links:6369 speed:460.3096 bw:2863 bw_percent:69.8 bound:4096

    三、创建cacti作图模板
    完成以上步骤,就可以在cacti中创建相应的模板啦,为我们辛苦取到的数据画图:
    1、登录cacti点击左侧菜单的data input motheds -> add
    如图:

    说明:设定如图所示,input string这里要在我们上面写的取值脚本后面跟,因为脚本后面要跟一个行参;Allow Empty Input的checkbox勾选;
    2、设定这个的input fields属性
    如图:

    说明:这里Special Type Code我们取主机名即 hostname,这样cacti就会知道是取devices name值;因为我们后面要创建host templates,然后再创建graph的时候把这个值赋给脚本;
    3、设定output fields属性
    就是我们脚本输出的5个数据;以bound举例,其他相同,如图:

    说明:依次创建5个数据的output fields,第一列的name必须与脚本输出的名字相同,最后点击save保存;
    4、创建data templates模板
    如图:


    说明:
    Data Source Item依次创建刚才输出的5个output fields这里的下拉菜单就是我们data input methods设定选择和你创建的Internal Data Source Name一一对应不能出错;
    Maximum Value这里设定尽量高些,免得出现溢出无法出图;
    Custom Data无需设定,其他全部默认;这里有个问题就是你每完成一个就要先点击save,否则会丢失之前修改的内容;
    5、创建graph templates模板,点击graph templates->add
    如图:


    说明:Vertical Label 这里是纵坐标名字可以填一个node status什么的随你喜欢,其他可以全部默认;
    Graph Template Items -> add 以TCP EST Connections为例:
    如图:

    说明:
    Data Source 下拉菜单选择之前我们在data templates里面创建的links一栏
    color自行选择(一定要选)
    Opacity/Alpha Channel cacti0.8.7新增默认就好;
    Graph Item Type 选择AREA(就是图的类型,AREA指的是区块表示,STACK是在原来区块上堆叠区块)
    Text Format 说明文字,自己写吧
    Insert Hard Return 勾选的话就会输入一个回车符
    CDEF Function不用选,因为我们输入的数据已经是正确数据,
    GPRINT Type:只有在Graph Item Type 选择GPRINT才用到,我们后面的%就是通过这个实现的;
    图中item 2、3、4添加方法如下图:

    说明:
    这里全部使用的Graph Item Type为GPRINT类型,GPRINT Type选择Exact Numbers(不打印小数点类型)
    Consolidation Function 选择LAST 即当前数值;其他的max min average不用说了吧;对应你自己的选择在text format中打印标签名;
    顺便说一下加%的GPRINT Type的方法:
    点击Graph Management->GPRINT Presets->add 如图:可参看rrdgraph_graph官方说明

    Graph Item Inputs部分会根据Graph Template Items自动创建默认即可;
    点击save保存,完成设定;
    6、创建host templates并画图:
    点击add;然后如下图:

    save保存,然后选择左侧菜单的devices->add开始作图,设定如下图:

    说明:这里重要的一点就是Hostname一栏一定要对应我们脚本中的行参值,就是你数据文本里面的第一列;其他snmp等全部为空;

    点击save->Create Graphs for this Host->勾选Graph Template Name中的
    Create: node_boundstatus graph->create 作图成功,大功告成;
    7、一次添加所有的idc host devices并加入到graph trees。

    四、心得总结
    我在做这个监控前,也没有想到过cacti这些附加功能,所以在做任何一个技术的时候,我们都应该多想想是否还有其他我们可以利用的价值。这里起到一个抛砖引玉的效果,希望网友们有更好的idea呈现给我们~

    阅读内文 Tags: , , , , , , , ,

    负载均衡环境中和如何设置Expires和Etag

    8月 8th, 2008 | 2 Comments | Posted in Apache, Squid < by Martian Guo >

    在负载均衡环境中(LVS, LoadBalance)为了减少浏览器数据的重复请求操作,一般需要设置 Http Header 的 Etage 和 Expires 告诉浏览器请求数据是否已过期。以下内容主要考虑Apache+squid 环境

    ETag Header是文件修改时间、文件大小和inode号生成的校验(checksum),在多台服务器的负载均衡环境下会因部署内容的inode节点差异造成 ETag 的不同,在多台WEB前端做负载均衡的情况下,会因为请求同一个数据但不同机器的 ETag 而影响了响应. 具体表现为用户在第一次请求某一内容时下载而再次时浏览器会发现ETag不同而再次请求下载.。(再次刷新时查看是否响应码为:304)
    对于Apache 可以使用 FileEtag 选项配置
    Apache 的默认ETag的值总是由文件的索引节点(Inode)、大小(Size)、最后修改时间(MTime)决定
    这里我们只需要去掉Inode即可
    FileETag MTime Size
    具体关于 FileETag 详细内容可以查看Apache官方文档

    Expires用于控制请求文件的有效时间,当请求数据在有效期内时客户端浏览器从缓存请求数据而不是服务器端. 当缓存中数据失效或过期,才决定从服务器更新数据。
    可以使用Apache的mod_expires 模块来设置,这包括控制应答时的Expires头内容和Cache-Control头的max-age指令

    ExpiresActive On
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/x-icon "access plus 1 month"
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType text/html "access plus 30 minutes"
    ExpiresByType text/css  "access plus 30 minutes"
    ExpiresByType text/js   "access plus 30 minutes"
    ExpiresByType application/x-javascript   "access plus 30 minutes"
    ExpiresByType application/x-shockwave-flash     "access plus 30 minutes"

    以上设置为 图片文件的有效期为从请求文件开始1个月,html,css,js,flash文件的有效期为从请求文件开始30分钟
    这里只是一个常规设置,Apache官方文档 对此设置有详细介绍
    当设置了expires后,会自动输出Cache-Control 的max-age 信息,这个数值是expires有效期内的秒数,(一个月的数值为2592000) 在这个时间段里,该文件的请求都将直接通过缓存服务器获取,当然如果需要忽略浏览器的刷新请求(F5),缓存服务器squid还需要使用refresh_pattern 选项来忽略该请求

    refresh_pattern -i .jpg  1440 50% 10080 reload-into-ims ignore-reload ignore-no-cache ignore-private

    以下为实际输出的HTTP Header信息

    Date Thu, 07 Aug 2008 07:27:57 GMT
    Server Apache
    Last-Modified Fri, 27 Jun 2008 07:18:52 GMT
    Etag "df6-b8c8cf00"
    Accept-Ranges bytes
    Content-Length 3574
    Cache-Control max-age=2592000
    Expires Sat, 06 Sep 2008 07:27:57 GMT
    Content-Type image/jpeg
    Age 34241
    X-Cache HIT from s1.ihompy.com
    Connection keep-alive

    对于动态页面的缓存如果不是频繁更新的页面数据,可以在squid缓存,只需要注意两点
    1. session : 对于需要缓存的数据,一定要关闭session防止在http header 中包括session id 字段
    2. Last-Modified 和 Expires 标记: 一般般纯静态页面本身都会有Last-Modified信息,这是由WEB服务器获取文件的最后修改时间生成的,而动态页面需要默认的输出内容是

    Date Thu, 07 Aug 2008 16:58:37 GMT
    Expires Thu, 19 Nov 1981 08:52:00 GMT
    Last-Modified Thu, 07 Aug 2008 16:58:37 GMT

    这里的 Last-Modified 时间和请求文件的时间相同,也就是说该文件总是声明为最新的
    在程序中需要输出Last-Modifed 和 Expires信息,比如php

    header('Last-Modified: ' . gmdate("D, d M Y H:i:s"<