liyihongcug 发表于 2011-07-26 15:46

是否能自定义多个字段组成的主键在Memcache表?

传说中
 Memcache_engine是一个MySQL 5.1数据库的存储引擎,它能够让用户通过标准的SQL语句(SELECT/UPDATE/INSERTE/DELETE)访问Memcached(还支持新浪的Memcachedb、dbcached)中存放的数据。

  限制:
  1、Memcache表必须有主键。
  2、只能使用主键去查询,即只能使用SELECT ... FROM ... WHERE id = ... 方式去查询。
  3、不支持自增ID。

问题:
1 是否能自定义多个字段组成的主键在Memcache表
2 如何查询所有字段 (不可能只是查询一个字段的)?


参考
安装与使用:
  1、编译安装memcache_engine的步骤:

cd /tmp
wget http://dev.mysql.com/get/Downloads/MySQL-5.1/mysql-5.1.26-rc.tar.gz/from/http://mirror.x10.com/mirror/mysql/
tar zxvf mysql-5.1.26-rc.tar.gz
#安装、配置MySQL的步骤省略,注意不要以静态方式编译安装。

wget http://download.tangent.org/libmemcached-0.23.tar.gz
tar zxvf libmemcached-0.23.tar.gz
cd libmemcached-0.23/
./configure --prefix=/usr/local/memcache_engine
make
make install
cd ../

wget http://xmlsoft.org/sources/libxml2-2.6.32.tar.gz
tar zxvf libxml2-2.6.32.tar.gz
cd libxml2-2.6.32/
./configure --prefix=/usr/local/memcache_engine
make
make install
cd ../

wget http://download.tangent.org/libxmlrow-0.2.tar.gz
tar zxvf libxmlrow-0.2.tar.gz
cd libxmlrow-0.2/
export PKG_CONFIG_PATH=/usr/local/memcache_engine/lib/pkgconfig/
./configure --prefix=/usr/local/memcache_engine
make
make install
cd ../

wget http://download.tangent.org/memcache_engine-0.7.tar.gz
tar zxvf memcache_engine-0.7.tar.gz
cd memcache_engine-0.7/
sed -i "s#uint16_t#uint32_t#g" ./src/ha_memcache.cc
export PKG_CONFIG_PATH=/usr/local/memcache_engine/lib/pkgconfig/
./configure --prefix=/usr/local/memcache_engine --with-mysql=/tmp/mysql-5.1.26-rc
make
make install
cd ../
./configure --prefix=/usr/local/memcache_engine --with-mysql=/tmp/mysql-5.1.26-rc
  注意:红色标记部分为MySQL 5.1.22以上版本的源码路径。

  2、拷贝libmemcache_engine.so到MySQL默认插件目录(假设MySQL安装在/usr/local/mysql目录下):

mkdir -p /usr/local/mysql/lib/mysql/plugin/
cp /usr/local/memcache_engine/lib/libmemcache_engine.so.0.0.0 /usr/local/mysql/lib/mysql/plugin/libmemcache_engine.so
  3、安装libmemcache_engine.so插件的SQL语句:

INSTALL PLUGIN memcache SONAME 'libmemcache_engine.so';
  4、查看libmemcache_engine.so插件是否安装成功的SQL语句:

SELECT * FROM mysql.plugin;
SHOW PLUGINS;
  5、创建一张memcache_engine表的SQL语句:

CREATE TABLE `table` (
`id` int(11) NOT NULL DEFAULT '0',
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MEMCACHE DEFAULT CHARSET=latin1
CONNECTION='localhost:11211';
http://forum.z27315.com/topic/2281-mysql-memcache-engine%E7%9A%84%E5%AE%89%E8%A3%85%E4%B8%8E%E4%BD%BF%E7%94%A8/

liyihongcug 发表于 2011-07-26 17:03

本帖最后由 liyihongcug 于 2011-08-04 13:33 编辑

http://www.wenan8.com/blog/archives/313MEMCACHE 就是一个键值对。
但CREATE TABLE `table` (
`id` int(11) NOT NULL DEFAULT '0',
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MEMCACHE DEFAULT CHARSET=latin1
CONNECTION='localhost:11211';
很难以理解 ,难道 他支持在一个memcache服务器上放多张表 ?

问题:
1 是否能自定义多个字段组成的主键在Memcache表

liyihongcug 发表于 2011-07-26 17:03

本帖最后由 liyihongcug 于 2011-08-04 13:32 编辑

memcached是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。最初为了加速 LiveJournal 访问速度而开发的,后来被很多大型的网站采用。起初作者编写它可能是为了提高动态网页应用,为了减轻数据库检索的压力,来做的这个缓存系统。它的缓存是一种分布式的,也就是可以允许不同主机上的多个用户同时访问这个缓存系统, 这种方法不仅解决了共享内存只能是单机的弊端, 同时也解决了数据库检索的压力,最大的优点是提高了访问获取数据的速度!基于memcached作者对分布式cache的理解和解决方案。 memcached完全可以用到其他地方 比如分布式数据库, 分布式计算等领域。

1、 memcached 协议理解
memcache是为了加快http://www.livejournal.com/访问速度而诞生的一个项目。
它的官方主页是:http://www.danga.com/memcached/
目前在网站开发中应用较少,主要的应用有:

http://www.danga.com/memcached/users.bml

在国内的网站开发中,还很少没见到有应用的,中文资料十分匮乏。
工作机制:通过在内存中开辟一块区域来维持一个大的hash表来加快页面访问速度,和数据库是独立的。但是目前主要用来缓存数据库的数据。允许多个 server通过网络形成一个大的hash,用户不必关心数据存放在哪,只调用相关接口就可。存放在内存的数据通过LRU算法进行淘汰出内存。同时可以通过删除和设置失效时间来淘汰存放在内存的数据。
2、 memcached 使用入门
2.1 memcached的安装
?<1>memcached服务的安装
先检查linux内核版本,建议将memcached 安装在2.6以上。
因为memcached 需要用到libevent和 epoll 。
memcached安装前首先确定你的服务器上面安装了libevent库,
libevent下载地址( http://www.monkey.org/~provos/libevent/)。
下载memcached的源码( http://www.danga.com/memcached/download.bml)。
Memcached最初是用perl写的,现在的版本是用c写的。
下载后拷贝到一个目录,安装需要root用户来执行
tar -zxvf memcached-1.1.12.tar.gz
cd memcached-1.1.12
./configure
这里必须先要configure, 它会检测你的系统情况,然后生成一个config.h文件和其它的几个文件,另外和其它的configure一样,你可以配置它的安装路径等等。默认应用程序安装在/usr/local/bin目录下。
make //编译
make install //安装
<2>memcached客户端的安装
根据memcached协议,用户可以自己写出符合自己要求的客户端程序。目前http://www.danga.com/memcached/download.bml
提供perl,c,java,python,php等客户端程序供下载和参考。下面我就以perl客户端程序为例说明客户端的安装:
下载后拷贝到一个目录,安装需要root用户来执行
tar -zxvf Cache-Memcached-1.14.tar.gz
cd Cache-Memcached-1.14
perl makefile.pl
make
make install
make test
这样就安装好了memcahced, 启动memcached就可使用分布式缓存系统了!
2.2 快速入门
<1> memcached服务的启动
memcached的启动非常简单,它没有配置文件,只要配置好几个参数就可以使用了。下面我以一个实际应用的例子,具体说明一下:
memcached –d –m 500 -l 64.128.191.151 -p 11211 -vv >>/var/www/kelly/test/logs/memcached_$$.log
启动的这个memcached为一个后台守护进程模式(-d), 然后缓存的空间为500M(-m), 监听(-l)服务器64.128.191.15的11211号端口(-p).,将日志写道/var/www/kelly/test/logs /memcached_$$.log(-vv)。
其实memcached的参数也非常的有限,就下面这几个:
? -p port number to listen on
? -l interface to listen on, default is INDRR_ANY
? -d run as a daemon
? -r maximize core file limit
? -u assume identity of (only when run as root)
? -m max memory to use for items in megabytes, default is 64 MB
? -M return error on memory exhausted (rather than removing items)
? -c max simultaneous connections, default is 1024
? -k lock down all paged memory
? -v verbose (print errors/warnings while in event loop)
? -vv very verbose (also print client commands/reponses)
? -h print this help and exit
? -i print memcached and libevent license
我们也可以将这个启动脚本写道/etc/rc.d或者/erc/rc.local,这样可以在服务器启动时候执行。
<2> memcached客户端的连接
下面我就以perl客户端程序为例说明客户端的连接:
启动两个memcached server
memcached –d –m 500 -l 64.128.191.151 -p 11211 -vv >>/var/www/kelly/test/logs/memcached_$$.log
memcached –d –m 500 -l 64.128.191.151 -p 11212 -vv >>/var/www/kelly/test/logs/memcached_$$.log
perl客户端程序
#!/usr/bin/perl
use Cache::Memcached;
my $memd = new Cache::Memcached {
‘servers’ => [ "64.128.191.15:11211" , "64.128.191.15:11212"],
};
my $val = $memd->get( “my_key” );
if ( $val )
{
print “Value is ‘$val’\n”;
}
# Set a value
$memd->set(“my_key”, “123″);
$memd->disconnect_all();
?运行测试
$ perl test-memcache.pl
$ perl test-memcache.pl
Value is ’123′
可以看到,第一次没有取得my_key,第二次从memcached中得到my_key的值。
同时通过查看日志,可以发现的确存储在两个memcache server中。
这个简单的例子,解释了如何在memcached中存取数据,以及memcache是真正的分布式缓存系统。
当然,这还只是很简单的例子,体现不出memcache的优势,下面将通过一个很具体的例子,给出详细的应用。
3、 memcached在Zorpia的应用
http://www.zorpia.com 是一个网页相册,博客,交友,论坛的大型网站公司。现在已有超过140万活跃使用者遍布美国,香港,东南亚,欧洲,澳洲,亚洲等其它地区。每天的访问量都在增长,已成为全世界排名第五的社会生活关系网。
Memcached也采用了memcached来提高网站的访问速度,并且取得了很好的效果,我在负责zorpia的memcached项目时候积累了一些经验,主要的做法如下:
1) 通过对memcache的perl客户端进行包装,定制自己的客户端。
2) 通过制定符合zorpia规范的hash key命名规范
? ? memcache中需要存储的内容的key均由string组成。
这个string统一由一个memcache.pm的subroutine来实现。(假设这个subroutine是 get_key() )
? ? memcache中存放两种形式的数据
(1) result of SQL query :
(2) 普通变量(variable)
这两种数据的key的组合方式是不相同的,由get_key进行判断和完成
? ? 关于get_key 和 naming rule
get_key subroutine完成所有memcache key的命名,naming rule也是在它里边体现:
(1)输入参数 -- hash结构,里边定义了当前需要存放的数据的信息
结构
(2)返回值 -- string,返回数据的key_name
?必须确定 get_key 的传入hash的结构,
hash中主要有两个元素
type — 定义当前数据结构的类型 ,有 ‘var’ , ‘sql’两种值
object — 存放当前数据结构的详细信息,
当 type eq ‘var’时,object表示变量的名字,该名字由程序员指定
当 type eq ‘sql’时,object包含所存放sql的主要基本信息,hash结构,也由程序员按照规则制定
## 当variable 数据类型,比较简单
$var_hash = {
type => ‘var’, ## var表示当前类型是 variable
object => ‘language’, ## language代表variable的名字
};
生成的key是Zorpia::var| language
## sql 数据
比如select first_name from user where user_id =2那么hash为
$sql_hash = {
type => ‘sql’,
object => {
table => {table2=>”user”,}, ## sql 查询的表
column => {column1=>”first_name”,}, ## sql所要查询的column
condition => { user_id =>”2″,}, ## sql条件
},
};
生成的key是Zorpia::sql|user|first_name| user_id =2
get_key subroutine必须对传入hash进行判断,对不同类型的数据按照不同的方式组合,形成key,返回给使用者。这个key,必须保证其唯一性:
比如:所有字母小写,一些数组在组合成key之前必须首先排序
? ? get_key函数
sub get_key{
my $hash = shift;
return undef unless $hash && ref $hash eq “HASH”;
my $type = $hash->{type};
my $key_name;
if ($type eq ‘sql’) {
my ($table_key,$column_key,$condition_key);
$table_key=_get_key($hash->{object}->{table});
$column_key=_get_key($hash->{object}->{column});
$condition_key=_get_key($hash->{object}->{condition});
$key_name = join(‘|’,$type,$table_key,$column_key,$condition_key);
#Currently the length limit of a key is set at 250 characters
if (length($key_name)>250)
{
$key_name=substr(0,250,$key_name);
}
}
elsif($type eq ‘var’)
{
$key_name = join(‘|’,$type,$hash->{object});
}
return $key_name;
}
sub _get_key
{
my $hash=shift;
return undef unless $hash && ref $hash eq “HASH”;
my ($t,$ret,$i);
foreach $i (sort keys %$hash)
{
$i=~s/^\s+|\s+$//g;
$hash->{$i}=~s/^\s+|\s+$//g;
push(@$t,lc(“$i=$hash->{$i}”));
}
$ret=join(‘:’,sort { $a cmp $b } @$t);
return $ret;
}
3) 制定需要应用memcached的规则
?经常访问的表user,user_details
?合理设定变量在memcached的生存周期
?将活跃用户的信息预先导入到memcached
?分别在多台机器上启动多个memcached服务
?编写脚本监控memcached服务是否活动
4) User表的具体应用举例
? 在 select时候
先查询memcahce里有没有,有的话,返回;否则从数据库select,在memcache里设置,返回。
my $sql_hash = {
type => ‘sql’,
object => {
table => {table1=>”user”,},
column => {column1=>”user_id”,},
condition => {email=>$user_id,},
},
};
my $key=Zorpia::MemCache::get_key($sql_hash);
my $user_id_by_email=Zorpia::MemCache::get($key);
if(!$user_id_by_email)
{
my $sth;
my $query =”select user_id from user where email=?”;
$sth = $dbh->prepare($query);
$sth->execute($user_id);
my $user1 = $sth->fetchrow_hashref();
$user_id_by_email=$user1->{‘user_id’};
Zorpia::MemCache::set($key,$user_id_by_email,1800);
}
?在 update,insert,delete时候
先在数据库update,insert,delete,在memcache里设置,返回。
&Zorpia::DB::data_entry_no_return($dbh,”user”,”COUNT(*)”,”$account_information_insert_statement user_id=$current_user_id”, “user_id=$current_user_id”);
#add by kelly
my $sql_hash = {
type => ‘sql’,
object => {
table => {table1=>”user”,},
column => {column1=>”user_id”,},
condition => {user_id=>$current_user_id,},
},
};
my $key=Zorpia::MemCache::get_key($sql_hash);
my $query = “SELECT *, user_id AS id FROM user WHERE user_id=?”;
my $sth_memc = $dbh->prepare($query);
$sth_memc->execute($current_user_id);
my $user_memc = $sth_memc->fetchrow_hashref();
&Zorpia::MemCache::set($key,$user_memc,21600);
4、 memcached的应用展望
使用了memcached以后, 我发现以前做过的很多的项目都可以应用它提高效率,包括最近做的“大单追踪”, “数码搜索”等等。当然既然memcahced是分布式的缓存系统,那么它就是建立了一个分布式的平台, 我们可以用它来进行分布式的记数, 因为对于一个键值key我们可以设置它的数值以及有效期在参数中,另外还可以重新设置这个键值的数值。 所以我总结了一下目前可以应用到的地方:
<1>.数据库检索结果的缓存,也就是说可以有机的和数据库结合起来应用,提高效率。
这也是目前memcached用到的最多的地方,比如用于大型网站等。
可以这样来实现:
打开memcached服务器连接
编写sql语句, 同时算出它的一个hash key值
获取这个hash值的memcached保存数据(get)
如果获取的这个hash值的数据存在。返回
否则连接数据库查找
把这个查找结果保存在memcached中(set),可以设置有效期
返回查找结果
<2>.分布式计算
<3>.分布式共享数据
总之,memcached的机制比较灵活,可以适用于一切需要分布式缓存数据的地方,随着memcached逐渐为人所知,必将在更多的分布式应用领域大放异彩。 表

liyihongcug 发表于 2011-08-04 13:40

本帖最后由 liyihongcug 于 2011-08-04 13:51 编辑

MySQL user conference and expo 大会上发布的 MySQL 5.6.2 测试版本,该版本最值得关注的便是对 NoSQL 技术的支持,尽管目前还是实验阶段,该技术使得 MySQL 内置 NoSQL 技术,该技术可减少 memcached 的查询延迟。在单台机器中,NoSQL 当前只适用一张 InnoDB 表,但未来将支持多个表。在 memcached 中的 key 和 value 分别对应表中的相应字段,同时可为 key 定义多列的值。所有这些数据都存储在一张 InnoDB 表,可通过 SQL 命令来进行检索和修改。目前集成 memcached 守护进程的版本只能用于 Linux。

这么说来一个memcache服务职能支持一个表因为一个主键id的限制。导致功能拓展弱

memcache_engine + memcachedb = 高性能分布式内存数据库
memcachedb是一个由新浪网的开发人员开放出来的开源项目,给memcached分布式缓存服务器添加了Berkeley DB的持久化存储机制和异步主辅复制机制,让memcached具备了事务恢复能力、持久化能力和分布式复制能力,非常适合于需要超高性能读写速度,但是不需要严格事务约束,能够被持久化保存的应用场景,例如memcachedb被应用在新浪博客上面。

memcachedb给memcached添加了一些数据库才具备的特性,但是我们还不能说memcachedb已经是一个数据库了,这是因为 memcached不支持内存对象的遍历操作,当然更加不能支持复杂的查询操作,只能支持根据已知的key去查询对应的value。因此如果想把 memcachedb当成一个高性能的分布式内存数据库来使用的话,查询的问题就没有办法解决,只能在应用程序里面配合其他方案做一些折衷。

然而memcached的另外一个开源项目完美的填补了这一个缺陷,就是memcache_engine。

memcache_engine是一个MySQL数据库的存储引擎,目前只支持MySQL5.1数据库,他能够把memcachedb作为MySQL数据库的一个存储引擎和MySQL集成起来,让用户通过标准的SQL查询语句访问memcachedb中存放的数据,请看如下示例:

Sql代码 复制代码

   1. CREATE TABLE `a` (   
   2.   `a` int(11) NOT NULL DEFAULT '0',   
   3.   `b` int(11) DEFAULT NULL,   
   4.   `c` int(11) DEFAULT NULL,   
   5.   PRIMARY KEY (`a`)   
   6.   ) ENGINE=MEMCACHE DEFAULT CHARSET=latin1   
   7. CONNECTION='localhost:6666\;localhost:6688';

CREATE TABLE `a` (
`a` int(11) NOT NULL DEFAULT '0',
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=MEMCACHE DEFAULT CHARSET=latin1
CONNECTION='localhost:6666\;localhost:6688';



创建表a,存放在分布式memcached server:localhost:6666和localhost:6688当中。然后我们就可以使用标准的SQL语句随意的进行CRUD操作去使用 memcachedb了,这实在是太酷了!有了memcache_engine,我们就可以用SQL去访问memcached,有了 memcachedb,我们就不必担心数据丢失问题,事务恢复问题了,简直是绝配,让memcached真正成为了一个高性能的分布式数据库系统了。目前 memcache_engine项目还是早期试验阶段,让我们期待memcache_engine项目早日发布正式版本吧!

顺便多说几句:最近一年来,特别是最近一个月以来,围绕memcached的开源项目发展的非常非常活跃:

1、最近刚刚发布了memcached的新的高性能C客户端接口: libmemcached

2、由于有了libmemcached,该组织又发布了memcache_engine存储引擎,cool!

3、由于libmemcached的发布,不到一周时间,ruby的两个崭新的memcache client就问世了,他们是Caffeine和New memcache-client,让ruby访问memcached的速度大幅度提高,请看:libmemcached发布了,ruby访问memcached提速20倍

4、memcachedb发布了,这是中国的互联网公司贡献的开源项目

以上几个项目都是在2008年1月发布的,真的不是一般的繁荣阿。再加上之前发布的新的支持异步访问的Java Memcached API和C#接口,可以说除了Python,其他主流非主流编程语言都可以使用memcached了。其实即便是Python还没有公布出来的开源接口,我们也知道国内的web2.0网站豆瓣就是使用Python访问memcached,并且支持了极大的访问量,因此目前围绕memcached的开源项目发展的情况非常的繁荣。

memcached最近两年这么受欢迎,其实和互联网web2.0的流行有很大的关系,web2.0网站通常需要个性化页面,依赖于页面局部和数据细颗粒度的缓存来提升性能,并且web2.0网站流量都很大,因此memcached这种高性能分布式缓存服务器就大行其道了。

当然我觉得最具有**意义的还是memcache_engine和memcachedb这两个项目的发布,他们能够让memcached的用途不仅仅限于缓存服务器而已,而是能够真正充当分布式数据库来使用了,这无异是诸多大流量web2.0网站和开发人员的福音阿。
页: [1]
查看完整版本: 是否能自定义多个字段组成的主键在Memcache表?