Redis 高级实用特性

1、安全性

设置客户端连接后进行任何其他操作前先验证密码。

因为Redis速度相当快,所以在一台比较好的服务器下,一个外部用户可以在一秒钟进行150K次的密码尝试,这意味着需要指定一个非常强大的密码来防止暴力破解。

2、主从复制

Redis主从复制配置和使用都非常简单,通过主从复制可以允许多个slave server拥有和master server相同的数据库副本。

主从复制特点:

  • master可以拥有多个slave
  • 多个slave可以连接同一个master外,还可以连接到其他slave
  • 主从复制不会阻塞master,在同步数据时master可以继续处理client请求
  • 提高系统的伸缩性

主从复制过程:

  1. slave server启动连接到master server之后,salve server主动发送SYNC命令给master server
  2. master server接受SYNC命令之后,判断,是否有正在进行内存快照的子进程,如果有,则等待其结束,否则,fork一个子进程,子进程把内存数据保存为文件,并发送给slave server
  3. master server子进程进程做数据快照时,父进程可以继续接收client端请求写数据,此时,父进程把新写入的数据放到待发送缓存队列中
  4. slave server 接收内存快照文件之后,清空内存数据,根据接收的快照文件,重建内存表数据结构
  5. master server把快照文件发送完毕之后,发送缓存队列中保存的子进程快照期间改变的数据给slave server,slave server做相同处理,保存数据一致性
  6. master server 后续接收的数据,都会通过步骤1建立的连接,把数据发送到slave server

需要注意:slave server如果因为网络或其他原因断与master server的连接,当slave server重新连接时,需要重新获取master server的内存快照文件,slave server的数据会自动全部清空,然后再重新建立内存表,这样会让slave server 启动恢复服务比较慢,同时也给master server带来较大压力,可以看出redis的复制没有增量复制的概念,这是redis主从复制的一个主要弊端,在实际环境中,尽量规避中途增加从库。redis2.8之前不支持增量,到2.8之后就支持增量了!

配置主从服务器:

master服务器不用进行任何配置

slave服务器,只需在slave服务器的配置文件中加入以下配置

#指定master服务器的ip和端口
slaveof 192.168.1.99 6379
#指定master服务器认证信息
masterauth xxx

主从配置的作用:

配置master只能为写,slave只能为度,在客户端请求的时候会将写请求转到master上面,读请求转到slave上面,同时master和slave有同步功能,这就实现了(数据层)读写分离对上层(逻辑层)透明的正常逻辑,无需再通过中间件或者代码进行读写分离实现。

Redis cluster(集群)

Redis cluster至少需要3(Master)+3(Slave)才能建立集群,是无中心的分布式存储架构,可以在多个节点之间进行数据共享,解决了Redis高可用、可扩展等问题。

redis集群提供了以下两个好处

  1. 将数据自动切分(split)到多个节点
  2. 当集群中的某一个节点故障时,redis还可以继续处理客户端的请求。

集群中的主从复制

集群中的每个节点都有1个至N个复制品,其中一个为主节点,其余的为从节点,如果主节点下线了,集群就会把这个主节点的一个从节点设置为新的主节点继续工作,这样集群就不会因为一个主节点的下线而无法正常工作。
注意:

  1. 如果某一个主节点和他所有的从节点都下线的话,redis集群就会停止工作了。redis集群不保证数据的强一致性,在特定的情况下,redis集群会丢失已经被执行过的写命令
  2. 使用异步复制(asynchronous replication)是redis 集群可能会丢失写命令的其中一个原因,有时候由于网络原因,如果网络断开时间太长,redis集群就会启用新的主节点,之前发给主节点的数据就会丢失。

3、事物处理

Redis对事务的支持目前还比较简单。Redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他的client的命令。当一个client在一个连接中发出multi命令时,这个连接会进入一个事务上下文,改连接后续的命令不会立即执行,而是先放到一个队列中,当执行exex命令时,redis会顺序的执行队列中的所有命令。

multi开始事务的命令队列

discard清空事务的命令队列并退出事务上下文

exec执行事务队列

乐观锁:大多数是基于数据版本(version)的记录机制实现的。即为数据增加一个版本表示,在基于数据库表的版本解决方案中,一般是通过为数据库表添加一个“version”字段来实现读取出数据时,将此版本号一同读出,之后更新时,对此版本号加1.此时,将提交数据的版本号与数据库表对应记录的当前版本号进行对比,如果提交的数据版本号大于数据库当前版本号,则予以更新,否则认为是过期数据。

watch:watch命令会监视给定的key,当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败。也可以调用watch多次监视多个key,这样就可以对指定的key加乐观锁了。注意watch的key是对整个连接有效的,事务也一样。如果连接断开,监视和事务都会被自动清除。exec,discar,unwatch命令都会清除连接中的所有监视。

事务回滚问题:

redis只能保证事务的每个命令连续执行,但是如果事务中的一个命令失败了,并不回滚其他命令。

4、持久化机制

Redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到硬盘来保证持久化。

Redis支持两种持久化方式:

  • snapshotting(快照)默认方式

快照是默认的持久化方式。这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以通过配置设置自动做快照持久化的方式。配置redis在n秒内如果超过m个key被修改就自动做快照。

save 900 1 #900秒内如果超过1个key被修改,则发起快照保存
save 900 10 #300秒内如果超过10个key被修改,则发起快照保存
  • append-only file  aof方式

由于快照方式是在一定时间间隔做一次的,所以如果redis意外宕机,就回丢失最后一次快照后的所有修改。AOF比快照方式有更好的持久化性,是由于使用AOF时,redis会将每一个收到的写命令都通过write函数追加到文件中,当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。

当然由于os会在内核中缓存write做的修改,所以可能不是立即写到磁盘上。这样AOF方式的持久化也还是有可能会丢失部分修改,可以通过配置文件,使用fsync函数强制os写入到磁盘的时机。

appendonly yes #启用aof持久化方式

#appendfsync always //收到写命令就立即写入磁盘,最慢,但是保证完全的持久化

#appendfsync everysec //每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中

#appendfsync no //完全依赖os,性能最好,持久化没有保证

相关指令

./redis-cli bgsave  //异步保存数据到磁盘(快照保存)
./redis-cli 1h 127.0.0.1 -p 6379 bgsave
./redis-cli lastsave //返回上次成功保存到磁盘的unix时间戳
./redis-cli shutdown //同步保存到服务器并关闭redis服务器
./redis-cli bgrewriteaof //当日志文件过长时优化AOF日志文件存储

5、发布订阅消息

发布订阅(pub/sub)是一种消息通信模式,主要的目的是解除消息发布者和消息订阅者之间的耦合,Redis作为一个pub/sub的server,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向Redis server 订阅自己感兴趣的消息类型,redis将信息类型称为通道(channel)。当发布者通过publish命令向Redis server发送特定类型的信息时,订阅该信息类型的全部client都会收到此消息。

原理:下图展示了三个客户端client1, client2, client5订阅了频道channel1

当有新消息通过PUBLISH发送给channel1时,这时候channel1就会把消息同时发布给订阅者

 

创建订阅频道redisChat

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

打开几个客户端,订阅channel redisCha

localhost:6379> psubscribe redisChat
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "redisChat"
3) (integer) 1

然后给channel redisChat发送消息“Hello World”

localhost:6379> publish redisChat "Hello World"
(integer) 1

客户端会收到消息

Reading messages... (press Ctrl-C to quit)
1) "pmessage"
2) "redisChat"
3) "redisChat"
4) "Hello World"

6、虚拟内存的使用

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对象换入换出工作线程数量
原文地址:https://www.cnblogs.com/aaron911/p/7862394.html