9月 28

pyinotify监控文件和文件夹变化

【2011-9-28 张子萌】

之前写了脚本,死循环调用inotifywait监控文件夹,如果文件有变动,则启动

rsync进行同步。但是当前需求有点变化,文件要按照日期建文件夹进行存储,

且文件变化很快,如果直接监控最顶级目录系统资源将消耗很大,所以考虑还是自

写一下好,如果系统资源量变化大,且不用时时同步时可以根据文件变动对变动

对文件进行记录,可以按照优先规则进行同步。

官方网站 : http://trac.dbzteam.org/pyinotify

系统要求:Linux kernel with inotify 2.6.13

Python 2.4

直接使用easy_install安装非常简单

# sudo easy_install pyinotify

如果不能联网,则需要直接下载压缩包,进行编译安装。

首先测试下是否可用:

使用以下命令监控/tmp文件夹,

# python -m pyinotify /tmp

/tmp文件夹下新建1.txt,并随后进行删除。看到显示的记录如下:

效果不错,继续向下进行。只要有创建、删除和关闭写就打印出变化的文件或目录,代码如下:

import re

import pyinotify

wm = pyinotify.WatchManager()

mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE | pyinotify.IN_CLOSE_WRITE

class EventHandler(pyinotify.ProcessEvent):

def process_IN_CREATE(self, event):

self.rebuild(event)

def process_IN_DELETE(self, event):

self.rebuild(event)

def process_IN_CLOSE_WRITE(self, event):

self.rebuild(event)

def rebuild(self, event):

chang_name=re.compile(“.+.swp$|.+.swx$|.+.swpx$”)

if not chang_name.match(event.pathname):

print event.pathname

handler = EventHandler()

notifier = pyinotify.Notifier(wm, handler)

wdd = wm.add_watch(‘/tmp’, mask, rec=True,auto_add=True )

notifier.loop()

代码里使用正则表达式过滤因为使用vim打开文件产生的缓存文件。也可以用exclude_filter方法

在官方文档中例子如下,但是我测试多次没有成功,所以直接用正则过滤。

# Exclude patterns from list

excl_lst = [‘^/etc/apache[2]?/’,

‘^/etc/rc.*’,

‘^/etc/hostname’,

&nb
sp;
‘^/etc/hosts’,

‘^/etc/(fs|m)tab’,

‘^/etc/cron..*’]

excl = pyinotify.ExcludeFilter(excl_lst)

# Add watches

res = wm.add_watch([‘/etc/hostname’, ‘/etc/cups’, ‘/etc/rc0.d’],

pyinotify.ALL_EVENTS, rec=True, exclude_filter=excl)

如果监控文件太多,需要对系统做一下修改sysctl -n -w fs.inotify.max_user_watches=16384

9月 27

linux下用python生成二维码


【张子萌 2011-9-27】
库的官方网站

http://fukuchi.org/works/qrencode/index.en.html

需要使用CythonCython是用来生成 C 扩展到而不是独立的程序的。所有的加速都是针对一个已经存在的 Python

用的一个函数进行的。还需要安装PIL

先下载了qrencode-3.1.1.tar.gz,使用configuremakemake install进行安装,手动生成了一个图,却是可用。

开始制作。

安装Cypthon

# easy_install cython

在官方下载bitly-pyqrencode-1cfb23c.tar.gz

# tar zxvf bitly-pyqrencode-1cfb23c.tar.gz

# cd bitly-pyqrencode-1cfb23c

使用Cpython安装qrencode

# cython qrencode.pyx

阅读README确认系统中有以下文件

you need libqrencode somewhere in your LD path (/usr/local/lib)

you need qrencode.h somewhere on your include path (/usr/local/include)

# python setup.py install

安装完毕测试以下。

脚本如下

from qrencode import Encoder

cre = Encoder()

img = cre.encode(“博客地址:http://simon-zzm.blog.163.com/ n电子邮件:simon-zzm@163.com”, { ‘width’: 300 })

img.save(‘out.png’)

生成图片如下:

linux下用python生成二维码 - simon-zzm - simon个人观点

9月 27

[转发] nodejs下mysql性能测试

nodejs下mysql性能测试

By qingdu on 2011 年 02 月 14 日
本文为原创文章,出自http://cnodejs.org,转载请注明出处和作者
作者:qingdu
原文:http://cnodejs.org/blog/?p=404

近期对node下的几个mysql操作库做了一下简单的调研
主要是针对这3个module进行
libmysqlclient,mysql-native, mysql

node-libmysqlclient

https://github.com/Sannis/node-mysql-libmysqlclient
基于libmysql的封装, 支持阻塞与非阻塞两种操作方式,目前在query部分功能比较完善,prepare statement方面还是有些bug,实际测试中一直出core

安装

npm install mysql-libmysqlclient

node-mysql

https://github.com/felixge/node-mysql
纯node的实现, 支持prepare statement, 数据的获取支持事件与callback两种方式

安装

npm install mysql

node-mysql-native

https://github.com/sidorares/nodejs-mysql-native

纯node的实现, 内置有简单的连接池支持,支持prepare statement, 数据的获取只支持通过事件方式

安装

npm install mysql-native

测试设计

测试表结构

CREATE TABLE `test10` (
`id` int(10) unsigned NOT NULL DEFAULT '0',
`txt` varchar(500) DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

测试数据

分别生成了含10, 100, 500, 1500行记录的4张表
使用10个并发连接分别对其进行SELECT * FROM table的查询

测试结论

NewImage.jpg

其中数值表示qps值

在结果集较小时node-mysql-native明显胜出
当结果集增大到接近100行时,node-libmysqlclient开始表现出更佳的性能
node-mysql性能与其他两个module差距比较大,如果对性能有一定要求的话,则其基本不可用

测试代码

http://code.google.com/p/cnodejs/source/browse/#svn%2Ftrunk%2Fmysql-benchmark

9月 26

centos安装node.js简单测试

操作系统

Centos 5.4 Linux 2.6.18-164.el5 4G内存、Xeon(TM) CPU 3.20GHz

node-v0.5.7

node的官方网站http://nodejs.org/ 使用官方网站示例。

再安装前请将开发工具(tcl-developenssl-develglibc-devel bzip2*等)安装,可以使用yum工具。

安装

# tar zxvf node-v0.5.7.tar.gz

# cd node-v0.5.7

# ./configure

# make

有报make: [all] Error 1 (ignored) 但是没有找到问题,忽略了直接做下一步。

# make install

收到安装成功讯息。

建立一个node.js档案。

vim node.js

var http = require(‘http’);

http.createServer(function (req, res) {

res.writeHead(200, {‘Content-Type’: ‘text/plain’});

res.end(‘Hello Node.jsn‘);

}).listen(8124, “192.168.1.200”);

console.log(‘Server running at http://192.168.1.200:8124/’);

执行node.js

# node node.js

打开浏览器使用连接http:// 192.168.1.200:8124看到Hello Node.js,就表示node.js已经正在运作中。

进行个简单测试,使用apacheab工具

命令# ./ab -c10000 -n 40000 http:// 192.168.1.200:8124/

Complete requests: 40000

并发数: 3498.75 [#/sec]

平均返回相应时间: 0.286 [ms]

传输量: 266.51 [Kbytes/sec]

无请求失败。

在同一台机器上使用django写个,测试一下。

环境Python 2.6.6 django 1.3.0 关闭debug状态

代码为:

#!/bin/evn python

from django.http import HttpResponse

def index(request):

html = “Hello Djangon”

return HttpResponse(html)

直接使用python自带的调试服务器

# python manage.py runserver 192.168.1.200:9000

因为4000030000时将服务器跑死了(报错apr_socket_recv: Connection timed out (110)),所以修改为25000进行测试,结果也死了,改20000也死了,直接改15000也死了。算了我不测了。

总结:初步看node js效率确实很高,python+django自带的服务器的效

9月 11

mysql双机热备恢复问题

Mysql中双机热备比较常见。运维过程中遇到一个问题,备机或主机的其中一台遇到硬盘物理故障,重装系统后需要重新同步数据。这时就遇到了一个问题,用“FLUSH TABLES WITH READ LOCK;”命令锁上所有表或者再mysqldump数据时使用“–lock-all-tables”或“–master-data”参数导出数据,但是数据库被锁不能操作,前台业务会报错,问题很严重。在oracle中有SCNThe System Change Number),在mysql的二进制日志中有position,所以只能从此处考虑。

所以我写一个脚本,思维逻辑如下:

a) 使用语句“show master statusG;” 获得导出开始的position的点

b) 开始导出整库数据

c) 导出完毕,再使用语句“show master statusG;” 获得导出结束的position的点

d) binlog中导出开始position点到结束position点得变化的增量数据

导入逻辑:

a) 先导入整库数据

b) 再导入增量的数据

c) 然后确认开始同步的position点,开始同步

做增量的数据需要使用mysql自带的mysqlbinlog命令,mysqlbinlog也可以远程使用,为了防止网络问题所以没有采用远程的方案。

Mysqlbinlog命令的主要参数如下:

-d, –database=name 仅列出该数据库相关的

-F, –force-if-open 强行读出正在使用的二进制文件

-j, –start-position=# 开始读取点

–stop-position=# 结束读取点

 –start-date 开始获取时间

 –stop-date 结束获取时间

导出完毕,在备机上先恢复整库文件,再恢复增量文件,再设置恢复点。还有几个文件问题没有太仔细考虑,如备份过程中二进制日志切换,数据量大的时候会出现增量和整库的重复等问题未考虑。本处只是抛砖引玉。

脚本如下(注意折行问题):

#!/bin/sh

#————————————————

# file name: mysql_dump_binlog.sh

# Revision: 1.0

# Date: 2011-09-10

# Author: simon-zzm

# Email: simon-zzm@163.com

# ———————————————–

#############set bases value

mysql_path=’/usr/local/mysql’

dump_path=’/usr/local/checksystem’

mysql_host=’192.168.1.12′

mysql_user=’root’

mysql_pass=’qq’

mysql_data=’test’

#############main

start_time=`/bin/date +%Y-%m-%d %H:%M:%S`

${mysql_path}/bin/mysql -h${mysql_host} -u${mysql_user} -p${mysql_pass} -e ‘show master statusg;’>/tmp/mysql_start_read_mast

get_start_f=`tail -1 /tmp/mysql_start_read_mast|/bin/awk ‘ ”{print $1}’`

#${mysql_path}/bin/mysqldump -h${mysql_host} -u${mysql_user} -p${mysql_pass} ${mysql_data}>${dump_path}/${mysql_data}_${now_time}.sql

sleep 30

${mysql_path}/bin/mysql -h${mysql_host} -u${mysql_user} -p${mysql_pass} -e ‘show master statusg;’>/tmp/mysql_end_read_mast

get_end_p=`/usr/bin/tail -1 /tmp/mysql_end_read_mast|/bin/awk ‘ ”{print $2}’`

get_end_f=`/usr/bin/tail -1 /tmp/mysql_end_read_mast|/bin/awk ‘ ”{print $1}’`

echo “dump database ${mysql_data} ok.”

stop_time=`/bin/date +%Y-%m-%d %H:%M:%S`

${mysql_path}/bin/mysqlbinlog -d${mysql_data} -F –start-date=”${start_time}” –stop-date=”${stop_time}” ${mysql_path}/data/${get_start_f}>${dump_path}/${mysql_data}_repair_${now_time}.sql

echo “CHANGE MASTER TO MASTER_LOG_FILE=’${get_end_f}’,MASTER_LOG_POS=${get_end_p} ; “

/bin/rm -rf /tmp/mysql_start_read_mast /tmp/mysql_end_read_mast

echo “repair database ${mysql_data} ok.”