Redis 介绍
1. Redis介绍
1.1 Redis是什么
REmote DIctionary Server(Redis) 是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、key-value存储系统,并提供多种语言的API接口。
Redis能运行在大多数POSIX(Linux,*BSD, OS X 和Solaris等)系统上,官方没有支持Windows的版本。目前最新的版本是2.2.11,这个版本主要是修复了一个2.2.7版本中遍历方式优化带来的一个bug。
Redis提供了丰富的数据结构,包括 lists,sets, ordered sets 以及 hashes ,当然还有和Memcached一样的 strings结构,以及对这些数据结构的丰富操作。正是这些灵活的数据结构,丰富了Redis的应用场景,能满足更多业务上的灵活存储需求。
1.2 Redis的优点
a) 性能极高 – Redis能支持超过 100K+ 每秒的读写频率。
b) 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
c) 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
d) 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
1.3 Redis数据类型
Redis的数据都保存在内存中,而且底层实现上是自己写了epoll, event, loop部分,而没有采用开源的libevent等通用框架,所以读写效率很高。为了实现数据的持久化,Redis支持定期刷新(可通过配置实现)或写日志的方式来保存数据到磁盘。
作为Key-value型数据库,Redis也提供了键(Key)和键值(Value)的映射关系。但是,除了常规的数值或字符串,Redis的键值还包括其他类型。以下是Redis提供的键值形式:
l String(字符串)
l Lists(列表)
l Sets(集合)
l Sorted sets(有序集合)
l Hashes(哈希表)
键值的数据类型决定了该键值支持的操作。Redis支持诸如列表、集合或有序集合的交集、并集、查集等高级原子操作;同时,如果键值的类型是普通数字,Redis则提供自增等原子操作。
1.3.1 String类型
String是Redis最基本的类型,它是二进制安全的(可以包含任何数据,比如jpg图片或者序列化的对象)。从内部实现来看,string可以看作byte数组,最大上限是1G字节。下面是string类型的定义:
struct sdshdr {
long len;
long free;
char buf[];
};
buf是个char类型数组用于存贮实际的字符串内容,len是buf数组的长度,free是数组中剩余可用字节数。由此可以理解为什么string类型是二进制安全的,因为它本质上就是个byte数组,当然可以包含任何数据了。另外string类型可以被部分命令按int处理,比如incr等命令。还有Redis的其他类型像list、set、sorted set、hash它们包含的元素与都能是string类型。
下面介绍下String相关的一些命令,其他的请看相关文档:
|
命令 |
说明 |
示例 |
|
SET key value |
将字符串值value关联到key。 如果key已经持有其他值,SET就覆写旧值,无视类型。 |
redis 127.0.0.1:6379> set name naxsu OK |
|
MSET key value [key value ...] |
同时设置一个或多个key-value对。 |
redis 127.0.0.1:6379> mset one 1 two 2 three 3 four 4 OK |
|
APPEND key value |
如果key已经存在并且是一个字符串,APPEND命令将value追加到key原来的值之后。 如果key不存在,APPEND就简单地将给定key设为value |
redis 127.0.0.1:6379> append name -neng (integer) 10 redis 127.0.0.1:6379> get name "naxsu-neng" |
|
GET key |
返回key所关联的字符串值。 |
redis 127.0.0.1:6379> get name "naxsu-neng" |
|
STRLEN key |
返回key所储存的字符串值的长度 |
redis 127.0.0.1:6379> strlen name (integer) 10 |
1.3.2 List 类型
List类型是一个每个子元素都是string类型的双向链表,所以[lr]push和[lr]pop命令的算法时间复杂度都是O(1)。另外,list会记录链表的长度,因此llen操作也是O(1)。链表的最大长度是。我们可以通过push和pop操作从链表的头部或者尾部添加删除元素。这使得list既可以用作栈,也可以用作队列。有意思的是list的pop操作还有阻塞版本的。当我们[lr]pop一个list对象是,如果list是空,或者不存在,会立即返回nil。但是阻塞版本的b[lr]pop可以则可以阻塞,当然可以加超时时间,超时后也会返回nil。
为什么要阻塞版本的pop呢,主要是为了避免轮询。举个简单的例子如果我们用list来实现一个工作队列。执行任务的thread可以调用阻塞版本的pop去获取任务这样就可以避免轮询去检查是否有任务存在。当有任务来时,工作线程可以立即返回,可以避免轮询带来的延迟。
下面介绍下list相关的一些命令,其他的请看相关文档:
|
命令 |
说明 |
示例 |
|
LPUSH key value [value ...] |
将一个或多个值value插入到列表key的表头。 |
redis 127.0.0.1:6379> LPUSH mylist a b c (integer) 3 |
|
RPUSH key value [value ...] |
将一个或多个值value插入到列表key的表尾。 |
redis 127.0.0.1:6379> RPUSH mylist a b c (integer) 6[6个元素中包括上例PUSH的3个] |
|
LLEN key |
返回列表key的长度 |
redis 127.0.0.1:6379> llen mylist (integer) 6 |
|
LRANGE key start stop |
返回列表key中指定区间内的元素,区间以偏移量start和stop指定。 |
redis 127.0.0.1:6379> lrange mylist 0 6 1) "c" 2) "b" 3) "a" 4) "a" 5) "b" 6) "c" |
|
LPOP key |
移除并返回列表key的头元素 |
redis 127.0.0.1:6379> lpop mylist "c" |
|
RPOP key |
移除并返回列表key的尾元素 |
redis 127.0.0.1:6379> rpop mylist "c" |
1.3.3 Set 类型
Set是string类型的无序集合。set元素最大元素个数为。set的是通过hash table实现的,所以添加,删除,查找的复杂度都是O(1)。hash table会随着添加或者删除自动的调整大小。需要注意的是调整hashtable大小时候需要同步(获取写锁)会阻塞其他读写操作。关于set集合类型除了基本的添加删除操作,其他有用的操作还包含集合的取并集(union),交集(intersection),差集(difference)。通过这些操作可以很容易的实现SNS中的好友推荐和Blog的tag功能。
下面介绍下set相关的一些命令,其他的请看相关文档:
|
命令 |
说明 |
示例 |
|
SADD key member [member ...] |
将一个或多个member元素加入到集合key当中,已经存在于集合的member元素将被忽略 |
redis 127.0.0.1:6379> sadd languages java c lisp python ruby (integer) 5 |
|
SMEMBERS key |
返回集合key中的所有成员 |
redis 127.0.0.1:6379> smembers languages 1) "c" 2) "lisp" 3) "python" 4) "java" 5) "ruby" |
|
SREM key member [member ...] |
移除集合key中的一个或多个member元素 |
redis 127.0.0.1:6379> srem languages lisp (integer) 1 |
|
SISMEMBER key member |
判断member元素是否是集合key的成员 |
redis 127.0.0.1:6379> SISMEMBER languages php (integer) 0 |
|
SCARD key |
返回集合key的基数(集合中元素的数量) |
redis 127.0.0.1:6379> SCARD languages (integer) 4 |
|
SINTER key [key ...] |
返回一个集合的全部成员,该集合是所有给定集合的交集 |
redis 127.0.0.1:6379> sadd group_1 lilei tom jack (integer) 3 redis 127.0.0.1:6379> sadd group_2 naxsu jack (integer) 2 redis 127.0.0.1:6379> sinter group_1 group_2 1) "jack" |
|
SUNION key [key ...] |
返回一个集合的全部成员,该集合是所有给定集合的并集 |
redis 127.0.0.1:6379> sunion group_1 group_2 1) "naxsu" 2) "lilei" 3) "tom" 4) "jack" |
|
SDIFF key [key ...] |
返回一个集合的全部成员,该集合是所有给定集合的差集 |
redis 127.0.0.1:6379> SDIFF group_1 group_2 1) "lilei" 2) "tom" |
1.3.4 SortedSet
sortedset和set一样也是string类型元素的集合,不同的是每个元素都会关联一个double类型的score。sortedset的实现是skip list(跳表)和hash table的混合体当元素被添加到集合中时,一个元素到score的映射被添加到hash table中,所以给定一个元素获取score的开销是O(1),另一个score到元素的映射被添加到skip list并按照score排序,所以就可以有序的获取集合中的元素。添加,删除操作开销都是O(log(N))和skip list的开销一致,Redis的skip list实现用的是双向链表,这样就可以逆序从尾部取元素。sorted set最经常的使用方式应该是作为索引来使用。我们可以把要排序的字段作为score存储,对象的id当元素存储。
下面介绍下sortedset相关的一些命令,其他的请看相关文档:
|
命令 |
说明 |
示例 |
|
ZADD key score member [[score member] [score member] ...] |
将一个或多个member元素及其score值加入到有序集key当中 |
redis 127.0.0.1:6379> ZADD page_rank 9 baidu.com 8 bing.com 10 google.com (integer) 3 |
|
ZRANGE key start stop [WITHSCORES] |
返回有序集key中,指定区间内的成员, 其中成员的位置按score值递增(从小到大)来排序
ZREVRANGE key start stop [WITHSCORES] 其中成员的位置按score值递减(从大到小)来排列 |
redis 127.0.0.1:6379> ZRANGE page_rank 0 -1 WITHSCORES 1) "bing.com" 2) "8" 3) "baidu.com" 4) "9" 5) "google.com" 6) "10" |
|
ZREM key member [member ...] |
移除有序集key中的一个或多个成员,不存在的成员将被忽略 |
redis 127.0.0.1:6379> ZREM page_rank google.com (integer) 1 |
|
ZCARD key |
返回有序集key的基数 |
redis 127.0.0.1:6379> zcard page_rank (integer) 2 |
|
ZCOUNT key min max |
返回有序集key中,score值在min和max之间(默认包括score值等于min或max)的成员 |
redis 127.0.0.1:6379> zcount page_rank 7 9 (integer) 2 |
|
ZSCORE key member |
返回有序集key中,成员member的score值 |
redis 127.0.0.1:6379> zscore page_rank baidu.com "9" |
1.3.5 Hash 类型
Hash是一个string类型的field和value的映射表。它的添加,删除操作平均情况下都是O(1)。hash特别适合用于存储对象。相较于将对象的每个字段存成单个string类型,将一个对象存储在hash类型中会占用更少的内存,并且可以更方便的存取整个对象。
节省内存的原因是新建一个hash对象时开始是用zipmap(又称为small hash)来存储的。这个zipmap其实并不是hash table,但是zipmap相比正常的hash实现可以节省不少hash本身需要的一些元数据存储开销。尽管zipmap的添加、删除、查找都是O(n),但是由于一般对象的field数量都不太多,所以使用zipmap也是很快的,也就是说添加删除平均还是O(1)。如果field或者value的大小超出一定限制后,redis会在内部自动将zipmap替换成正常的hash实现. 这个限制可以在配置文件中指定,如下:
hash-max-zipmap-entries 64 #配置字段最多64个
hash-max-zipmap-value 512 #配置value最大为512字节
下面介绍下hash相关的一些命令,其他的请看相关文档:
|
命令 |
说明 |
示例 |
|
HSET key field value |
将哈希表key中的域field的值设为value |
redis 127.0.0.1:6379> hset website google www.google.com |
|
HGET key field |
返回哈希表key中给定域field的值 |
redis 127.0.0.1:6379> hget website google "www.google.com" |
|
HDEL key field [field ...] |
删除指定的hash field |
更多推荐
所有评论(0)