2012年10月29日星期一

进程运行于不同的 CPU 核

用 Gearman 搭建 Map/Reduce ,GearmanManager 来管理所有的 workers。启动多个 gearman-manager daemon,为了充分利用服务器资源,使其运行于不同的 CPU 内核上。 假设启动 10 个gearman-manager daemon,CPU 是 4核。
[root@www ~]# ps aux | grep gearman-manager | awk {'print $2;'} | sort -k1,1 | head -3 | xargs -n 1 taskset -cp 0
[root@www ~]# ps aux | grep gearman-manager | awk {'print $2;'} | sort -k1,1 | tail -3 | xargs -n 1 taskset -cp 1
[root@www ~]# ps aux | grep gearman-manager | awk {'print $2;'} | sort -k1,1 | sed -n '4,7p' | xargs -n 1 taskset -cp 2
上面命令是将前 3 个 deamon 运行于 CPU#0 (CPU 第一个核 上,从 0 开始计数),中间 4个运行于 CPU#2,最后三个运行于 CPU#1。 Backgrounds: 榨干服务器:让进程运行在指定的CPU
两个名词: SMP (Symmetrical Multi-Processing):指在一个计算机上汇集了一组处理器(多 CPU),各 CPU 之间共享内存子系统以及总线结构。 [MORE...] CPU affinity:中文唤作「CPU亲和力」,是指在 CMP 架构下,能够将一个或多个进程绑定到一个或多个处理器上运行。[MORE...]
  1. 在Linux上修改进程的「CPU亲和力」在Linux上,可以通过 taskset 命令进行修改。以 CentOS 为 例,taskset 在 util-linux-2.13-pre7 包中。下载源代码,编译安装即可。 对运行中的进程,可用如下命令将 CPU #1, #2, #3 分配给 PID 为 12345 的进程:
    [root@www ~]# taskset -cp 1,2,3 12345
    
    对于已经在运行中 MySQL 的服务,用上面命令修改其运行于哪颗 CPU 内核上是无效的。而是需要在启动时指定:
    [root@www ~]# taskset -c 1,2,3 /usr/local/mysql/bin/mysqld_safe &
    
    其它进程,也可类似处理 (Nginx 除外,见下文)。之后用 top 命令,回车后输入 1 查看所有 CPU 的使用情况:
  2. Nginx 绑定 CPU 上文说 Nginx 除外,是因为 Nginx 提供了更确切的配置,在其配置文件 conf/nginx.conf 中,有如下一行:
    worker_processes 1;  
    
    这用来配置 Nginx 启动几个工作进程,默认为 1。Nginx 还支持 worker_cpu_affinity 配置项,即 Nginx 可以为 每个工作进程绑定 CPU。例:
    worker_process      3;
    worker_cpu_affinity 0010 0100 1000;
    
    001001001000是掩码,分别代表第 2,3,4 颗 CPU 核。重启 Nginx,3 个工作进程就可以各自用各自的 CPU 。
  3. 深入
    • 如果自己写代码,要把进程绑定到 CPU,可用 sched_setaffinity 函数,在 Linux上,这会触发一次 系统调用
    • 如果父进程设置了affinity,之后其创建的子进程会继承父进程的affinity属性(其实用 taskset 启动进程就是一次fork+exec)。
  4. @Xitong Linode 默认只在 CPU#0 上工作,多半是由 Xen 的配置决定的。只要内核支持 SMP,默认都是尽可能将负载分摊在多个 CPU 上。

Some Notes


  1. ulimit -t 引起的kill血案

  2. 本机Linux下IO测试过程记录

  3. @hellodba :iostat中的 %util 代表一秒内 IO 操作所占的比例,计算公式是 (r/s+w/s)*(svctm/1000),对于一块磁盘,因为没有并发 IO 的概念,所以这个公式是正确的,但是对于 RAID 磁盘组或者 SSD 来说,这个计算公式就有问题了,就算这个值超过 100%,也不代表存储有瓶颈,容易产生误导。


    • @何_登成:#数据库内核分享# TPS1: InnoDB/Oracle 在数据文件头中记录有 Flush_LSN/Media Recovery CP SCN,二者均是用来标识当前数据文件对应的日志文件位置,但是维护与功能上有极大地不同。维护上:InnoDB Flush LSN 仅仅在 MySQL 数据库正常关闭时才更新;Oracle 的 MR SCN 是在日志文件切换后逐步更新。

    • @何_登成: 想到一个让 InnoDB 也支持 Media Recovery Checkpoint 的方案,让 InnoDB 在日志文件切换后,进行 MRC,并将新日志文件的 First LSN 作为 Flush LSN 写入每个 Data Files 的第一个 Page 中。如此做的优势,任何时候直接 Copy InnoDB 的数据文件,均可找到 Redo 的恢复起点。


  4. @stvchu :存储相关(数据库,文件存储)的工程师必须知道的 3 个计算公式。。。特别是第三个。。。知道为什么一般 I/O 利用率要保持在 60%~70% 以下了吧。。。PS: 图中红色数字参考希捷 300G SAS 15KRPM 的规格。



    • @hellodba:昨天团队又出现个 case,MySQL 复制一切正常,但是实际数据并没有复制过去,IO 和 SQL 线程都正常,relaylog 也有,原因还在进一步查。幸好发现了,如果主备切换就惨了,另外监控也要加强,不能只看状态,还要检测心跳的时间才行。

    • @hellodba:解析 binlog 发现主库 tableid 发生变化,备库复制时被忽略掉,原因不明,坑爹啊。

    • @AlibabaDBA:实际案例:MySQL 空表加字段,因为 BP(Buffer Pool) 比较大,Innodb 会多次遍历 BP 作清理,导致每个操作需要 1s,期间持有 LOCK_open 全局锁,造成其他查询均等待 Opening tables,实际操作中连续作了 64 个 DDL,造成整个系统 hang 了接近 1 分钟。结论:MySQL作大量 create, alter, drop操作必须 sleep。分析人:@希羽hickey

    • @hellodba:原因在此,宝贵经验。


  5. Ext4 data corruption trouble

  6. SystemTap,Linux 内核诊断工具,提供从运行中的 Linux 内核获取信息。

  7. Google Data Center

  8. Line,简短介绍,相当于微信,但比微信强大。

MongoDB: Why "Uncaught exception 'MongoConnectionException... endpoint not connected"

在 PHP 中访问 MongoDB,建立连接时收到异常:
[bash gutter="fasle"]
"Uncaught exception 'MongoConnectionException transport endpoint is not connected"
[/bash]

Mongo Exception 中有说明引发这异常的原因:

Transport endpoint is not connected
Generally means that the connection string isn't correct, the driver couldn't even find the database server.


具体就是指定义提供服务的 server 的格式不对,正常的格式是: mongodb://[username:password@]host1[:port1][,host2[:port2:],...]/db

CPAN02packagesDetails包错误导致cpan不能用



新主机上用 cpan 安装失败,用上面方法未解决。于是,删除 $HOME/.cpan,然后从其它可用的主机上 copy 了一份,重新加载 (reload index),报源 404 错误。从 CPAN 不可用 文中看到这段:

再次尝试安装模块,系统按照顺序尝试各个源,两个404之后(就是那两个碰不到的源),ftp://cpan.cdpa.nsysu.edu.tw/Unix/Lang/CPAN/里找到了我们需要的package信息,不过因为已经有了,所以需要手动先删除 /root/.cpan/sources/modules/02packages.details.txt.gz 和 /root/.cpan/sources/modules/03modlist.data.gz,再重新install CGI,一切正常了。不过老看到两个404也很不爽,就干脆手动编辑配置文件/usr/lib/perl5/5.8.8/CPAN/Config.pm,把"'urllist' =>" 中的两个不能访问的源干掉,一切都好了,以下是修改后的配置文件

试着修改 /usr/lib/perl5/5.8.8/CPAN/Config.pmurllist,将报 404 的源删除。安装,成功。

这里,不知道是不是因为 404 错误的源在 urllist 最前面,以至报整个安装失败,还是有别的因素导致失败。总之,后面这无礼而又粗暴的方法算暂时解决了问题。

编译 PHP 时报 undefined reference to `libiconv_open'

编译 PHP 5.4.7,配置参数:
[bash]
./configure --prefix=/usr/local/php --with-freetype-dir --with-jpeg-dir --with-png-dir --with-curl --with-gd --with-iconv --with-mcrypt --with-mhash --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-openssl --with-pdo-mysql=mysqlnd --with-gettext --with-zlib --enable-bcmath --enable-ftp --enable-fpm --with-fpm-user=www --with-fpm-group=www --enable-gd-native-ttf --enable-mbstring --enable-pcntl --enable-pdo --enable-sockets --enable-shmop --enable-zip --disable-ipv6 --disable-debug --without-pear
[/bash]
configure 正常,make 时报错:
[bash]
ext/gd/libgd/gdkanji.o: In function `do_convert':
/usr/local/src/php-5.4.7/ext/gd/libgd/gdkanji.c:350: undefined reference to `libiconv_open'
/usr/local/src/php-5.4.7/ext/gd/libgd/gdkanji.c:365: undefined reference to `libiconv'
/usr/local/src/php-5.4.7/ext/gd/libgd/gdkanji.c:381: undefined reference to `libiconv_close'
ext/iconv/iconv.o: In function `_php_iconv_strlen':
.....
collect2: ld returned 1 exit status
make: *** [sapi/cli/php] Error 1
[/bash]

看错误提示,gd 库调用 libiconv, 但没找到 libiconv。下载 libiconv,编译,安装。

再重新配置 PHP ,加上 --with-iconv=/usr/local/lib
[bash]
[root@www php-5.4.7]# ./configure --prefix=/usr/local/php --with-freetype-dir --with-jpeg-dir --with-png-dir --with-curl --with-gd --with-iconv --with-mcrypt --with-mhash --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-openssl --with-pdo-mysql=mysqlnd --with-gettext --with-zlib --enable-bcmath --enable-ftp --enable-fpm --with-fpm-user=www --with-fpm-group=www --enable-gd-native-ttf --enable-mbstring --enable-pcntl --enable-pdo --enable-sockets --enable-shmop --enable-zip --disable-ipv6 --disable-debug --without-pear
[root@www php-5.4.7]# make
[root@www php-5.4.7]# make install
[/bash]

PHP Notes

exec()


  1. 获得命令执行结果,命令和参数完后加上 2>&1
    [bash]
    $output = array();
    $lastLine = exec("php -l test.php 2>&1", $output);
    [/bash]

  2. 立即退出,而不是等命令执行完后再退出
    [bash]
    exec("php -l test.php > /dev/null &");
    [/bash]



php_sapi_name()

返回 小写的 PHP 使用的 interface。如从命令行执行时返回 cli


Deprecated: Assigning the return value of new by reference is deprecated in ...

运行旧时代码,收到错误:
[php gutter="false"]
Deprecated: Assigning the return value of new by reference is deprecated in .. line
[/php]
Google ,原来是 PHP 升级引发的问题。PHP 从 5.3 起,废除了 =& 符号,用 = 就等于是直接引用。详细如下:

  1. PHP5 对象复制是采用引用的方式

  2. 如果不采用引用方式,则需要在复制对象时加关键字 clone

  3. 如果在复制的过程中,同时要变更某些属性,则增加函数 _clone()



Problem: Fatal error: Call to undefined function: pcntl_fork() in ...

编译 PHP 有加上参数 --enable-pcntl,且安装成功后,在 PHP 信息中,能看到 PHP 支持 pcntl 的信息:
[bash]
[root@www ~]# php -i | grep pcntl
Configure Command => './configure' '--prefix=/usr/local/php' '--with-freetype-dir' '--with-jpeg-dir' '--with-png-dir' '--with-curl' '--with-gd' '--with-iconv' '--with-mcrypt' '--with-mhash' '--with-mysql=mysqlnd' '--with-mysqli=mysqlnd' '--with-openssl' '--with-pdo-mysql=mysqlnd' '--with-gettext' '--with-zlib' '--enable-bcmath' '--enable-ftp' '--enable-fpm' '--with-fpm-user=www' '--with-fpm-group=www' '--enable-gd-native-ttf' '--enable-mbstring' '--enable-pcntl' '--enable-pdo' '--enable-sockets' '--enable-sqlite-utf8' '--enable-shmop' '--enable-zip' '--disable-ipv6' '--disable-debug' '--without-pear'
pcntl
pcntl support => enabled
[/bash]

在浏览器中访问有调用 pcntl_fork()的脚本时,收到下面的错误提示,但在命令行执行该脚本时正常运行:
[bash]
Problem: Fatal error: Call to undefined function: pcntl_fork() in ...
[/bash]

PHP 官方网站在 介绍 pcntl 时有提到:
Process Control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment.

即调用 pcntl_xxx 系列函数的脚本,不能在浏览器或是任何 web 方式的环境下访问。


Strict Standards: Only variables should be passed by reference

[php]
<?php
$string = 'test1 test2 test3 test4';
$array = array_shift(explode(' ', $string));

print_r($array);
?>
[/php]
执行上面代码,收到错误:
[bash gutter="false"]
[root@www tmp]# php test.php
PHP Strict Standards: Only variables should be passed by reference in /tmp/test.php on line 3

Strict Standards: Only variables should be passed by reference in /tmp/test.php on line 3
[/bash]
之所以报这错误,因为 array_shift 的参数是引用传递的,PHP 5.3+ 默认只能传递具体的变量,而不能直接是传递函数返回值。代码修改成:
[php]
<?php
$string = 'test1 test2 test3 test4';
$array = explode(' ', $string);
$value1 = array_shift($array);

print_r($value1);
?>
[/php]
另外,当程序设置的报错模式为严格模式时也会收到上面的错误:
[php]
error_reporting (E_ALL | E_STRICT);
[/php]

Resources:

Gearman 1.1.0 + PECL Gearman PHP 1.03 - compilation problem

Gearman 1.1.0 安装成功,安装扩展 PECL Gearman PHP 1.0.3, 编译失败:
[bash]
[root@www gearman-1.0.3]# make
/bin/sh /usr/local/src/gearman-1.0.3/libtool --mode=compile cc -I. -I/apps/home/folder/local/folder4/gearman-1.0.3 -DPHP_ATOM_INC -I/usr/local/src/gearman-1.0.3/include -I/usr/local/src/gearman-1.0.3/main -I/apps/home/folder/local/folder4/gearman-1.0.3 -I/usr/local/php/include/php -I/usr/local/php/include/php/main -I/usr/local/php/include/php/TSRM -I/usr/local/php/include/php/Zend -I/usr/local/php/include/php/ext -I/usr/local/php/include/php/ext/date/lib -I/usr/local/php/include -DHAVE_CONFIG_H -g -O2 -Wall -c /usr/local/src/gearman-1.0.3/php_gearman.c -o php_gearman.lo
cc -I. -I/apps/home/folder/local/folder4/gearman-1.0.3 -DPHP_ATOM_INC -I/usr/local/src/gearman-1.0.3/include -I/usr/local/src/gearman-1.0.3/main -I/apps/home/folder/local/folder4/gearman-1.0.3 -I/usr/local/php/include/php -I/usr/local/php/include/php/main -I/usr/local/php/include/php/TSRM -I/usr/local/php/include/php/Zend -I/usr/local/php/include/php/ext -I/usr/local/php/include/php/ext/date/lib -I/usr/local/php/include -DHAVE_CONFIG_H -g -O2 -Wall -c /usr/local/src/gearman-1.0.3/php_gearman.c -fPIC -DPIC -o .libs/php_gearman.o
/usr/local/src/gearman-1.0.3/php_gearman.c: In function ‘zif_gearman_job_send_data’:
/usr/local/src/gearman-1.0.3/php_gearman.c:1486: error: dereferencing pointer to incomplete type
/usr/local/src/gearman-1.0.3/php_gearman.c: In function ‘zif_gearman_job_send_warning’:
/usr/local/src/gearman-1.0.3/php_gearman.c:1514: error: dereferencing pointer to incomplete type
/usr/local/src/gearman-1.0.3/php_gearman.c: In function ‘zif_gearman_job_send_status’:
/usr/local/src/gearman-1.0.3/php_gearman.c:1537: error: dereferencing pointer to incomplete type
/usr/local/src/gearman-1.0.3/php_gearman.c: In function ‘zif_gearman_job_send_complete’:
/usr/local/src/gearman-1.0.3/php_gearman.c:1559: error: dereferencing pointer to incomplete type
/usr/local/src/gearman-1.0.3/php_gearman.c: In function ‘zif_gearman_job_send_exception’:
/usr/local/src/gearman-1.0.3/php_gearman.c:1581: error: dereferencing pointer to incomplete type
/usr/local/src/gearman-1.0.3/php_gearman.c: In function ‘zif_gearman_job_send_fail’:
/usr/local/src/gearman-1.0.3/php_gearman.c:1600: error: dereferencing pointer to incomplete type
/usr/local/src/gearman-1.0.3/php_gearman.c: In function ‘_php_worker_function_callback’:
/usr/local/src/gearman-1.0.3/php_gearman.c:3521: error: dereferencing pointer to incomplete type
/usr/local/src/gearman-1.0.3/php_gearman.c: In function ‘zm_startup_gearman’:
/usr/local/src/gearman-1.0.3/php_gearman.c:4638: error: ‘GEARMAN_MAGIC_TEXT’ undeclared (first use in this function)
/usr/local/src/gearman-1.0.3/php_gearman.c:4638: error: (Each undeclared identifier is reported only once
/usr/local/src/gearman-1.0.3/php_gearman.c:4638: error: for each function it appears in.)
/usr/local/src/gearman-1.0.3/php_gearman.c:4641: error: ‘GEARMAN_MAGIC_REQUEST’ undeclared (first use in this function)
/usr/local/src/gearman-1.0.3/php_gearman.c:4644: error: ‘GEARMAN_MAGIC_RESPONSE’ undeclared (first use in this function)
make: *** [php_gearman.lo] Error 1
......
[/bash]

bugs.php.net 有列出该问题 Bug #63062 gearman extension compile error,从评论中可得知,该问题在 Gearman 上也有对应 gearman_worker_st no longer visible from gearman_job_st,下面有说明在 gearmand-1.1.1 中该问题已被 fix。

Herman J. Radtke III (hermanradtke) wrote on 2012-09-20: #8
I was able to successfully compile against the gearmand-1.1.1 release.

Brian Aker (brianaker) on 2012-09-20
Changed in gearmand:
status: Fix Committed → Fix Released

GearmanMonitor 和 GearmanManager

GearmanMonitor

GearmanMonitor 是用来查看 Gearman 服务状态的工具,包括 运行中/过的队列 Queue,运行中的所有 workers,及服务器 servers。GearmanMonitor 需要有 Net_Gearman 支持。安装 pear 后,直接执行:
[bash]
[root@www bin]# pear install Net_Gearman
# 如果提示
# No releases available for package "pear.php.net/Net_Gearman"
# 则执行
[root@www bin]# pear install channel://pear.php.net/Net_Gearman-0.2.3
[/bash]

GearmanManager

GearmanManager 用来统一管理用 PHP 编写的 Gearman workers。需要 PHP 启用 pcntl。用 install/install.sh 安装完成后,根据需要和设置,修改 /etc/init.d/gearman-manager:
[bash gutter="false"]
##PATH##
DAEMON=/usr/local/bin/gearman-manager
PIDDIR=/tmp
PIDFILE=${PIDDIR}/manager.pid
LOGFILE=/tmp/gearman-manager.log
CONFIGDIR=/data/gearman-manager
GEARMANUSER="gearmand"
PARAMS="-c ${CONFIGDIR}/config.ini"
[/bash]

GearmanManager 安装时,选择的是 PECL library,启动时可能会遇见如下的问题:
[bash]
[root@www gearman-manager]# /etc/init.d/gearman-manager start
Starting gearman-manager: [ OK ]
[root@www gearman-manager]# php: libgearman/universal.cc:553: bool gearman_request_option(gearman_universal_st&, gearman_string_t&): Assertion `con->recv_state == GEARMAN_CON_RECV_UNIVERSAL_NONE' failed.
php: libgearman/universal.cc:553: bool gearman_request_option(gearman_universal_st&, gearman_string_t&): Assertion `con->recv_state == GEARMAN_CON_RECV_UNIVERSAL_NONE' failed.
.....
[/bash]

解决办法如 Bug #60764 Enabling Non-Blocking Mode causes asseration 这里所提, 修改 pecl-manager.php :
[bash]
//注释下面这句
//$thisWorker->addOptions(GEARMAN_WORKER_NON_BLOCKING);
[/bash]

Temporary failure in name resolution

用 wget 下载资源,出现
[bash gutter="false"]
[root@ src]# wget http://cdn.mysql.com/Downloads/MySQL-5.5/mysql-5.5.28.tar.gz
Resolving http://cdn.mysql.com/Downloads/MySQL-5.5/mysql-5.5.28.tar.gz failed: Temporary failure in name resolution.
[/bash]
错误提示表示在解析 URL 时候失败。
检测机器的网络问题: 可 ping 外部 IP 地址, 但 ping 外部 URL 时, 提示 the host is unknown
修改 /etc/resolv.conf DNS 设置文件, service network restart 重启网络服务。问题解决。


用命令 yum 安装软件时,收到类似如下的错误提示:
[bash gutter="false"]
[root@www ~]# yum install boost.x86_64
Could not retrieve mirrorlist [url]http://mirrorlist.centos.org/?release=5&arch=i386&repo=os[/url] error was
[Errno 4] IOError: <urlopen error (-3, '\xe5\x9f\x9f\xe5\x90\x8d\xe8\xa7\xa3\xe6\x9e\x90\xe6\x9a\x82\xe6\x97\xb6\xe5\xa4\xb1\xe8\xb4\xa5')>
Error: Cannot retrieve repository metadata (repomd.xml) for repository: base. Please verify its path and try again
[/bash]
这也是 DNS 设置的问题。

Hadoop 常用命令


  1. hadoop namenode -format
    HDFS 格式化

  2. hadoop fs -rmr wordoutput
    删除 HDFS 中 wordcount 目录

  3. hadoop fs -put word-input/ wordinput
    将本地文件系统中 word-input 上传到 HDFS 中,对应目录名为 wordinput

  4. hadoop dfs -copyFromLocal /tmp/gutenberg /user/hduser/gutenberg
    将本地文件系统上的文件 /tmp/gutenberg 复制到 Hadoop 的 HDFS /user/hduser/gutenberg 中

  5. hadoop dfs -getmerge /user/hduser/gutenberg-output /tmp/gutenberg-output
    将 HDFS 中文件 /user/hduser/gutenberg-output 复制到 本地文件系统的 /tmp/gutenberg-output

  6. hadoop dfs -ls /user/hduser/wordinput
    列出 HDFS 中 /user/hduser/wordinput 目录/文件 的信息

  7. hadoop dfs -cat /user/hduser/gutenberg-output/part-r-00000
    查看 HDFS 中文件 /user/hduser/gutenberg-output/part-r-00000

  8. hadoop jar hadoop-examples-1.0.3.jar wordcount wordinput wordoutput
    运行 wordcount JOB, wordinput 为数据处理源,wordoutput 存储 JOB 处理结果,wordinput 和 wordoutput 都为 HDFS 中目录。

  9. hadoop jar contrib/streaming/hadoop-streaming-1.0.3.jar -file /usr/local/hadoop/python/mapper.py -mapper /usr/local/hadoop-/python/mapper.py -file /usr/local/hadoop/python/reducer.py -reducer /usr/local/hadoop/python/reducer.py -input /user/hduser/wordinput -output /user/hduser/wordinput-python
    利用 Hadoop Streaming,使用 Python 脚本做为 mapper/reducer,JOB 处理的源数据为/user/hduser/wordinput, 输出结果保存于/user/hduser/wordinput-python。

  10. hadoop fsck /user
    检查 HDFS 中 /user 目录下 Blocks 的完整性

  11. hadoop fsck --delete
    删除损坏的文件

  12. hadoop balancer -threshold 5
    对 Hadoop 集群中对各个 Datanode 进行评估并使他们保持平衡。参数 threshold 表示的平衡的阀值,取值范围在 0% 到 100% 之间。该参数表示每个 Datanode 中空间使用率与 HDFS 集群总的空间使用率的差距百分比。


Linux 系统 NFS 服务端配置方法

FROM: NFS 伺服器
NFS(Network FileSystem)藉由网络共享文件系统的架设比较简单,最大的问题在于「权限」方面的概念。因为用户与服务器可能必须要具备相同的帐号才能读写某些目录或文件。另外,NFS 的启动需要使用远程过程调用协议(RPC)。也就是说,在使用 NFS 服务时,必须启动 RPC 服务。

修改 /etc/exports,增加共享目录


[bash]
[root@www ~]# vim /etc/exports
/tmp 192.168.100.0/24(ro) localhost(rw) *.edu.net(ro,sync)
#[共享目录] [第一部主机(权限)] [可用主机名] [可用域名]
/home/linux *.centos.vbird(rw,all_squash,anonuid=45,anongid=45)
# 如果要开发匿名,那重点是 all_squash,并且要配合 anonuid, anongid
[/bash]
上面说明:将 /tmp 分別共享给三个不同的主机或域。主机后面以小括号 () 括起来的部分表示权限参数,若权限参数不止一个,则以逗号 , 分开。小括号与主机名之间不能有空格。# 开头表示该行已被注释。

主机名称的设定方式:

  • 使用完整的 IP 或 网段,如: 192.168.100.10192.168.100.0/24, 或 192.168.100.0/255.255.255.0

  • 使用主机名称,但主机名称必须在 /etc/hosts 内,或可使用 DNS 找到该名称。如果是主机名称,支持匹配符号 *?



权限常见参数(小括号内参数):

























参数值 说明
rw
ro
目录功效的权限是可读写(read-write)或只读(read-only),但最终能不能读写,还与文件系统的 rwx 及其属主有关。
sync
async
sync 表示数据会同步写入到内存和硬盘中,async 表示数据会先暂存于内存中,而不后再写入到硬盘中。
no_root_squash
root_squash
挂载端若使用 NFS 文件系统的帐号为 root ,默认情况下,root 的身份会由 root_squach 的设置成为 nfsnobody,这种对服务器会比较有保障。但如果想要开放挂载端使用 root 身份来操作服务器的文件系统,那这里就需设置成 no_root_squach。
all_squash 不论使用 NFS 的 身份为何,都会被设置为匿名使用者,即 noboby(nfsnobody)。
anonuid
anongid
anon 意指 anonymous(匿名者),前面关于 *_squash 提到的匿名使用的 UID 设定值,通常为 nobody(nfsbody),但可以自行设定这个 UID 的值,当然,这个 UID 必需要存在于 /etc/passwd 当中。anonuid指 UID, 而 anongid指 GID。

启动与停止 NFS 服务


上面已提到,NFS 启动需要 rpcbind 的协助。
[bash gutter="false"]
[root@www ~]# /etc/init.d/rpcbind start
# 如果 rpcbind 本來就已經在运行,就不需要重新启动

[root@www ~]# /etc/init.d/nfs start
# 有时候某些 distributions 可能会出现如下的警告讯息:
exportfs: /etc/exports [3]: No 'sync' or 'async' option specified
for export "192.168.100.10:/home/test".
Assuming default behaviour ('sync').
# 上面的警告信息是在告知没有指定 sync 或 async 参数,NFS 默认会使用 sync,该警告可不理。

[root@www ~]# /etc/init.d/nfslock start
[root@www ~]# chkconfig rpcbind on
[root@www ~]# chkconfig nfs on
[root@www ~]# chkconfig nfslock on
[/bash]
若修改 /etc/exports 文件增加新的共享,应先停止 NFS 服务,再启动 NFS 服务方能使新增的共享起作用。使用命令 exportfs -rv也可达到同样的效果。

Linux 挂载其它 Linux 的 NFS 共享


[bash]
[root@www ~]# mkdir /mnt/nfs
# 建一个目录用作挂载点
[root@www ~]# mount -t nfs -o rw 192.168.100.1:/tmp /mnt/nfs
# 192.168.100.1 表示 NFS 服务端的主机 IP 地址,也可使用主机名,但需在 /etc/hosts 文件中。/tmp 是服务端共享的目录。
[root@www ~]# umount -f /mnt/nfs
#取消挂载
[/bash]

Using WGET with HTTP GET Parameters

FROM: Using WGET with HTTP GET Parameters

wget 在 *nix 系统中是一非常有用的工具,一般已由系统默认安装。

wget 可用来下载资源,如:
[bash]
wget http://cdn.mysql.com/Downloads/MySQL-5.5/mysql-5.5.28.tar.gz
[/bash]

附带参数:
[bash]
wget https://www.google.com/search?q=mysql
[/bash]
但当参数个数 >= 2 时,如果不将访问的链接用引号括起来,shell 会认为链接在 & 后就已经结束,请求解析失败。正确请求应是:
[bash]
wget "https://www.google.com/search?q=mysql&hl=en"
[/bash]

MySQL server has gone away

PHP 5.3.8,PDO 扩展在 PHP 源代码安装时启用。MySQL 5.1.4, Linux 2.6.27。

脚本伪代码:
[php]
$flags = array(
PDO::ATTR_PERSISTENT => true,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
$db = init_db($flags);

while(true) {
// retrieve data from db
}
[/php]

脚本运行时间超过 MySQL 服务器中设置的 wait_timeout 时间后,收到错误:
[sql gutter="false"]
SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
[/sql]

修改脚本,初始化 DB 连接时,设置 PDO::ATTR_PERSISTENT = false,问题不再出现。


在 PHP 的 bug 列表中找到类似的问题
Bug #37319 "MySQL server has gone away", with PDO::ATTR_PERSISTENT => true
,从下面评论来看,似乎对于 PDO::ATTR_PERSISTENT = true 出现的问题还是没解决。