Hello,Redis (memcached的姐妹篇)

分类:技术知识2010-11-1614:05

Redis和memcached类似,都提供了key-value的方便操作,但是redis解决了memcached没有存储的问题。当然开源的MemcacheDB在memcached基础上也提供了存储的功能。

NoSQL正试图打破关系数据型数据库一统天下的局面。Redis也是NoSQL的一种尝试。Redis是什么?其网站上如是说:

Apersistentkey-valuedatabasewithbuilt-innetinterfacewritteninANSI-CforPosixsystems

Redis最值得拿出来说事的优点就是“快”!Github就用了Redis为自己加速。

我们选择下载稳定的发布版:

http://code.google.com/p/redis/downloads/list

也可以直接获取源码:

http://github.com/antirez/redis

现在的redis与一般的C开源项目相比,非常简单,只有很少的一些文件。它的构建过程也不像其它的项目那些,需要先配置再构建。它只有一个简单的makefile,构建它,只要make一下即可。当然,正如其声称的那样,目前redis只是为Posix系统而打造,所以,如果想在Windows上构建,也许Cygwin是个选择。

先来做一下简单的体验,启动redis的服务器端:

>./redis-server

redis本身还附带了一个命令行的客户端,用它就可以对redis本身进行测试:

>./redis-clisetkeyvalue

OK

>./redis-cligetkey

value

在上面的这个会话里面,我们通过设置的一个键值对(key和value),然后,用键值取回其对应的值,非常简单。除了最简单的键值对,Redis还支持list、set和有序的set。下面的会话是对list的操作:

>./redis-clilpushlist1

OK

>./redis-clilpushlist2

OK

>./redis-clilrangelist0-1

1.2

2.1

>./redis-clirpushlist3

OK

>./redis-clilrangelist0-1

1.2

2.1

3.3

这里的lpush命令在list的头部添加元素,rpush命令在list的尾部添加元素,而lrange用来查询list里面的元素。

上面我们用的命令行对Redis进行操作,实际上,Redis本身就是具备网络接口的数据库,它有着自己的协议,一种简单的文本协议。这个协议本身并不复杂,只要实现了这个协议就可以与Redis进行互联互通了,所以,Redis有着不同语言的客户端实现,而上面用到的命令行也是用同样的协议实现的。

通过以最普通的telnet直连Redis,我们稍微了解一下这个协议。

>telnetlocalhost6379

这里的6379是Redis的缺省端口,下面是一段简单的会话:

SETkey5

value

+OK

GETkey

$5

value

QUIT

这段会话等同上面命令行的第一段会话。SET是命令字,key是键值,5是随后值的长度,value就是值的内容,这就是我们发送的内容,+OK是服务器端给出的应答,告诉我们操作成功。然后,我们获取key对应的值,GET是命令字,key是键值,之后是服务器给出的应答,$5是值的长度,value是值的内容。最后的QUIT是断开连接的命令字。

如此简单的Redis,不妨把它当做了解NoSQL的起步台阶。

Redis的介绍

数据库主要类型有对象数据库,关系数据库,键值数据库等等,对象数据库太超前了,现阶段不提也罢;关系数据库就是平常说的MySQL,PostgreSQL这些熟的不能再熟的东西,至于键值数据库则是本文要着重说的,其代表主要有MemcacheDB,TokyoCabinet等等。

Redis本质上也是一种键值数据库的,但它在保持键值数据库简单快捷特点的同时,又吸收了部分关系数据库的优点。从而使它的位置处于关系数据库和键值数据库之间。Redis不仅能保存Strings类型的数据,还能保存Lists类型(有序)和Sets类型(无序)的数据,而且还能完成排序(SORT)等高级功能,在实现INCR,SETNX等功能的时候,保证了其操作的原子性,除此以外,还支持主从复制等功能。

详细描述参见官方手册,同时,官方提供了一个名为Retwis的项目的源代码,可以对照着官方介绍学习,注意其中关于DataLayout的描述,其他没什么。

项目实践中,多以关系数据库为主,不过合理的使用Redis这样的键值数据库,往往能扬长避短,比如说实现一个类似消息队列的功能,对MySQL来说,除非使用Q4M,否则很难满足高并发请求,不过对Redis来说,通过内建的Lists支持,消息队列就是小菜一碟。

Redis的安装

tarzxvfredis-version.tar.gz

cdredis-version

make

由于没有makeinstall,所以得把源代码目录里的关键文件手动复制到适当的位置:

cpredis.conf/etc/

cpredis-benchmarkredis-cliredis-server/usr/bin/

如果内存情况比较紧张的话,需要设定内核参数:

echo1>/proc/sys/vm/overcommit_memory

然后编辑redis.conf配置文件(/etc/redis.conf),按需求做出适当调整,比如:

daemonizeyes

logfile/dev/null

如果要记录日志的话,最好先调整loglevel到一个合适的级别,然后设定logfile,如果不需要,则可以像上面这样直接把日子丢弃到/dev/null里,还有一点,缺省情况下,数据文件dump.rdb会被生成到当前目录,可以通过dir参数设定合适的目录。

此外,如果你决定把Redis用于产品环境,还要注意maxmemory选项,因为Redis在启动时会把所有数据加载到内存中,所以设定maxmemory相对安全。

接下来直接启动服务就可以了,只有配置文件一个参数:

redis-server/etc/redis.conf

确认运行了之后,可以用redis-benchmark命令测试看看,还可以通过redis-cli命令实际操作一下,比如:

redis-clisetfoobar

OK

redis-cligetfoo

bar

在设置键对应的值的时候,按照协议的规定是要提供数据大小这个参数的,上面的redis-cli命令之所以没有提供这个参数是因为redis-cli本身进行了封装。

可以通过telnet来验证一点:

telnet127.0.0.16379

Trying127.0.0.1...

Connectedtolocalhost.localdomain(127.0.0.1).

Escapecharacteris'^]'.

setfoo3

bar

+OK

getfoo

$3

bar

^]

telnet>quit

Connectionclosed.

更多命令介绍参考文档介绍。

Redis源代码里附带了多种客户端的扩展,比如说php(client-libraries/php),这是一个纯PHP的实现方案,也有二进制版本的实现(phpredis)。其他语言即便没有现成的扩展实现,也可以自己按照协议规范写一个扩展,应该不是什么难事。

Redis内存要求很高,如果你的数据量很大的话,可能会导致系统使用swap,这会使性能急剧下降。此时更好的方法是通过consistenthashing把数据分布到多个服务器上,文档上给出了简单的例子解释:

ForexampleimaginetohaveNRedisservers,server-0,server-1,...,server-N.Youwanttostorethekey"foo",what'stherightserverwheretoput"foo"inordertodistributekeysevenlyamongdifferentservers?Justperformthecrc=CRC32("foo"),thenservernum=crc%N(therestofthedivisionforN).Thiswillgiveanumberbetween0andN-1foreverykey.Connecttothisserverandstorethekey.

Redis

分享到编辑文章

章节

收起

1简介2性能3安装Redis、Redis启动参数介绍4redis数据结构5redis数据存储6redis主从配置7redis起步(链接整理)84.利用Redis构建简单的微博系统

简介

Redis是一个key-value存储系统。和Memcached类似,但是解决了断电后数据完全丢失的情况,而且她支持更多无化的value类型,除了和string外,还支持lists(链表)、sets(集合)和zsets(有序集合)几种数据类型。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。

性能

下面是官方的bench-mark数据:

Thetestwasdonewith50simultaneousclientsperforming100000requests.

ThevalueSETandGETisa256bytesstring.

TheLinuxboxisrunningLinux2.6,it’sXeonX33202.5Ghz.

Textexecutedusingtheloopbackinterface(127.0.0.1).

Results:about110000SETspersecond,about81000GETspersecond.

安装Redis、Redis启动参数介绍

3.1.1.获取源码、解压、进入源码目录:

wgethttp://redis.googlecode.com/files/redis-1.2.6.tar.gz

tarxzfredis-1.2.6.tar.gz

cdredis-1.2.6

3.1.2.编译生成可执行文件:

由于makefile文件已经写好,我们只需要直接在源码目录执行make命令进行编译即可:

make

make命令执行完成后,会在当前目录下生成本个可执行文件,分别是redis-server、redis-cli、redis-benchmark、redis-stat,它们的作用如下:

redis-server:Redis服务器的daemon启动程序

redis-cli:Redis命令行操作工具。当然,你也可以用telnet根据其纯文本协议来操作

redis-benchmark:Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能

redis-stat:Redis状态检测工具,可以检测Redis当前状态参数及延迟状况

3.1.3.建立Redis目录(非必须)

这个过程不是必须的,只是为了将Redis相关的资源统一管理而进行的操作。

执行以下命令建立相关目录并拷贝相关文件至目录中:

sudo-s

mkdir-p/usr/local/redis/bin

mkdir-p/usr/local/redis/etc

mkdir-p/usr/local/redis/var

cpredis-serverredis-cliredis-benchmarkredis-stat/usr/local/redis/bin/

cpredis.conf/usr/local/redis/etc/

3.2.Redis配置参数详解

在我们成功安装Redis后,我们直接执行redis-server即可运行Redis,此时它是按照默认配置来运行的(默认配置甚至不是后台运行)。我们希望Redis按我们的要求运行,则我们需要修改配置文件,Redis的配置文件就是我们上面第二个cp操作的redis.conf文件,目前它被我们拷贝到了/usr/local/redis/etc/目录下。修改它就可以配置我们的server了。如何修改?下面是redis.conf的主要配置参数的意义:

daemonize:是否以后台daemon方式运行

pidfile:pid文件位置

port:监听的端口号

timeout:请求超时时间

loglevel:log信息级别

logfile:log文件位置

databases:开启数据库的数量

save**:保存快照的频率,第一个*表示多长时间,第三个*表示执行多少次写操作。在一定时间内执行一定数量的写操作时,自动保存快照。可设置多个条件。

rdbcompression:是否使用压缩

dbfilename:数据快照文件名(只是文件名,不包括目录)

dir:数据快照的保存目录(这个是目录)

appendonly:是否开启appendonlylog,开启的话每次写操作会记一条log,这会提高数据抗风险能力,但影响效率。

appendfsync:appendonlylog如何同步到磁盘(三个选项,分别是每次写都强制调用fsync、每秒启用一次fsync、不调用fsync等待系统自己同步)

下面是一个略做修改后的配置文件内容:

daemonizeyes

pidfile/usr/local/redis/var/redis.pid

port6379

timeout300

logleveldebug

logfile/usr/local/redis/var/redis.log

databases16

save9001

save30010

save6010000

rdbcompressionyes

dbfilenamedump.rdb

dir/usr/local/redis/var/

appendonlyno

appendfsyncalways

glueoutputbufyes

shareobjectsno

shareobjectspoolsize1024

将上面内容写为redis.conf并保存到/usr/local/redis/etc/目录下

然后在命令行执行:

/usr/local/redis/bin/redis-server/usr/local/redis/etc/redis.conf

即可在后台启动redis服务,这时你通过

telnet127.0.0.16379

即可连接到你的redis服务。

redis数据结构

redis的作者antirez曾笑称其为一个数据结构服务器(datastructuresserver),我认为这是一个非常准确的表述,redis的所有功能就是将数据以其固有的几种结构保存,并提供给用户操作这几种结构的接口。我们可以想象我们在各种语言中的那些固有数据类型及其操作。

redis目前提供四种数据类型:string,list,set及zset(sortedset)。

string是最简单的类型,你可以理解成与Memcached一模一个的类型,一个key对应一个value,其上支持的操作与Memcached的操作类似。但它的功能更丰富。

list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等。操作中key理解为链表的名字。

set是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中key理解为集合的名字。

zset是set的一个升级版本,他在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序。可以理解了有两列的mysql表,一列存value,一列存顺序。操作中key理解为zset的名字。

在官网上给出了所有支持的接口列表,并副副附有详细的介绍,地址:

http://code.google.com/p/redis/wiki/CommandReference

另外,作者还提供了一个非常贴心的web命令行模拟页面,供初学者试用redis,地址:

http://try.redis-db.com/

redis数据存储

redis的快速是业内闻名的,但是我想说,这个速度还是有一定水分的,且看下文。

redis的存储分为内存存储、磁盘存储和log文件三部分,配置文件中有三个参数对其进行配置。

savesecondsupdates,save配置,指出在多长时间内,有多少次更新操作,就将数据同步到数据文件。这个可以多个条件配合,比如默认配置文件中的设置,就设置了三个条件。

appendonlyyes/no,appendonly配置,指出是否在每次更新操作后进行日志记录,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为redis本身同步数据文件是按上面的save条件来同步的,所以有的数据会在一段时间内只存在于内存中。

appendfsyncno/always/everysec,appendfsync配置,no表示等操作系统进行数据缓存同步到磁盘,always表示每次更新操作后手动调用fsync()将数据写到磁盘,everysec表示每秒同步一次。

redis主从配置

redis支持master-slave的主从配置,配置方法是在从机的配置文件中指定slaveof参数为主机的ip和port即可,原理上来说,是从机请求主机的方式,按照tokyotyrant的做法,是可以实现主-主,主-从等灵活形式的,而redis只能支持主从,不能支持主-主,可能是其同步原理的差异所致。(本人还没有试过将两台机器的slaveof参数互指的情况是否可实现主-主。)

redis起步(链接整理)

项目首页,下方是各种语言支持列表:

http://code.google.com/p/redis/

作者在wiki中给出了一个非常好的例子,以使我们可以快速上手,地址:

http://code.google.com/p/redis/wiki/TwitterAlikeExample

同时作者推荐的另一个教程,地址:

http://labs.alcacoop.it/doku.php?id=articles:redis_land

一个redis爱好者创建的相关问题讨论网站:

http://www.rediscookbook.org/

4.利用Redis构建简单的微博系统

具体例子见官方文档:

《Acasestudy:DesignandimplementationofasimpleTwittercloneusingonlytheRediskey-valuestoreasdatabaseandPHP》

体验新版博客

相关推荐