Redis 学习之持久化机制、发布订阅、虚拟内存
该问使用centos6.5 64位 redis3.2.8
一、持久化机制
Redis是一个支持持久化的内存数据库,redis会经常将内存中的数据同步到硬盘上来保证数据持久化,从而避免服务器宕机数据丢失问题,或者减少服务器内存消耗提高性能。
持久化方式:
1、Snapshotting:快照,redis默认持久化方式,这种方式是将内存中的数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key被修改就自动做快照。
Save 900 1 #900秒内如果有超过1个key被修改,则发起快照保存。
Save 300 10 #300秒内如果有超过10个key被修改,则发起快照保存。
Save 60 1000 #60秒内如果有超过1000个 key被修改,则发起快照保存。
################################ SNAPSHOTTING ################################ # # Save the DB on disk: # # save <seconds> <changes> # # Will save the DB if both the given number of seconds and the given # number of write operations against the DB occurred. # # In the example below the behaviour will be to save: # after 900 sec (15 min) if at least 1 key changed # after 300 sec (5 min) if at least 10 keys changed # after 60 sec if at least 10000 keys changed # # Note: you can disable saving completely by commenting out all "save" lines. # # It is also possible to remove all the previously configured save # points by adding a save directive with a single empty string argument # like in the following example: # # save "" save 900 1 save 300 10 save 60 10000
注意:该方式每次做快照都有一个时间间隔,如果服务器在间隔内宕机,那在间隔内修改的数据将不能持久化到磁盘中。建议使用 aof方式。
2、Append-only file :aof方式
Aof方式原理:redis会将每一个收到的写命令都通过write函数追加到文件中(aof文件),当redis重启时会通过重新执行该文件保存的写命令来在内存中重建整个数据库的内容。由于操作系统 OS 会在内核中缓存write做的修改,所以可能不会立即写到磁盘中。这样aof方式的持久化也还是可能丢失数据。但我们可以通过配置文件告诉redis我们想通过fsync函数强制os写入到磁盘中。
配置aof:
Appendonly yes #启用aof持久化方式
Appendfsync always #收到写入命令就立即写入磁盘,效率最慢,但会保证完全的数据次持久化
Appendfsync everysec #每秒中写入磁盘一次,在性能和持久化之间做了很好的折中。
Appendfsync no # 完全以来OS,性能最好,但在持久化方面没保证。
实例:
appendonly yes # The name of the append only file (default: "appendonly.aof") appendfilename "appendonly.aof" # The fsync() call tells the Operating System to actually write data on disk # instead of waiting for more data in the output buffer. Some OS will really flush # data on disk, some other OS will just try to do it ASAP. # # Redis supports three different modes: # # no: don't fsync, just let the OS flush the data when it wants. Faster. # always: fsync after every write to the append only log. Slow, Safest. # everysec: fsync only one time every second. Compromise. # # The default is "everysec", as that's usually the right compromise between # speed and data safety. It's up to you to understand if you can relax this to # "no" that will let the operating system flush the output buffer when # it wants, for better performances (but if you can live with the idea of # some data loss consider the default persistence mode that's snapshotting), # or on the contrary, use "always" that's very slow but a bit safer than # everysec. # # More details please check the following article: # http://antirez.com/post/redis-persistence-demystified.html # # If unsure, use "everysec". # appendfsync always appendfsync everysec # appendfsync no
测试aof是否成功:
重启redis:
[root@localhost etc]# pkill redis-server
[root@localhost etc]# cd ../bin
[root@localhost bin]# ./redis-server /usr/local/redis/etc/redis.conf
链接客户端:
[root@localhost bin]# ./redis-cli -a jalja
127.0.0.1:6379> set addr bj
OK
查看 bin下是否存在aof文件
[root@localhost bin]# ll
总用量 26356
-rw-r--r--. 1 root root 54 2月 18 22:56 appendonly.aof
-rw-r--r--. 1 root root 97 2月 18 22:55 dump.rdb
-rw-r--r--. 1 root root 566 2月 17 22:51 mkreleasehdr.sh
-rw-r--r--. 1 root root 5578343 2月 17 22:52 redis-benchmark
-rw-r--r--. 1 root root 22217 2月 17 22:51 redis-check-aof
-rw-r--r--. 1 root root 7827978 2月 17 22:52 redis-check-rdb
-rwxr-xr-x. 1 root root 5707211 2月 17 22:52 redis-cli
-rwxr-xr-x. 1 root root 7827978 2月 17 22:52 redis-server
在这里出现了appendonly.aof文件打开该文件
[root@localhost bin]# cat appendonly.aof *2 $6 SELECT $1 0 *3 $3 set $4 addr $2 bj
二、发布及订阅消息
发布订阅(pub/sub)是一种消息通信模式,主要的目的是解耦消息发布者和消息订阅者之间的耦合,这点和设计模式中的观察者模式比较相似。pub /sub不仅仅解决发布者和订阅者直接代码级别耦合也解决两者在物理部署上的耦合。redis作为一个pub/sub server,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向redis server订阅自己感兴趣的消息类型,redis将消息类型称为通道(channel)。当发布者通过publish命令向redis server发送特定类型的消息时。订阅该消息类型的全部client都会收到此消息。这里消息的传递是多对多的。一个client可以订阅多个 channel,也可以向多个channel发送消息。
1、开启两个订阅session
session1:
127.0.0.1:6379> subscribe tv1 订阅频道tv1 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "tv1" 3) (integer) 1
session2:
127.0.0.1:6379> subscribe tv1 tv2 订阅频道tv1和tv2 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "tv1" 3) (integer) 1 1) "subscribe" 2) "tv2" 3) (integer) 2
2、开启发布session 在这里我们发布两个频道的信息
127.0.0.1:6379> publish tv1 "Hello word" #给频道tv1发布信息 (integer) 2 # tv1的订阅者2位 127.0.0.1:6379> publish tv2 "Hello tv2" #给频道tv2发布信息 (integer) 1 # tv2的订阅者1位 127.0.0.1:6379>
3、再次查看两个订阅频道
session1:
127.0.0.1:6379> subscribe tv1 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "tv1" 3) (integer) 1 1) "message" #获取了tv1发布的信息 2) "tv1" 3) "Hello word"
session2:
127.0.0.1:6379> subscribe tv1 tv2 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "tv1" 3) (integer) 1 1) "subscribe" 2) "tv2" 3) (integer) 2 1) "message" #获取了tv1发布的信息 2) "tv1" 3) "Hello word" 1) "message" #获取了tv2发布的信息 2) "tv2" 3) "Hello tv2"
三、虚拟内存的使用
Redis的虚拟内存与操作系统中的虚拟内存不是一回事,但思路相同。就是将不经常访问的数据从内存交换到磁盘中,从而腾出宝贵的内存空间用户其他需要访问的数据,这对于redis这样的内存数据库来说很重要,除了可以将数据分割到多个redis server外。另外能够提高数据库容量的方式就是使用虚拟内存把哪些不经常访问的数据交换到磁盘上。
配置方式( redis.conf):
Vm-enable yse #开启虚拟内存
Vm-swap-file /tmp/redis.swap #交换出来的value保存文件路径
Vm-max-memory 1000000 #redis使用最大内存的上限
Vm-page-size 32 #每个页面的大小32字节
Vm-pages 134217728 #最多使用多少个页面
Vm-max-threads 4#用于执行value对象换入缓存的工作线程数量
四、redis的缓存更新策略
相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:
voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据