月归档:六月 2007

利用web应用中的不均衡性重构你的技术细节

前提: Lamp架构(原理上虽然jsp,.net等都一样,但我现在只懂php了) 1.用户对准确度的要求是不一样的.银行会要求客户帐上的钱的数目永远是精确的,但是论坛的在线人数,贴子数没这个必要.每天有成千上成的贴子发表。谁会去对质?我们只半个小时算一个甚至每天算一次就行了.所以,应用中要是没加Cron,那就肯定不是一个好应用.想象一下awstats,每当你的老板让你给演示一下前一周的访问周数据时,它就嘎吱嘎吱地算上老半天,然后在你的老板快要睡着时IE终于弹出一个页:服务器超时…. 你就知道要把一些服务设为定时跑一次,而不是时时保持最新最准确了 2.瓶颈永远是先在CPU/内存/磁盘IO中的一个出现.他们很少是同时告急的.因此,针对这个设计一个.比如:某台服务器上CPU占用平均为60%左右,而内存占用是5%左右。那么我们可以预先猜测,CPU资源会首先占尽。由于日志显示占用CPU最多的是mysqld进程,说明mysql查询耗尽了CPU.再查之,原来是贴子主题太多,一个表有上G大小,索引不当. 找到问题,于是马上做出改进.原来的URL已经优化成***.com/topic/10/10001.html,***.com/topic/12/12001.html…这样的了,但其实后台是用rewrite的.而id从1到100,000的主题都因为已经太老,无人参与回复了,所以没必要每次都查库.马上写个脚本,将***.com/topic/1.html….***.com/topic/10/10001.html…这些页面都读下来,保存为web根下/topic/***/***.html文件。现在这些文件是实际存在的了,Apache会优先读这个静态文件,而不是适用rewriterule了. (注:我的apache 的rewrite规则是这样写的,这样文件找不到的时候会交给index.php来处理. rewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d rewriterule . /index.php [L] ) 现在再看一看,mysqld占CPU是少了不了.但还是不够啊.咱们的内存还没有用上呢。才10%,不行.于是又有了办法:架上squid或是类似缓存服务,大量起用内存缓存,现在就好多了.内存,CPU都用上了.如果这时CPU使用率仍然领先内存,那咱们再启用mem_cache,不过启用mem_cache后要改程序,改得好才能真正提交效率. 3.同是数据,用户名跟用户发的贴子内容这两个数据就不一样.一个咱们用varchar存在库中,另一个咱们得用text来存.这两个占用资源也大不一样啊.而且,贴子主题和发表用户名的读取的次数远大于贴子内容读取次数.这也是一个不均衡。于是基于这样的考虑,我把存储贴子数据表分开了。 现在的表是这样的:一个表存储用户名,发表时间,贴子标题等信息.另外建10个表,专门用来存储发贴内容.具体存在哪一个表,由这个主题贴ID的最后一位来定. 好了,由于发贴内容比较长,我把它分表(为了简化模型,是分表。实际有可能是分库,分服务器)了.而贴子主题由于要进行列表显示,搜索等操作,就没有分表.内容的查询效率是提高了。可是由于贴子主题要进行大量列表显示和搜索,且都在一个表中,还是慢啊. 不急,咱再分析. a:这个表中存储的数据都比较短小. b:这个表中常用来做列表显示,用户往往在论坛中是看了第一页标题,可能没什么吸引人的,于是又点了下一页…部分贴子会进去看一下内容.但是你见过用户一直点到第100页吗?而且,用户看贴子的量也绝对大于发贴子….除非他是供职于某论坛的版主…. 好了,又总结出不均衡性来了.大多数情况下用户只看前100页,那咱们就把这100页数据拿出来,建一个内存表,再放一份.Mysql内存表有一个限制,就是字段不能超过255字节,但咱们的这个表刚好符合.现在咱们写数据时主题表和存主题的内存表中都写入一次,读数据的时候,就从内存表中读…这样是不是快很多了? 参考: 把握web 开发的平衡与不平衡, http://www.162cm.com/archives/388.html 本文由蝌蚪安尼友情赞助.

发表在 未分类 | 标签为 , , , | 一条评论

Mysql server tuning(译文)

从某个英文pdf文档译过来的,很久了,还是Mysql Conference 2007时的PDF. (如果能找到,我把原文地址和pdf给出来) 向原作者致谢…. 调整Server Config时需要考虑的事情 设置是针对负载的,不存在说有什么针对一个16GB内存的优化方案这种说法. 存储引擎的选择或是混用是很重要的 有些设置取决于您的硬件和操作系统。 Approaching?tuning 您只需要设置一部分,其余的一些要具体分析(这些也很难决定如何去调整) 有些设置会影响Mysql的行为和安全,要小心 有些设置是可以基于连接的,利用这一点! 首先优化您的查询,否则您需要重新检阅您的设置。 常见错误: 运行默认设置。(当然如果您用来在您的本儿上存您的DVD收集资料, 那当然可以) 直接使用其他人的My.conf文件,都没检查一下是否符合您的需求。 虽然只有一两个查询需要,您仍为它设置了一个巨大的全局设置。您可以这样: SET sort_buffer_size=128000000; set sort_buffer_size=DEFAULT 我们能得到的信息: SHOW STATUS SHOW INNODB STATUS 操作系统的命令比如:vmstat,iostat,mpstat 使用内存: 为Mysql server分配更多内存常常带来显著的性能提升. 但是分配过多的内存会损失性能甚至是稳定性 检查一下: Swapping 查看swap IO ,这比简单地使用swap … 继续阅读

发表在 未分类, 译文 | 标签为 , , | 一条评论

升级了!Fedora 7 moonshine 升级成功

昨天以5Mb/s的速度提心吊胆地下Fedora core 7,一直担心网管会过来叫我停。还好,到下完他也没有过来。 马上烧盘,先在台式机上安装,接着又在notebook上安装。终于都安装成功,不过有点小问题: 1. Fedoar Core 6时,我的硬盘 显示是hda1,hda2…..hda6,没想到到7之后,变成了sda1,sda2,sda3,直接导致我的swap分区和windows分区无法加载。于是改了fstab,将hda3改成sda3,加载成功。 2. 原来安装的madwifi不起作用了.madwifi是依赖于内核的,内核升级一次,madwifi就需要重新安装一次。不过这次我惊喜地发现,yum search ***时,下载的不再是primary.xml,而是primary.sqlite.bz2,也就是说源数据不再以xml格式存储了,而是sqlite的格式,同时压缩方式也改了。不错的进步。原来分析这个数据要老长一段时间 .这次我不再自行编译madwifi,而是yum install madwifi kmod-madwifi,安装之后,仍是无动静。这时想起来madwifi是依赖于内核的,果然,重启之后就能用wireless 连AP了。 升级之后,界面漂亮多了,不再是那个难看的DNA了。本来宏伟前几天老秀他新装的vista的界面(在这这前,我的fedora core 6+beryl可要比他的XP 好看多了),现在,fedora 7 界面也不输vista 了。 本文由蝌蚪安尼友情赞助.

发表在 未分类 | 标签为 , , | 2 条评论

150行代码,搞定中文分词

中文分词一直是一个看起来似乎比较神秘的东西。记得java中的lucene好像自带了两个分词器。一个是按汉字分,就是一个字分成一个词。比如”我要到饭馆吃饭“,就被分成”我/要/到/饭/馆/吃/饭”.别一个是相邻的两个字分成一个词,分出来的结果是”我要/要到/到饭/饭馆/馆吃/吃饭”.然而这两种虽说在做搜索时建索引什么的操作时也是相当有用的,但是毕竟是一种权宜之计,咱不能一直停留在这个水平上。 下面是来自Rlucene的一段示例代码,154行,利用sogou的词库搞定了中文分词。代码如下: #! /usr/bin/ruby require “socket” #通过网络得到分词结果 def segChinese_net(line) @conn=TCPSocket.open(“localhost”,1099) @conn.write(line) line=@conn.read return line.split(” “) end @f= open(“dict/sogou.txt”) @datas=@f.read.split(“\n”) @f.close @f2=open(“dict/firstword.txt”) @firstwords=@f2.read.split(“\n”) @f2.close @maintable=Hash.new() @firstwords.each{|x| @maintable[x]=[x] } @datas.each{|x| @maintable[x[0].chr+x[1].chr+x[2].chr].push(x) } def segChinese(line) temp=0 max=(line.length/3) words=[] while(temp pos=temp*3 str1=line[pos].chr+line[pos+1].chr+line[pos+2].chr str12=str1 str1234=str1 … 继续阅读

发表在 Ruby, 未分类 | 标签为 , , , | 2 条评论

lighttpd上搞定wordpress,给出详细步聚.

千辛万苦,终于将博客搬家了。原来是用的edong.com的主机,现在转到了lighttpd+fastcgi上面。 第一步:导出原空间的数据。这个得用phpmyadmin来进行。注意的时,在导出数据时,由于导出来的中文有乱码,故而我先将所有text,varchar类型数据转成了blob类型 ,然后选中将“二进制区域使用十六进制显示”这一项,这样,导出的数据中就不会有显示不了的乱码什么的,有文字的地方都是0xf535acd….这样的东东。 第二步:自然是在新服务器上用mysql -u *** -p newdatabasename < export.sql 将数据库导入进去。 第三步:修改wp-config.php中数据库连接信息。 第四步:如果这时你访问时,能直接用原密码直接进入数据库,那么很幸运,你直接登陆就是了! 如果能登陆,但进入后台时,提示你无权限进入本页面,那么也很幸运,你又可以再熟悉一次安装流程了。这时很简单,把wp-config.php中的表示数据表前缀的改掉,然后再走流程安装一次。安装完后之后,记得登陆phpmyadmin把你需要的表比如wp_posts改成新的前缀名(之前你当然得删除wordpress的安装流程为你生成的对应的表)。比如,本来我的表都是带wp_的前缀,现在将table_prefix改为wp_2然后进行了安装,那么您应该把wp2_posts表删掉,然后把wp_posts改名为wp2_posts.同理,其他需要转移的表比如comments,categories等 等也要转移地过来。 在安装时,我遇到了一点小麻烦:当输入我的email进行下一步时,系统提示这是第二步,并告诉我将要进行一些建表,加载数据操作。但是不幸地是,没有告诉我新生成的密码!我找到了这一行: </p> <p>$random_password = substr(md5(uniqid(microtime())), 0, 6);</p> <p> 改成为 </p> <p>$random_password="123456";<br /> 然后将 </p> <p>@wp_mail($admin_email,_("New wordpress blog",....)</p> <p> 注释掉。现在没有什么拦住我了。我猜想是因为新的机器上没有sendmail服务,所以导致安装进程不能进行下去。现在安装成功能,默认密码就是:123456. 最后一步:太重要了:修改永久链接,以保持和原来的url一致。如果你的博客pr不高,访问量不怎么高,那么做不做无所谓。但是从SEO角度讲,最好还是保持一致。我原来的博客的链接设置的是: </p> <p>/archives/%post_id%.html</p> <p> 但是现在是lighttpd做server,它不支持apache的.htaccess文件里写mod_rewrite规则,怎么办? 我google了一下,找到一段巨复杂的正则表达式,却仍 … 继续阅读

发表在 未分类 | 标签为 , , , , | 一条评论