• 2009-11-11

    我的第一个python脚本 - [python]

    呵呵,最近在学习python,只明白了大概,很多还不会,不熟悉。现在放一个python程序,目标是:遍历文件夹里的torrent文件,分析hash info 加密后是否跟原文件的文件名相同,不同的话,记录log文件。我写起来有点复杂,感觉还不是按照python的思维来写程序,要学的还很多。

    #! /usr/bin/python

    from sys import *
    from bencode import *
    import hashlib
    import os
    import os.path

    #-----test-----
    #if len(argv) != 2:
    #    print "ERROR: use ./33.py filename"
    #    exit(2)
    #file_name = argv[1]
    #-----test-----

    def check_torrent_hash(file_name):
        filename ='torrent/'+file_name
        metainfo_file = open(filename, 'rb')
        if metainfo_file:
            metainfo = bdecode(metainfo_file.read())
        else:
            print "ERROR: Not a valid torrent file"
            exit(1)
        metainfo_file.close()
        info = metainfo['info']
        hahaha =  bencode(info)
        mySha1 = hashlib.sha1()   
        mySha1.update(hahaha)
        mySha1_Digest = mySha1.hexdigest()
        up_str = mySha1_Digest.upper();
        OK = file_name.split('.')   
        #print up_str
        #print OK[0]
        if not up_str==OK[0]:
            error_file = open('/home/changyou/wget/error.log', 'a+')
            error_file.writelines(up_str+'\n')
            error_file.close()
            return 'NO~~please check /home/changyou/wget/error.log'
        else:
            return 'OK!!!'

    rootdir = "/home/changyou/wget/torrent/"
    for parent, dirnames, filenames in os.walk(rootdir):
        for filename in filenames:
            print check_torrent_hash(filename)


     

  • 2009-11-10

    python取BT种子的hashinfo - [python]

    折腾了1天,BT果然是变态,名副其实。

    BT是python编写,他的种子文件时以Bencoding编码格式编码,具体如下
    无论是web服务器提供的那个.torrent文件,还是peers和trackers进行的信息交互,都是基于Bencoding格式的。
    1 字符串:首先是字符串长度,然后是一个:号,接着是串内容,比如5:hello,就是指hello这个字符串。
    2 整数:以“i”开头(int的意思),然后是十进制数字,最后是一个“e”结尾,如i3e表示3,i-3e表示-3,i0e表示0,i-0e是非法的。
    3 列表:以“l”开头(list的意思),以“e”结尾。比如 l5:hello5:worldi1234ee 代表 ["hello","world",1234]
    4 字典:以“d”开头(dictionary),以“e”结尾。比如 d3:cow3:moo4:spam4:eggse,则代表{"cow":"moo", "spam","eggs"}

    这里,我们要取的info是种子文件里‘字典’info后面的所有(包括d,到最后的包括e),很长一串。

    最开始写了一个PHP脚本,只是分析的种子文件,只是把种子文件里的数据用数组的形式显,然后用函数sha1(),结果得到的hashinfo不正确。崩溃ing

    后来google了下,发现用python比较靠谱,因为有现成的模块,代码如下:

    #! /usr/bin/python
    ffrom sys import *
    from bencode import *
    import hashlib

    mySha1 = hashlib.sha1()  //新建对象
    if len(argv) != 2:
        print "ERROR: use ./hash_info.py filename"

        exit(2)
    filename = argv[1]
    metainfo_file = open(filename, 'rb')
    try:
        metainfo = bdecode(metainfo_file.read())
    except ValueError:
        print "ERROR: Not a valid torrent file"
        exit(1)
    metainfo_file.close()
    info = metainfo['info'] //取列表的info
    hahaha =  bencode(info) //取torrent的info

    mySha1.update(hahaha)
    mySha1_Digest = mySha1.hexdigest()
    print mySha1_Digest  //得到info sha加密后的数据!!

    ---------------------------------------------------------------------

    注意:在linux下自带的python里没有hashlib模块,和bencod模块

    需要下载安装,hashlib     http://code.krypto.org/python/hashlib/

    bencod需要下载BitTorrent源码,或者下载单独文件:http://www.pinking.net.cn/scrip/bencode.py,跟脚本程序放在同一目录下即可

  • 2009-10-25

    123

    去年的这个时候

    Tag:
  • 2009-10-14

    7个简易网页效果mootools插件 - [JQuery]

    最近研究,前台展示的东西,发觉会的东西实在是少,不会div切图,JS也不咋地,看来要学习的还很多啊。转帖,留下以备后用!

    脚本的最大优点就是仅仅一小段巧妙就可以极大地提升网站的用户体验,得意于Mootools开发社区非常擅长于开发一些专业的高质量插件,我今天可 以收集到一些值得在网站设计中使用的插件,他们可以帮助你提高网站用户体验到一个新的层次,当前前提是你喜欢mootools。

    引文原文:http://davidwalsh.name/7-mootools-plugins

    AutoGrow

    我很确信文本域和文本框都应该提供一个可以自动放大的效果,AutoGrow 可以让文本域的大小自动的渐变,这样你即便输入很多容内也可以在文本域内完整的看到所有内容。
    Download && DEMO 

    Fancy Form

    FancyForm

    FancyForm 是checkbox增强插件,用来替换表单中奇丑的checkbox和radio,FancyForm 的样式完全由css控制。

    Website & Download Documentation Example Usage

     

    Milkbox

    Milkbox

    图片丰富的网站都少补了一个好的灯箱效果(更多的灯箱效果可以猛点这里:http://jsssc.cn/30-useful-ajax-lightbox-and-modal-dialog-solutions/)插件,Milkbox包含了实现所有灯箱效果的脚本,它可以轻松实现各种经典的渐变效果到页面元素上,经常用在flash视频,图片集,xml画廊。

    Website, Download, Documentation, & Example Usage

     

    Quickboxes

    不要让用户一个亿个去点击很多的复选框,Quickboxes允许通过点击并拖动来同时选中多个复选框,只需点击其中一个然后拖动鼠标,有鼠标经过 的复选框都可以被选中(也可以设置成切换选中状态),有时候你的用户可能需要选中复选框中的一部分而已, Quickboxes可以帮你忙。

    Website & Download Documentation Example Usage

     

    SmoothScroll

    SmoothScroll可以让页面缓缓地移动到指定的锚点,从而可以代替默认的跳动效果。

    Website & Download Documentation Example Usage

     

    MooTools Tooltip

    Tips

    Tips是用来代替默认的提示title的效果,它帮你创建富有质感的提示框。

    Website & Download Documentation Example Usage

     

    Zebra Tables

    ZebraTables

    ZebraTables 帮你实现表格的隔行换色、单击变色、鼠标滑过变色效果。

    Website & Download Documentation Example Usage

    Tag:JS
  • 2009-10-13

    提交textarea到mysql,换行 - [php]

    郁闷,折腾了半天,提交的数据室带换行的,结果取出来不换行,google了半天,说得云里雾里,一会又是css一会又是js的,最后PHP的nl2br函数搞定。$data = nl2br($data);

    真是郁闷,被这个小东西搞了半天,丢人啊

  • 2009-09-25

    mysql 关于索引 - [mysql]

    MySQL索引 在数据库表中,对字段建立索引可以大大提高查询速度。假如我们创建了一个 mytable表:

    CREATE TABLE mytable(

    ID INT NOT NULL,

    username VARCHAR(16) NOT NULL

    );

    我们随机向里面插入了10000条记录,其中有一条:5555, admin。

    在查找username="admin"的记录 SELECT * FROM mytable WHERE username='admin';时,如果在username上已经建立了索引,MySQL无须任何扫描,即准确可找到该记录。相反,MySQL会扫描 所有记录,即要查询10000条记录。

    索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索包含多个列。

    索引的类型包括:

    (1)普通索引
    这是最基本的索引,它没有任何限制。它有以下几种创建方式:

    ●     创建索引

    CREATE INDEX indexName ON mytable(username(length));

    如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length,下同。

    ●     修改表结构

    ALTER mytable ADD INDEX [indexName] ON (username(length))

    ●     创建表的时候直接指定

    CREATE TABLE mytable(

    ID INT NOT NULL,

    username VARCHAR(16) NOT NULL,

    INDEX [indexName] (username(length))

    );

    删除索引的语法:

    DROP INDEX [indexName] ON mytable;

    (2)唯一索引
    它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:

    ●     创建索引

    CREATE UNIQUE INDEX indexName ON mytable(username(length))

    ●     修改表结构

    ALTER mytable ADD UNIQUE [indexName] ON (username(length))

    ●     创建表的时候直接指定

    CREATE TABLE mytable(

    ID INT NOT NULL,

    username VARCHAR(16) NOT NULL,

    UNIQUE [indexName] (username(length))

    );

    (3)主键索引
    它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引:

    CREATE TABLE mytable(

    ID INT NOT NULL,

    username VARCHAR(16) NOT NULL,

    PRIMARY KEY(ID)

    );

    当然也可以用 ALTER 命令。记住:一个表只能有一个主键。

    (4)组合索引
    为了形象地对比单列索引和组合索引,为表添加多个字段:

    CREATE TABLE mytable(

    ID INT NOT NULL,

    username VARCHAR(16) NOT NULL,

    city VARCHAR(50) NOT NULL,

    age INT NOT NULL

    );

    为了进一步榨取MySQL的效率,就要考虑建立组合索引。就是将 name, city, age建到一个索引里:

    ALTER TABLE mytable ADD INDEX name_city_age (name(10),city,age);

    建表时,usernname长度为 16,这里用 10。这是因为一般情况下名字的长度不会超过10,这样会加速索引查询速度,还会减少索引文件的大小,提高INSERT的更新速度。

    如果分别在 usernname,city,age上建立单列索引,让该表有3个单列索引,查询时和上述的组合索引效率也会大不一样,远远低于我们的组合索引。虽然此时有了三个索引,但MySQL只能用到其中的那个它认为似乎是最有效率的单列索引。

    建立这样的组合索引,其实是相当于分别建立了下面三组组合索引:

    usernname,city,age

    usernname,city

    usernname

    为什么没有 city,age这样的组合索引呢?这是因为MySQL组合索引“最左前缀”的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这三列的查询都会用到该组合索引,下面的几个SQL就会用到这个组合索引:

    SELECT * FROM mytable WHREE username="admin" AND city="郑州"

    SELECT * FROM mytable WHREE username="admin"

    而下面几个则不会用到:

    SELECT * FROM mytable WHREE age=20 AND city="郑州"

    SELECT * FROM mytable WHREE city="郑州"

    (5)建立索引的时机
    到这里我们已经学会了建立索引,那么我们需要在什么情况下建立索引呢?一般来说,在WHERE和JOIN中出现的列需要建立索引,但也不完全如此,因为 MySQL只对<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE才会使用索引。例如:

    SELECT t.Name

    FROM mytable t LEFT JOIN mytable m

    ON t.Name=m.username WHERE m.age=20 AND m.city='郑州'

    此时就需要对city和age建立索引,由于mytable表的userame也出现在了JOIN子句中,也有对它建立索引的必要。

    刚才提到只有某些时候的LIKE才需建立索引。因为在以通配符%和_开头作查询时,MySQL不会使用索引。例如下句会使用索引:

    SELECT * FROM mytable WHERE username like'admin%'

    而下句就不会使用:

    SELECT * FROM mytable WHEREt Name like'%admin'

    因此,在使用LIKE时应注意以上的区别。

    (6)索引的不足之处
    上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:

    ●     虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

    ●     建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。

    索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。

    (7)使用索引的注意事项
    使用索引时,有以下一些技巧和注意事项:

    ●     索引不会包含有NULL值的列

    只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。

    ●     使用短索引

    对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。

    ●     索引列排序

    MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

    ●     like语句操作

    一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。

    ●     不要在列上进行运算

    select * from users where YEAR(adddate)<2007;将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成select * from users where adddate<‘2007-01-01’;

    ●     不使用NOT IN和<>操作

    NOT IN和<>操作都不会使用索引将进行全表扫描。NOT IN可以使用NOT EXISTS代替,id<>3则可以使用id>3 or id<3来代替。

    Tag:Mysql
  • 2009-09-22

    用nginx的反向代理做负载均衡 - [service]

    1. ngnix之所以比apache高效,得益于Nginx使用了最新的epoll(Linux 2.6内核)和kqueue(freebsd)网络I/O模型,而Apache则使用的是传统的select模型。目前Linux下能够承受高并发访问的 Squid、Memcached都采用的是epoll网络I/O模型。也就是说,在高并发服务器中,轮询(round-robin)I/O是最耗时间的操作。

    2. 反向代理工作原理
    反向代理服务器位于本地WEB服务器和Internet之间.
    当用户浏览器发出一个HTTP请求时,通过域名解析将请求定向到反向代理服务器(如果要实现多个WEB服务器的反向代理,需要将多个WEB服务 器的域名都指向反向代理服务器)。由反向代理服务器处理器请求。反向代理一般只缓存可缓冲的数据(比如html网页和图片等),而一些CGI脚本程序或者 ASP之类的程序不缓存。它根据从WEB服务器返回的HTTP头标记来缓冲静态页面。有四个最重要HTTP头标记:

    Last-Modified: 告诉反向代理页面什么时间被修改
    Expires: 告诉反向代理页面什么时间应该从缓冲区中删除
    Cache-Control: 告诉反向代理页面是否应该被缓冲
    Pragma: 告诉反向代理页面是否应该被缓冲.
    例如:在默认情况下,ASP页面返回” Cache-control: private.” ,所以ASP页面时不会在反向代理服务器缓存的。

    ----------------------------------------------------------------------------------

    3. ngnix最常见的用法之一就是作为反向代理使用,安装和配置相当简便,对于负载均衡它使用的是最简单的轮询算法(round-robin),不过效果还是很不错的。

    要用nginx做负载均衡的话,首先要在配置文件里面定义一组用来负载均衡的后端服务器(backend servers),例如:
    upstream backend {
      server 192.168.1.11;
      server 192.168.1.12;
      server 192.168.1.13;
    }

    那个server指令的语法是 server name [parameters],这里的name是服务器名,可以是域名、ip或者unix socket,也可以指定端口,例如:
    server 192.168.1.11:8080;

    server指令可用的参数有:

    weight —— 设置服务器的权重,默认值是1,权重值越大那么该服务器被访问到的几率就越大,例如 server 192.168.1.11 weight=5;

    max_fails和fail_timeout —— 这俩是关联的,如果某台服务器在fail_timeout时间内出现了max_fails次连接失败,那么nginx就会认为那个服务器已经挂掉,从而在 fail_timeout时间内不再去查询它,fail_timeout的默认值是10s,max_fails的默认值是1(这意味着一发生错误就认为服 务器挂掉),如果把max_fails设为0则表示把这个检查取消。
    举个例子:server 192.168.1.11 max_fails=3 fail_timeout=30s; 这表示,如果服务器192.168.1.11在30秒内出现了3次错误,那么就认为这个服务器工作不正常,从而在接下来的30秒内nginx不再去访问这个服务器。

    down —— 表示该服务器已经停用,例如server 192.168.1.11 down;

    backup —— 表示该服务器是备用服务器,只有其它后端服务器都挂了或者很忙才会访问到。

    关于upstream的更多信息请参考 http://wiki.nginx.org/NginxHttpUpstreamModule

    定义好了一组后端服务器,就该来设置nginx的反向代理配置了,例如:
    server {
      listen 80;
      server_name www.domain.com;
      location / {
        proxy_pass http://backend;
      }
    }

    关于nginx的proxy有很多配置参数的,具体可以参考 http://wiki.nginx.org/NginxHttpProxyModule
    这里有个配置可能比较有用:
    proxy_set_header Host $host;
    这表示传递给后端服务器的头部信息里面的Host信息保持跟客户端传过来的一致,如果不设置那么默认传给后端服务器的值是$proxy_host,所以不 设置可能会有问题,例如:后端服务器会处理两个域名的请求,例如www.a.com和www.b.com,这时如果nginx不把客户端的请求信息中的 host信息传给后端服务器,那么后端服务器完全不知道到底这个客户是想访问域名a还是域名b,从而导致传输数据可能不正确。
    如果你想把客户端的ip也传给后端服务器的话,可以用这个设置:
    proxy_set_header X-Real-IP $remote_addr;

    4. 负载均衡
    参考:http://blog.s135.com/nginx_php_v5/
  • 2009-09-18

    2009-09-18

    最近工作不忙,无所事事,正临10月国庆大假,再加上感情变故,因此无比的浮躁,时不时就想抓狂,在taobao买了块表,还没到货,心里也欠欠的,就跟等考试成绩似的,很不爽,感觉内心有无数小蚂蚁在乱窜,我觉得我该去踢踢球,或许运动运动,累得精疲力尽就会好了吧。

    买的书到了,《mysql性能调优与架构设计》,大家都对此书评价超高,希望它对我的工作会有些帮助。其实走程序员这条路太辛苦,需要不停的学习不停的积累,光靠一个看家本领混饭吃还不够,需要更多才行。最近2个月实在是太荒废了,需要好好调整一下,10月回家好好休息休息吧,思考思考,心平气和才是上策。

    生活艰辛啊,不过在这里哀怨不是办法,付出了多少就会回报多少,加油吧。

    Tag:
  • 2009-09-14

    http_load 一个httpd 压力测试工具 - [service]

    到http://www.acme.com/software/http_load/ 下载http_load ,安装也很简单直接make;make instlall 就行。

    http_load的标准的两个例子是:

    1. http_load -parallel 5 -fetches 1000 urls.txt  
    2. http_load -rate 2 -seconds 300 urls.txt  

     

    例子只是个参考,参数其实可以自由组合,参数之间的选择并没有什么限制。比如你写成http_load -parallel 5 -seconds 300 urls.txt也是可以的。我们把参数给大家简单说明一下。-parallel 简写-p 含义是并发的用户进程数。

    -fetches 简写-f 含义是总计的访问次数

    -rate    简写-p 含义是每秒的访问频率

    -seconds简写-s 含义是总计的访问时间


    urls.txt 是一个url 列表,每个url 单独的一行。当然也可以直接跟一个url 而不是url 列表文件。
    实例:
    1. http_load -rate 5 -seconds 10 urls  
    2. 49 fetches, 2 max parallel, 289884 bytes, in 10.0148 seconds  
    3. 5916 mean bytes/connection  
    4. 4.89274 fetches/sec, 28945.5 bytes/sec  
    5. msecs/connect: 28.8932 mean, 44.243 max, 24.488 min  
    6. msecs/first-response: 63.5362 mean, 81.624 max, 57.803 min  
    7. HTTP response codes:  
    8.   code 200 -- 49  
     
    分析:
    1.49 fetches, 2 max parallel, 289884 bytes, in 10.0148 seconds
    说明在上面的测试中运行了49个请求,最大的并发进程数是2,总计传输的数据是289884bytes,运行的时间是10.0148秒

    2.5916 mean bytes/connection
    说明每一连接平均传输的数据量289884/49=5916

    3.4.89274 fetches/sec, 28945.5 bytes/sec
    说明每秒的响应请求为4.89274,每秒传递的数据为28945.5 bytes/sec

    4.msecs/connect: 28.8932 mean, 44.243 max, 24.488 min
    说明每连接的平均响应时间是28.8932 msecs,最大的响应时间44.243 msecs,最小的响应时间24.488 msecs

    5.msecs/first-response: 63.5362 mean, 81.624 max, 57.803 min

     6、HTTP response codes: code 200 -- 49
    说明打开响应页面的类型,如果403的类型过多,那可能要注意是否系统遇到了瓶颈。
    特殊说明:这里,我们一般会关注到的指标是fetches/sec、msecs/connect
    他们分别对应的常用性能指标参数Qpt-每秒响应用户数和response time,每连接响应用户时间。测试的结果主要也是看这两个值。当然仅有这两个指标并不能完成对性能的分析,我们还需要对服务器的cpu、men进行分析,才能得出结论
  • 2009-08-25

    mysqldumpslow分析mysql运行 - [mysql]

    mysql自带的这个玩意挺好使的,可以对慢查询里的sql进行排序、计算等操作。

    首先得配置my.cnf:
    log_slow_queries = /path/slow.log # 定义log位置,注意要有写入的权限

    具体的使法如下:
    mysqldumpslow -s c -t 40 /path/slow.log

    出来的结果是访问次数最多的40个sql,几个参数大概意思如下:

    -t 显示多少条
    -s 排序,默认是at。c是次数,t是时间,l是lock时间,r是返回结果。如果是ac,at,al,ar则是倒序
    -g 可以用正则匹配部分语句

    可以参考mysqldumpslow --help,通过这个工具可以看到哪些锁表,或者其他性能问题,还能看到某些SQL_NO_CACHE提示呢,去想办法优化把!

    Tag:Mysql
  • 2009-08-25

    Nginx中文参考资料!! - [service]

    http://code.google.com/p/nginxsrp/wiki/NginxCodeReview

    概述:
    Nginx
     ("engine x") 是一个高性能的 HTTP 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器
    Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的Rambler.ru 站点开发的,它已经在该站点运行超过四年多了。
    Igor 将源代码以类BSD许可证的形式发布。自Nginx 发布四年来,Nginx 已经因为它的稳定性、丰富的功能集
    、示例配置文件和低系统资源的消耗而闻名了。目前国内各大门户网站已经部署了Nginx
    如新浪、网易、腾讯等;国内几个重要的视频分享网站也部署了Nginx,如六房间、酷6等。
    新近发现Nginx 技术在国内日趋火热,越来越多的网站开始部署Nginx
    Tag:nginx
  • 2009-08-21

    中文全文搜索解决方案sphinx+mysql+mmseg,安装,配置,API调用 - [service]

    最近在研究中文搜索引擎,找了许多解决方案,有JAVA下的的Lucene,还有强大的C++下的fietex,哪些比较复杂,对现在的项目来讲,不是很实用,所以把目光瞄向了轻便的sphinx,今天安装还算顺利,以下备忘。
    首先,Sphinx默认不支持中文索引及检索,以前用补丁搞定,现在,写补丁那个项目组的人又弄了个CSFT,全称是:CoreSeek Fulltext Search Server,CoreSeek 全文检索服务器。于是呢,就把sphinx集成过来,挺好用的。

    1. 去Coreseek官网下载源码,需要mmseg和Coreseek Fulltext Server最好用源码安装,那个RPM文件包反正我没搞定,呵呵。
    2. 装mmseg。
          # tar zxf mmseg3_0b3.tar.gz
          # cd mmseg3_0b4;
          # ./configure –prefix=/Data/apps/mmseg
    (这个目录可以改)
          # make && make install
         运行mmseg,如果成功会有显示
         
    3. 装CSFT   
      # tar zxf csft3_0b4.tar.gz
          # cd csft3_0b3
          # ./configure -prefix=/Data/apps/sphinx  (这个需要mysql和mmseg,别把目录写错了)
          -with-mysql=/Data/apps/mysql        
          -with-mmseg=/Data/apps/mmseg
          -with-mmseg-includes=/Data/apps/mmseg/include/mmseg
          -with-mmseg-libs=/Data/apps/mmseg/lib/
          -with-mysql-includes=/Data/apps/mysql/include/mysql/
          -with-mysql-libs=/Data/apps/mysql/lib/mysql/
          # make && make install


    4. sphinx.conf
        安装完成后,会生成/Data/apps/sphinx/etc/sphinx.conf.dist  要更改为.conf
        #cp /Data/apps/sphinx/etc/sphinx.conf.dist /Data/apps/sphinx/etc/sphinx.conf
       
    5. 生成字典
        因为用到中文分词,需要生成字典,去安装目录,比如我的是 /home/changyou/mmseg.3.0b3/data/
        #mmseg -u unigram.txt 该命令执行后,将会产生一个名为unigram.txt.uni的文件,将该文件改名为uni.lib,完成词典的构造。
        然后,在/Data/apps/sphinx/var/下建立文件夹 dict,然后把uni.lib放进去
       
    6. 配置
        sphinx.conf 文件中需要对charset_dictpath指定uni.lib的路径/Data/apps/sphinx/var/dict/
        还有连接mysql的信息,这个不用说了罢。
        这里有个参数对于中文用户要注意一下:
        charset_type
        字符集编码类型。可选选项,默认为“sbcs”。已知的值包括“sbcs”和“utf-8”。
        对于中文用户,可选的值还可以有“zh_cn.utf-8 ”和“zh_cn.gbk”。当设置charset_type值为上面的两种时,系统默认您开启了中文分词特性。
        但是我设置了zh_cn.utf-8,报错说“unknown charset type 'zh_cn.utf-8'”,不知道为什么。。。。。

    7. 运行
         # /Data/apps/sphinx/bin/indexer
         启动索引服务时,如果报下面的错:
         error while loading shared libraries: libmysqlclient.so.15: cannot open shared object file: No such file or directory
         原因应该是因为mysql的lib文件不在系统的lib搜索路径上导致的。
         运行命令,解决:
         # ln -s /Data/apps/mysql/lib/mysql/libmysqlclient.so.15 /usr/lib/libmysqlclient.so.15
         
    8. 导入测试数据
         # mysql -uroot -p test < /Data/apps/sphinx/etc/example.sql
         这里千万注意,mysql编码一定要为UTF-8 !!!
        
    9. 测试建立索引
         #indexer --all
         出错,Coreseek Full Text Server 3.1
         Copyright (c) 2006-2008 coreseek.com
         FATAL: no readable config file (looked in /usr/local/sphinx/etc/csft.conf, ./csft.conf)
         这是因为 Coreseek 默认要去读 csft.conf,所以要复制一份
         # cp /Data/apps/sphinx/etc/sphinx.conf /Data/apps/sphinx/bin/csft.conf
         ( 或者,也可以指定conf文件,#indexer --config /Data/apps/sphinx/etc/sphinx.conf --all  这里我没有指定,所以用了2个conf文件,很不靠谱)

    10. 然后继续运行 #indexer --all ,应该会看到如下输出:
            Coreseek Full Text Server 2.1
            Copyright (c) 2006-2008 coreseek.com
            using config file '/usr/local/etc/csft.conf'...
            indexing index 'test1'...
            collected 5 docs, 0.0 MB
            sorted 0.0 Mhits, 100.0% done
            total 5 docs, 230 bytes
            total 0.146 sec, 1577.50 bytes/sec, 34.29 docs/sec
            indexing index 'test1stemmed'...
            collected 5 docs, 0.0 MB
            sorted 0.0 Mhits, 100.0% done
            total 5 docs, 230 bytes
            total 0.011 sec, 21879.74 bytes/sec, 475.65 docs/sec

    11. 测试全文检索
        # search doc     应该会看到如下输出:
            Coreseek Full Text Server 3.1
             Copyright (c) 2006-2008 coreseek.com
            using config file './csft.conf'...
            index 'test1': query 'doc ': returned 2 matches of 2 total in 0.000 sec
            
            displaying matches:
            1. document=3, weight=1, group_id=2, date_added=Sat Aug 22 03:54:19 2009
                    id=3
                    group_id=2
                    group_id2=7
                    date_added=2009-08-22 03:54:19
                    title=another doc
                    content=this is another group
            2. document=4, weight=1, group_id=2, date_added=Sat Aug 22 03:54:19 2009
                    id=4
                    group_id=2
                    group_id2=8
                    date_added=2009-08-22 03:54:19
                    title=doc number four
                    content=this is to test groups
            words:
            1. 'doc': 2 documents, 2 hits
            index 'test1stemmed': query 'doc ': returned 2 matches of 2 total in 0.000 sec
            displaying matches:
            1. document=3, weight=1, group_id=2, date_added=Sat Aug 22 03:54:19 2009
                    id=3
                    group_id=2
                    group_id2=7
                    date_added=2009-08-22 03:54:19
                    title=another doc
                    content=this is another group
            2. document=4, weight=1, group_id=2, date_added=Sat Aug 22 03:54:19 2009
                    id=4
                    group_id=2
                    group_id2=8
                    date_added=2009-08-22 03:54:19
                    title=doc number four
                    content=this is to test groups
            words:

            1. 'doc': 2 documents, 2 hits
    12. 启动searchd进程
         # searchd

    PHP接口在源安装包下面的api/下,可以调用测试,很好用,明天继续研究!

    接上一回,调用sphinx,我们先插入一个中文的数据:
    INSERT INTO `test`.`documents` (`id` ,`group_id` ,`group_id2` ,`date_added` ,title` ,`content`)VALUES (NULL , '3', '9', NOW( ) ,'sphinx中文搜索','Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。Sphinx特别为一些脚本语言设计搜索API接口,如 PHP,Python,Perl,Ruby等,同时为 MySQL也设计了一个存储引擎插件');

    因为有新数据,所以要重建索引(关于这个问题,以后遇到再研究,如果每天有新数据都要重建索引,很不靠谱)
    先kill searchd进程,运行:
    # searchd --stop    然后
    # indexer --all

    1.调用sphinx:
       一是通过Sphinx官方提供的API接口(接口有Python,Java,Php三种版本)
       二是通过安装SphinxSE(具体见1.2部分),然后创建一个中介sphinxSE类型的表,再通过执行特定的SQL语句实现。
    现在,我们用API接口,在sphinx安装目录有一个API目录,里面有三个PHP文件:test.php,test2.php和 sphinxapi.php。 sphinxapi.php是sphinx调用接口封装文件,test.php是一个在命令行下执行的查询例子文件,test2.php是一个生成摘要的例子文件。
    运行:
    # php /home/changyou/csft-3.1/api/test.php -i test1 doc
    返回结果:
    Query 'doc ' retrieved 2 of 2 matches in 0.000 sec.
    Query stats:  'doc' found 2 times in 2 documents
    Matches:
    1. doc_id=3, weight=100, group_id=2, date_added=2009-08-22 03:54:19
    2. doc_id=4, weight=100, group_id=2, date_added=2009-08-22 03:54:19

    注意:这里,如果不输入参数 -i test1 doc ,那test.php就不会知道你要查那个索引并且搜索什么字句。
    所以,如果想引入生产环境中,我们需要手动修改一下test.php

    a.  注释掉10行-43行,
    b.  然后添加:$search_info = array("1" => "-i", "2" => "test1", "3" => "$keyword");
    c.  foreach ( $search_info as $arg ) 替换原来的foreach
    d.  自己定义下$keyword="设计",记得把文件另存为utf-8
    e.   然后,运行:     # php /home/changyou/csft-3.1/api/test.php
       Query '(乱码)' retrieved 1 of 1 matches in 0.000 sec.
       Query stats:
        '(乱码)' found 8 times in 1 documents
    Matches:
    1. doc_id=5, weight=2, group_id=3, date_added=2009-08-26 20:18:33

    哈哈,OK啦!可以将sphinx文件封装好,就可以用与生产环境了。

    从上面可以看出Query并不能全部取得我们想要的记录内容,比如说Title,Contents字段就没有取出来,根据官方的说明是sphinx 并没有连到mysql去取记录,只是根据它自己的索引内容进行计算,因此如果想用sphinxAPI去取得我们想要的记录,还必须将Query的结果为依据去查询MySQL才可以得到最终我们想要的结果集。

    2.搜索全文时的摘要,高亮显示。
    假设我要搜索关键词"test",通过sphinx可以取到搜索结果,在显示搜索结果时,我希望将含有"test"的进行红色或加粗显示,同时,我不希望全部都显示出来,只需要显示一段摘要,就象google或百度那样,搜出来的结果不是全篇显示,只是部分显示,这个就是摘要的作用。
    以test2.php中为例,可以利用BuildExcerpts方法可以实现摘要的功能。具体可以看看test2.php的代码。这里不说了。

    3.后记
    从网上看到,还可以用SphinxSE方式调用Sphinx。但问题是,我安装的时候,不知道为什么没有安装SphinxSE引擎,在mysql 里用mysql> show engine; 查看。可能是我没有直接编译sphinx然后打2个中文补丁吧,而是用了官网推荐的中文搜索安装包。从索引得到ID号,然后再去查询数据库,也可以实现中文搜索的效果,但是具体效率怎么样就不知道了。
    最后,在sphinx配置文件里,如要用自己的数据,需要修改源数据,这一项:sql_query = \SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content \ FROM documents;
    让他自己抓取合适你数据结构的语句即可。

    参考:http://blog.c1gstudio.com/archives/722

  • 2009-08-21

    linux 安装Mysql - [mysql]

    很简单,但是,草,过程很痛苦,因为少做一步,最后真是要骂街了。

    # useradd mysql

    # tar zxvf mysql-5.0.56.tar.gz  //解压
    # cd /home/changyou/
    mysql-5.0.56 
    # ./configure --prefix=/Data/apps/mysql  // 指定安装目录,公司的应用都在这里,怪异
    --without-debug //去除debug模式
    --with-extra-charsets=gb2312 //添加gb2312中文字符支持
    --enable-assembler //使用一些字符函数的汇编版本
    --without-isam //去掉isam表类型支持 现在很少用了 isam表是一种依赖平台的表
    --without-innodb //去掉innodb表支持 innodb是一种支持事务处理的表,适合企业级应用
    --with-pthread //强制使用pthread库(posix线程库)
    --enable-thread-safe-client //以线程方式编译客户端
    --with-client-ldflags=-all-static 
    --with-mysqld-ldflags=-all-static //以纯静态方式编译服务端和客户端

    # make
    # make install
    # scripts/mysql_install_db //生成mysql用户数据库和表文件,草,就是这里!!
    # cp support-files/my-medium.cnf /etc/my.cnf  //copy配置文件,有large,medium,small三个环境下的,根据机器性能选择,如果负荷比较大,可修改里面的一些变量的内存使用值
    # cp support-files/mysql.server /etc/init.d/mysqld  //copy启动的mysqld文件
    # chmod 700 /etc/init.d/mysqld
    # cd /web
    # chmod 750 mysql -R
    # chgrp mysql mysql -R

    # chown mysql mysql/var -R    (如果没有var目录,可以自己建一个,记得权限)
    # cd /web/mysql/libexec
    # cp mysqld mysqld.old
    # strip mysqld
    # chkconfig --add mysqld
    # chkconfig --level 345 mysqld on
    # service mysqld start
    # netstat -atln
    看看有没有3306的端口打开,如果mysqld不能启动,看看/web/mysql/var下的出错日志,一般都是目录权限没有设置好的问题
    # ln -s /web/mysql/bin/mysql /sbin/mysql
    # ln -s /web/mysql/bin/mysqladmin /sbin/mysqladmin
    # mysqladmin -uroot password "youpassword"   //设置root帐户的密码
    # mysql -uroot -p
    # 输入你设置的密码
    mysql>use mysql;
    mysql>delete from user where password=""; #删除用于本机匿名连接的空密码帐号
    mysql>flush privileges;
    mysql>quit


    注意,如果mysql服务启动不了,提示:
    Starting MySQL/etc/init.d/mysqld: line 159: kill: (21755) - No such process
    看看是否是启动脚本的问题。
    编辑mysqld:
    #vi /etc/init.d/mysqld
    找到类似这样一行:
    $bindir/mysqld_safe --datadir=$datadir --pid-file=$server_pid_file $other_args >/dev/null 2>&1 &
    改为(加上参数--user=root):
    $bindir/mysqld_safe --user=root --datadir=$datadir --pid-file=$server_pid_file $other_args >/dev/null 2>&1 &

    然后再试:
    service mysqld start

    Tag:linux Mysql
  • 2009-08-20

    php的调试工具XHProf的安装,运用 - [php]

    分了台新服务器做测试,最近很闲,正好拿来练手,哈哈,先拿XHProf玩吧。调试PHP时,XDebug一直是大众的不二选择,搭配上Webgrind,可以获得不错的效果,但是很耗资源,CPU一会就到100%了。最近看别人的blog,发现了XHProf,于是想体验了一下。安装过程很简单,但也遇到不少挫折,因为新服务器,上面有些东西是运维装好了,所以没有仔细了解。都是些小问题,不过折腾死了。

    1.#wget http://pecl.php.net/get/xhprof-0.9.2.tgz  一开始wget用不了,报错:Resolving dada... failed: Temporary failure in name resolution.查明是DNS解析的原因,然后更改 /etc/resolv.conf,问运维,写上正确的IP。

    2.下载完了,解压 #tar zxf xhprof-0.9.2.tgz  然后,#cd cd xhprof-0.9.2/extension/

    3.然后 #phpize   (一般编译安装的PHP都有,没有去下)

    4.#./configure --with-php-config=/usr/bin/php-config

    5.#make    #make install  #make test    就搞定了

    6.然后  更改php.ini  把下面的加到文件中

    [xhprof]
    extension=xhprof.so
    ;
    ; directory used by default implementation of the iXHProfRuns
    ; interface (namely, the XHProfRuns_Default class) for storing
    ; XHProf runs.
    ;xhprof.output_dir=<这里写你要保存xhp生成log的目录>

    7.搞定啦!!  整个过程最郁闷的是,php.ini中的extend扩展地址没写,还是默认的“./”一直没发现,试了半天都不成功,崩溃了,最后还是抽了根烟才发现,呵呵,烟是好东西啊。

    测试下,

    <?php
    function bar($x) {
      if ($x > 0) {
        bar($x - 1);
      }
    }
    function foo() {
      for ($idx = 0; $idx < 2; $idx++) {
        bar($idx);
        $x = strlen("abc");
      }
    }
    // start profiling
    xhprof_enable();
    // run program
    foo();
    // stop profiler
    $xhprof_data = xhprof_disable();
    // display raw xhprof data for the profiler run
    print_r($xhprof_data);

    ?> 


    最后返回数组,就表示安装好了。具体哪些值是什么意思先别管,因为下面有UI的配置。会很直观!

    8.首先,为了好看,装个Graphviz:
    wget http://www.graphviz.org/pub/graphviz/stable/SOURCES/graphviz-2.24.0.tar.gz
    tar zxf graphviz-2.24.0.tar.gz
    cd graphviz-2.24.0
    ./configure
    make
    make install

    安装完成后,会生成/usr/local/bin/dot文件,你应该确保路径在PATH环境变量里,以便XHProf能找到它。

    9.把上面的测试代码拿过来改改,在最后面,加上几行:

    include_once ("/Data/web/changyou/xhprof_lib/utils/xhprof_lib.php");
    include_once ("/Data/web/changyou/xhprof_lib/utils/xhprof_runs.php");
    $xhprof_runs = new XHProfRuns_Default();
    // Save the run under a namespace "xhprof_foo".
    // **NOTE**:
    // By default save_run() will automatically generate a unique
    // run id for you. [You can override that behavior by passing
    // a run id (optional arg) to the save_run() method instead.]
    //
    $run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_foo");

    echo "<br>---------------<br>".
    "Assuming you have set up the http based UI for <br>".
    "XHProf at some address, you can view run at <br>".
    "http://192.168.5.148/changyou/xhprof_html/index.php?run=$run_id&source=xhprof_foo<br>".
    "---------------<br>";

    ?>

    然后,好了,运行那个打印出来的URL,OK啦!看看效果,如果你安装了Graphviz,还会有华丽的大图噢


    Tag:php linux
  • 2009-08-14

    Mysql 全中文索引的实现

    1.mysqlcft 1.0.0

    2.基于Sphinx+MySQL的千万级数据全文检索(搜索引擎)架构设计

    Tag: