从零开始的Redis

什么是redis

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
换句话说,Redis就像是一个HashMap,不过不是在JVM中运行,而是以一个独立进程的形式运行。
一般说来,会被当作缓存使用。 因为它比数据库(mysql)快,所以常用的数据,可以考虑放在这里,这样就提高了性能。

NoSQL数据库的四大分类

键值(Key-Value)存储数据库

这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。举例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB.

列存储数据库

这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak.

文档型数据库

文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可 以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,目前已经开源。

图形数据库

图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。 如:Neo4J, InfoGrid, Infinite Graph.
因此,我们总结NoSQL数据库在以下的这几种情况下比较适用:1、数据模型比较简单;2、需要灵活性更强的IT系统;3、对数据库性能要求较高;4、不需要高度的数据一致性;5、对于给定key,比较容易映射复杂值的环境。

CAP的三进二

CAP理论就是说在分布式存储系统中,最多只能实现两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是必须要实现的。

只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点

C:强一致性
A:高可用性
P:分布式容忍性

CA 传统数据库
AP 大多数网站的架构
CP Redis Mongodb

redis入门

概述

REmote DIctionary Server 远程字典服务器
是个完全开源 遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行,并支持持久化的NoSQL数据库

redis的特点

1.Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候还可以再次加载进行使用
2.Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据的存储方式
3.Redis支持数据的备份,即master-slave模式的数据备份

功能介绍

1.内存存储和持久化:redis支持一部将内存中的数据写到硬盘上,同时不影响继续服务
2.取最新N个数据的操作
3.模拟类似于HttpSession这种需要设置定时过期的功能
4.发布 订阅消息系统
5.定时器 计数器

五种数据类型

String(字符串)
List(列表)
Hash(字典)
Set(集合)
Sorted Set(有序集合)

Redis 安装 Linux

下载地址:http://redis.io/download

1.下载获得Redis-3.0.4.tar.gz放入opt目录
2.opt目录下,解压命令tar-zxvfredis-3.0.4.tar-gz
3.解压完成后出现文件夹 redis-3.0.4
4.进入redis-3.0.4目录下执行make命令
5.make完成后继续执行make install

下载完成之后放入 目录中

1
2
3
4
$ wget http://download.redis.io/releases/redis-2.8.17.tar.gz
$ tar xzf redis-2.8.17.tar.gz
$ cd redis-2.8.17
$ make

make完后 redis-2.8.17目录下会出现编译后的redis服务程序redis-server,还有用于测试的客户端程序redis-cli,两个程序位于安装目录 src 目录下

启动redis服务

1
2
$ cd src
$ ./redis-server

这种方式启动redis 使用的是默认配置。也可以通过启动参数告诉redis使用指定配置文件使用下面命令启动。

1
2
$ cd src
$ ./redis-server ../redis.conf

redis.conf 是一个默认的配置文件。我们可以根据需要使用自己的配置文件。
启动redis服务进程后,就可以使用测试客户端程序redis-cli和redis服务交互了

1
2
3
4
5
6
$ cd src
$ ./redis-cli
redis> set foo bar
OK
redis> get foo
"bar"

Redis配置

Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf

Redis数据类型

String

string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。

string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。

string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。

1
2
3
4
redis 127.0.0.1:6379> SET name "runoob"
OK
redis 127.0.0.1:6379> GET name
"runoob"

Hash

Redis hash 是一个键值(key=>value)对集合。

Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。

1
2
3
4
5
6
7
redis 127.0.0.1:6379> DEL runoob
redis 127.0.0.1:6379> HMSET myhash field1 "Hello" field2 "World"
"OK"
redis 127.0.0.1:6379> HGET myhash field1
"Hello"
redis 127.0.0.1:6379> HGET myhash field2
"World"

List

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

1
2
3
4
5
6
7
8
9
10
11
12
redis 127.0.0.1:6379> DEL runoob
redis 127.0.0.1:6379> lpush runoob redis
(integer) 1
redis 127.0.0.1:6379> lpush runoob mongodb
(integer) 2
redis 127.0.0.1:6379> lpush runoob rabitmq
(integer) 3
redis 127.0.0.1:6379> lrange runoob 0 10
1) "rabitmq"
2) "mongodb"
3) "redis"
redis 127.0.0.1:6379>

Set

Redis的Set是string类型的无序集合。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

sadd命令
添加一个 string 元素到 key 对应的 set 集合中,成功返回1,如果元素已经在集合中返回 0,如果 key 对应的 set 不存在则返回错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
redis 127.0.0.1:6379> DEL runoob
redis 127.0.0.1:6379> sadd runoob redis
(integer) 1
redis 127.0.0.1:6379> sadd runoob mongodb
(integer) 1
redis 127.0.0.1:6379> sadd runoob rabitmq
(integer) 1
redis 127.0.0.1:6379> sadd runoob rabitmq
(integer) 0
redis 127.0.0.1:6379> smembers runoob

1) "redis"
2) "rabitmq"
3) "mongodb"

zset

Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

zset的成员是唯一的,但分数(score)却可以重复。

zadd命令
添加元素到集合,元素在集合中存在则更新对应score

1
2
3
4
5
6
7
8
9
10
11
12
13
redis 127.0.0.1:6379> DEL runoob
redis 127.0.0.1:6379> zadd runoob 0 redis
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 mongodb
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 rabitmq
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 rabitmq
(integer) 0
redis 127.0.0.1:6379> > ZRANGEBYSCORE runoob 0 1000
1) "mongodb"
2) "rabitmq"
3) "redis"

类型应用场景

类型 简介 特性 场景
String 二进制安全 可以包含任何数据,比如jpg图片或者序列化的对象,一个键最大能存储512M
Hash 键值对集合,即编程语言中的Map类型 适合存储对象,并且可以像数据库中update一个属性一样只修改某一项属性值(Memcached中需要取出整个字符串反序列化成对象修改完再序列化存回去) 存储 读取 修改用户属性
List 链表(双向链表) 增删快,提供了操作某一段元素的API 1,最新消息排行等功能(比如朋友圈的时间线) 2,消息队列
Set Hash表实现,元素不重复 1、添加、删除,查找的复杂度都是O(1) 2、为集合提供了求交集、并集、差集等操作 1、共同好友 2、利用唯一性,统计访问网站的所有独立ip 3、好友推荐时,根据tag求交集,大于某个阈值就可以推荐
ZSet 将Set中的元素增加一个权重参数score,元素按score有序排列 数据插入集合中,已进行天然的排序 1、排行榜 2、带权重的消息队列

Redis 命令

启动

启动 redis 客户端,打开终端并输入命令 redis-cli。该命令会连接本地的 redis 服务

1
2
3
4
5
$redis-cli
redis 127.0.0.1:6379>
redis 127.0.0.1:6379> PING

PONG //redis服务启动成功

远程服务上执行命令

1
2
3
4
5
$redis-cli -h 127.0.0.1 -p 6379 -a "mypass"
redis 127.0.0.1:6379>
redis 127.0.0.1:6379> PING

PONG

发布订阅

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis 客户端可以订阅任意数量的频道。


当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端

创建了订阅频道名为 redisChat

1
2
3
4
5
6
redis 127.0.0.1:6379> SUBSCRIBE redisChat

Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1

重新开启个 redis 客户端,然后在同一个频道 redisChat 发布两次消息,订阅者就能接收到消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"

(integer) 1

redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by runoob.com"

(integer) 1

# 订阅者的客户端会显示如下消息
1) "message"
2) "redisChat"
3) "Redis is a great caching technique"
1) "message"
2) "redisChat"
3) "Learn redis by runoob.com"

Redis 事务

redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:

批量操作在发送 EXEC 命令前被放入队列缓存。
收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

一个事务从开始到执行会经历以下三个阶段:

开始事务。
命令入队。
执行事务。

命令 描述
DISCARD 取消事务,放弃执行事务块内的所有命令。
EXEC 执行所有事务块内的命令。
DISCARD 取消事务,放弃执行事务块内的所有命令。
DISCARD 取消事务,放弃执行事务块内的所有命令。
DISCARD 取消事务,放弃执行事务块内的所有命令。