您的位置:首页 > 数据库 > Redis

redis简介

2015-08-16 21:54 393 查看
    Redis是一个使用C语言开发的开源高性能键值对数据库。它通过提供多种键值数据类型来适应不同场景
下的存储需求,并借助许多高层级的接口使其可以胜任如缓存、队列系统等不同的角色
    redis的高效是因为redis将数据储存在内存中,同时也支持持久化到磁盘里
    redis操作简单,性能高效,稳定易学,基本可以胜任数据库的功能(事务、主从同步、储存过程:可以用自定义脚本实现、备份等)
redis是单线程运行的,在处理一个任务完成之前时必须阻塞其他的进程,但是因为redis是内存数据库,操作非常迅速,所以任务处理时间
不是主要的瓶颈,redis的任务耗时主要是客户端和服务端直接的网络传输时延,因此,redis提供的管道通讯即一次发送多条任务到服务端
执行,这样减少了客户端和服务端的通信次数!
下面简单介绍下redis的基本知识
首先redis有服务端和客户端,就像mysql一样这个很好理解,关于安装和使用请参考其他文献,这里不讨论如何安装
我们知道redis是一个键值对数据库,也就是获取值时必须有一个唯一的key,这个key在一个数据库内必须唯一(redis支持
多数据库),redis存储数据的形式就是key-value的实现,下面我们讲下redis里value支持的类型
1、Redis字典中的键值除了可以是字符串,还可以是其他数据类型。到目前为止Redis支持的键值数据类型如下

●字符串类型
●散列类型
●列表类型
●集合类型
●有序集合类型

1、字符串类型

是Redis中最基本的数据类型,它能存储任何形式的字符串,包括二进制数
据。你可以用其存储用户的邮箱、JSON化的对象甚至是一张图片。一个字符串类型键允许存
储的数据的最大容量是512MB。字符串类型是其他4种数据类型的基础,其他数据类型和字符串类型的差别从某种角度来
说只是组织字符串的形式不同。例如,列表类型是以列表的形式组织字符串,而集合类型是以
集合的形式组织字符串,判断一个key属于那种类型TYPE key!
字符简单操作
1.赋值与取值
SET key value
GET key

2、散列类型(hash)

散列类型的键值也是一种字典结构,其存储了字段(field)和字段值的映射,但字段值只能是字符串,不
支持其他数据类型,换句话说,散列类型不能嵌套其他的数据类型。一个散列类型键可以包含 至多232-1个字段。
散列类型非常适合存储对象接结构,因为它是key field value结构,对应:对象名 字段 字段值
对比关系型数据库的二维表结构存储数据,两个同属于一个对象,对其中一个对象新增减少任意一个字段而不影响
另一个对象,但是关系型数据库对其中一条记录新增一个字段(相当于改变表结构)影响全部记录!
1.赋值与取值
HSET key field value
HGET key field
HMSET key field value [field value …]
HMGET key field [field …]
HGETALL key

3、列表类型(list)

列表类型可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或 者获得列表的某一个片段。 
列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时 间复杂度为0(1),
获取越接近两端的元素速度就越快。
集合类型
集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,由于集合
类型在Redis内部是使用值为空的散列表(hash table)实现的,所以这些操作的时间复杂度都是
0(1)。最方便的是多个集合类型键之间还可以进行并集、交集和差集运算,稍后就会看到灵活
运用这一特性带来的便利

4、有序集合类型(sorted set)

有序集合的特点从它的名字中就可以猜到,它与上一节介绍的集合类型的区别就是“有序”二字。
在集合类型的基础上有序集合类型为集合中的每个元素都关联了一个分数,这使得我们
不仅可以完成插入、删除和判断元素是否存在等集合类型支持的操作,还能够获得分数最高
(或最低)的前N个元素、获得指定分数范围内的元素等与分数有关的操作。虽然集合中每个元
素都是不同的,但是它们的分数却可以相同。
有序集合类型在某些方面和列表类型有些相似。
(1)二者都是有序的。
(2)二者都可以获得某一范围的元素。但是二者有着很大的区别,这使得它们的应用场景也是不同的。
(1)列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问
中间数据的速度会较慢,所以它更加适合实现如“新鲜事”或“日志”这样很少访问中间元素的应用。
(2)有序集合类型是使用散列表和跳跃表(Skip list)实现的,所以即使读取位于中间部分
的数据速度也很快(时间复杂度是O(log(N)))。
(3)列表中不能简单地调整某个元素的位置,但是有序集合可以(通过更改这个元素的分数)。
(4)有序集合要比列表类型更耗费内存。
有序集合类型算得上是 Redis的5种数据类型中最高级的类型了,在学习时可以与列表类
型和集合类型对照理解。

以上大概讲解redis的基本概念和数据类型,那么redis作为一个数据库,肯定也有数据库的基本功能:事务,备份等等
别急,马上为你献上

redis高级特性
事务是数据一致性的保证,很简单的列子,你去银行转账,第一步银行先扣除你账户上的转账金额,第二部你转入得账户
必定也得加上相应的金额,这两步要不都成功,要么都失败!怎么保证,那就是使用事务!
Redis中的事务(transaction)是一组命令的集合。事务同命令一样都是Redis的最小执行单 位,一个事务中的命令要么都
执行,要么都不执行。事务的原理是先将属于一个事务的命令发送给Redis,然后再让Redis依次执行这些命令。
例如:
redis>MULTI
OK
redis>SADD "user:1:following" 2
QUEUED
redis>SADD "user:2:followers" 1
QUEUED
redis>EXEC
1) (integer) 1
2) (integer) 1
有些读者会有疑问,如果一个事务中的某个命令执行出错,Redis会怎样处理呢?要回答
这个问题,首先需要知道什么原因会导致命令执行出错。
(1)语法错误。语法错误指命令不存在或者命令参数的个数不对,这里错误在执行前redis语法检查会发现这类错误。而只要有
一个命令有语法错误,执行EXEC命令后Redis就会直接返回错误, 连语法正确的命令也不会执行
(2)运行错误。运行错误指在命令执行时出现的错误,比如使用散列类型的命令操作集合 类型的键,这种错误在实际执行之
前Redis是无法发现的,所以在
d12f
事务里这样的命令是会被 Redis接受并执行的。如果事务里的一条命令出现了运行错误,事务
里其他的命令依然会继续 执行(包括出错命令之后的命令)。
Redis的事务没有关系数据库事务提供的回滚(rollback)功能。为此开发者必须在事务
执行出错后自己收拾剩下的摊子(将数据库复原回事务执行前的状态等)
WATCH命令可以监控一个或多 个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行。监控一直持续到EXEC命 
令(事务中的命令是在EXEC之后才执行的,所以在MULTI命令后可以修改WATCH监控的键 值)
redis键生存时间
常用命令:
设置key生存时间:EXPIRE,PEXPIRE时间单位是毫秒
查看key存活时间(秒)TTL,PTTL
设置成永久:PERSIST
EXPIREAT命令与EXPIRE命令的差别在于前者使用Unix时间作为第二个参数表示键的生
存时间的截止时间。PEXPIREAT命令与EXPIREAT命令的区别是前者的时间单位是毫秒

redis排序功能
SORT命令 BY GET STORE 
SORT是Redis中最强大最复杂的命令之一,如果使用不好很容易成为性能瓶颈。SORT命
令的时间复杂度是0(n+mlogm),其中n表示要排序的列表(集合或有序集合)中的元素个数,m
表示要返回的元素个数。当n较大的时候SORT命令的性能相对较低,并且Redis在排序前会建
立一个长度为n① 的容器来存储待排序的元素,虽然是一个临时的过程,但如果同时进行较多
的大数据量排序操作则会严重影响性能。
注释:①有一个例外是当键类型为有序集合且参考键为常量键名时容器大小为m而不是 n。 
所以开发中使用SORT命令时需要注意以下几点。
(1)尽可能减少待排序键中元素的数量(使n尽可能小)。
(2)使用LIMIT参数只获取需要的数据(使m尽可能小)。
(3)如果要排序的数据数量较大,尽可能使用STORE参数将结果缓存。

redis实现消息通知和任务队列
消息通知要知道的概念,生产者和消费者,生产消息,消费消息
使用任务队列有如下好处。
(1)松耦合。生产者和消费者无需知道彼此的实现细节,只需要约定好任务的描述格式。
这使得生产者和消费者可以由不同的团队使用不同的编程语言编写。
(2)易于扩展消费者可以有多个,而且可以分布在不同的服务器中,如图4-1所示。借此可
以轻易地降低单台服务器的负载
任务队列实现可以使用redis的列表类型实现,LPUSH往队列左边新增元素,RPOP队列右边获取元素
BRPOP命令接收两个参数,第一个是键名,第二个是超时时间,单位是秒。当超过了此时
间仍然没有获得新元素的话就会返回nil。上例中超时时间为“0”,表示不限制等待的时间,即
如果没有新元素加入列表就会永远阻塞下去。

除了实现任务队列外,Redis还提供了一组命令可以让开发者实现“发布/订
阅”(publish/subscribe)模式。“发布/订阅”模式同样可以实现进程间的消息传递,其原理是这样
的:
“发布/订阅”模式中包含两种角色,分别是发布者和订阅者。订阅者可以订阅一个或若干
个频道(channel),而发布者可以向指定的频道发送消息,所有订阅此频道的订阅者都会收到
此消息。

redis支持脚本扩展现有的功能,比如你需要用到redis多个命令来完成一项功能时,可以把这些命令写成脚本语言
客户端直接调用脚本即可,是不是很像mysql的pl/sql。
使用脚本语言的好处,可以减少指令在客户端服务端之间传输,挺高效率。可以把同一的功能封装以来,方便复用。
redis脚本使用 的是Lua语言编写的,Lua很像javaScript,大小写敏感,解释性语言,可嵌入到其他语言一起执行
关于Lua语言的,请自行查看其他文献

redis持久化
Redis的强劲性能很大程度上是由于其将所有数据都存储在了内存中,为了使Redis在重 启之后仍能保证数据不丢失,
需要将数据从内存中以某种形式同步到硬盘中,这一过程就是 持久化。 
Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一 种或将二者结合使用。
主从同步
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  缓存 redis