Warning: curl_exec() has been disabled for security reasons in /pub/host/sunboyu/sunboyu/www/wp-includes/http.php on line 1022
一个程序猿 孙小一,孙小二,PHP,MYSQL,LINUX,APACHE,原创技术,扯淡

mysql5.5.8安装笔记

作者 : admin 于 2011年01月19日, 11:46:42
2011
01-19

mysql5.5.8对于守旧的人绝对是一种惨无人道的蹂躏。

我开始用mysql5.5.8了,被忽悠得天花乱坠,说性能提升,说主从同步迅速……

不过我是专用udf功能的,因为我常用的mysql稳定版本5.0.22官方说有点小bug,使用udf有点问题,被迫升级了5.5.8版本。

mysql5.5.8抛弃了我们钟爱的configure,而次用了cmake。

当然你要先安装cmake http://www.cmake.org/files/v2.8/cmake-2.8.3.tar.gz

cmake安装简单,tar后make && make install 搞定。

mysql5.5.8到官网下载 http://dev.mysql.com/downloads/mirror.php?id=399302#mirrors

tar出来,就找不到configure了,不过官方提供了高仿configure的转换脚本,不过神马都是浮云,自己折腾脚本吧

  1. cmake -DCMAKE_INSTALL_PREFIX=/opt/mysql-5.5.8 \
  2.       -DMYSQL_DATADIR=/opt/mysql-5.5.8/data \
  3.       -DSYSCONFDIR=/opt/mysql-5.5.8/etc \
  4.       -DINSTALL_PLUGINDIR=dir_name=/opt/mysql-5.5.8/plugin \
  5.       -DWITH_INNOBASE_STORAGE_ENGINE=1 \
  6.       -DWITH_ARCHIVE_STORAGE_ENGINE=1 \
  7.       -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
  8.       -DWITH_FEDERATED_STORAGE_ENGINE=1 \
  9.       -DWITH_PARTITION_STORAGE_ENGINE=1 \
  10.       -DMYSQL_UNIX_ADDR=/tmp/mysqld.sock \
  11.       -DMYSQL_TCP_PORT=3306 \
  12.       -DENABLED_LOCAL_INFILE=1 \
  13.       -DEXTRA_CHARSETS=all \
  14.       -DDEFAULT_CHARSET=utf8 \
  15.       -DDEFAULT_COLLATION=utf8-general_ci \
  16.       -DMYSQL_USER=mysql

然后make && make install就行。

剩下的事情就跟老版本的一样了,不过我编译的时候没有成功安装 mysql_install_db 脚本,自己写了一个,也算成功完成任务了。

discuz论坛大表优化

作者 : admin 于 2011年01月11日, 23:15:17
2011
01-11

通过观察,大部分的dz论坛在数据量发展到一定程度,在线人数逐渐提高后,首先锁表的是sessions,这个表我已经写过多种优化的方式,不外乎寻找一些比mysql负载性能好的程序来代替这部分工作。但时间长了,随着在线人数继续增加,那个附加的程序也会面临瓶颈。提高硬件性能和软件性能固然能提高负载,但一旦到瓶颈,必须想其他的方案。

硬件和简约的程序能提高性能,在大数据量下,算法的优势就能体现出来了。

顺便提一下主从:很多人认为主从可以解决问题,其实未必。设想一主多从结构,假如主库写压力很大,那同样压力会同步到从库,会造成N个从库压力同时很大。事实上从库压力会小于主库,因为主库是多进程写,而从库是单进程写, 但总的来说,执行的语句不会少。所以,主从这种结构在一定情况下也就失去了优势。(在硬件资源充裕,压力不是很大的环境下,这种问题发生较少,在硬件条件比较差的一些环境下,这种瓶颈很容易表现出来)

这里拿discuz7的posts表举例,摆脱主从结构,硬件比较差,表很大,10G以上。

一个负载大的dz论坛,在线人数多,又比较活跃,那posts表的压力肯定不会小。在一个回复比较频繁,存储引擎使用myisam的posts表,锁表是经常发生的,我所遇见的问题发生的环境为:数据库单点,无主从,io压力中等。posts表频繁锁表,而造成查询排队,查询速度骤然下降。

在不提升硬件的情况下,要想提速,显然是比较困难的,大量的文本数据装入memcached显然也不合适。所以,这个问题我用优化数据存储的角度对数据表进行了改造。

TIPS:同样100M带宽的集线器和交换机,交换机的吞吐性能远远高于集线器,原因在于:交换机建立专有通道,避免了冲突。

而在mysql中,锁表可以形象描述为冲突了,读写冲突了。但如果我们分表,把读写分散,也许会好点。

分表规则:按照tid进行hash,分散到16个表中。

假设,一读一写,两个操作,同时进行,那么他们撞在一起的几率就是1。如果分为两个表,那么他们撞在一起的几率就是1/2 = 0.5,用一个函数来表示,就是F(x)=1/x ,显然,分的表越多,冲突的机会越小,锁表的几率就越少。即时锁表,影响的也只是1/x的数据,不会对所有的用户造成影响。

数据模型解释:如果是绝对同步发生,几率应该是 F(x)=1/((x-1)*x),但在计算机里,无论两个操作时间间隔多小,在cpu时间片上都是顺序执行,因为,函数我认定为:F(x)=1/x。

以上用数学的方式解释了算法优化对性能的提升。实际上,通过对逍遥论坛的用户行为统计:posts表95%以上的操作都是在读写,搜索和管理占小部分。

补充一种分表算法:在discuzX里,后台启用了分表,我没有细看,大概是把表按照时间段或者其他条件分开。我猜测,作者本意是拆分老数据,主表只留最新数据和一些命中高的数据。这种方式可以起到一定效果,但根据统计,大部分用户习惯浏览回复最新帖子,因此,大部分的读写还是定位到了一张表,也就是没有彻底解决读写冲突的问题。
还有一个朋友使用的是顺序分表,500w个pid一张表,但这个方法同上个方法,没解决冲突问题。
所以,在他的基础上,我考虑出按照tid进行hash分表的方案。

说到这里,分表又给我们带来了麻烦,有些查询并不能用tid主键进行定位,这里我用了mysql合并表,这个合并表可以合并16个分表,成为一个大表进行查询,而表名依然用原始的表明,这样,dz中原来的功能就不受影响了。

此方案已经实现,我用的新老数据+分别hash的方式,即32张表存储posts数据的方式。但未做压力测试。最近努力学习loadrunner使用,这个压测马上就可以进行了。

小货倒库绝版秘籍

作者 : admin 于 2011年01月10日, 00:07:31
2011
01-10

AB库,车子默认在B库内。

1、B库到考试初试地点:前进->右杆进入右边第一个盲区(两块玻璃中间的盲区),右打轮一圈半,待车头变正,停止。
2、开始考试,帖库:看车后窗户,缓行,中杆(AB库中间的杆)进入右后盲区(驾驶室右后角的盲区),右打轮两圈打满,倒行,后窗户右侧立柱跟中杆重合后,左打轮一圈,倒行,中杆到右后盲区跟右侧立柱中间的位置,右打轮一圈打满,看左倒车镜,出现A库左后杆后,逐渐调整车子对准A库后边左右杆中间,右打轮两圈,方向盘打正,倒行,待车子后侧将近后侧的时候,停车,帖库完成。
3、移库:右打轮两圈打满,前进,待中杆移动到将近左倒车镜左数1/3的时候,停,左打轮四圈打满,前进,待车头打正的时候停止,如果车头不到前边线,可适当前进,右打轮四圈打满,倒行,视线看准后窗户立柱左边的立柱并且瞄准车后边左侧第二颗铆钉与第一颗铆钉中间,B库右后杆移动到第二颗铆钉上,停车,左打轮四圈打满,看车头,倒车,待车头摆正,停止,右打轮两圈,方向盘打正,前进,并且适当调整车子在车库中央,然后倒车,车子后边接近后边线,停止。
4、出库:左打轮一圈,前进,从A库出去,看车子右后角,将近出线的时候,左打轮一圈半,带车头摆正后,停止。
5、倒库:A库左杆刚出左边第一个盲区(左边两块玻璃中间的盲区),停止,左打轮两圈打满,倒行,待AB库中间的杆出线在后盲区后,后盲区最下边的边与杆相切,停止,右打轮一圈,继续倒行,待中杆第二次与后盲区最下边的杆相切,左打轮一圈打满,看右倒车镜,待B库右后杆出线在右倒车镜中,看左右倒车镜后边的杆线,调整车子摆正,倒车,待车头离前边线两米左右,停车。

考试完毕。必须6分钟内完成,不得压线,不得撞杆,不得违法步骤。

http://www.zyue.com/n/BU83/na70809.html 皮卡科目二蝴蝶桩过关技巧配图详解

http://teli.blog.hexun.com/36153356_d.html 科目二考试内容及技巧皮卡怎样定点停车,上坡起步,侧方位,单边桥,过圆饼

利用loadrunner做mysql压力测试

作者 : admin 于 2011年01月06日, 23:05:07
2011
01-6

loadrunner下的mysql c api

一个很简单的模拟用户访问论坛帖子的loadrunner测试脚本

最近跟测试组学习loadrunner的使用,测试组的姑娘们习惯用界面进行操作,而习惯linux平台使用的我很多功能都使用代码来实现了。

最近用loadrunner写了一个模拟社区用户压测论坛数据库的一个脚本,进行数据库的压力测试和优化工作。

用户行为分析:

在社区中,看帖的人是发帖人的10倍以上,而看帖人大概80%以上都在看新帖,20以下的用户有挖坟行为。

因此,设定如此的比率:每11个用户,1个发帖,8个看最近30%的帖,两个看老的70%的帖。

我的论坛帖子回复表大概是:973505个帖子的回复,两千多万的回帖。

根据这些数据,配合mysql的c api,写如下脚本:

注:脚本的my_mysql_insert()函数是有问题的,多线程下有一个资源符没处理好,因为还不太了解loadrunner的线程机制,所以留下了一个bug。

在做完这个脚本后,我发现我们测试机性能都不错,很难在一个5G大小的单表上主键查询造成很大的压力,所以,计划把dz论坛架设,用php+mysql真实环境下进行压测,这样可以顺便练习http函数下的loadrunner编程。

  1. globals.h
  2. #ifndef _GLOBALS_H
  3. #define _GLOBALS_H
  4. #include "lrun.h"
  5. #include "web_api.h"
  6. #include "lrw_custom_body.h"
  7. #include "modal_dialog_callbacks.h"
  8. #define random(x) (rand()%x)
  9. #include <mysql .h>
  10. #include <mysql_com .h>
  11. #include <mysql_time .h>
  12. #include <mysql_version .h>
  13. #include <typelib .h>
  14. #include <my_list .h>
  15. #include <my_alloc .h>
  16. #endif // _GLOBALS_H
  17. </my_alloc></my_list></typelib></mysql_version></mysql_time></mysql_com></mysql>
  1. vuser_init.c
  2. MYSQL *db;
  3. MYSQL_ROW record;
  4. vuser_init()
  5. {
  6. char sql[128];
  7. MYSQL_RES *results1;
  8.     lr_load_dll("libmysql.dll");
  9.     db = mysql_init(NULL);
  10. mysql_real_connect(db, "192.168.8.32", "root", "123456", "sunboyu_test", 3311, "/tmp/mysql3311.sock", 1);
  11.     
  12. sprintf(sql, "show tables");
  13. mysql_query(db, sql);
  14.     results1 = mysql_store_result(db);
  15.     while((record = mysql_fetch_row(results1)))
  16. {
  17.     lr_log_message("table = %s", record[0]);
  18.      }
  19. mysql_free_result(results1);
  20. return 0;
  21. }
  1. vuser_end.c
  2. vuser_end()
  3. {
  4.    mysql_close(db);
  5.    mysql_server_end();
  6. return 0;
  7. }
  1. Action.c
  2. Action()
  3. {
  4. int r1 = 0;
  5. char sql[128];
  6. r1 = random(11);            //10种用户,8种正常访问,两种在挖坟
  7. lr_log_message(" %d", r1);
  8.         if(r1==11)
  9.         {
  10.             my_mysql_insert();
  11.         }
  12.         else
  13.         {
  14.             my_mysql_query( r1 );
  15.         }
  16. return 0;
  17. }
  18.  
  19. int my_mysql_query( int randid )
  20. {
  21. int r2 = 0;
  22. int j = 0;
  23. int count = 0;
  24. int page = 0;
  25. char sql[128];
  26. MYSQL_RES *results2;
  27. if(randid&lt;2)  //老数据,小部分 20%
  28. {
  29. r2 = random(700000);
  30. sprintf(sql, "SELECT COUNT(*) AS count FROM posts_jx3 WHERE tid = %d;",r2);
  31. lr_log_message("%s",sql);
  32.         mysql_query(db, sql);
  33.         results2 = mysql_store_result(db);
  34.         while((record = mysql_fetch_row(results2)))
  35. {
  36.         lr_log_message("count = %d", record[0]);
  37.         }
  38. mysql_free_result(results2);
  39. page = count/10;
  40. lr_log_message("page = %d", page);
  41. for(j=0;j< =page;j++)
  42. {
  43. sprintf(sql, "SELECT *  FROM posts_jx3 WHERE tid = %d LIMIT %d,10;",r2,j);
  44. mysql_query(db, sql);
  45. lr_log_message("%s", sql);
  46. if (j>0) {
  47.   results2 = mysql_store_result(db);
  48.                   while((record = mysql_fetch_row(results2)))
  49.           {
  50.                      lr_log_message("pid = %d", record[0]);
  51.                    }
  52.           mysql_free_result(results2);
  53. }
  54. }
  55. }
  56. else //新数据,大部分 80%
  57. {
  58.         r2 = random(273505);
  59. r2 = r2+700000;
  60. sprintf(sql, "SELECT COUNT(*) AS count FROM posts_jx3 WHERE tid = %d;",r2);
  61. lr_log_message("%s",sql);
  62.         mysql_query(db, sql);
  63.         results2 = mysql_store_result(db);
  64.         while((record = mysql_fetch_row(results2)))
  65. {
  66. lr_log_message("count = %d", record[0]);
  67.         }
  68. mysql_free_result(results2);
  69. page = count/10;
  70. lr_log_message("page = %d", page);
  71.  
  72. for(j=0;j< =page;j++)
  73. {
  74. sprintf(sql, "SELECT *  FROM posts_jx3 WHERE tid = %d LIMIT %d,10;",r2,j);
  75. lr_log_message("%s", sql);
  76. mysql_query(db, sql);
  77. if (j>0) {
  78.   results2 = mysql_store_result(db);
  79.                   while((record = mysql_fetch_row(results2)))
  80.           {
  81.                       lr_log_message("pid = %d", record[0]);
  82.                    }
  83.           mysql_free_result(results2);
  84. }
  85. }
  86. }
  87. mysql_free_result(results2);
  88. return 0;
  89. }
  90.  
  91.  
  92.  
  93. int my_mysql_insert()
  94. {
  95. int t;
  96.     char sql[500];
  97. MYSQL_RES *results3;
  98. sprintf(sql,"%s","INSERT INTO posts_jx3 ( fid, tid, first, author, authorid, subject, dateline, message, useip, invisible, anonymous, usesig, htmlon, bbcodeoff, smileyoff, parseurloff, attachment, rate, ratetimes, status) VALUES ( 12345, 215053, 0, 'fdsafsdfsd', 2265065, '', 1240535917, 'fdsfsdfdsfd', '118.239.49.229', 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0);");
  99. lr_log_message("%s", sql);
  100.     t = mysql_query(db, sql);
  101. if(t)
  102. {
  103. lr_log_message("%s", mysql_error(db));
  104. }
  105. else
  106. {
  107. lr_log_message("%s", "suc");
  108. }
  109. }

linux挂载ntfs分区

作者 : admin 于 2010年12月22日, 21:54:06
2010
12-22

最近有点数据需要在linux环境下处理,我用的是centos,最简方式安装,默认不支持ntfs格式。

查资料后,有两种方式可以使centos支持ntfs:1、重新编译内核 2、增加一个插件

重新编译内核成本有点高,而且风险比较大,尝试以下插件后,很好用:

http://tuxera.com/opensource/ntfs-3g-2010.10.2.tgz

下载后,解压,进入目录 ./configure && make && make install 即可

然后查看硬盘分区信息:fdisk -l

我的移动硬盘可以显示如下信息:

  1. Device Boot      Start         End      Blocks   Id  System
  2. /dev/sda1               2       19457   156280320    f  W95 Ext'd (LBA)
  3. /dev/sda5               2        1306    10482381    7  HPFS/NTFS
  4. /dev/sda6            1307        5222    31455238+   7  HPFS/NTFS
  5. /dev/sda7            5223       19457   114342606    7  HPFS/NTFS

挂载命令 mount -t ntfs-3g /dev/sda7 /data1

访问 /data1 即可访问/dev/sda7 分区

discuz全文检索lucene解决方案图例

作者 : admin 于 2010年12月17日, 11:17:12
2010
12-17

discuz论坛搜索方案

已经全部调试通过,正在往一个线上环境上部署。文档也在敢写之中,谢谢关注。

discuz优化心得

作者 : admin 于 2010年12月14日, 15:16:41
2010
12-14

自从09年10月份接到公司论坛改造升级任务到现在,逍遥论坛 http://bbs.xoyo.com 在性能和负载方面相对稳定,修改了原来的结构,单程序可以支持多论坛(模仿5d6d http://www.5dforum.com/ )。有几个参数可以参考:

平时在线人数:5000~10000人 峰值:50000+(超过5w后,统计表性能明显下降,关闭了统计)

之前每逢峰值论坛常挂,改造之后有充足的预案防止出问题,保证论坛用户能及时在论坛传达必要消息。

在论坛改造过程中,我写了很多文章来表述改造中的一些心得,也认识了很多朋友一起讨论dz的优化。其中最宝贵的经验,是一些无能为力的站长把他们的服务器交给我,让我亲手在一个大负载的服务器上去做优化,在这个过程中学到了很多系统优化方面的知识,更宝贵的是获得了大负载下dz的一些瓶颈点的数据。

由于考虑用户群的问题,很多技术没有办法用开源的软件实现,也无法找到替代品,考虑实际,很多dz站长自己并没有实力去涉入维护一个更改很多的论坛,所以我的方案并没有大量去应用。

在帮朋友优化的过程中,提到更多的是技术实力与维护、需求的增删与性能的平衡。

所以,我得出这样的结论供大家参考:

1、每个功能都会吃系统资源,充分考虑每个功能是否必须,不必须的功能一定要砍。

2、找系统压力点:根据我对逍遥论坛用户日志的分析,90%的压力集中在 forumdisplay.php viewthread.php上,而这些脚本的压力主要体现在表联查而造成的锁表上,最主要的表就是sessions表。sessions表集合了很多用户统计相关功能,因为,优化此表,结合上条原则,合理增删功能,达到压力减小。

3、硬件的优化。硬件优化也是我最近考虑的一个方案,想对于开发人员,硬件的开销还是很小的。合理升级硬件也是一个不错的方案。

以上结论是针对中小型网站已经碰到瓶颈的dz程序做出的建议。

而对于一个负载很大,并且有实力的团队,那在discuz上要做的文章就太多了。

1、拆表是必然的,而对于一些数据量不大但经常变动的表,完全可以全cache。

2、根据需求删改功能。discuz很强大, 但不是每个功能都是你必须使用的。

3、开源产品会给你很多灵感。

推荐的一些开源技术方案:

memcached(不用说了)

Tokyo Cabinet DBM:性能极佳的持久存储的keyvalue数据库

mysql udf http http://blog.s135.com/mysql-udf-http/ 让tt变成从库?

lucene 必须要替换discuz默认的搜索

你还有什么想法?

一时兴起,写此文。欢迎有兴趣的朋友加 discuz性能优化讨论群 qq:41886598

使用awstats对nginx的日志进行分析

作者 : admin 于 2010年12月10日, 16:13:31
2010
12-10

抛弃apache很长时间了,一直在用nginx,基于第三方的统计系统很多,故很久没有分析过web服务器的日志。最近日志突然暴增,从站长统计无法看出具体暴增的原因,故配置awstats进行分析。

awstats在nginx上运行,这个配置我没做过,所以,我依然使用apache作为awstats的服务器使用。只不过换一个端口而已。

apache配置:安装请看之前的日志,配置文件增加一行配置,具体为

  1. <directory "/opt/httpd-2.2.9/cgi-bin">
  2.     AddHandler cgi-script .pl .cgi  #这行即可
  3.     AllowOverride None
  4.     Options None
  5.     Order allow,deny
  6.     Allow from all
  7. </directory>

配置好,基本就可以启动了。注意端口号,别跟nginx重复了。

下载awstats:http://downloads.sourceforge.net/project/awstats/AWStats/7.0/awstats-7.0.tar.gz?r=http%3A%2F%2Fawstats.sourceforge.net%2F&ts=1291968393&use_mirror=cdnetworks-kr-1

解压后,找到 cgi-bin classes css icon js 这几个文件夹。其中cgi-bin里的文件放到apache的 cgi-bin目录下,其他放到apache的网站根目录。

然后访问 hostname:8080/cgi-bin/awstats.pl 看是不是有结果。

配置站点:

复制 cgi-bin目录下 awstats.model.conf 文件 为 awstats.hostname.conf

修改如下几个关键点

  1. LogFile="/home/www/log/www.google.com.log" #nginx的日志
  2. SiteDomain="www.google.com"
  3. HostAliases="localhost google.com 127.0.0.1 REGEX[myserver\.com$]"

配置完这些, 基本就可以使用了。

另外,还要生成报表:命令为

/opt/httpd-2.2.9/cgi-bin/awstats.pl -update -config=hostname 为了方便,可以加到crontab里。到这里就配置完了。

逍遥问问正式上线

作者 : admin 于 2010年12月08日, 22:22:45
2010
12-8

逍遥问问今天正式上线。 http://ask.xoyo.com

逍遥问问是我2010年下半年9月份接到的项目,项目需要替换老的逍遥问答系统,打造一个新的游戏问答互动系统。

产品涉及老数据的导入,系统的开发,兼容游戏产品的接口,团队配备三个开发人员、四个测试人员、一个前端页面制作人员和一个产品设计人员。

经过一期二期的努力开发,几百个bug的修改,数次需求跟进完善,逍遥问问成功上线。

我们团队有新人老人,男生女生,在各种困难、争执、矛盾的情况下,按照既定日期顺利上线。

感谢大家,我们是一个很强的团队。

开始学车

作者 : admin 于 2010年12月04日, 21:53:38
2010
12-4

公司组织团购了北方驾校的培训班,金山大部队,一个屋子全是金山的弟兄,还碰上了一个非常富有激情的法培教室,那是相当的刺激啊。

怀念家里的拖拉机,就报了手动挡皮卡小车。

周末学习,居然比上班起的都早,累的要死,不过痛并快乐着,虽然短期不买车,不过驾照也是一个相当实用的社会文凭。

感谢金山优秀的后勤经理克明大哥。

 Page 3 of 48 « 1  2  3  4  5 » ...  Last »