显示标签为“todo”的博文。显示所有博文
显示标签为“todo”的博文。显示所有博文

2009年6月1日星期一

apache2配置fastcgi

参考:http://www.cyberciti.biz/faq/freebsd-apache22-fastcgi-php-configuration/

遇到一个问题
[notice] mod_fcgid: process /usr/local/www/phpPgAdmin/images/themes/default/title.png(2905) exit(communication error), terminated by calling exit(), return code: 255
除了php都无法加载
解决办法, 把 SetHandler fcgid-script 注释掉 换上 AddHandler fcgid-script .php就成了

疑问:
1.FCGIWrapper /usr/local/bin/php-cgi .php 是做什么的
2.[notice] mod_fcgid: call /data/www/shop/shopadmin/index.php with wrapper /usr/local/bin/php-cgi 怎么解决?

没测过, 但是直观感觉是网站快了.. 呵呵

大量小文件的实时同步方案

转:http://blog.daviesliu.net/2008/04/24/sync/

大量小文件的实时同步方案

davies 发表于 2008 年 04 月 24 日

传统的文件同步方案有rsync(单向) 和 unison(双向)等,它们需要扫描所有文件后进行比对,差量传输。如果文件数量达到了百万甚至千万量级,扫描所有文件将非常耗时。而且正在发生变化的往往是其中很少的一部分,这是非常低效的方式。

之前看了Amazon的Dynamo的设计文档,它们每个节点的数据是通过Hash Tree来实现同步,既有通过日志来同步的软实时特点(msyql, bdb等),也可以保证最终数据的一致性(rsync, unison等)。Hash Tree的大体思路是将所有数据存储成树状结构,每个节点的Hash是其所有子节点的Hash的Hash,叶子节点的Hash是其内容的Hash。这样一旦某个节点发生变化,其Hash的变化会迅速传播到根节点。需要同步的系统只需要不断查询跟节点的hash,一旦有变化,顺着树状结构就能够在logN级别的时间找到发生变化的内容,马上同步。

文件系统天然的是树状结构,尽管不是平衡的数。如果文件的修改时间是可靠的,可以表征文件的变化,那就可以用它作为文件的Hash值。另一方面,文件的修改通常是按顺序执行的,后修改的文件比早修改的文件具有更大的修改时间,这样就可以把一个目录内的最大修改时间作为它的修改时间,以实现Hash Tree。这样,一旦某个文件被修改,修改时间的信息就会迅速传播到根目录。

一般的文件系统都不是这样做的,目录的修改时间表示的是目录结构最后发生变化的时间,不包括子目录,否则会不堪重负。因为我们需要自己实现这个功能,利用Linux 2.6内核的新特性inotify获得某个目录内文件发生变化的信息,并把其修改时间传播到它的上级目录(以及再上级目录)。Python 有 pyinotify,watch.py的代码如下:

  1. #!/usr/bin/python
  2. from pyinotify import *
  3. import os, os.path
  4. flags = IN_CLOSE_WRITE|IN_CREATE|IN_Q_OVERFLOW
  5. dirs = {}
  6. base = '/log/lighttpd/cache/images/icon/u241'
  7. base = 'tmp'
  8. class UpdateParentDir(ProcessEvent):
  9. def process_IN_CLOSE_WRITE(self, event):
  10. print 'modify', event.pathname
  11. mtime = os.path.getmtime(event.pathname)
  12. p = event.path
  13. while p.startswith(base):
  14. m = os.path.getmtime(p)
  15. if m <>
  16. print 'update', p
  17. os.utime(p, (mtime,mtime))
  18. elif m > mtime:
  19. mtime = m
  20. p = os.path.dirname(p)
  21. process_IN_MODIFY = process_IN_CLOSE_WRITE
  22. def process_IN_Q_OVERFLOW(self, event):
  23. print 'over flow'
  24. max_queued_events.value *= 2
  25. def process_default(self, event):
  26. pass
  27. wm = WatchManager()
  28. notifier = Notifier(wm, UpdateParentDir())
  29. dirs.update(wm.add_watch(base, flags, rec=True, auto_add=True))
  30. notifier.loop()

在已经有Hash Tree的时候,同步就比较简单了,不停地获取根目录的修改时间并顺着目录结构往下找即可。需要注意的是,在更新完文件后,需要设置修改时间为原文件的修改时间,目录也是,保证Hash Tree的一致性,否则没法同步。mirror.py的代码如下

  1. #!/usr/bin/python
  2. import sys,time,re,urllib
  3. import os,os.path
  4. from os.path import exists, isdir, getmtime
  5. src = sys.argv[1]
  6. dst = sys.argv[2]
  7. def local_mirror(src, dst):
  8. if exists(dst) and mtime == getmtime(dst):
  9. return
  10. if not isdir(src):
  11. print 'update:', dst
  12. open(dst,'wb').write(open(src).read())
  13. else:
  14. if not exists(dst):
  15. os.makedirs(dst)
  16. for filename in os.listdir(src):
  17. local_mirror(os.path.join(src,filename), os.path.join(dst,filename))
  18. os.utime(dst, (mtime,mtime))
  19. def get_info(path):
  20. f = urllib.urlopen(path)
  21. mtime = f.headers.get('Last-Modified')
  22. if mtime:
  23. mtime = time.mktime(time.strptime(mtime, '%a, %d %b %Y %H:%M:%S %Z'))
  24. content = f.read()
  25. f.close()
  26. return int(mtime), content
  27. p = re.compile(r'([\d.]+?) +([\w/]+)')
  28. def remote_mirror(src, dst):
  29. mtime, content = get_info(src)
  30. if exists(dst) and mtime == int(getmtime(dst)):
  31. return
  32. print 'update:', dst, src
  33. if not src.endswith('/'):
  34. open(dst,'wb').write(content)
  35. else:
  36. if not exists(dst):
  37. os.makedirs(dst)
  38. for mt,filename in p.findall(content):
  39. mt = int(float(mt))
  40. lpath = dst+filename
  41. if not exists(lpath) or int(getmtime(lpath)) != mt:
  42. remote_mirror(src+filename, lpath)
  43. os.utime(dst, (mtime,mtime))
  44. if src.startswith('http://'):
  45. mirror = remote_mirror
  46. else:
  47. mirror = local_mirror
  48. while True:
  49. mirror(src, dst)
  50. time.sleep(1)

如果源文件不在同一台机器上,可以通过NFS等共享过来。或者可以通过支持列目录的HTTP服务器来访问远程目录,mirror.py 已经支持这种访问方式。server.py 是用webpy做的一个简单的只是列目录的文件服务器。由于瓶颈在IO上,它的性能不是关键。server.py的代码如下:

  1. #!/usr/bin/python
  2. import os,os.path
  3. import web
  4. import time
  5. root = 'tmp'
  6. HTTP_HEADER_TIME = '%a, %d %b %Y %H:%M:%S %Z'
  7. class FileServer:
  8. def GET(self, path):
  9. path = root + path
  10. if not os.path.exists(path):
  11. return 404
  12. mtime = time.localtime(os.path.getmtime(path))
  13. web.header('Last-Modified', time.strftime(HTTP_HEADER_TIME, mtime))
  14. if os.path.isdir(path):
  15. for file in os.listdir(path):
  16. if file.startswith('.'): continue
  17. p = os.path.join(path,file)
  18. m = os.path.getmtime(p)
  19. if os.path.isdir(p):
  20. file += '/'
  21. print m, file
  22. else:
  23. print open(path,'rb').read()
  24. urls = (
  25. "(/.*)", "FileServer",
  26. )
  27. if __name__ == '__main__':
  28. web.run(urls, globals())

为了获得更好性能,以达到更好的实时性,Hash Tree最好是平衡的,比如BTree。如果一个文件发生变化,同步它需要进行的IO操作为N*M,其中N为数的层数,M为每层的文件数目。现在我们N为2,M最大为10000,适当减少它可以获得更好的性能,比如N为4,M为100。在以后创建目录结构时,最好能够考虑这方面的因素。

之前hongqn推荐过一个利用inotify的文件同步方案,同步方式类似于mysql和bdb等,由于过于复杂导致不可靠而没有采用。上面这个方案只用了一百多行Python代码就基本解决问题了,是不是很帅?:-)


2009年5月13日星期三

2009年3月26日星期四

svn lock 问题

今遇一问题:
svn 在客户端lock一个文件,无法解锁. 自己被自己锁掉了
解决方法:
到svn 所在目录 /[项目]/db/locks 清一下就ok 了. 日后再行了解

2009年1月13日星期二

php 自我编写规范

1. 用拿的准的方式 最快开发 敏捷. 写完一个function 优化, 写完一个class优化

2009年1月12日星期一

php 性能测试

http://bbs.phpchina.com/viewthread.php?tid=100306&extra=&page=1&sid=XJQSZd

2009年1月8日星期四

dired

待整理
http://learn.tsinghua.edu.cn:8080/2005211356/emacs/Dired.html
http://blog.chinaunix.net/u1/54415/showart_1716689.html
http://www.emacs.cn/Doc/Dired
info

2009年1月3日星期六

动态规划学习

http://www.comp.nus.edu.sg/~xujia/mirror/algorithm.myrice.com/algorithm/technique/dynamic_programming/chapter6.htm

2008年12月30日星期二

emacs 配置编写顺序问题

(setq load-path
(cons "~/Configurations"
(cons "~/Extensions" load-path)))
(load "macros") ;;宏定义文件
(load "modes")
(load "extensions");; 扩展配置
(load "emacs-std") ;; 标准配置
(load "bindings") ;; 绑定键
(setq outline-minor-mode-prefix [(control o)])

扩展配置放到了标准配置之前, 可今天遇到一个灵异问题 (setq outline-minor-mode-prefix [(control o)]),怎么都无效. 无奈之下 采用分段测试发, 一段段执行 找到问题...

在配置中有调用 org-mode(放在extensions.el中), (setq outline-minor-mode-prefix [(control o)]) 放在加载org-mode 之前有效而置后无效. 究其原因是因为 org-mode 是以outline-mode 为基础扩展的. 具体细节不得而知

需要重新思考 配置的加载顺序 是否要将 emacs-std 加载 拉到前边去

2008年12月11日星期四

第二阶段 工作重点

时间上放到 2009年 3月份开始,之前 加紧学习emacs 并初涉elisp
elisp 学习入门 http://learn.tsinghua.edu.cn:8080/2005211356/elispintro/HelloWorld.html
还需要一本好书 暂订 elisp manul http://www.gnu.org/software/emacs/manual/elisp.html

之后语言如下, 具体时间另行计划
1. c++
2. python
3.lisp
4.erlang Erlang 程序设计

2008年12月9日星期二

2008.12.10 需整理学习item

language:
erlang 了解一下
mysql:
http://www.jianzhaoyang.com/database/mysql_join_buffer_nested_loop_implement
http://www.jianzhaoyang.com/database/mysql_group_by_implement

emacs ibuffer

       自以为是
       ibuffer 是个我一直忽略掉的模式 ,虽然每天都在用, 但也不过略用皮毛而已. 
       今天突然想把所有 php 的文件标志出来, 并一切删除.  本打算用 宏来小试身手 却始终不够方便. 随意的 c-h m 看了下帮助, 才知道她的强大,  小看她了
       有点小感悟想写写,  未避免雷同 google 一下, 想写的已被人写的详尽, 那不如借他山之石以攻玉了
      Emacs中Ibuffer.el的使用 http://www.0-dong.com/blog/rewrite.php/read-473.html

补充:
     1.   所有ibuffer模式下的功能氛围  5大类
          +  在标记的buffer上的操作
          + 标记命令                 
          + 过滤命令
          + 过滤组命令
          + 其他命令   
   2.  / / 删除 所有过滤器..   这个很常用
        / a   +  [saved filters]
   3.  求人不如求己, 不会用了 c-h m 一下, 才是最方便的

2008年12月8日星期一

批量去掉bom头

windows下 find ./core -type f -name "*.php" -exec sed -i '1s/^\xef\xbb\xbf//' {} ;
linux 下 find ./core -type f -name "*.php" -exec sed -i '1s/^\xef\xbb\xbf//' {}  \;
bsd 下的sed比较奇怪 需要研究一下. 
bsd7.0下测试正常