都是转义惹的祸

在做一个跳转页面时出现一个bug,是引号引起的,原始代码基本如下:

<html>
<head>
<title>redirect</title>
<meta http-equiv="refresh" content="0; url=&#39;http://www.baidu.com/?\40abc&#39;">
</head>
<body bgcolor="#ffffff" text="#000000" link="#0000cc" vlink="#551a8b" alink="#ff0000">
<script type="text/javascript" language="javascript">
location.replace("http://www.baidu.com/?\40abc");
</script>
</body>
</html>

这里的蓝色的双引号没有影响url中反斜线的转义,可能是因为&#39;的缘故;如果写为:
<meta http-equiv="refresh" content=0; url=&#40;http://www.baidu.com/?\40abc&#40;>
发现是不行的

javascript中的红色的双引号使得里面的反斜线有了转移的作用,所以,这里的双引号要修改为单引号

linux下查看网卡实时流量工具

nload是一个网络流量统计工具,当前版本为0.7.2。
下载地址:http://sourceforge.net/project/showfiles.php?group_id=35865

使用yum 安装也可以。

yum install nload

源码安装
wget http://heanet.dl.sourceforge.net/project/nload/nload/0.7.2/nload-0.7.2.tar.gz
tar zxvf nload-0.7.2.tar.gz
cd nload-0.7.2
./configure
make -j4
make install
安装目录自己定,安装十分简单,基本上不会出什么错误!
完成后就可以用来监测网卡流量了:
nload
linux下使用nload查看网卡实时流量 - linux - 我的博客

 


默认第一行是网卡的名称及IP信息,使用键盘上的左右键可以切换网卡。
默认上边Incoming是进入网卡的流量;
默认下边Outgoing是网卡出去的流量;
默认右边(Curr当前流量)、(Avg平均流量)、(Min最小流量)、(Max最大流量)、(Ttl流量统计);
默认情况,统计数据的左边会使用显示流量图,用#号拼出来的,根据实时流量变化显示。
遇到的问题:在网卡流量特别大即超过网卡本身传输速率的时候,右边的几个值会不固定的变为负数。我感觉原因好像是网卡超负荷所以计算出错了!不是很确定,不知有没有高手明白这个问题!!!
还有很多参数可以使用,帮助里面的例子:  nload -t 200 -i 1024 -o 128 -U M
查看参数帮助命令:
nload –help
-a:这个好像是全部数据的刷新时间周期,单位是秒,默认是300.
-i:进入网卡的流量图的显示比例最大值设置,默认10240 kBit/s.
-m:不显示流量图,只显示统计数据。
-o:出去网卡的流量图的显示比例最大值设置,默认10240 kBit/s.
-t:显示数据的刷新时间间隔,单位是毫秒,默认500。
-u:设置右边Curr、Avg、Min、Max的数据单位,默认是自动变的.注意大小写单位不同!
   h|b|k|m|g    h: auto, b: Bit/s, k: kBit/s, m: MBit/s etc.
   H|B|K|M|G    H: auto, B: Byte/s, K: kByte/s, M: MByte/s etc.
-U:设置右边Ttl的数据单位,默认是自动变的.注意大小写单位不同(与-u相同)!
Devices:自定义监控的网卡,默认是全部监控的,使用左右键切换。
如只监控eth0命令: nload eth0

关于OAuth的一点初步认识

原来以为OAuth是解决登录问题,初步了解了一下,感觉是在解决服务授权问题; 和openid不是一回事儿,他们解决的问题不同;
根据我的理解OAuth并不神秘,而且像这样的服务授权问题,SSO里面已经有这种功能了,Proxy ticket似乎就是解决这种问题的,我们的SSO很多情况下也是在做这样一件事情。至于为什么要有OAuth,还需要继续了解OAuth。

PHP 版的一致性hash算法

今天看豆瓣的架构PPT,其中有谈到Consistent Hashing的算法,网上搜了下,发现这方面的介绍也不算多。

通常比较常用的使用地方就是memcache分布式的时候,例如我有三台memcache,那么普通的hash算法,直接用你要取的key的hash值模取memcache的数量。

server = hash(key) mod server num;

但是如果要增加一台,那么将会有大量的缓存信息失效。所以更好的办法Consistent Hashing.

Consistent hashing算法:环状结构。虚拟节点来替换实体节点被分配到环状某一位置上(根据处理能力不同可以将一个实体节点映射到多个虚拟节点上)。主键为key的节点position = hash(key),在环上按照顺时针查找value大于position的第一个虚拟节点,由它对应的实体节点处理。下图中k就优先由虚拟节点 B来处理。

按照我的理解方式 就是将所有的cache服务器的标识分别hash到的值分布到0-pow(2,32)中. 然后将你要取的key的hash值进行比较。取第一个大于key的hash值的服务器。 如果从0-pow(2,32)也没有找到,那么则取最小hash值的服务器。

例如 上图中, 服务器 a 的hash值 为 1, b的hash值为 10, c的hash值为20, 我们取 key K 的hash值为5的位置,发现key K 大于 a 小于 b , 那么key k就存放于服务器b上, 如果 我们取 key x 的hash值为30的位置,发现 a,b,c三个服务器的hash值都小于 key x的hash值 , 那么 我们取 a 服务器作为存放服务器。

这样的存放方法,只会影响你最后一台服务器存放的key.而不会像取模方法的全局影响。

当然这样取key的效率就没有取模的高了,至于采用哪种方法,还是要根据你当前业务的规模来选择的。

另附上简单的算法

<?php

function consistent_hash_key($key,$servers){
   if(empty(
$servers)){
       return 
false;
   }
   
$hash_serv = array();
   
$hash_key sprintf("%un",crc32($key));
   foreach (
$servers as $server){
       
$hash_serv[sprintf("%u",crc32($server))] = $server;
   }
  
   
ksort($hash_serv,SORT_REGULAR);
  
   if(
count($hash_serv) == 1){
       return 
array_pop($hash_serv);
   }
   
$maxHash pow(2,32);
   foreach (
$hash_serv as $k => $v){
       if(
$hash_key $k){
           return 
$v;
       }
   }
   return 
array_shift($hash_serv);
}

for ($i=0;$i<100;$i++){
   echo 
consistent_hash_key('s:'.$i,array('a','b','c','d','e'))."t".consistent_hash_key('s:'.$i,array('a','b','c','d','e','f'))."n";
?>

一致性hash算法

一致性hash算法(Consitent Hash)用于解决动态cache问题 http://baike.baidu.com/view/1588037.html
memcach中一个具体实现算法:
初始化:
已有server m个和各自权重,构建 40*server个数*4个bucket,每个bucket实际上就是一个long值,按照权重分配给各个server,所有的bucket会分布在2的32次方的空间中,用一个TreeMap来存储。
double factor = Math .floor(((double) (40 * this.servers.length * thisWeight)) / (double) this.totalWeight);
            for (long j = 0; j < factor; j++)
            { 
                //md5结果为16个字节,每4个一组,转成一个long值(在0到2的32次方间)
                byte[] d = md5.digest((servers + "-" + j).getBytes());
                for (int h = 0; h < 4; h++)
                {
                    Long k = ((long) (d[3 + h * 4] & 0xFF) << 24)
                            | ((long) (d[2 + h * 4] & 0xFF) << 16)
                            | ((long) (d[1 + h * 4] & 0xFF) << 8)
                            | ((long) (d[0 + h * 4] & 0xFF));

                    consistentBuckets.put(k, servers);
                   
                }
            }

根据key来查找来分配server:
计算key的hash code,从TreeMap中查找大于它的节点,如果有则取第一个,没有则取TreeMap的第一个(相当于一个圆环)
        SortedMap<Long, String> tmap = this.consistentBuckets.tailMap(hv);

        return (tmap.isEmpty()) ? this.consistentBuckets.firstKey() : tmap
                .firstKey();

关于Linux的文件系统cache

关于linux中系统cache的测试:
当我们第一次访问某文件(或其中的一部分时),速度是比较慢的,但是再次访问就很快了,下面我们通过一个程序做一下冷热数据的访问速度的比较。

----------测试脚本------------
<?
$fp = fopen($argv[1], "r");
echo
microtime();
$offset = isset($argv[2])?$argv[2]:0;
fseek($fp,$offset);
$content = fread($fp,4096);
echo
"\n";
echo
microtime();
echo "\n";

fclose($fp);
?>

-----------------------------

测试结果:

[junjie2@bsso ~]$ php cache.php MySQL-devel-community-5.1.40-0.rhel5.i386.rpm
0.49064700 1258509003
0.49845600 1258509003
// 第一次访问耗时约8ms

[junjie2@bsso ~]$ php cache.php MySQL-devel-community-5.1.40-0.rhel5.i386.rpm
0.04973400 1258509015
0.04988900 1258509015
// 第二次访问相同的数据,耗时约1.5ms

[junjie2@bsso ~]$ php cache.php MySQL-devel-community-5.1.40-0.rhel5.i386.rpm
0.50933300 1258509019
0.50948600 1258509019

// 第二次访问相同的数据,耗时约1.5ms

[junjie2@bsso ~]$ php cache.php MySQL-devel-community-5.1.40-0.rhel5.i386.rpm 10
0.63028200 1258509035
0.63044500 1258509035
// 访问和上次稍有差异的数据,耗时约0.2ms,

[junjie2@bsso ~]$ php cache.php MySQL-devel-community-5.1.40-0.rhel5.i386.rpm 4096
0.89414900 1258509055
0.89434800 1258509055
// 访问和上次差异4k的数据,耗时约0.2ms
// 说明第一次系统缓存起来的数据不仅仅是我们访问的4k的数据,而是更多,具体多少,看内核源代码吧,似乎比测试更快、更准确一些

[junjie2@bsso ~]$ php cache.php MySQL-devel-community-5.1.40-0.rhel5.i386.rpm 4096000
0.24825000 1258509072
0.25472600 1258509072
// 访问和原来差异4M的数据,耗时6ms,说明这部分数据没有被系统cache给缓存

[junjie2@bsso ~]$ mv MySQL-devel-community-5.1.40-0.rhel5.i386.rpm MySQL-devel-community-5.1.40-0.rhel5.i386.rpm2
[junjie2@bsso ~]$ php cache.php MySQL-devel-community-5.1.40-0.rhel5.i386.rpm2 4096000            
0.54055900 1258510429
0.54070300 1258510429
// 重命名文件后访问相同内容,耗时约0.2ms
// 说明文件重命名不影响系统cache,即系统cache和文件名没有关系; 大概是根据inode来cache的,因为重命名前后的inode是没有变化的,name仅仅是文件的一个属性罢了

[junjie2@bsso ~]$

遗留问题:
1. 系统cache的换出机制是怎样的?
2. 系统cache的具体内容能查看吗? 肯定能的,怎么查看呢?
3. 如何刷新系统cache? 上面的测试说明,至少重命名文件是不行的;

另外:
系统cache是系统级别的cache,和进程没有关系; 如mysqld因系统cache加快了访问的速度,这时,重启mysqld是没用的。

参考:
文件系统的cache可以通过/dev/mem 这个字符设备来查看,好像系统利用缓存时是根据inode来查询的,就像memcached那样,至少现在要枚举所有信息是比较麻烦的。

/dev/mem  与 /dev/kmem 的区别:
 原创内容,转载请标明来自http://lixings.cublog.cn

区别:

        

  1. /dev/mem: 物理内存的全镜像。可以用来访问物理内存。
  2.     

  3. /dev/kmem: kernel看到的虚拟内存的全镜像。可以用来访问kernel的内容。

作用:

        

  1. 前者用来访问物理IO设备,比如X用来访问显卡的物理内存,或嵌入式中访问GPIO。用法一般就是open,然后mmap,接着可以使用map之后的地址来访问物理内存。这其实就是实现用户空间驱动的一种方法。
  2.     

  3. 后者一般可以用来查看kernel的变量,或者用作rootkit之类的。参考1和2描述了用来查看kernel变量这个问题。

参考:

        

  1. http://lwn.net/Articles/147902/
  2.     

  3. http://lkml.org/lkml/2005/8/11/301

rpmdb: Lock table is out of available locker entries…

如果运行一些程序后,远行yum命令出现

“rpmdb: Lock table is out of available locker entries…”的问题时, 你可以按照如下操作来修复它:

错误表现如下:
rpmdb: Lock table is out of available locker entries
error: db4 error(22) from db->close: Invalid argument
error: cannot open Packages index using db3 – Cannot allocate memory (12)
error: cannot open Packages database in /var/lib/rpm

操作之前请先备份 /var/lib/rpm :
tar cvzf rpmdb-backup.tar.gz /var/lib/rpm

去除rpm使用的BDB数据库:
rm /var/lib/rpm/__db.00*

重建立 rpm 使用的数据库,注意:此处可能需要一点时间:
rpm –rebuilddb

现在检查,看看 rpm 包是否一切正常:
rpm -qa | sort

为什么为发生这个问题呢?
其实当您用rpm命令后,rpm访问BDB数据库,首先会设置一个临时锁。如果在它运行时您用 control-c 中断它,或者是给它发了中断信号。那么rpm就很可能会出错误。因为这个临时锁还没有被释放呢。找到原因,相信您还可以找到其它的解决方法。