Archive

Archive for February, 2008

PDO和sqlite的一点体会

February 22nd, 2008 Fwolf No comments

用php写了一个小工具,顺便体验了下PDO和sqlite,一个是php5自带的数据库层,一个是简易的文件型数据库,没什么章法,简单记录在这里。

  • 配合pdo使用,只用安装php5-sqlite即可,php5-sqlite3这个extension可能是单独的sqlite支持,就是类似mysql,有专门的sqlite_connect函数。
  • 系统中也可以安装单独的sqlite3(不带3的是sqlite2),采用类似mysql的shell方式管理库文件。
  • 通过PDO好像无法查询数据库的结构等信息,只能操作DML。
  • 不知道pdo使用sybase(dblib)的时候是否能在sql中使用limit,以及使用了是否有效,要到hardy 8.04 php5-sybase才支持pdo,到时候再试验。
  • Bug: rowCount()无法工作于pdo_sqlite数据库,其他一些函数也有小问题,官方文档的user comment中有说到。
  • PDO的exec方法可以一次执行多条sql,但不返回结果,而query则只能执行一条,返回结果信息。
  • 使用PDO的prepare和PDOStatement的execute不仅有助于加速同一sql不同参数的调用速度,还有助于防止sql注入攻击。
  • prepare的:name不能是表名,大概只能是where中的变值,prepare中的字符型:name不需要带上引号,这一点很方便。

总体感觉,PDO还没有AdoDb方便,大概是用熟了的感觉,但功能上的确要少一些。sqlite数据库表现不错,但由于数据类型、结构、功能相对简单,还是主要用在小型、简单一点的应用里更合适。

Update @ 2008-03-23

来一个使用PDO调sqlite库的例子:

try {
    $db = new PDO("sqlite:/path/to/db/file", null, null, array(PDO::ATTR_PERSISTENT => true));
} catch (PDOException $ex) {
    die("[Error] " . $ex->getMessage() . "\n");
}

// Useless but carefully is better, set encoding.
// Sqlite always use utf-8 internaly, UTF-8 is also it's default value.
$db->query('PRAGMA encoding = "UTF-8"');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// Begin query
$stmt = $db->query("PRAGMA table_info({$tbl})");
// PHP bug: rowCount() not work with pdo_sqlite
if (0 == count($stmt->fetchAll())) {
    // Table not exists or have no columns
    ......

另外在使用ADODB的时候,它默认好像并不直接支持sqlite3,而是sqlite2(ADODB版本为V5.04 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com)),所以只能通过pdo来实现(即ADODB中使用的数据库类型为pdo),可pdo在这个版本的ADODB中支持也不是很全面,drivers目录下甚至没有adodb-pdo_sqlite.inc.php文件(网上搜了一下,这个文件似乎在某些地方有),所以,只能这样用了:

//ADODB设定
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;

try
{
    $conn = &ADONewConnection('pdo');
    @$conn->Connect('sqlite://path/to/db/file');
}
catch (Exception $e)
{
    adodb_backtrace($e->getTrace());
    exit();
}

// Check create table, adodb&sqlite3 not work very well, MetaTables() un-usable
//$rs = $conn->MetaTables();
$rs = $conn->Execute("SELECT name FROM sqlite_master WHERE type='table' AND name='my_table_name'");
if (1 > $rs->RecordCount())
{
    // Table does not exists
    ......

Connect前面的@如果去掉,会有Notice错误出现:

Notice: Undefined property:  ADODB_pdo_base::$_genIDSQL in /home/fwolf/dev/php_includes/adodb5/drivers/adodb-pdo.inc.php on line 106

Notice: Undefined property:  ADODB_pdo_base::$_dropSeqSQL in /home/fwolf/dev/php_includes/adodb5/drivers/adodb-pdo.inc.php on line 108

所以,只能说是ADODB对sqlite3的兼容性还不是很好。

Related posts

Categories: Database, PHP Tags: , , , ,

[MediaTemple]虚拟主机内存优化的一点心得

February 19th, 2008 Fwolf 2 comments

今天下午好像有人对服务器ddos,或者大量灌spam(我不敢说每个人都安装了anti spam插件,即使安装了,“应对”spammer也要消耗服务器资源),http服务器耗尽服务器资源后挂掉,一会儿被watchdog重启,过不了多一会儿再次挂掉。。。以前也尝试过优化apache,不过今天似乎终于摸到了一点儿窍门。

我们合租的MediaTemple服务器cpu负载不高,内存相对紧张:

top - 23:39:45 up 16 days,  7:24,  2 users,  load average: 0.58, 0.50, 0.47
Tasks:  46 total,   1 running,  45 sleeping,   0 stopped,   0 zombie
Cpu(s):  9.9% us,  2.5% sy,  0.0% ni, 87.6% id,  0.0% wa,  0.0% hi,  0.0% si
Mem:    689496k total,   550892k used,   138604k free,        0k buffers

所以优化主要针对如何节约内存。主机内存实际是256M,可能是多核的缘故,总显示接近700M内存,不过对应的各个进程占用的内存也相应增加了。MediaTemple的KB中有一篇(dv) HOWTO: Performance tuning (Optimization),先按照这个来优化一下,主要分为三个部分。

优化Apache(httpd)

缩短超时时限:

#Timeout 120
Timeout 30

调整prefork参数,我调整的结果是:

<IfModule prefork.c>
#1/1/3
StartServers       1
MinSpareServers    1
MaxSpareServers    3
# 50 ?
ServerLimit       20
MaxClients        20
MaxRequestsPerChild  2000
</IfModule>

StartServers是开始的httpd进程数,Min和Max SpareServers是最少和最多空闲进程数,ServerLimit和MaxClients是总进程数限制,这两个参数一般来说是相同的,httpd所消耗的总内存数就和这个相关(实际进程数还会多两个,应该是负责管理子进程的“父进程”),内存不够可以把这两个数值进一步缩小,但这也同时对应着httpd同时处理的并发数。MaxRequestsPerChild是每个进程在处理多少个任务后自杀,根据需要和相关设置还会再启动新的子进程,这种机制有利于释放一些内存碎片。

MaxClients不够会在log产生错误信息,可以用下面的命令查询:

grep -i maxclient /var/log/httpd/error_log

可以根据情况再调整MaxClients的值,但如果内存就是短缺,又能有什么办法呢?

优化Mysql

设置缓存,在my.cnf的[mysqld]段中增加:

# Cache
query-cache-type = 1
query-cache-size = 16M

虽然会多占用一些内存,但能加快处理的速度,尽快把等待队列“消化”掉,还是有利于加速的。在mysql中可以查询cache使用情况:

mysql> show status like 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 12       |
| Qcache_free_memory      | 13028408 |
| Qcache_hits             | 35117    |
| Qcache_inserts          | 751      |
| Qcache_lowmem_prunes    | 0        |
| Qcache_not_cached       | 56       |
| Qcache_queries_in_cache | 377      |
| Qcache_total_blocks     | 872      |
+-------------------------+----------+
8 rows in set (0.00 sec)
...... some times late ......
mysql> show status like 'Qcache%';
+-------------------------+---------+
| Variable_name           | Value   |
+-------------------------+---------+
| Qcache_free_blocks      | 88      |
| Qcache_free_memory      | 8837920 |
| Qcache_hits             | 164437  |
| Qcache_inserts          | 3572    |
| Qcache_lowmem_prunes    | 0       |
| Qcache_not_cached       | 432     |
| Qcache_queries_in_cache | 1177    |
| Qcache_total_blocks     | 2579    |
+-------------------------+---------+
8 rows in set (0.00 sec)

调整query-cache-size的值让Qcache_lowmem_prunes保持在0最好,设置太大了也是浪费内存。

关闭不需要的服务

比如named,域名解析使用域名注册商提供的就足够了,关闭spamassassin,邮件服务仅限于对外发送邮件,不接收:

chmod 644 /etc/init.d/psa-spamassassin

watchdog暂时不建议关闭,人不在的时候它会自动重启服务,还是有一点用处的。

其它优化设置

从其它地方还看到可以开启KeepAlive:

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15

这样每个连接可以发送100次请求,超时时间为15秒。如果KeepAliveTimeout减少一些,MaxKeepAliveRequests还可以设置得更大一点。

还可以启用apache的压缩输出功能:

<ifmodule mod_deflate.c>
#   DeflateCompressionLevel 2
    AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-httpd-php application/x-javascript text/css
</ifmodule>

简单观察一下,开启deflate之后,服务器cpu idle值大概会减少15~20%,国外主机数据传输本身就慢,希望这些花销值得。

top - 01:39:03 up 16 days,  9:23,  3 users,  load average: 2.16, 2.09, 1.97
Tasks:  48 total,   1 running,  47 sleeping,   0 stopped,   0 zombie
Cpu(s): 24.1% us,  8.4% sy,  0.0% ni, 67.6% id,  0.0% wa,  0.0% hi,  0.0% si
Mem:    689496k total,   431452k used,   258044k free,        0k buffers
Swap:        0k total,        0k used,        0k free,        0k cached

结果

现在看一下结果,ps -U apache u能看到一共有20个apache进程在运行,占用内存总量为:

root@fwolf:~# ps -U apache u|awk '{S+=$6} END {print S}'
385396

随着服务运行,内存使用量还会增加(所以MaxRequestsPerChild别设太大,定期重启一些进程)。再看看那个疑似对我ddos的家伙:

root@fwolf:~# netstat -nap|grep :80|wc -l
513
root@fwolf:~# netstat -nap|grep TIME_WAIT|wc -l
9
root@fwolf:~# netstat -nap|grep 124.115|wc -l
464
root@fwolf:~# netstat -nap|grep 124.115.0|wc -l
376
root@fwolf:~# netstat -nap|grep 124.115.4|wc -l
93

此时服务器访问稍慢,有时会超时,但起以前动不动内存不足,httpd挂掉要好一些了。查了一下,这个IP地址属于“陕西省西安市 电信”,地址总换,但基本都在上面两个网段之内。

再后来,访问量降下来之后,系统就恢复正常了,优化应该还是对服务器速度有一些作用的。

root@fwolf:~# netstat -nap|grep :80|wc -l; netstat -nap|grep TIME_WAIT|wc -l
69
47

最后贴两张后台流量图表,异常大概开始于18号下午16点,导致18号流量剧增。服务器时间是西8区,所以小时图表中的0点就是16点。按天的那个图表不知为什么出不来,不过注意18号的流量只是前9个小时的就是了。

Free Image Hosting at www.ImageShack.us

Free Image Hosting at www.ImageShack.us

另外,合租的兄弟们,现在新的dv主机默认是PHP 5.2了,咱们啥时候升级呢?

参考

Update @ 2008-01-19

看来我的担心是多余的,mod_deflate启用之后并没有耗费太多系统资源,访问量恢复正常之后,cpu load也恢复了正常:

top - 16:15:45 up 17 days, 0 min,  1 user,  load average: 0.04, 0.05, 0.07
Tasks:  51 total,   1 running,  50 sleeping,   0 stopped,   0 zombie
Cpu(s):  1.8% us,  0.7% sy,  0.0% ni, 95.9% id,  1.7% wa,  0.0% hi,  0.0% si
Mem:    689496k total,   510200k used,   179296k free,        0k buffers
Swap:        0k total,        0k used,        0k free,        0k cached

好像启用了KeepAlive后httpd进程轮换得特别快,不像以前半天不重生一个。现在可以清楚的看到18号全天的流量图标了,再补两张图:

Free Image Hosting at www.ImageShack.us

Free Image Hosting at www.ImageShack.us

按每小时400M流量计算,每秒流量为110K,不知道算是个什么样的水平。

Update @ 2008-01-19

关闭named服务后,jail环境的ssh用户使用wget下载文件会遇到Name or service not known错误,把/etc/resolv.conf也配置到chroot中就可以了。有趣的是,如果named服务启动着就不存在这个问题。

顺便还把denyhosts装上了,daemon模式运行,占内存不多,攻击者还不少呢,值得。参考:使用DenyHosts阻止SSH暴力破解

Related posts

为了Linux,BT可别没喽

February 13th, 2008 Fwolf 7 comments

看标题,Linux怎么能和BT扯上关系呢?并非因为这两个都是开源东东,而是,对日常拿linux作为桌面系统的使用者来说,BT真是越来越重要了。。。为什么捏?

现在用Linux免不了上网,上网就免不了下载东西,传统的下载无外呼http或者ftp方式,这两种方式基本上用wget都能搞定,除非文件比较大,而比较大的文件提供的更多下载方式是BT,包括我们喜爱的各种电影,应该说现在下载电影的主要方式就是BT了。所幸,Linux下的BT软件还是非常丰富的,那我们还担心什么呢?

说实话,我担心的是迅雷、脱兔之类的软件,今天在神话论坛下载电影的时候就发现,下载的链接是这样的:

下载 || 迅雷下载:【www.btmyth.com】先婚后友◎BT神话论坛◎神话.torrent (42.62 KB)

只有前面两个字“下载”点击是BT的种子,后面包括名称的一长串链接都是迅雷的下载链接,作为BT用户有一种“失落”感。还有很多软件下载站,提供的http或ftp下载链接根本不能用,然后再给一个迅雷的下载链接,简直就是逼良为娼,好在我很少上这种下载站。

迅雷、脱兔在国内占有很大市场,很多人也都喜欢用,在这里我不评论他们的好歹,但我知道他们都没有linux版,所以作为linux桌面用户,下载我还是只能用BT。至于emule/amule,一般下载站很少提供这样的链接,不讨论了,和BT性质类似,反正用mldonkey也都支持。

对了,现在还有个新出的什么scm烂格式,别说不兼容linux了,在windows下也不稳定,还没法转码,比avchd还难搞定。

假如没有了BT,大家都只提供迅雷或脱兔的下载链接,电影都是scm格式,Linux用户怎么办?像qq一样放弃么?

Related posts

Categories: Internet Tags: , ,