类似 Big Table的tokyo Cabinet研究记录

Tokyo Cabinet是小人开发的一款数据库,它的功能比较简单,只能键值保存,没有检索功能,以hash table、b+tree、fixed-length array保存。功能类似的Bigtable的东东。
这套Tokyo系列有三个产品,Cabinet是数据库,Tyrant提供管理Cabinet的接口,Dystopia提供全文索引。我把Cabinet理解为存储引擎,Tyrant类似mysql的管理器,Dystopia则是插件。

Tokyo Cabinet有如下特点:

  • 键值保存数据库
  • 数据文件小
  • 高性能,插入1百万记录只需0.4秒(250万 rps),查询1百万记录只需0.3秒(300万 rps)
  • 高并发,支持多线程,读写支持锁记录
  • 使用简单,通过memcached客户端直接使用(需Tyrant)
  • 支持64位架构,容量大
  • 支持事务
Tokyo Tyrant提供管理Cabinet的接口,支持memcached协议,所以,可以通过memcached客户端连接Cabinet。
Tokyo Tyrant有如下特点:
  • 提供使用Cabinet的接口
  • 支持通过memcached和http协议连接
  • 高并发,查询100万记录17.2秒(5.8万 rps)
  • 支持热备份,复制功能,主持主主(可读写)和主从(分写和读)方式
Tokyo Dystopia是一个全文检索系统,你可以搜索包含某短语的一系列记录,它的特性如下:
  • 搜索的高性能。
  • 目标文标的高可靠性
  • N-gram模型的高召回率
  • 短语匹配,前缀匹配,后缀匹配搜索.
  • Unicode下多语种支持。
  • API的分层架构支持。
cabinet的文档:
http://tokyocabinet.sourceforge.net/spex-en.html

tyrant的文档:
http://tokyocabinet.sourceforge.net/tyrantdoc/

cabinet和tyrant的ppt幻灯片介绍:
http://tokyocabinet.sourceforge.net/tokyoproducts.pdf
可关注下其中的TCTDB,就是对table database的支持

使用哪种存储方式,取决于tyrant启动时指定的存储文件名称,table database的文件后缀是.tct

发布一个日志,看完

RT

,不明真相的围观群众,受人控制的组织者,矫情的演说。

[原创]mediawiki安装改进手记-使用mediawikit和postgresql搭建有强大搜索功能的wiki

[ 文章作者:陈臻 本文版本:v1.1 最后修改:2009.7.28 转载请注明原文链接:http://www.54chen.com/c/640 ]

在yahoo工程技术部,最有趣的事情当属打开工程技术部的wiki,慢慢阅读来自前辈们的大作。

yahoo以前使用的是twiki,后来更换了mediawiki,扩展了postgresql的搜索,使mediawiki的搜索功能得到了加强,这里,记录下我在校内搭建一整套的手记:

第一步.准备php和postgresql环境

大环境:因为是内部系统,所以图省事,WEB使用的是一个ubuntu的机器,安装这些丝毫不用费力了。就是先用apt安装php、nginx,源码包安装lighttpd取spawn-cgi一枚备用。源码包安装postgresql8.3.3。

#apt-get install php5 php5-pgsql php5-mbstring php5-cgi

#apt-get install nginx

#wget http://www.lighttpd.net/download/lighttpd-1.4.19.tar.gz #tar -xvf lighttpd-1.4.19.tar.gz
#cd lighttpd-1.4.19/
#./configure
#make
#cp src/spawn-fcgi /usr/local/bin/spawn-fcgi

(这里图快,没使用php-fpm)

#adduser www

#spawn-fcgi -a 127.0.0.1 -p 9000 -C 5 -u www-data -g www-data -f /usr/bin/php-cgi

修改php.ini文件
cgi.fix_pathinfo=1; 这样php-cgi方能正常使用SCRIPT_FILENAME这个变量

在/etc/nginx/sites-enable/default中添加以下代码

server {
listen 80; //端口
server_name wiki.54chen.com; //虚拟域名
access_log /var/log/nginx/hwiki.54chen.com.access.log; //访问日志
location / {
root /home/wiki.54chen.com; //size根目录
index index.php;
location ~ \.php$ { #php fastcgi的配置
fastcgi_pass 127.0.0.1:9000; #php fastcgi的代理端口与ip
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/wiki.54chen.com$fastcgi_script_name; #要处理的php文件的路径
include /etc/nginx/fastcgi_params; #fastcgi的参数文件地址
}

启动

/etc/init.d/nginx start
大功告成!

postgresql的安装请进使用postgreSQL+bamboo搭建比lucene方便N倍的全文搜索 第一部分

第二步.安装mediawiki

#wget http://downloads.sourceforge.net/sourceforge/wikipedia/mediawiki-1.8.2.tar.gz?use_mirror=jaist

#解压到/home/wiki.54chen.com

通过浏览器访问安装,安装时选择postgresql.

将wiki目录下connfig目录中的LocalSettings.php剪切到wiki目录中,把$wgEnableUploads = false;改为$wgEnableUploads = true;(这样允许上传图片了),还有就是把Wiki的Logo改成您所需要的$wgLogo = "$wgStylePath/common/images/wiki.png"。

第三步.修改meidawiki及修改sql 1.修改DB
按标题搜的触发器修改为 CREATE OR REPLACE FUNCTION mediawiki.ts2_page_title()
RETURNS "trigger" AS
$BODY$
BEGIN
IF TG_OP = 'INSERT' THEN
NEW.titlevector = to_tsvector('chinesecfg',COALESCE(REPLACE(NEW.page_title,'/',' '),''));
ELSIF NEW.page_title != OLD.page_title THEN
NEW.titlevector := to_tsvector('chinesecfg',COALESCE(REPLACE(NEW.page_title,'/',' '),''));
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION mediawiki.ts2_page_title() OWNER TO wikiuser;

按内容搜索的触发器修改为 CREATE OR REPLACE FUNCTION mediawiki.ts2_page_text()
RETURNS "trigger" AS
$BODY$
BEGIN
IF TG_OP = 'INSERT' THEN
NEW.textvector = to_tsvector('chinesecfg',COALESCE(NEW.old_text,''));
ELSIF NEW.old_text != OLD.old_text THEN
NEW.textvector := to_tsvector('chinesecfg',COALESCE(NEW.old_text,''));
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION mediawiki.ts2_page_text() OWNER TO wikiuser;

对标题的索引修改 drop index ts2_page_title;
CREATE INDEX ts2_page_title
ON mediawiki.page
USING gin
(titlevector);

对内容的索引修改 drop index ts2_page_text;
CREATE INDEX ts2_page_text
ON mediawiki.pagecontent
USING gin
(textvector);

修改 includes/SearchPosgres.php 146行: $prefix = $wgDBversion < 8.3 ? "'default'," : "'chinesecfg',";

大功告成,搜索的时候就使用了bamboo的分词来搜了,如果还有兴趣可以加强175-179行的sql就能得到更加强大的wiki。

[原创]使用postgreSQL+bamboo搭建比lucene方便N倍的全文搜索 第二部分

[文章作者:陈臻 本文版本:v1.0 最后修改:2009.7.17 转载请注明原文链接:http://www.54chen.com/_linux_/postgresql-bamboo-lucene-part2.html ]

书接上回。上回说到建立好一整套的中文分词和pgsql的环境,这回来说如何搜。

一、基础篇

本回从一条sql开始:

select * from dbname where field_name @@ 'aa|bb' order by rank(field_name, 'aa|bb');

从这个sql字面意思讲解:从 dbname这个表中查field_name匹配aa或者是bb的词,并且按照他们的匹配的RANK排序。

基本上明白上面这段话后,来学习四个概念:tsvector、tsquery、@@ 、gin。

1.tsvector:

在postgreSQL 8.3自带支持全文检索功能,在之前的版本中需要安装配置tsearch2才能使用。它提供两个数据类型(tsvector,tsquery),并且通过 动态检索自然语言文档的集合,定位到最匹配的查询结果,tsvector正是其中之一。

一个tsvector的值是唯一分词的分类列表,把一话一句词格式化为不同的词条,在进行分词处理的时候,tsvector会自动去掉分词中重复的词条,按照一定的顺序装入。例如

SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector;
tsvector
----------------------------------------------------
'a' 'on' 'and' 'ate' 'cat' 'fat' 'mat' 'rat' 'sat'

通过tsvector把一个字符串按照空格进行分词,这可以把分词后的词按照出现的次数排成一排(还会按词长度)。

对于英文和中文的全文检索我们还要看下面这条sql:

SELECT to_tsvector('english', 'The Fat Rats');
to_tsvector
-----------------
'fat':2 'rat':3

to_tsvector函数来是tsvector规格化的,在其中可指定所使用的分词。

2.tsquery:

顾名思义,tsquery,表示的应该是查询相关的.tsquery是存储用于检索的词条.并且可以联合使用boolean 作符来连接, & (AND), | (OR), and ! (NOT). 使用括号(),可以强制分为一组.

同时,tsquery 在做搜索的时候,也可以使用权重,并且每个词都可以使用一个或者多个权重标记,这样在检索的时候,会匹配相同权重的信息.跟上面的tsvector相同,tsquery也有一个to_tsquery函数.

3.@@:

在postgresql中全文检索匹配作使用@@ 作符,如果一个
tsvector(document) 匹配到 tsquery(query)则返回true.

看一个简单的例子:

SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector @@ 'cat & rat'::tsquery;
?column?
----------
t 我们在处理索引的时候还是要使用他们的函数如下:
SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat & rat');
?column?
----------
t 并且作符 @@ 可以使用text作为tsvector和tsquery.如下作符可以使使用的方法

tsvector @@ tsquery
tsquery  @@ tsvector
text @@ tsquery
text @@ text
上面的前两种我们已经使用过了,但是后两种,
text @@ tsquery 等同于 to_tsvector(x) @@ y.
text @@ text 等同于 to_tsvector(x) @@ plainto_tsquery(y).(~)plainto_tsquery在后面讲。。。

4.gin:

gin是一种索引的名称,全文索引用的。

我们可以通过创建gin索引来加速检索速度.例如

CREATE INDEX pgweb_idx ON pgweb USING gin(to_tsvector('english', body));

创建索引可以有多种方式.索引的创建甚至可以连接两个列:
CREATE INDEX pgweb_idx ON pgweb USING gin(to_tsvector('english', title || body));

二、提高篇

基础知识学完了,应该上阵了,为了实现全文检索,我们需要把一个文档创建一个tsvector 格式,并且通过tsquery实现用户的查询,在查询中我们返回一个按照重要性排序的查询结果。

先看一个to_tsquery的sql:

SELECT to_tsquery('english', 'Fat | Rats:AB');
to_tsquery
------------------
'fat' | 'rat':AB

可以看出,to_tsquery函数在处理查询文本的时候,查询文本的单个词之间要使用逻辑作符(& (AND), | (OR) and ! (NOT))连接(或者使用括号)。

如果执行下面这条sql就会出错:

SELECT to_tsquery('english', 'Fat  Rats');

plainto_tsquery函数却可以提供一个标准的tsquery,如上面的例子,plainto_tsquery会自动加上逻辑&作符。
SELECT plainto_tsquery('english', 'Fat  Rats');

plainto_tsquery
-----------------
'fat' & 'rat'
但是plainto_tsquery函数不能够识别逻辑作符和权重标记。
SELECT plainto_tsquery('english', 'The Fat & Rats:C');
plainto_tsquery
---------------------
'fat' & 'rat' & 'c'

三、终结篇

看完上面的一堆后,千言万语汇成一句话,本文主要讲的是一条sql,在加了第一部分里所讲述的扩展后,使用下面的sql,从一个字段中搜一句话,还要排序出来:

select * from tabname where to_tsvector('chinesecfg',textname) @@ plainto_tsquery('搜点啥') order by ts_rank(to_tsvector('chinesecfg',textname),plainto_tsquery('搜点啥')) limit 10;

之前的create table create index就不写了。授人以渔才是关键。

一个把TortoiseSVN转成命令行的svn的bat脚本

TortoiseSVN是windows里常用的svn客户端了,有些IDE(比如说Zend Studio)要设置svn.exe的地址才能绑上svn来用,一般情况下,他附带的都是很古老的版本。

把下面的脚本保存为svn.bat,再在ide里设置svn客户端为这个bat文件,很好用

@ECHO OFF
rem This is a svn for IDE
rem from http://www.54chen.com
start "TortoiseSVN" "C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe" /notempfile /command:%1 /path:%2

[原创]使用postgreSQL+bamboo搭建比lucene方便N倍的全文搜索 第一部分

[文章作者:陈臻 本文版本:v1.2 最后修改:2009.7.7 转载请注明原文链接:http://www.54chen.com/_linux_/postgresql-bamboo-lucene-fulltextindex.html ]

修正:一些“--”(连续的两个杠)被转成了全角的“-”(一个杠)了,运行不过的试试-变成--

所有用到到包有:

cmake-2.6.4.tar.gz (编nlpbamboo用)

CRF++-0.53.tar.gz(同上)

nlpbamboo-1.1.1.tar.bz2(分词用)

postgreSQL-8.3.3.tar.gz(索引用)

安装pgsql

tar -zxvf postgreSQL-8.3.3.tar.gz

cd postgre-8.3.3

./configure --prefix=/opt/pgsql
make
make install

useradd postgre

chown -R postgre.postgre /opt/pgsql
su - postgre
vi ~postgre/.bash_profile
添加
export PATH
PGLIB=/opt/pgsql/lib
PGDATA=/data/PGSearch
PATH=$PATH:/opt/pgsql/bin
MANPATH=$MANPATH:/opt/pgsql/man
export PGLIB PGDATA PATH MANPATH

# mkdir -p /data/PGSearch

# chown -R postgre.postgre /data/PGSearch

# chown -R postgre.postgre /opt/pgsql

#sudo -u postgre /opt/pgsql/bin/initdb --locale=zh_CN.UTF-8 --encoding=utf8 -D /data/PGSearch
#sudo -u postgre /opt/pgsql/bin/postmaster -i -D /data/PGSearch &  //允许网络访问
#sudo -u postgre /opt/pgsql/bin/createdb kxgroup
# vim /data/PGSearch/pg_hba.conf  如下增加可访问的机器

host    all         all         10.2.19.178 255.255.255.0               trust

#su - postgre

$pg_ctl stop

$postmaster -i -D /data/PGSearch & 安装中文分词(Cmake CRF++ bamboo) Cmake是为了编译bamboo,CRF++是bamboo依赖的。

tar -zxvf cmake-2.6.4.tar.gz

cd cmake-2.6.4
./configure
gmake
make install

tar -zxvf CRF++-0.53.tar.gz
cd CRF++-0.53
./configure
make
make install

tar -jxvf nlpbamboo-1.1.1.tar.bz2
cd nlpbamboo-1.1.1
mkdir build
cd build/
cmake .. -DCMAKE_BUILD_TYPE=release
make all
make install

cp index.tar.bz2 /opt/bamboo/
cd /opt/bamboo/
tar -jxvf index.tar.bz2

#/opt/bamboo/bin/bamboo

如果出现:

ERROR: libcrfpp.so.0: cannot open shared object file: No such file or directory

就执行:

ln -s /usr/local/lib/libcrfpp.so.* /usr/lib/
ldconfig

增加上中文分词扩展到pgsql

#vim /root/.bash_profile 也增加:

PGLIB=/opt/pgsql/lib
PGDATA=/data/PGSearch
PATH=$PATH:/opt/pgsql/bin
MANPATH=$MANPATH:/opt/pgsql/man
export PGLIB PGDATA PATH MANPATH

#source ~/.bash_profile

cd /opt/bamboo/exts/postgres/chinese_parser/
make
make install

su - postgre
cd /opt/pgsql/share/contrib/
touch /opt/pgsql/share/tsearch_data/chinese_utf8.stop
psql kxgroup
\i chinese_parser.sql 导入

再执行下面的sql,已经可以将一段话分词了:

SELECT to_tsvector('chinesecfg', '结果在命令行下执行bamboo才知道');

先到这里,下一部分讲述对TEXT字段进行索引和查询,完整构造一整个搜索引擎。