linux loadavg 算法

linux loadavg 算法

发表人:biti_rainy

今天读linux  source  code关于cpu  load 的计算方法,同时在google上搜索到处参考,晕乎了半天,终于弄明白cpu  load 的计算方法了,并不是简单的移动算术平均。

对于linux来说,采样计算load时间间隔为5秒,这都是在source code里面定义的固定数字,其采样结构通过动态内存文件系统  /proc/loadavg 可以动态的得到适时数据,其他工具的输出,比如 uptime / top/sar 等都是读该内存数据所产生的。我们在这里主要考究kernel的算法。

对于5秒的间隔,是动态地采样cpu状态数据,也就是run queue size ,这包括正在cpu中running的进程数量以及在cpu等待队列里面的进程数量。对于linux来说,实际上会计算1分钟、5分钟、15分钟的移动平均。为此首先我们要介绍linux 里面定义的3个常量:

 #define EXP_1           1884            /* 1/exp(5sec/1min)  */
 #define EXP_5           2014            /* 1/exp(5sec/5min)  */
 #define EXP_15          2037            /* 1/exp(5sec/15min) */

三个常量分别表示1/5/15分钟的常量,计算方法是:

1884 = 2048/(power(e,(5/(60*1))))   /* e = 2.71828 */

2014 = 2048/(power(e,(5/(60*5))))   

2037 = 2048/(power(e,(5/(60*15))))   

我们假定前一时刻按常量1884计算的load为 load1(t-1),当前采样run queue size 为 rq1,则当前load1(t) = ((load1(t-1) * 1884) + rq1 * (2048 – 1884))/2048

同理可以5分钟和15分钟移动平均的算法分别为 load5(t) =  ((load5(t-1) * 2014) + rq1 * (2048 – 2014))/2048和load_15(t) =  ((load15(t-1) * 2037) + rq1 * (2048 – 2037))/2048

由此可以看出,移动平均间隔越大,当前run queue size 对移动平均的影响趋向减小。

至于为什么取这个数,涉及到微积分方面的知识了,这样做出的图象更平滑。

RSA 公钥格式转换之PHP实现


在.net中公钥的格式总是以modules 、exponent的格式存在的,但是openssl做加密、解密总是使用pem格式的,这里实现了前者到后者的格式转换。

.net生成的public key的格式:
<modulus>
jY39vkCL8xCrUK9eepK2SQ447xiU/bZmnJi6G+4ripHzOJ65YTsxJ3sEOrXCyb0P
MBXQchQ2xpE8g7PyHe4zv07/Q7hbRFJ2CJAIyFj7OD5aejOiIptMzPsYNMx5Gkbs
</modulus>
<exponent>
AQAB
</exponent>

<?php
/** 
 * Zeal Extends of ZendFramework 
 * 
 * @category   Zeal 
 * @package    Zeal 
 * @subpackage Security 
 */  
  
/** 
 * RSA公钥格式转化 
 * 
 * @category   Zeal 
 * @package    Zeal 
 * @subpackage Security 
 */  
class Zeal_Security_RSAPublicKey  
{  
    
/** 
     * ASN.1 type INTEGER class 
     */  
    
const ASN_TYPE_INTEGER 0x02;  
  
    
/** 
     * ASN.1 type BIT STRING class 
     */  
    
const ASN_TYPE_BITSTRING 0x03;  
  
    
/** 
     * ASN.1 type SEQUENCE class 
     */  
    
const ASN_TYPE_SEQUENCE 0x30;  
  
    
/** 
     * The Identifier for RSA Keys 
     */  
    
const RSA_KEY_IDENTIFIER '300D06092A864886F70D0101010500';  
  
    
/** 
     * Constructor  (disabled) 
     * 
     * @return void 
     */  
    
private function __construct()  
    {  
    }  
  
    
/** 
     * Transform an RSA Key in x.509 string format into a PEM encoding and 
     * return an PEM encoded string for openssl to handle 
     * 
     * @param string $certificate x.509 format cert string 
     * @return string The PEM encoded version of the key 
     */  
    
static public function getPublicKeyFromX509($certificate)  
    {  
        
$publicKeyString "-----BEGIN CERTIFICATE-----n" .  
                           
wordwrap($certificate64"n"true) .  
                           
"n-----END CERTIFICATE-----";  
  
        return 
$publicKeyString;  
    }  
  
    
/** 
     * Transform an RSA Key in Modulus/Exponent format into a PEM encoding and 
     * return an PEM encoded string for openssl to handle 
     * 
     * @param string $modulus The RSA Modulus in binary format 
     * @param string $exponent The RSA exponent in binary format 
     * @return string The PEM encoded version of the key 
     */  
    
static public function getPublicKeyFromModExp($modulus$exponent)  
    {  
        
$modulusInteger  self::_encodeValue($modulus,   
                                               
self::ASN_TYPE_INTEGER);  
        
$exponentInteger self::_encodeValue($exponent,   
                                               
self::ASN_TYPE_INTEGER);  
        
$modExpSequence  self::_encodeValue($modulusInteger .   
                                              
$exponentInteger,   
                                               
self::ASN_TYPE_SEQUENCE);  
        
$modExpBitString self::_encodeValue($modExpSequence,   
                                               
self::ASN_TYPE_BITSTRING);  
  
        
$binRsaKeyIdentifier pack"H*"self::RSA_KEY_IDENTIFIER );  
  
        
$publicKeySequence self::_encodeValue($binRsaKeyIdentifier .   
                                                
$modExpBitString,   
                                                 
self::ASN_TYPE_SEQUENCE);  
  
        
$publicKeyInfoBase64 base64_encode$publicKeySequence );  
  
        
$publicKeyString "-----BEGIN PUBLIC KEY-----n";  
        
$publicKeyString .= wordwrap($publicKeyInfoBase6464"n"true);  
        
$publicKeyString .= "n-----END PUBLIC KEY-----n";  
  
        return 
$publicKeyString;  
    }  
  
    
/** 
     * Encode a limited set of data types into ASN.1 encoding format 
     * which is used in X.509 certificates 
     * 
     * @param string $data The data to encode 
     * @param const $type The encoding format constant 
     * @return string The encoded value 
     * @throws Zend_InfoCard_Xml_Security_Exception 
     */  
    
static protected function _encodeValue($data$type)  
    {  
        
// Null pad some data when we get it  
        // (integer values > 128 and bitstrings)  
        
if( (($type == self::ASN_TYPE_INTEGER) && (ord($data) > 0x7f)) ||  
            (
$type == self::ASN_TYPE_BITSTRING)) {  
                
$data "�$data";  
        }  
  
        
$len strlen($data);  
  
        
// encode the value based on length of the string  
        
switch(true) {  
            case (
$len 128):  
                return 
sprintf("%c%c%s"$type$len$data);  
            case (
$len 0x0100):  
                return 
sprintf("%c%c%c%s"$type0x81$len$data);  
            case (
$len 0x010000):  
                return 
sprintf("%c%c%c%c%s"$type0x82,   
                                              
$len 0x0100,   
                                              
$len 0x0100$data);  
            default:  
                throw   
                  new 
Zeal_Security_RSAPublicKey_Exception("Could not encode value",1);  
        }  
  
        throw   
          new 
Zeal_Security_RSAPublicKey_Exception("Invalid code path",2);  
    }  
}  
  
class 
Zeal_Security_RSAPublicKey_Exception extends Exception  
{  
  
}

// example
 
$hCert openssl_pkey_get_public(  
            
Zeal_Security_RSAPublicKey::getPublicKeyFromModExp(  
                
file_get_contents("/home/zeal/certs/public.key"),  
                
"AQAB"  
            
)  
        );  
$dataToCheck "This is Data should be verified!";  
$signBinary ".................................";  
$ok openssl_verify(  
        
$dataToCheck,   
        
$signBinary,   
        
$hCert,  
        
OPENSSL_ALGO_SHA1  
);  
if (
$ok == 1) {  
    echo 
"good";  
}   
elseif (
$ok == 0) {  
    echo 
"bad";  
}   
else {  
    echo 
"error occured";  
}  
?>

如何解压rpm文件

实例:rpm2cpio a.rpm | cpio -ivmd

详细用法
解压cpio文件
cpio -idmv < filename.cpio
同样可以解压img文件:
cpio -idmv < filename.img
cpio 备份命令
备份:cpio -covB > [file|device] 将数据备份到文件或设备上
还原:cpio -icduv < [file|device} 将数据还原到系统中
常用参数:
-o   :将数据copy到文件或设备上
-i    :将数据从文件或设备上还原到系统中
-t    :查看cpio建立的文件或设备内容
-c   :一种比较新的portable format方式存储
-v   :在屏幕上显示备份过程中的文件名
-B   :让预设的blocks可以增加到5120bytes,默认是512bytes,这样可以使备份速度加快
-d   :自动建立目录,这样还原时才不会出现找不到路径的问题
-u   :更新,用较新的文件覆盖旧的文件
cpio常与find 配合使用

打包命令cpio和tar的使用

在DOS或Windows下,有各种压缩与解压缩工具软件,其主要功能是将一目录下的众多文件或子目录打包并压缩成一个文件,便于备份、组织与管理。而在Unix系统中,却无此类能打包并同时压缩的工具。 

本人在Unix系统业务使用(特别是数据管理与备份)中,经过一番研究、整理后,充分利用Unix系统本身的命令tar、cpio和compress等来做到打包和压缩,使之充当类似DOS下的压缩软件,同时在Unix系统中亦具有通用性。 

在Unix系统中,是先通过cpio或tar将众多的文件打包成一个文件库后,再用compress将文件库压缩来达到目的的。下面分别以cpio和tar来说明使用的方法和步骤。 

一、cpio 

1.文件或目录打包。 

打包有如下多种情况: 

A)含子目录打包: 

find /usr/lib -print cpio -o〉/u0/temp1.cpio 

将/usr /lib目录下的文件与子目录打包成一个文件库为/u0/temp1.cpio。 

若通过-o选项来打包整个目录下的所有文件与子目录,常先利用find目录名-print来找出所有文件与子目录的名称,通过管道“ ”传给cpio打包。 

B)不含子目录的打包:
ls /usr/lib cpio -o〉/u0/temp1.cpio

将/usr/lib目录下的文件(不含子目录下的文件)打包成一个文件库为/u0/temp1.cpio。 

C)特定文件打包:
可利用文本搜索命令grep与管道配合,可以排除或选择特定类型的文件传给cpio打包。
如:ls /usr/lib/*.c cpio -o〉/u0/temp1.cpio
或ls /usr/lib grep ′\.c$′ cpio -o〉/u0/temp1.cpio 

意思均为找出/usr/lib目录下以.c结尾的文件予以打包。 

又如:ls /usr/lib grep abcd cpio -o〉/u0/temp1.cpio ,其意为找出/usr/lib目录
下文件名中含有abcd字符的文件予以打包。 

ls /usr/lib grep -v abcd cpio -o〉/u0/temp1.cpio,其意为找出/usr/lib目录下文
件名中不含 abcd 字符的文件予以打包。-v选项在grep命令中的意思是排除含有字符串的行
列。 

如此,可充分利用Unix的管道和一些命令的强大功能来实现文件的打包。 

2.压缩: 

文件打包完成后,即可用Unix中的compress命令(/usr/bin下)压缩打包文件。对一般的文
本文件,压缩率较高,可达81%。 

compress /u0/temp1.cpio则将文件库/u0/temp1.cpio压缩为/u0/temp1.cpio.Z(自动添
加.Z并删除/u0/temp1.cpio )。 

3.解压: 

uncompress /u0/temp1.cpio.Z则自动还原为/u0/temp1.cpio。 

4.解包展开: 

将按原目录结构解包展开到当前所在目录下。若以相对路径打包的,当解包展开时,也是以相
对路径存放展开的文件数据;若以绝对路径打包的,当解包展开时,也是以绝对路径存放展开的文
件数据。因此注意若为相对路径,应先进入相应的目录下再展开。 

cd /u1 
cpio -id〈/u0/tmp1.cpio则将/u0/temp1.cpio解压到/u1下(这里假设temp1.cpio以相对路径压缩)。 

若加u选项,如cpio -iud〈/u0/temp1.cpio则文件若存在将被覆盖,即强制覆盖。 

cpio -id〈/u0/temp1.cpio *.c 则展开其中的*.c文件,类似于DOS系统中的Pkzip软件中Pkunzip -d temp1.zip解包功能。 

5.显示: 

cpio -it〈/u0/temp1.cpio [*.c] 显示文件库内的文件名称,类似于DOS系统中的Pkzip软件中Pkunzip -vbnm temp1.zip功能。 

二、tar 

1.文件或目录打包: 

tar -cvf /u0/temp2.tar /usr/lib 

将/usr/lib目录下的文件与子目录打包成一个文件库为/u0/temp2.tar。 

tar -cvf /u0/temp2.tar /usr/lib *.c *.f 

将/usr/lib目录下的*.c *.f等文件(不含子目录)打包。 

注意:如果指定文件如*.c *.f或*.*,则打包时均不含子目录。如果指定为.或*,则含
子目录。 

2.压缩: 

同上:compress /u0/temp2.tar压缩为/u0/temp2.tar.Z 

3.解压: 

uncompress /u0/temp2.tar.Z则还原为/u0/temp2.tar。 

4.解包展开: 

tar -xvf /u0/temp2.tar 

若以相对路径打包的,解包时,以相对路径存放展开的文件数据;若以绝对路径打包的,解包
时,以绝对路径存放展开的文件数据。 

若指定展开的文件名,须注意文件的目录路径。 

5.显示: 

tar -tvf /u0/temp2.tar 显示文件库内的文件名称。当指定文件名时,亦须注意文件的路
径。 

相对来说这两个命令各有优缺点。 

1)tar速度比cpio慢,且不能跨越两份存储媒体,但文件格式几乎在所有的Unix系统中都能通用,且使用简便。 

2)cpio则由于可通过管道功能,使得其打包时的文件选择、排除功能非常强,且能跨越多份媒体,并能备份特殊的系统文件。 

另外,压缩命令compress比DOS下的Pkzip的压缩率要低些。经测试,在一个目录下527个文本文件共15.7MB,在Unix打包后用compress压缩,大小为 2.1MB;相同的文件拷到DOS系统用Pkzip压缩,则大小为1.4MB。

Linux操作系统中内存buffer和cache的区别

Linux 的内存管理,实际上跟windows的内存管理有很相像的地方,都是用虚拟内存这个的概念,说到这里不得不骂MS,为什么在很多时候还有很大的物理内存的 时候,却还是用到了pagefile. 所以才经常要跟一帮人吵着说Pagefile的大小,以及如何分配这个问题,在Linux大家就不用再吵什么swap大小的问题,我个人认为,swap设 个512M已经足够了,如果你问说512M的SWAP不够用怎么办?只能说大哥你还是加内存吧,要不就检查你的应用,是不是真的出现了memory leak.
夜也深了,就不再说废话了。

在Linux下查看内存我们一般用command free
[root@nonamelinux ~]# free
             total        used       free     shared    buffers     cached
Mem:        386024      377116       8908          0      21280     155468
-/+ buffers/cache:      200368     185656
Swap:       393552           0     393552

下面是对这些数值的解释:
第二行(mem):
total: 总计物理内存的大小。
used:  已使用多大。
free:  可用有多少。
Shared:多个进程共享的内存总额。
Buffers/cached:磁盘缓存的大小。

第三行:
-buffers/cache 的内存数:200368(等于第2行的 used – buffers – cached)
+buffers/cache 的内存数: 185656(等于第2行的 free + buffers + cached)
 

由上看出,-buffers/cache反映的是被系统被实际使用掉的内存,而+buffers/cache反映的是可以挪用的内存总数。所以一般来讲我们是比较关心第三行的


第四行就不多解释了。
区别:
第二行(mem)的used/free与第三行(-/+ buffers/cache) used/free的区别。
这 两个的区别在于使用的角度来看,第二行是从OS的角度来看,因为对于OS,buffers/cached 都是属于被使用,所以他的可用内存是8908KB,已用内存是377116KB,其中包括,内核(OS)使 用+Application(X,oracle,etc)使用的+buffers+cached.
第三行所指的是从应用程序角度来看,对于应用程序来说,buffers/cached 是等于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。
所以从应用程序的角度来说,可用内存=系统free memory+buffers+cached.
如上例:
185656=8908+21280+155468
接下来解释什么时候内存会被交换,以及按什么方交换。
当可用内存少于额定值的时候,就会开会进行交换.
如何看额定值(RHEL4.0):
#cat /proc/meminfo
交换将通过三个途径来减少系统中使用的物理页面的个数: 
1.减少缓冲与页面cache的大小,
2.将系统V类型的内存页面交换出去, 
3.换出或者丢弃页面。(Application 占用的内存页,也就是物理内存不足)。
事实上,少量地使用swap是不是影响到系统性能的。

 

 对于共享内存(Shared memory),主要用于在UNIX 环境下不同进程之间共享数据,是进程间通信的一种方法,一般的应用程序不会申请使用共享内存,笔者也没有去验证共享内存对上面等式的影响。如果你有兴趣, 请参考:What is Shared Memory?

  cache 和 buffer的区别:
Cache:高速缓存,是位于CPU与主内存间的一种容量较小但速度很高的存储器。由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周期,Cache中保存着CPU刚用过或循环使用的一部分数据,当CPU再次使用该部分数据时可从Cache中直 接调用,这样就减少了CPU的等待时间,提高了系统的效率。Cache又分为一级Cache(L1 Cache)和二级Cache(L2 Cache),L1 Cache集成在CPU内部,L2 Cache早期一般是焊在主板上,现在也都集成在CPU内部,常见的容量有256KB或512KB L2 Cache。

  Buffer:缓冲区,一个用于存储速度不同步的设备或优先级不同的设备之间传输数据的区域。通过缓冲区,可以使进程之间的相互等待变少,从而使从速度慢的设备读入数据时,速度快的设备的操作进程不发生间断。

  Free中的buffer和cache:(它们都是占用内存):

  buffer : 作为buffer cache的内存,是块设备的读写缓冲区

  cache: 作为page cache的内存, 文件系统的cache

  如果 cache 的值很大,说明cache住的文件数很多。如果频繁访问到的文件都能被cache住,那么磁盘的读IO bi会非常小。

PHP debug

<?php

c();
function 
c() {
    
d("error is here");
}

function d($msg) {
    
$e = new Exception();
    
//print_r($e->getTrace());
    
$arr $e->getTrace();
    echo 
time().":".$arr[0]["file"].":".$arr[0]["line"].":".$arr[1]["function"]."n";
    echo 
$msg;
    echo 
"n";
}

?>