redis高级应用
主要讲这么几个:主从设置;事务处理;持久化机制;发布订阅消息;虚拟内存使用
一:主从设置:
redis的主从设置很简单,比mysql还要简单。
1:复制过程(原理)
a:slave与master建立连接,发送sync同步命令
b:master启动一个后台进程,将数据库快照保存在文件中,同时master主进程开始收集行的写命令并缓存
c:后台完成保存后,将此文件发送给slave
d:slave将此文件保存在硬盘上
2:配置方法(在slave上配置),有三种方法
a:在配置文件中加入 slaveof{masterHost}{masterPort} redis重启生效。
b:在 redis-server 启动命令后加入--slaveof{masterHost}{masterPort}
c:进入redis控制台,直接使用命令:slaveof{masterHost}{masterPort}
用第一种试一下:主服务器为:160,从服务器为161
修改slave服务器的redis.conf:
slaveof 192.168.17.160 6379 #指定IP端口 masterauth 123 #主机密码,如果主redis有密码必须加上这个授权
主服务器看一下bind是多少,如果bind 127.0.0.1 改成实际IP,或者改成0.0.0.0,然后启动redis即可。另外记得开启6379端口,或者关闭防火墙。
我们在master服务器设置一个set age 100;
然后看一下slave服务器
可以看到复制成功!
主从相关信息可以用命令:info replication 查看
redis默认从节点使用 slave-read-only=yes 配置为只读模式,可以修改配置,不过建议不要修改,从节点只读取。
如图,从节点写入报错!
redis以前只支持全量复制,2.8以上版本使用psync完成主从复制,且支持部分(增量)复制。
二:事务处理
redis只能处理简单的事务,因为redis并不支持回滚。
一个client发起的事务命令可以连续执行,中间不会插入其他client的命令。multi命令表示发起事务操作,这时候事务中的所有命令先放入一个队列中,当执行exec命令时,redis安装顺序执行队列中的所有命令,下面是一个事务的执行过程
127.0.0.1:6379> multi #发起事务 OK 127.0.0.1:6379> set age 10 QUEUED #放入队列 127.0.0.1:6379> set name lijie QUEUED #放入队列 127.0.0.1:6379> exec #执行 1) OK 2) OK
如果有一条语句报错,出问题,并不影响其他的语句执行,这和mysql大不一样,所以说redis支持简单的事务。
取消事务用:discard
127.0.0.1:6379> multi OK 127.0.0.1:6379> set age 20 QUEUED 127.0.0.1:6379> set name li QUEUED 127.0.0.1:6379> discard #取消事务 OK
乐观锁事务控制:乐观锁要与事务结合起来使用,通过watch监视key,可以监视一个或者多个key,exec的时候,一旦发现监视的key发生过改变,那么整个事务失败。
这里用watch监视 age,age值为10,现在打开另外一个窗口修改age的值为11,然后这里执行exec
可以看到,这里执行失败。
三:持久化
Redis支持持久化机制,Redis通过能够将内存中的数据同步到硬盘从而保证持久化。
Redis有两种持久化机制:
1:Snapshotting(RDB快照,redis默认)
将数据生成快照存入一个二进制文件里面,默认文件为:dump.rdb
RDB触发方式有两种:
(1):自动触发
自动触发,看一下redis默认配置文件:
# Save the DB on disk: # # save# # 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 # By default Redis will stop accepting writes if RDB snapshots are enabled # (at least one save point) and the latest background save failed. # This will make the user aware (in a hard way) that data is not persisting # on disk properly, otherwise chances are that no one will notice and some # disaster will happen.
save 900 1 :表示900秒内有1个key发生变化,则保存一次,以下两个类推,redis默认了以上三个;如果redis只是用来做缓存,不需要持久化,则把以上三个save注释即可。
一些配置参数说明:
rdbcompression yes #数据是否压缩,默认值是yes,开启会消耗cpu,但同时会减小体积,建议开启。 rdbchecksum yes #默认为yes,redis对存储快照通过CRC64校验,可能会消耗10%的性能,追求性能最大化可以关闭。 dbfilename dump.rdb #设置快照的文件名,默认是 dump.rdb dir ./ #设置快照文件的存放路径,路径非文件名
(2):手动触发
手动触发有两个命令
a:save
阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。不建议使用该命令,该命令已经废弃。
b:bgsave
bgsave属于异步方式,redis会在后台开启一个子进程,Redis进程执行fork操作创建子进程,RDB过程由子进程负责执行,redis主进程可以处理其他命令,两者互不影响,推荐使用该命令触发。
这两个命令使用方式一样,其实就是备份命令:
127.0.0.1:6379> bgsave Background saving started
(3):数据恢复
如果需要恢复数据,将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可,redis会自动加载文件数据至内存。Redis 服务器在载入 RDB 文件期间,会一直处于阻塞状态,直到载入工作完成为止。
127.0.0.1:6379> config get dir #获取redis安装目录 1) "dir" 2) "/usr/local/redis"这里可以看到redis安装目录为/usr/local/redis,我们看一下这里是否有dump.rdb:
RDB方式的优点是,直接保存数据库快照,方便,加载恢复速度远快于AOF。缺点也很明显,没有办法做到实时备份(秒级),因为 bgsave 每次运行都要执行 fork 操作创建子进程,频繁执行成本过高。另外二进制文件在各个版本的reids中可能不兼容。正因为有上诉问题,于是redis提供了另外一个持久化方案——AOF
2:Append-only file(AOF)
将一些列诸如插入,更新,修改等操作存入文件里面。
redis会将每一个收到的命令通过write函数追加到文件中,redis重启的时候,会通过重新执行文件中保存的命令在内存中重建整个数据库内容。
开启AOF:配置文件设置:appendonly yes;默认为no,不开启
由于系统会在内核中缓存write修改,所以可能不是立即写入磁盘,注意aof方式持久化还是有可能部分丢失,所以Redis 提供了多种AOF缓冲区同步文件策略,由参数 appendfsync 控制。通过fsync函数强制操作系统写入到磁盘的时机。
该图为:AOF 缓冲区同步文件策略
对三个配置值做进一步通俗的解释:
always:收到命令立即写入磁盘,最慢,但最能保证持久化。
everysec:每秒写入一次磁盘,兼顾了性能和持久化。
no:完全依赖操作系统,性能最好,持久化没保证。
Redis配置文件默认为第二个,一般也是用第二个。
配置完后重启,这时候会发发现生产了一个appendonly.aof文件,查看一下:
输入命令:set name zhansan 然后打开appendonly.aof文件查看:
可以看到命令追加进去了。
四:发布订阅:
发布订阅(pub/sub)是一种消息通信模式,主要的目的是解耦消息发布者和消息订阅者之间的耦合,这点和设计模式中的观察者模式比较相似。pub /sub不仅仅解决发布者和订阅者直接代码级别耦合也解决两者在物理部署上的耦合。redis作为一个pub/sub server,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向redis server订阅自己感兴趣的消息类型,redis将消息类型称为通道(channel)。当发布者通过publish命令向redis server发送特定类型的消息时。订阅该消息类型的全部client都会收到此消息。这里消息的传递是多对多的。一个client可以订阅多个 channel,也可以向多个channel发送消息。
几个常用的命令:
//订阅 subscribe t1 #监控t1这个频道,可以监控多个频道 psubscribe t* #这个命令和上面差不多,不过可以用通配符,监视以t开头的所有频道 //发布 publish t1 message #往t1频道发送消息message
1:订阅
这就开始订阅了,订阅t1频道
2:发布
再打开一个客户端,发送一条消息
订阅的客户端立马就收到了消息:
3:退订(取消订阅)
unsubscribe t1 punsubscribe t1* #取消在控制台连接工具中无法模拟。注意:redis的发布订阅,只能实现简单的功能,并不能保证消息一定能接受到,而且数据不持久化,毕竟redis的主要目的不是干这个。
五:虚拟内存使用
vm配置:
vm-enabled yes #开启vm功能 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对象换入换出的工作线程数量