上篇文章介绍了redis的基本情况和支持的数据类型,本篇文章将介绍redis持久化、主从复制、简单的事务支持及发布订阅功能。
持久化
•redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到磁盘来保证持久化,这是相对memcache来说的一个大的优势。redis支持两种持久化方式,一种是 Snapshotting(快照)也是默认方式,另一种是Append-only file(缩写aof)的方式。
Snapshotting
快照是默认的持久化方式。这种方式将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以配置自动做快照持久 化的方式。我们可以配置redis在n秒内如果超过m个key被修改就自动做快照,下面是默认的快照保存配置
save 900 1 #900秒内如果超过1个key被修改,则发起快照保存
save 300 10 #300秒内容如超过10个key被修改,则发起快照保存
save 60 10000
Append-only file
aof 比快照方式有更好的持久化性,是由于在使用aof持久化方式时,redis会将每一个收到的写命令都通过write函数追加到文件中(默认是 appendonly.aof)。当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。当然由于os会在内核中缓存 write做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。不过我们可以通过配置文件告诉redis我们想要 通过fsync函数强制os写入到磁盘的时机。有三种方式如下(默认是:每秒fsync一次)
appendonly yes //启用aof持久化方式
# appendfsync always //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
appendfsync everysec //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
# appendfsync no //完全依赖os,性能最好,持久化没保证
主从复制
•
主从复制允许多个
slave server
拥有和
master server
相同的数据库副本。下面是关于
redis
主从复制的一些特点
–
1.master
可以有多个
slave
–
2.
除了多个
slave
连到相同的
master
外,
slave
也可以连接其他
slave
形成图状结构
–
3.
主从复制不会阻塞
master
。也就是说当一个或多个
slave
与
master
进行初次同步数据时,
master
可以继续处理
client
发来的请求。相反
slave
在初次同步数据时则会阻塞,不能处理
client
的请求。
–
4.
主从复制可以用来提高系统的可伸缩性(我们可以用多个
slave
专门用于
client
的读请求,比如
sort
操作可以使用
slave
来处理),也可以用来做简单的数据冗余。
-5.可以在master禁用数据持久化,只需要注释掉master 配置文件中的所有save配置,然后只在slave上配置数据持久化。
事物
•
redis
对事务的支持目前还比较简单。
redis
只能保证一个
client
发起的事务中的命令可以连续的执行,而中间不会插入其他
client
的命令。
–
Multi
事物开始
–
Exec
执行事务
–
Discard
放弃事物
–
Watch
监听
key
–
Unwatch
放弃所有
key
的监听
•
watch
命令会监视给定的
key,
当
exec
时候如果监视的
key
从调用
watch
后发生过变化,则整个事务会失败。注意
watch
的
key
是对整个连接有效的,和事务一样,如果连接断开,监视和事务都会被自动清除。
发布订阅(pub/sub )
•
发布订阅
(pub/sub)
是一种消息通信模式。订阅者可以通过
subscribe
和
psubscribe
命令向
redis
server
订阅自己感兴趣的消息类型,
redis
将消息类型称为通道
(channel)
。当发布者通过
publish
命令向
redis
server
发送特定类型的消息时。订阅该消息类型的全部
client
都会收到此消息。这里消息的传递是多对多的。一个
client
可以订阅多个
channel,
也可以向多个
channel
发送消息。
–
Subscribe
–
Unsubscribe
–
Psubscribe
–
Punsubscribe
–
Publish
管道(pipeline)
•
redis
是一个
cs
模式的
tcp
server
,使用和
http
类似的请求响应协议。一个
client
可以通过一个
socket
连接发起多个请求命令。每个请求命令发出后
client
通常 会阻塞并等待
redis
服务处理,
redis
处理完后请求命令后会将结果通过响应报文返回给
client
。基本的通信过程如下
Client: INCR X
Server: 1
Client: INCR X
Server: 2
Client: INCR X
Server: 3
Client: INCR X
Server: 4
•
基本上四个命令需要
8
个
tcp
报文才能完成。由于通信会有网络延迟
,
假如从
client
和
server
之间的包传输时间需要
0.125
秒。那么上面的四个命令
8
个报文至少会需要
1
秒才能完成。
利用pipeline的方式从client打包多条命令一起发出,不需要等待单条命令的响应返回,而redis服务端会处理完多条命令后会将多条命令的处理结果打包到一起返回给客户端。通信过程如下
Client: INCR X
Client: INCR X
Client: INCR X
Client: INCR X
Server: 1
Server: 2
Server: 3
Server: 4
虚拟内存(VM)
VM的作者已经放弃该功能
•
redis
没有使用
os
提供的虚拟内存机制而是自己实现了自己的虚拟内存机制 ,但是思路和目的都是相同的。就是暂时把不经常访问的数据从内存交换到磁盘中,从而腾出内存空间用于其他需要访问的数据。尤其是对于
redis
这样的内存数据库,内存总是不够用的。除了可以将数据分割到多个
redis
server
外。另外的能够提高数据库容量的办法就是使用
vm
把那些不经常访问的数据交换的磁盘上。如果我们的存储的数据总是有少部分数据被经常访问,大 部分数据很少被访问,对于网站来说确实总是只有少量用户经常活跃。当少量数据被经常访问时,使用
vm
不但能提高单台
redis
server
数据库的容量,而且也不会对性能造成太多影响。
–
vm
-enabled yes #
开启
vm
功能
–
vm
-swap-file /
tmp
/
redis.swap
#
交换的
value
保存的文件路径
/
tmp
/
redis.swap
–
vm
-max-memory 1000000 #
最大内存上限,超过后开始交换
value
到磁盘文件
–
vm
-page-size 32 #
每个页面的大小
32
个字节
–
vm
-pages 134217728 #
最多使用在文件中使用多少页面
vm
-max-threads 4 #
用于执行
value
对象换入换出的工作线程数量,
0
表示不使用工作线程