虽然Redis已经很火了,相信还是有很多同学对Redis只是有所听闻或者了解并不全面,下面是一个比较系统的Redis介绍,对Redis的特性及各种数据类型及操作进行了介绍。是一个很不错的Redis入门教程。
1.介绍
1.1 Redis是什么
REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。Redis提供了一些丰富的数据结构,包括 lists,sets,ordered sets 以及 hashes ,当然还有和Memcached一样的 strings结构.Redis当然还包括了对这些数据结构的丰富操作。
1.2 Redis的优点
性能极高 – Redis能支持超过 100K+ 每秒的读写频率。
丰富的数据类型 – Redis支持二进制案例的 Strings,Lists,Hashes,Sets 及 Ordered Sets 数据类型操作。
原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
丰富的特性 – Redis还支持 publish/subscribe,通知,key 过期等等特性。
2.数据类型
2.1 String类型
Redis能存储二进制安全的字符串,最大长度为1GB
redis127.0.0.1:6379>SETname"JohnDoe" OK redis127.0.0.1:6379>GETname "JohnDoe" String类型还支持批量的读写操作 redis127.0.0.1:6379>MSETage30sex"male" OK redis127.0.0.1:6379>MGETagesex 1)"30" 2)"male" |
String类型其实也可以用来存储数字,并支持对数字的加减操作。
redis127.0.0.1:6379>INCRage (integer)31 redis127.0.0.1:6379>INCRBYage4 (integer)35 redis127.0.0.1:6379>GETage "35" redis127.0.0.1:6379>DECRage (integer)34 redis127.0.0.1:6379>DECRBYage4 (integer)30 redis127.0.0.1:6379>GETage "30" |
redis127.0.0.1:6379>APPENDname"Mr." (integer)12 redis127.0.0.1:6379>GETname "JohnDoeMr." redis127.0.0.1:6379>STRLENname (integer)12 redis127.0.0.1:6379>SUBSTRname03 "John" |
2.2 List类型
Redis能够将数据存储成一个链表,并能对这个链表进行丰富的操作
redis127.0.0.1:6379>LPUSHstudents"JohnDoe" (integer)1 redis127.0.0.1:6379>LPUSHstudents"CaptainKirk" (integer)2 redis127.0.0.1:6379>LPUSHstudents"SheldonCooper" (integer)3 redis127.0.0.1:6379>LLENstudents (integer)3 redis127.0.0.1:6379>LRANGEstudents02 1)"SheldonCooper" 2)"CaptainKirk" 3)"JohnDoe" redis127.0.0.1:6379>LPOPstudents "SheldonCooper" redis127.0.0.1:6379>LLENstudents (integer)2 redis127.0.0.1:6379>LRANGEstudents01 1)"CaptainKirk" 2)"JohnDoe" redis127.0.0.1:6379>LREMstudents1"JohnDoe" (integer)1 redis127.0.0.1:6379>LLENstudents (integer)1 redis127.0.0.1:6379>LRANGEstudents00 1)"CaptainKirk" |
redis127.0.0.1:6379>LINSERTstudentsBEFORE"CaptainKirk""DexterMorgan" (integer)3 redis127.0.0.1:6379>LRANGEstudents02 1)"DexterMorgan" 2)"CaptainKirk" 3)"JohnDoe" redis127.0.0.1:6379>LPUSHstudents"PeterParker" (integer)4 redis127.0.0.1:6379>LRANGEstudents03 1)"PeterParker" 2)"DexterMorgan" 3)"CaptainKirk" 4)"JohnDoe" redis127.0.0.1:6379>LTRIMstudents13 OK redis127.0.0.1:6379>LLENstudents (integer)3 redis127.0.0.1:6379>LRANGEstudents02 1)"DexterMorgan" 2)"CaptainKirk" 3)"JohnDoe" redis127.0.0.1:6379>LREMstudents1"JohnDoe" (integer)1 redis127.0.0.1:6379>LLENstudents (integer)1 redis127.0.0.1:6379>LRANGEstudents01 1)"CaptainKirk" |
2.3 集合(Sets)类型
Redis能够将一系列不重复的值存储成一个集合
redis127.0.0.1:6379>SADDbirdscrow (integer)1 redis127.0.0.1:6379>SADDbirdspigeon (integer)1 redis127.0.0.1:6379>SADDbirdsbat (integer)1 redis127.0.0.1:6379>SADDmammalsdog (integer)1 redis127.0.0.1:6379>SADDmammalscat (integer)1 redis127.0.0.1:6379>SADDmammalsbat (integer)1 redis127.0.0.1:6379>SMEMBERSbirds 1)"bat" 2)"crow" 3)"pigeon" redis127.0.0.1:6379>SMEMBERSmammals 1)"bat" 2)"cat" 3)"dog" |
redis127.0.0.1:6379>SREMmammalscat (integer)1 redis127.0.0.1:6379>SMEMBERSmammals 1)"bat" 2)"dog" redis127.0.0.1:6379>SADDmammalshuman (integer)1 redis127.0.0.1:6379>SMEMBERSmammals 1)"bat" 2)"human" 3)"dog" |
Redis还支持对集合的子交并补等操作
redis127.0.0.1:6379>SINTERbirdsmammals 1)"bat" redis127.0.0.1:6379>SUNIONbirdsmammals 1)"crow" 2)"bat" 3)"human" 4)"pigeon" 5)"dog" redis127.0.0.1:6379>SDIFFbirdsmammals 1)"crow" 2)"pigeon" |
2.4 有序集合(Sorted Sets)类型
Sorted Sets和Sets结构相似,不同的是存在Sorted Sets中的数据会有一个score属性,并会在写入时就按这个score排好序。
redis127.0.0.1:6379>ZADDdays0mon (integer)1 redis127.0.0.1:6379>ZADDdays1tue (integer)1 redis127.0.0.1:6379>ZADDdays2wed (integer)1 redis127.0.0.1:6379>ZADDdays3thu (integer)1 redis127.0.0.1:6379>ZADDdays4fri (integer)1 redis127.0.0.1:6379>ZADDdays5sat (integer)1 redis127.0.0.1:6379>ZADDdays6sun (integer)1 redis127.0.0.1:6379>ZCARDdays (integer)7 redis127.0.0.1:6379>ZRANGEdays06 1)"mon" 2)"tue" 3)"wed" 4)"thu" 5)"fri" 6)"sat" 7)"sun" redis127.0.0.1:6379>Zscoredayssat "5" redis127.0.0.1:6379>ZCOUNTdays36 (integer)4 redis127.0.0.1:6379>ZRANGEBYscoredays36 1)"thu" 2)"fri" 3)"sat" 4)"sun" |
2.5 Hash类型
Redis能够存储key对多个属性的数据(比如user1.uname user1.passwd)
redis127.0.0.1:6379>HKEYSstudent 1)"name" 2)"age" 3)"sex" redis127.0.0.1:6379>HVALSstudent 1)"Ganesh" 2)"30" 3)"Male" redis127.0.0.1:6379>HGETALLstudent 1)"name" 2)"Ganesh" 3)"age" 4)"30" 5)"sex" 6)"Male" redis127.0.0.1:6379>HDELstudentsex (integer)1 redis127.0.0.1:6379>HGETALLstudent 1)"name" 2)"Ganesh" 3)"age" 4)"30" |
redis127.0.0.1:6379>HMSETkidnameAkshiage2sexFemale OK redis127.0.0.1:6379>HMGETkidnameagesex 1)"Akshi" 2)"2" 3)"Female" 3.Publish/Subscribe |
Redis支持这样一种特性,你可以将数据推到某个信息管道中,然后其它人可以通过订阅这些管道来获取推送过来的信息。
3.1 订阅信息管道
用一个客户端订阅管道
redis127.0.0.1:6379>SUBSCRIBEchannelone Readingmessages...(pressCtrl-Ctoquit) 1)"subscribe" 2)"channelone" 3)(integer)1 |
另一个客户端往这个管道推送信息
redis127.0.0.1:6379>PUBLISHchannelonehello (integer)1 redis127.0.0.1:6379>PUBLISHchanneloneworld (integer)1 |
然后第一个客户端就能获取到推送的信息
redis127.0.0.1:6379>SUBSCRIBEchannelone Readingmessages...(pressCtrl-Ctoquit) 1)"subscribe" 2)"channelone" 3)(integer)1 1)"message" 2)"channelone" 3)"hello" 1)"message" 2)"channelone" 3)"world" |
3.2 按一定模式批量订阅
用下面的命令订阅所有channel开头的信息通道
redis127.0.0.1:6379>PSUBSCRIBEchannel* Readingmessages...(pressCtrl-Ctoquit) 1)"psubscribe" 2)"channel*" 3)(integer)1 |
在另一个客户端对两个推送信息
redis127.0.0.1:6379>PUBLISHchannelonehello (integer)1 redis127.0.0.1:6379>PUBLISHchanneltwoworld (integer)1 |
然后在第一个客户端就能收到推送的信息
redis127.0.0.1:6379>PSUBSCRIBEchannel* Readingmessages...(pressCtrl-Ctoquit) 1)"psubscribe" 2)"channel*" 3)(integer)1 1)"pmessage" 2)"channel*" 3)"channelone" 4)"hello" 1)"pmessage" 2)"channel*" 3)"channeltwo" 4)"world" |
4.数据过期设置
Redis支持按key设置过期时间,过期后值将被删除(在客户端看来是补删除了的)
用TTL命令可以获取某个key值的过期时间(-1表示永不过期)
redis127.0.0.1:6379>SETname"JohnDoe" OK redis127.0.0.1:6379>TTLname (integer)-1 |
下面命令先用EXISTS命令查看key值是否存在,然后设置了5秒的过期时间
redis127.0.0.1:6379>SETname"JohnDoe" OK redis127.0.0.1:6379>EXISTSname (integer)1 redis127.0.0.1:6379>EXPIREname5 (integer)1 |
5秒后再查看
redis127.0.0.1:6379>EXISTSname (integer)0 redis127.0.0.1:6379>GETname (nil) |
这个值已经没有了。
上在是直接设置多少秒后过期,你也可以设置在某个时间点过期,下面例子是设置2011-09-24 00:40:00过期。
redis127.0.0.1:6379>SETname"JohnDoe" OK redis127.0.0.1:6379>EXPIREATname1316805000 (integer)1 redis127.0.0.1:6379>EXISTSname (integer)0 |
5.事务性
Redis本身支持一些简单的组合型的命令,比如以NX结尾命令都是判断在这个值没有时才进行某个命令。
redis127.0.0.1:6379>SETname"JohnDoe" OK redis127.0.0.1:6379>SETNXname"DexterMorgan" (integer)0 redis127.0.0.1:6379>GETname "JohnDoe" redis127.0.0.1:6379>GETSETname"DexterMorgan" "JohnDoe" redis127.0.0.1:6379>GETname "DexterMorgan" |
当然,Redis还支持自定义的命令组合,通过MULTI和EXEC,将几个命令组合起来执行
redis127.0.0.1:6379>SETcounter0 OK redis127.0.0.1:6379>MULTI OK redis127.0.0.1:6379>INCRcounter QUEUED redis127.0.0.1:6379>INCRcounter QUEUED redis127.0.0.1:6379>INCRcounter QUEUED redis127.0.0.1:6379>EXEC 1)(integer)1 2)(integer)2 3)(integer)3 redis127.0.0.1:6379>GETcounter "3" |
你还可以用DICARD命令来中断执行中的命令序列
redis127.0.0.1:6379>SETnewcounter0 OK redis127.0.0.1:6379>MULTI OK redis127.0.0.1:6379>INCRnewcounter QUEUED redis127.0.0.1:6379>INCRnewcounter QUEUED redis127.0.0.1:6379>INCRnewcounter QUEUED redis127.0.0.1:6379>DISCARD OK redis127.0.0.1:6379>GETnewcounter "0" |
6.持久化
Redis的所有数据都存储在内存中,但是他也提供对这些数据的持久化。
6.1 数据快照
数据快照的原理是将整个Redis中存的所有数据遍历一遍存到一个扩展名为rdb的数据文件中。通过SAVE命令可以调用这个过程。
redis127.0.0.1:6379>SETname"JohnDoe" OK redis127.0.0.1:6379>SAVE OK redis127.0.0.1:6379>SETname"SheldonCooper" OK redis127.0.0.1:6379>BGSAVE Backgroundsavingstarted |
如果你是使用的brew在Mac OSX上安全的Redis,那么rdb文件会存在如下路径
/usr/local/var/db/redis/dump.rdb
6.2 Append-Only File(追加式的操作日志记录)
Redis还支持一种追加式的操作日志记录,叫append only file,其日志文件以aof结局,我们一般各为aof文件。要开启aof日志的记录,你需要在配置文件中进行如下设置:
appendonlyyes |
这时候你所有的操作都会记录在aof日志文件中
redis127.0.0.1:6379>GETname (nil) redis127.0.0.1:6379>SETname"GaneshGunasegaran" OK redis127.0.0.1:6379>EXIT →cat/usr/local/var/db/redis/appendonly.aof *2 $6 SELECT $1 0 *3 $3 SET $4 name $18 GaneshGunasegaran |
7.管理命令
Redis支持多个DB,默认是16个,你可以设置将数据存在哪一个DB中,不同DB间的数据具有隔离性。也可以在多个DB间移动数据。
redis127.0.0.1:6379>SELECT0 OK redis127.0.0.1:6379>SETname"JohnDoe" OK redis127.0.0.1:6379>SELECT1 OK redis127.0.0.1:6379[1]>GETname (nil) redis127.0.0.1:6379[1]>SELECT0 OK redis127.0.0.1:6379>MOVEname1 (integer)1 redis127.0.0.1:6379>SELECT1 OK redis127.0.0.1:6379[1]>GETname "JohnDoe" |
Redis还能进行一些如下操作,获取一些运行信息
redis127.0.0.1:6379[1]>DBSIZE (integer)1 redis127.0.0.1:6379[1]>INFO redis_version:2.2.13 redis_git_sha1:00000000 redis_git_dirty:0 arch_bits:64 multiplexing_api:kqueue ...... |
Redis还支持对某个DB数据进行清除(当然清空所有数据的操作也是支持的)
redis127.0.0.1:6379>SETname"JohnDoe" OK redis127.0.0.1:6379>DBSIZE (integer)1 redis127.0.0.1:6379>SELECT1 OK redis127.0.0.1:6379[1]>SETname"SheldonCooper" OK redis127.0.0.1:6379[1]>DBSIZE (integer)1 redis127.0.0.1:6379[1]>SELECT0 OK redis127.0.0.1:6379>FLUSHDB OK redis127.0.0.1:6379>DBSIZE (integer)0 redis127.0.0.1:6379>SELECT1 OK redis127.0.0.1:6379[1]>DBSIZE (integer)1 redis127.0.0.1:6379[1]>FLUSHALL OK redis127.0.0.1:6379[1]>DBSIZE (integer)0 |
8.客户端
Redis的客户端很丰富,几乎所有流行的语言都有其客户端,这里就不再赘述,有兴趣的同学可以上Redis的Clients页面去查找。
9.资料引用
Simon Willison – Redis tutorial
Michael J. Russo – Redis from ground up
10.总结
转载:http://www.searchdatabase.com.cn/showcontent_53373.htm