什么是redis?
1、Redis 缓存是基于 key - value 存储的内存缓存;
2、提供list、set、zset、hash等数据结构类型;
3、支持数据的备份, master-slave模式的数据备份;
4、支持数据的持久化,重启的时候可以再次加载使用;
一、Redis 安装
Window 下安装
下载地址:https://github.com/MSOpenTech/redis/releases。
Redis 支持 32 位和 64 位。这个需要根据你系统平台的实际情况选择,这里我们下载 Redis-x64-xxx.zip压缩包到 C 盘,解压后,将文件夹重新命名为 redis。
打开一个 cmd 窗口 使用cd命令切换目录到 C:\redis 运行 redis-server.exe redis.windows.conf 。
如果想方便的话,可以把 redis 的路径加到系统的环境变量里,这样就省得再输路径了,后面的那个 redis.windows.conf 可以省略,如果省略,会启用默认的。输入之后,会显示如下界面:
这时候另启一个cmd窗口,原来的不要关闭,不然就无法访问服务端了。
切换到redis目录下运行 redis-cli.exe -h 127.0.0.1 -p 6379 。
设置键值对 set myKey abc
取出键值对 get myKey
Linux 下安装
下载地址:http://redis.io/download,下载最新文档版本。
本教程使用的最新文档版本为 2.8.17,下载并安装:
$ 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服务.
$ cd src
$ ./redis-server
注意这种方式启动redis 使用的是默认配置。也可以通过启动参数告诉redis使用指定配置文件使用下面命令启动。
$ cd src
$ ./redis-server redis.conf
redis.conf是一个默认的配置文件。我们可以根据需要使用自己的配置文件。
启动redis服务进程后,就可以使用测试客户端程序redis-cli和redis服务交互了。 比如:
$ cd src
$ ./redis-cli
redis> set foo bar
OK
redis> get foo
"bar"
Ubuntu 下安装
在 Ubuntu 系统安装 Redis 可以使用以下命令:
$sudo apt-get update
$sudo apt-get install redis-server
启动 Redis
$ redis-server
查看 redis 是否启动?
$ redis-cli
以上命令将打开以下终端:
redis 127.0.0.1:6379>
127.0.0.1 是本机 IP ,6379 是 redis 服务端口。现在我们输入 PING 命令。
redis 127.0.0.1:6379> ping
PONG
以上说明我们已经成功安装了redis。
二、redis常用配置
配置文件:redis.conf
常见配置项:
bind 127.0.0.1 [绑定ip地址,远程访问请注释]
port 6379 [默认访问地址 6379]
daemonize yes [是否以后台进程<守护进程>运行]
dbfilename dump.rdb [存储数据的文件]
dir ./. [存储数据的文件所在路径
三、redis的数据类型
redis的数据存储:key=value 键值对
key<键>的数据类型:字符串
value<值的类型>:
string字符串
hash哈希
list列表
set集合
zset有序集合
3.1 keys
keys pattern 返回匹配模式的所有keys
keys * : 查看该数据库中所有的key
type key 查看key类型
ttl key 返回key的剩余过期时间,-1表示key不存在或者没有设置过过期时间
exists key 测试key是否存在
del key1 key2 … keyN
randomkey 返回当前数据库随机选择的一个key,如数据库是空的,则返回空串
persist key : 取消掉key的过期时间
exprie key seconds 为key设置过期时间,单位s。返回1成功,0表示key已设置过过期时间或者不存在
3.2 string字符串操作
string 是 redis 最基本的类型,而且 string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象。从内部实现来看其实 string 可以看作 byte 数组,最大上限是 1G 字节。下面是 string 类型的定义。
set key value :给一个key赋值value
setex key seconds value:给一个key设置值value,过期时间seconds
mset key value [key value]:设置多个键值对
get key:根据key获取一个值
mget key [key]:根据多个key获取多个值
incr key :将key对应的值+1
incrby key increment:将key对应的值+increment
decr key:将key对应的值-1
decrby key increment:将key对应的值-increment
append key value:将value的值拼接到x后面
strlen key:获取key对应的值的长度
3.3 hash(用于存储对象)【键值对】
redis 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 实现. 这个限制可以在配置文件中指定。
hset key field value 设置 hash field 为指定值,如果 key 不存在,则先创建
hget key field 获取指定的 hash field
hmget key filed1....fieldN 获取全部指定的 hash filed
hmset key filed1 value1 ... filedN valueN 同时设置 hash 的多个 field
hincrby key field integer 将指定的 hash filed 加上给定值
hexists key field 测试指定 field 是否存在
hdel key field 删除指定的 hash field
hlen key 返回指定 hash 的 field 数量
hkeys key 返回 hash 的所有 field
hvals key 返回 hash 的所有 value
hgetall key 返回 hash 的所有 filed 和 value
3.4 list列表:有序存储多个数据
list类型实质是一个每个元素都是string类型的双向链表,所以push和pop命令的算法时间复杂度都是O(1),另外list还会记录链表的长度,所以llen操作也是O(1)。链表的最大长度是(2的32次方-1)。我们可以通过push,pop操作从链表的头部或者尾部添加删除元素。这使得list既可以用作栈,也可以用作队列。有意思的是list的 pop 操作还有阻塞版本的。当我们[lr]pop一个list对象是,如果list是空,或者不存在,会立即返回nil。但是阻塞版本的b[lr]pop 可以则可以阻塞,当然可以加超时时间,超时后也会返回nil。
lpush key value [value]:列表头部增加多个数据
rpush key value [value]:列表尾部增加多个数据
linsert key before | after privot value:在一个元素钱/后插入数据
lset key index value:设置指定索引的元素的值
lpop key:删除并且获取key对应的list第一个元素
rpop key:删除并且获取key对应的list最后一个元素
lrange key start stop:返回存在在key的list中指定范围的数据
llen key:获取列表的长度
lindex key index:获取列表中索引对应的元素
ltrim key start stop:获取列表中start~stop组成的新的列表
3.5 set集合:无序存储多个数据
redis 的 set 是 string 类型的无序集合。 set 元素最大可以包含(2 的 32 次方-1)个元素。 set 的是通 过 hash table 实现的,所以添加,删除,查找的复杂度都是 O(1)。 hash table 会随着添加或者删除自 动的调整大小。需要注意的是调整 hash table 大小时候需要同步(获取写锁)会阻塞其他读写操作。
sadd key value 添加一个 string 元素到,key 对应的 set 集合中,成功返回 1,如果元素已经在集合中返回 0,key 对应的 set 不存在返回错误
srem key value 从 key 对应 set 中移除给定元素,成功返回 1,如果 value 在集合中不存在或者key 不存在返回 0,如果 key 对应的不是 set 类型的值返回错误
spop key 删除并返回 key 对应 set 中随机的一个元素,如果 set 是空或者 key 不存在返回 nil
srandmember key 同 spop,随机取 set 中的一个元素,但是不删除元素
smove srckey dstkey value 从 srckey 对应 set 中移除 value 并添加到 dstkey 对应 set 中,整个操作是原子的。成功返回 1,如果 value 在 srckey 中不存在返回 0,如果 key 不是 set 类型返回错误
scard key 返回 set 的元素个数,如果 set 是空或者 key 不存在返回 0
sismember key value 判断 value 是否在 set 中,存在返回 1, 0 表示不存在或者 key 不存在
smembers key 返回 key 对应 set 的所有元素,结果是无序的
set 交、并、差集
sinter key1 key2...keyN 返回所有给定 key 的交集
sinterstore dstkey key1...keyN 同 sinter,但是会同时将交集存到 dstkey 下
sunion key1 key2...keyN 返回所有给定 key 的并集
sunionstore dstkey key1...keyN 同 sunion,并同时保存并集到 dstkey 下
sdiff key1 key2...keyN 返回所有给定 key 的差集
sdiffstore dstkey key1...keyN 同 sdiff,并同时保存差集到 dstkey 下
3.6 zset集合:有序存储多个数据
和 set 一样, sorted set 也是 string 类型元素的集合,不同的是每个元素都会关联一个 double 类型 的 score ,元素顺序有score决定。 sorted set 的实现是 skip list 和 hash table 的混合体。 当元素被添加到集合中时,一个元素到 score 的映射被添加到 hash table 中,所以给定一个元素获取 score 的开销是 O(1),另一个 score 到元素 的映射被添加到 skip list 并按照 score 排序,所以就可以有序的获取集合中的元素。
zadd key score member 添加元素到集合,元素在集合中存在则更新对应 score,当该member已存在时,
返回0,并更新该member的score值
zrem key member 删除指定元素, 1 表示成功,如果元素不存在返回 0
zincrby key n member 增加对应 member 的 score 值,然后移动元素并保持 skip list 保持有序。
返回更新后的 score 值
zrank key member 返回指定元素在集合中的排名(下标) ,集合中元素是按 score 从小到大排序的
zrevrank key member 同上,但是集合中元素是按 score 从大到小排序
zrange key start end 类似 lrange 操作从集合中去指定区间的元素。返回的是有序结果
zrevrange key start end 同上,返回结果是按 score 逆序的
zrangebyscore key min max 返回集合中 score 在给定区间的元素
zcount key min max 返回集合中 score 在给定区间的数量
zcard key 返回集合中元素个数
zscore key element 返回给定元素对应的 score
zremrangebyrank key min max 删除集合中排名在给定区间的元素
zremrangebyscore key min max 删除集合中 score 在给定区间的元素
四 redis高级操作
4.1 主从双备
Redis主从双备配合和使用比较简单,通过主从复制可以允许多个slave server拥有和master server相同的数据库副本。
master可以拥有多个salve server,多个slave可以连接同一个master外,还可以连接到其他slave。主从复制不会阻塞master,同步数据时,master可以继续处理client,提高系统伸缩性。
Redis主从双备过程:
- Salve与master建立连接,发送sync同步命令。
- Master会启动一个后台进程,将数据库快照保存到文件中,同时master主进程会开始收集新的写命令缓存。
- 后台完成保存后,就将此文件发送给slave。
- slave将此文件保存到硬盘上。
Redis环境说明:
window下Redis服务作为master主机,window的IP为192.168.1.100,虚拟机下linux下的Redis作为slave,linux的IP为192.168.1.150。
在redis从机(linux环境)的redis.conf配置文件中加入以下配置:
主机写入2条记录到数据库,然后从从机中读取,注意:总计无法更新值,只能读取。
3.3 事务处理
Redis对事务的支持还比较简单,redis只能保证一个client发起的事务中的命令可以连续执行,而中间不会插入其他client的命令。当一个client在一个连接中发出multi命令时,这个连接会进入一个事务的上下文,连接后续命令不会立即执行,而是先放到一个队列中,当执行exec命令时,redis会顺序的执行队列中的所有命令。
在事务处理中使用discard可以取消事务的处理。redis在事务中如果发生错误时事务退出,但是在该错误之前的操作无法回滚。
3.4 持久化
redis是一个支持持久化的内存数据库。snapshotting快照方式,默认的存储方式,默认写入dump.rdb的二进制文件中,可以配置redis在n秒内如果超过m个key被修改过就自动做快照append-only file aof方式,使用aof时候redis会将每一次的函 数都追加到文件中,当redis重启时会重新执行文件中的保存的写命令在内存中。
3.5 发布订阅消息
发布订阅(pub/sub)是一种消息通知模式,主要的目的是截除消息发布者和消息订阅者之间的耦合,Redis作为一个pub/sub的server,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向redis server订阅自己感兴趣的消息类型,redis将消息类型称为通道(channel)。当发布者通过publish命令向redis server发送特定类型的信息时,订阅该信息类型的全部client都会收到此消息。
第一个redis客户端订阅changnel1,第二个redis客户端订阅channel1和channel2,第三个redis客户端负责产生channel1和channel2消息,然后观察第一个和第二个redis客户端是否收到了订阅消息。
3.6 虚拟内存
Redis的虚拟内存与操作系统的虚拟内存不是一回事,但是思路和目的都是相同的。就是暂时把不经常访问的数据从内存交换到磁盘中,从而腾出宝贵的内存空间用于其他需要访问的数据。尤其是对于redis这样的内存数据库,内存总是不够用的。除了可以将数据分割到多个redis server外。另外能够提高数据库容量的办法就是使用虚拟内存把那些不经常访问的数据交换到磁盘上。
如果想启用虚拟内存功能,在配置文件redis.conf中增加配置如下: