redis
Redis
Redis 特点
-
开源数据库
-
配置简单
-
支持内存存储数据
-
支持持久化存储数据
datafile 数据文件 *.rdb
aof(append only file)文件,日志文件
-
支持多实例部署
-
支持主从复制、集群
-
支持事务transaction
-
以key-value键值对的方式存储
-
value类型:string字符串、list列表、set集合、sorted_set有序集合、hash值
安装
docker
使用 bitnami镜像 https://hub.docker.com/r/bitnami/redis
services:
redis:
image: bitnami/redis:6.2
container_name: redis
restart: always
ports:
- "6379:6379"
volumes:
- /data/redis:/data
environment:
- REDIS_PASSWORD=Password123
redis 命令解释
- redis-server:启动redis服务
- redis-cli:redis客户端工具
- redis-benchmark:redis性能测试
- redis-check-rdb:检测rdb文件
- redis-check-aof:检测aof日志文件
Redis 操作
[root@redis01 ~]# redis-cli
127.0.0.1:6379> set age 16
OK
127.0.0.1:6379> get age
"16"
127.0.0.1:6379> set name martin
OK
127.0.0.1:6379> get name
"martin"
127.0.0.1:6379>
127.0.0.1:6379> keys *
1) "age"
2) "name"
127.0.0.1:6379> del age
(integer) 1
127.0.0.1:6379> get age
(nil)
127.0.0.1:6379>
127.0.0.1:6379> set name martin
OK
127.0.0.1:6379> get name
"martin"
127.0.0.1:6379> mset name tom age 15 sex male
OK
127.0.0.1:6379> mget name age sex
1) "tom"
2) "15"
3) "male"
127.0.0.1:6379>
127.0.0.1:6379> strlen name
(integer) 3
127.0.0.1:6379>
127.0.0.1:6379> set count 1
OK
127.0.0.1:6379> incr count
(integer) 2
127.0.0.1:6379> incr count
(integer) 3
127.0.0.1:6379> incr count
(integer) 4
127.0.0.1:6379> get count
"4"
127.0.0.1:6379> decr count
(integer) 3
127.0.0.1:6379> get count
"3"
127.0.0.1:6379>
127.0.0.1:6379> set count 1
OK
127.0.0.1:6379> incrby count 3
(integer) 4
127.0.0.1:6379> get count
"4"
127.0.0.1:6379> decrby count 2
(integer) 2
127.0.0.1:6379> get count
"2"
127.0.0.1:6379>
密码连接redis
# 方法1
[root@redis01 ~]# redis-cli
127.0.0.1:6379>
127.0.0.1:6379> AUTH redhat
OK
# 方法2
[root@redis01 ~]# redis-cli -a redhat
127.0.0.1:6379> set age 10
OK
Redis 事物
192.168.122.102:6379> set count 1
OK
192.168.122.102:6379> multi
OK
192.168.122.102:6379> incr count
QUEUED
192.168.122.102:6379> incr count
QUEUED
192.168.122.102:6379> exec
1) (integer) 2
2) (integer) 3
192.168.122.102:6379>
192.168.122.102:6379> get count
"3"
192.168.122.102:6379>
192.168.122.102:6379> set number 1
OK
192.168.122.102:6379> MULTI
OK
192.168.122.102:6379> incr number
QUEUED
192.168.122.102:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
192.168.122.102:6379>
192.168.122.102:6379>
192.168.122.102:6379>
192.168.122.102:6379> get number
"1"
192.168.122.102:6379>
Redis 别名
[root@redis01 ~]# grep "^rename" /usr/local/redis/conf/redis.conf
rename-command set uplooking
[root@redis01 ~]#
[root@redis01 ~]# redis-cli -a redhat
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> set age 10
(error) ERR unknown command 'set'
127.0.0.1:6379>
127.0.0.1:6379> uplooking age 10
OK
127.0.0.1:6379> get age
"10"
127.0.0.1:6379>
别名可以用于规避危险命令
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command KEYS ""
如果想要保留命令,但是不能轻易使用,可以重命名命令来设定,设置随机字符代替:
rename-command FLUSHALL joYAPNXRPmcarcR4ZDgC81TbdkSmLAzRPmcarcR
rename-command FLUSHDB qf69aZbLAX3cf3ednHM3SOlbpH71yEXLAX3cf3e
rename-command CONFIG FRaqbC8wSA1XvpFVjCRGryWtIIZS2TRvpFVjCRG
rename-command KEYS eIiGXix4A2DreBBsQwY6YHkidcDjoYA2DreBBsQ
Redis持久化存储与备份
RDB持久化
将Redis在内存中的数据定时dump
到磁盘上,实际操作过程是fork
一个子进程,先将数据写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储
AOF持久化
AOF持久化:将Redis的操作日志以文件追加的方式写入文件,只记录写、删除操作,查询操作不会记录(类似于MySQL的Binlog日志)
自动间隔性保存
因为BGSAVE命令可以在不阻塞服务器进程的情况下执行,所以Redis允许用户通过设置服务器配置的save选项,让服务器每隔一段时间自动执行一次BGSAVE命令
用户可以通过save选项设置多个保存条件,但只要其中任意一个条件被满足,服务器就会执行BGSAVE命令 举个例子,如果我们向服务器提供以下配置
# redis
save 900 1
save 300 10
save 60 10000
那么只要满足以下三个条件中的任意一个,BGSAVE命令就会被执行 服务器在900秒之内,对数据库进行了至少1次修改
服务器在300秒之内,对数据库进行了至少10次修改
服务器在60秒之内,对数据库进行了至少10000次修改。
RDB持久化实现
# redis.conf
# 默认redis会开启RDB持久化
备份文件的名称
dbfilename dump.rdb
备份文件存放路径
dir /var/lib/redis
Redis的SAVE
命令和BGSAVE
命令用于将当前数据库备份
127.0.0.1:6379> save #数据量大的话cpu会爆炸
OK
127.0.0.1:6379> bgsave #建议使用这个
Background saving started
SAVE和BGSAVE命令的区别在于:SAVE
命令是阻塞主进程,save操作完成之后,主进程才开始工作,客户端可以连接;BGSAVE
命令是fork一个专门save的子进程,此操作不会影响主进程
注:SAVE
只是将当前的数据库备份,备份文件名默认为dump.rdb
,可通过配置文件修改备份文件名 dbfilename xxx.rdb
(发现一个问题:如果要对多个数据库进行备份,那么最终只能备份最后一个数据库,因为dump.rdb
文件会相互覆盖)
恢复
将备份的RDB文件,cp
到要恢复的redis指定目录,重启Redis即可自动读取持久化文件,自动恢复数据
- 备份的RDB文件: 通过命令
redis 127.0.0.1:6379> CONFIG GET dir
查看执行SAVE
命令之后,redis默认存放备份文件的目录;通过命令redis 127.0.0.1:6379> CONFIG GET dbfilename
查看备份RDB文件的文件名称;
root@pa6:~# redis-cli
127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/var/lib/redis"
127.0.0.1:6379> CONFIG GET dbfilename
1) "dbfilename"
2) "dump.rdb"
AOF持久化实现
备份过程分以下三个阶段
- 命令传播: Redis将执行完的命令、命令参数等信息发送到AOF程序
- 缓存追加: AOF程序将接收到的命令内容追加到服务器的AOF缓存中
- 文件写入和保存: AOF缓存中的内容被写入到AOF文件末尾,如果满足AOF保存条件,写入的内容会真正保存到磁盘中
进行AOF备份
- 首先开启AOF功能
#此选项为aof功能的开关,默认为“no”,通过“yes”来开启aof功能
appendonly yes
#指定aof文件名称
appendfilename appendonly.aof
#备份文件存放路径(此参数同样适用于指定RDB备份文件存放路径)
dir /var/lib/redis
二者优缺点
RDB持久化
优点:
- RDB方式备份,整个Redis数据库最终备份成一个文件,这对于文件备份而言是完美的(方便管理、还原、压缩、转储)
- 对服务进程影响最小,唯一需要做的是
fork
出子进程,之后所有的持久化工作交由子进程处理 - 相比于
AOF
机制,如果数据量比较大,RDB的启动效率会更高(记录的是源数据,而非数据操作)
缺点:
- 数据的可用性得不到太大的保障,如果在定时持久化之前出现宕机现象,此前没来得及写入磁盘的数据都将丢失
- 如果数据量较大,
fork
子进程的操作可能会使服务短暂停止(通常是几百毫秒)
AOF持久化
优点:
- 拥有更高的数据可用性,数据持久化最完整
- 日志文件采用
append
模式,即使在写入过程中出现宕机现象,也不会破坏日志文件之前已经存在的内容 - 提供
rewrite
机制,当日志过大时,Redis以append
模式不断将修改的日志写入老的磁盘文件,同时Redis还会创建一个新的文件用于记录此期间有哪些命令被执行
缺点:
- 对于相同数量的数据,AOF文件通常大于RDB文件,RDB文件在恢复大数据集的速度比AOF恢复的更快(RDB省去了执行的步骤,直接导入源数据)
总结
RDB持久化,性能更好(所有操作均由子进程处理,主进程不进行任何IO操作),数据一致性一般。
AOF持久化,数据一致性更好,性能一般(记录操作日志,写入日志和执行日志恢复数据的时间都比RDB更长)。
Redis 恢复的机制
- 如果只配置 AOF ,重启时加载 AOF 文件恢复数据;
- 如果同时配置了 RDB 和 AOF ,启动是只加载 AOF 文件恢复数据;
- 如果只配置 RDB,启动是将加载 dump 文件恢复数据。
#!/bin/bash
# 避免造成雪崩
set -e
# bak 目录
BACKUPDIR=/data/redis/backup
#PASSWD='redis密码'
#DATADIR=`/usr/local/bin/redis-cli -p 端口 -a "$PASSWD" config get dir|grep -Ev 'dir|grep'`
# 获取redis-cli 二进制文件
REDIS_CMD=$(which redis-cli)
DATADIR=`$REDIS_CMD config get dir|grep -Ev 'dir|grep'`
DATE=`date +'%Y-%m-%d-%H-%M'`
BACKUPDIR_DATE=$BACKUPDIR_$DATE
if [ ! -d $BACKUPDIR ];then
mkdir -p $BACKUPDIR \
|| echo "can't make dir !!!" \
&& exit 1
fi
#以日期分类
mkdir -p $BACKUPDIR/$BACKUPDIR_DATE
$REDIS_CMD bgsave
sleep 3
cp -rf $DATADIR/* $BACKUPDIR/$BACKUPDIR_DATE
redis 集群
-
高可用性:Redis集群可以在某个节点发生故障时,自动进行故障转移,保证服务的持续可用。
-
负载均衡:Redis集群可以将客户端请求分发到不同的节点上,有效地分摊节点的压力,提高系统的整体性能。
-
容灾恢复:通过主从复制或哨兵模式,Redis集群可以在主节点出现故障时,快速切换到从节点,实现业务的无缝切换。
-
数据分片:在Cluster模式下,Redis集群可以将数据分散在不同的节点上,从而突破单节点内存限制,实现更大规模的数据存储。
-
易于扩展:Redis集群可以根据业务需求和系统负载,动态地添加或移除节点,实现水平扩展。
模式:
- 主从
- 哨兵
- cluster
主从复制
主从复制是Redis的一种基本集群模式,它通过将一个Redis节点(主节点)的数据复制到一个或多个其他Redis节点(从节点)来实现数据的冗余和备份。
主节点负责处理客户端的写操作,同时从节点会实时同步主节点的数据。客户端可以从从节点读取数据,实现读写分离,提高系统性能。
一个主节点可以有多个从节点,一个redis可以即是主又是从,类似树状结构
配置:
1)配置主节点:在主节点的redis.conf配置文件中,无需进行特殊配置,主节点默认监听所有客户端请求。
# 主节点默认端口号6379
port 6379
2)配置从节点:在从节点的redis.conf配置文件中,添加如下配置,指定主节点的地址和端口:
# 从节点设置端口号6380
port 6380
# replicaof 主节点IP 主节点端口
replicaof 127.0.0.1 6379
或者,通过Redis命令行在从节点上执行如下命令:
redis> replicaof 127.0.0.1 6379
3)验证主从复制:在主节点上执行写操作,然后在从节点上进行读操作,检查数据是否一致。
主从复制的优缺点
优点:
- 配置简单,易于实现。
- 实现数据冗余,提高数据可靠性。
- 读写分离,提高系统性能。
缺点:
- 主节点故障时,需要手动切换到从节点,故障恢复时间较长。
- 主节点承担所有写操作,可能成为性能瓶颈。
- 无法实现数据分片,受单节点内存限制。
主从复制场景应用
主从复制模式适用于以下场景:
- 数据备份和容灾恢复:通过从节点备份主节点的数据,实现数据冗余。
- 读写分离:将读操作分发到从节点,减轻主节点压力,提高系统性能。
- 在线升级和扩展:在不影响主节点的情况下,通过增加从节点来扩展系统的读取能力。
总结:主从复制模式适合数据备份、读写分离和在线升级等场景,但在主节点故障时需要手动切换,不能自动实现故障转移。如果对高可用性要求较高,可以考虑使用哨兵模式或Cluster模式。
哨兵模式
Sentinel
哨兵模式是在主从复制基础上加入了哨兵节点,实现了自动故障转移。哨兵节点是一种特殊的Redis节点,它会监控主节点和从节点的运行状态。当主节点发生故障时,哨兵节点会自动从从节点中选举出一个新的主节点,并通知其他从节点和客户端,实现故障转移。
哨兵模式配置和实现
-
配置主从复制:首先按照主从复制模式的配置方法,搭建一个主从复制集群(上面已经讲过)。
-
配置哨兵节点:在哨兵节点上创建一个新的哨兵配置文件(如:sentinel.conf),并添加如下配置:
# sentinel节点端口号 port 26379 # sentinel monitor 被监控主节点名称 主节点IP 主节点端口 quorum sentinel monitor mymaster 127.0.0.1 6379 2 # sentinel down-after-milliseconds 被监控主节点名称 毫秒数 sentinel down-after-milliseconds mymaster 60000 # sentinel failover-timeout 被监控主节点名称 毫秒数 sentinel failover-timeout mymaster 180000
其中,
quorum
是指触发故障转移所需的最小哨兵节点数。down-after-milliseconds
表示主节点被判断为失效的时间。failover-timeout
是故障转移超时时间。为什么只配置了sentinel监控主节点,没有配置监控从节点? 因为通过主节点,就可以找到从节点。
-
启动哨兵节点:使用如下命令启动哨兵节点:
redis> redis-sentinel /path/to/sentinel.conf
-
验证哨兵模式:手动停止主节点,观察哨兵节点是否自动选举出新的主节点,并通知其他从节点和客户端。
哨兵模式的优缺点
优点:
- 自动故障转移,提高系统的高可用性。
- 具有主从复制模式的所有优点,如数据冗余和读写分离。
缺点:
- 配置和管理相对复杂。
- 依然无法实现数据分片,受单节点内存限制。
哨兵模式场景应用
哨兵模式适用于以下场景:
- 高可用性要求较高的场景:通过自动故障转移,确保服务的持续可用。
- 数据备份和容灾恢复:在主从复制的基础上,提供自动故障转移功能。
总结:哨兵模式在主从复制模式的基础上实现了自动故障转移,提高了系统的高可用性。然而,它仍然无法实现数据分片。如果需要实现数据分片和负载均衡,可以考虑使用Cluster模式。
Cluster模式
Cluster模式原理
Cluster模式是Redis的一种高级集群模式,它通过数据分片和分布式存储实现了负载均衡和高可用性。在Cluster模式下,Redis将所有的键值对数据分散在多个节点上。每个节点负责一部分数据,称为槽位。通过对数据的分片,Cluster模式可以突破单节点的内存限制,实现更大规模的数据存储。
数据分片与槽位
Redis Cluster将数据分为16384个槽位,每个节点负责管理一部分槽位。当客户端向Redis Cluster发送请求时,Cluster会根据键的哈希值将请求路由到相应的节点。具体来说,Redis Cluster使用CRC16算法计算键的哈希值,然后对16384取模,得到槽位编号。
Cluster模式配置和实现
-
配置Redis节点:为每个节点创建一个redis.conf配置文件,并添加如下配置:
# cluster节点端口号 port 7001 # 开启集群模式 cluster-enabled yes # 节点超时时间 cluster-node-timeout 15000
像这样的配置,一共需要创建6个,我们做一个三主三从的集群。
-
启动Redis节点:使用如下命令启动6个节点:
redis> redis-server redis_7001.conf
-
创建Redis Cluster:使用Redis命令行工具执行如下命令创建Cluster:
redis> redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1
cluster-replicas 表示从节点的数量,1代表每个主节点都有一个从节点。
-
验证Cluster模式:向Cluster发送请求,观察请求是否正确路由到相应的节点。
Cluster模式的优缺点
优点:
- 数据分片,实现大规模数据存储。
- 负载均衡,提高系统性能。
- 自动故障转移,提高高可用性。
缺点:
- 配置和管理较复杂。
- 一些复杂的多键操作可能受到限制。
Cluster模式场景应用
Cluster模式适用于以下场景:
- 大规模数据存储:通过数据分片,突破单节点内存限制。
- 高性能要求场景:通过负载均衡,提高系统性能。
- 高可用性要求场景:通过自动故障转移,确保服务的持续可用。
总结:Cluster模式在提供高可用性的同时,实现了数据分片和负载均衡,适用于大规模数据存储和高性能要求的场景。然而,它的配置和管理相对复杂,且某些复杂的多键操作可能受到限制。
模式选择
- 主从复制模式:适用于数据备份和读写分离场景,配置简单,但在主节点故障时需要手动切换。
- 哨兵模式:在主从复制的基础上实现自动故障转移,提高高可用性,适用于高可用性要求较高的场景。
- Cluster模式:通过数据分片和负载均衡实现大规模数据存储和高性能,适用于大规模数据存储和高性能要求场景。
在实际应用中,可以根据系统的需求和特点选择合适的Redis集群模式,以实现高可用性、高性能和大规模数据存储