Redis的使用
Redis的安装启动及配置文件
安装
CentOS:
yum install redis
# 配置文件默认在
vim /etc/redis.conf
Ubuntu
apt-get install redis
# 配置文件默认在
sudo vim /etc/redis/redis.conf
配置文件修改如下
sudo vim /etc/redis/redis.conf
# 进入配置文件后,为了方便修改 使用vim语法:/要搜索的内容 进行搜索。
# 比如在扩展模式在直接输入:/bind 然后回车,表示搜索bind,此时按n为下一个
# 这里是绑定redis的启动地址,如果你支持远程连接,把bind改为0.0.0.0
bind 0.0.0.0
# 设置端口
port 6500
# 设置redis的密码为haohaio
requirepass haohaio
# 默认打开了安全模式
protected-mode yes
# 打开一个redis后台运行的参数
daemonize yes
启动Redis
systemctl start redis
# 如果你按我的设置进行操作,将会提示无法连接,为什么呢?
# 因为这个命令默认连接6379端口,我们改了redis端口,因此无法连接了。
# 使用如下命令,指定配置文件启动
test@bogon:~$ sudo redis-server /etc/redis/redis.conf
# 检查redis的进程
test@bogon:~$ ps -ef |grep redis
root 2225 1 0 15:59 ? 00:00:00 redis-server 0.0.0.0:6500
test 2231 1495 0 15:59 pts/1 00:00:00 grep --color=auto redis
连接Redis服务端,指定端口及密码连接redis
test@bogon:~$ redis-cli -p 6500
127.0.0.1:6500> ping
(error) NOAUTH Authentication required.
127.0.0.1:6500> auth haohaio
OK
127.0.0.1:6500> ping
PONG
Redis数据持久化操作rdb与aof
向redis中写入一些数据,重启进程,查看数据是否存在
# 1.环境准备,准备一个redis.conf配置文件,不开启数据持久化
test@bogon:~$ cat no_rdb_redis.conf
bind 0.0.0.0
daemonize yes
# 2.指定该文件启动
test@bogon:~$ redis-server no_rdb_redis.conf
# 3.登录数据库,写入数据,然后退出数据库杀死进程,查看数据是否存在
以上操作是为了演示未配置持久化数据会丢失
rdb机制的数据持久化
# RDB持久化产生的RDB文件是一个经过压缩的二进制文件,我们看不懂的,这个文件被保存在硬盘中,redis可以通过这个文件还原数据库当时的状态。
# 1. vim /opt/redis/redis.conf,写入如下内容
daemonize yes # 后台运行
port 6379 # 端口
logfile /data/6379/redis.log # 指定redis的运行日志,存放位置
dir /data/6379 # 定义持久化文件存储位置
dbfilename dbmp.rdb # 指定数据rdb持久化文件的名字
bind 10.0.0.10 127.0.0.1 # redis绑定地址
requirepass redhat # redis登录密码
# 900秒内有1个修改的命令操作,如set .mset del
save 900 1 # rdb机制 每900秒 有1个修改操作,触发
save 300 10 # 每300秒 10个修改操作,触发
save 60 10000 # 每60秒内 10000修改操作,触发
# 2.创建redis的数据文件夹
mkdir -r /data/6379
# 3.指定配置了rdb的redis配置文件,启动
sudo redis-server /opt/redis/redis.conf
# 4.如果没有触发redis的持久化时间机制,数据文件是不会生成的,数据重启进行也会丢
# 5.可以通过编写脚本,让redis手动执行save命令,触发持久化,在redis命令行中直接输入save即可触发持久化
# 6.存在了rdb持久化的文件之后,重启redis进程,数据也不会丢了,redis在重启之后,会读取dbmp.rdb文件中的数据
# 7.rdb的弊端在于什么,如果没有触发持久化机制,就发生了机器宕机,数据就会丢失了,因此redis有一个更好的aof机制
aof机制的数据持久化
# AOF(append-only log file)
# 记录服务器执行的所有变更操作命令(例如set del等),并在服务器启动时,通过重新执行这些命令来还原数据集
# AOF 文件中的命令全部以redis协议的格式保存,新命令追加到文件末尾。
# 优点:最大程序保证数据不丢
# 缺点:日志记录非常大
AOF持久化配置,两条参数
appendonly yes # 开启aof功能
appendfsync always # 总是修改类的操作
everysec # 每秒做一次持久化(正常都够用了)
no # 依赖于系统自带的缓存大小机制
# 1.准备aof配置文件 redis.conf
# vim /data/redis.conf
daemonize yes
port 6379
logfile /data/6379aof/redis.log
dir /data/6379aof
dbfilename dbmp.rdb
requirepass redhat
appendonly yes
appendfsync everysec
# 2.创建aof的数据文件夹
mkdir -r /data/6379aof
# 3.启动redis服务
redis-server /etc/redis.conf
# 4.aof机制的数据库,在首次启动的时候,就会生成aof数据文件了
# 5.登录redis,写入数据,检查数据是否持久化。可以用tail -f监测日志变化
# 6.写入的操作,会被记录到aof文件中
Redis主从复制故障切换
在一台机器上运行2个及以上的redis,是redis支持多实例的功能,基于端口号的不通,就能够运行多个相互独立的redis数据库
# 什么是多实例?
# 就是机器上运行了多个redis相互独立的进程
# 互不干扰的独立数据库
# 叫做多个redis数据库的实例,基于配置文件区分即可
# 1.上午的最后一步,演示的是当我们删除aof文件,或者rdb,aof文件异常损坏,丢失,数据不也没了吗?
操作笔记:
一主一从(较简单,高可用性不高)
如图是redis的多实例功能,且配置主从同步的图
# 1.准备好2个redis的配置文件,分别写入如下内容
# vim /data/6380/redis-master.conf
port 6380
daemonize yes
pidfile /data/6380/redis.pid
loglevel notice # 日志级别,普通的verbose,常用于生产环境
logfile "/data/6380/redis.log"
dbfilename dump.rdb
dir /data/6380
protected-mode no
# vim /data/6381/redis-slave.conf
port 6381
daemonize yes
pidfile /data/6381/redis.pid
loglevel notice
logfile "/data/6381/redis.log"
dbfilename dump.rdb
dir /data/6381
protected-mode no
slaveof 127.0.0.1 6380 # 也可以直接在配置文件中定义好复制关系,启动后,立即就会建立复制
# 2.分别生成两个redis的数据文件夹
mkdir -p /data/{6380,6381}
# 3.分别启动2个redis数据库
redis-server /data/6380/redis-master.conf
redis-server /data/6381/redis-slave.conf
# 4.分别检查他们的进程,以及复制关系
`test@bogon:/data/6381$ redis-cli -p 6380 info replication
role:master
connected_slaves:0
master_replid:5c8f1698e3aec10fce8db9223b6719e1388ee6e2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
`test@bogon:/data/6381$ redis-cli -p 6381 info replication
role:master
connected_slaves:0
master_replid:b5a0572e1b4e5bb2b59edad63265129b02219a20
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# 通过一条命令,配置他们的复制关系,注意,这个命令只是临时配置redis的复制关系,想要永久修改,还得修改配置文件
# redis-cli -p 要设置的奴隶端口号 slaveof 主的地址 主端口号
`test@bogon:/data/6381$ redis-cli -p 6381 slaveof 127.0.0.1 6380
OK
`test@bogon:/data/6381$ redis-cli -p 6381 info replication
# Replication
role:slave # 当前redis角色,slave奴隶
master_host:127.0.0.1 # 连接主机
master_port:6380 # 连接端口
master_link_status:up # 连接状态
# 5.此时6380已然是主库,6381已然是从库
此时可以向6380写入,会同步到6381中,且6381是一个只读库,无法写入数据
一主多从的形式,一级主从复制故障切换
# 1.在创建一个配置文件,port是6399,且加入到一主一从的复制关系中去
# vim /data/6399/redis-slave2.conf
port 6399
daemonize yes
pidfile /data/6399/redis.pid
loglevel notice
logfile "/data/6399/redis.log"
dbfilename dump.rdb
dir /data/6399
protected-mode no
slaveof 127.0.0.1 6380
# 2.启动6399的数据库,查看他的身份复制关系
`test@bogon:/data/6381$ redis-cli -p 6399 info replication
# 1.环境准备,准备3个redis的数据库实例,分别是 6379,6389,6399,配置好一主两从的关系
`test@bogon:/data/6399$ ps -ef | grep redis
root 5651 1 0 11:05 ? 00:00:10 redis-server *:6380
root 5661 1 0 11:05 ? 00:00:09 redis-server *:6381
root 5821 1 0 11:30 ? 00:00:07 redis-server *:6399
分别查看复制关系
`test@bogon:/data/6399$ redis-cli -p 6380 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=1904,lag=0
slave1:ip=127.0.0.1,port=6399,state=online,offset=1904,lag=0
# 2.此时直接干掉主库即可
kill 6380的pid即可
# 3.此时留下2个从库,还没法写入数据
# 4.这时一位从库不乐意了,翻身农奴做主人
`test@bogon:/data/6399$ redis-cli -p 6381 slaveof no one`
# 5.此时6381已然是主库了,修改6399的复制信息
`test@bogon:/data/6399$ redis-cli -p 6399 slaveof 127.0.0.1 6381`
# 6.此时检查他们的复制关系
# 7.此时可以向6381写入数据,6399查看数据即可
你会发现,如此的手动切换复制关系其实是很难受的,如果在夜里凌晨,redis主库突然挂了,怎么办?
Redis Sentinel高可用哨兵
redis哨兵的工作原理
配置好redis哨兵进程,一般都是使用3个哨兵(保安)
哨兵的作用是盯着redis主库,不断询问它是否存活,如果超过30s(设置的时间阈值)都没有回应,3个哨兵会判断主库宕机,谈话进行投票机制,因为3个哨兵要自动的去选择从库为新的主库,每个哨兵的意见可能不一样
因此引出投票机制,少数服从多数
当多个哨兵意见达成一致,选择某一个从库,自动的修改他们的配置文件,切换为新的主库。
此时如果宕机的主库恢复后,哨兵也会自动将其加入集群,且自动分配为新的从库
这一些都是自动化的
哨兵集群的配置
# 1.准备3个redis主从复制的redis实例,1主2从,启动并确认数据库关系信息
上面已经有了,省略。。。
# 2.三个redis-sentinel配置文件写入如下,三个哨兵的配置仅仅是端口号不同
# vim redis-sentinel-26380.conf
# Sentinel节点的端口
port 26380
dir /var/redis/data/
logfile "26380.log"
# 当前Sentinel节点监控 127.0.0.1:6380 这个主节点
# 2代表判断主节点失败至少需要2个Sentinel节点节点同意
# mymaster是主节点的别名
sentinel monitor mymaster 127.0.0.1 6380 2
# 每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒30s且没有回复,则判定不可达
sentinel down-after-milliseconds mymaster 30000
# 当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,
# 原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
sentinel parallel-syncs mymaster 1
# 故障转移超时时间为180000毫秒
sentinel failover-timeout mymaster 18000
# 后台运行
daemonize yes
# 3.启动哨兵
redis-sentinel redis-sentinel-26380.conf
`# 如果提示命令不存在,检查一下输入redis- ,然后按两次tab补全查看是否有redis-sentinel`
`# 如果没有redis-sentinel,比如我使用的kali就没有,`
`# 下载方式:apt-get install redis-sentinel`
# 4.查看哨兵状态
`test@bogon:/data/sentinel$ redis-cli -p 26380 info sentinel`
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1:6380,slaves=2,sentinels=3
如果可以看到上面一行,则证明哨兵搭建成功
# 5.哨兵搭建好之后,模拟干掉主库,然后等待主从的一个自动化切换
- 检查6380的进程,杀死后,哨兵能够自动的进行投票选举,剩下来的一个slave为新的master,然后重新分配主从关系;
- 故障的修复,重启6380这个redis数据库,且检查它的一个复制关系
6380数据库会重新加入到主从复制,且变为一个从库
- 如果你想恢复他们的主从关系,全部kill掉,重新启动,默认就会以配置文件分配主从关系了
Redis集群redis-cluster
集群
# 1.准备好6匹马儿,也就是6个redis节点,也就是6个配置文件,redis集群节点最少是使用6个
这6个配置文件仅仅是端口号不同而已
redis-7000.conf
redis-7001.conf
redis-7002.conf
redis-7003.conf
redis-7004.conf
redis-7005.conf
`sed 's/7000/7002/g' redis-7000.conf > redis-7002.conf` # 命令替换,把7000替换为7002
# vim redis-7000.conf
port 7000
daemonize yes
dir "/opt/redis/data"
logfile "7000.log"
dbfilename "dump-7000.rdb"
cluster-enabled yes #开启集群模式
cluster-config-file nodes-7000.conf #集群内部的配置文件
cluster-require-full-coverage no #redis cluster需要16384个slot都正常的时候才能对外提供服务,换句话说,只要任何一个slot异常那么整个cluster不对外提供服务。 因此生产环境一般为no
# 2.分别启动了6个redis节点,且检查进程
redis-server redis-7000.conf
...
此时尝试写入数据,发现不能写入成功
我们仅仅是启动了6个redis节点,准备好了6匹马儿,马儿身上的框还没分配
此时准备好ruby的环境,用于一键创建redis集群,给马儿分配框,给redis节点分配slot槽位,用于写入数据
### 注意!!!经过操作,建议先执行第5,6步,如果创建失败,再从1开始执行。一般5,6步可直接创建成功!
# 1.使用包管理工具进行安装
ruby====python gem====pip gem是ruby的包管理工具
# kali使用apt-get安装
apt-get insatll ruby
# Centos
yum install ruby
# 2.检查ruby和gem的环境
`test@bogon:/data/sentinel$ gem -v`
3.1.4
`test@bogon:/data/sentinel$ ruby -v`
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux-gnu]
# 3.下载ruby操作redis的模块,用于创建集群
wget http://rubygems.org/downloads/redis-3.3.0.gem
# 4.用gem安装此模块
gem install -l redis-3.3.0.gem
# 5.搜索ruby创建redis集群的脚本
redis-trib.rb 如何知道它的绝对路径?
which是搜索PATH环境变量中的命令的绝对路径!
find才是搜索系统上的文件路径!!
find / -name redis-trib.rb
# --replicas 1 代表每个主节点,有一个从节点
# 6.1一键创建集群,中间输入yes即可,可能出现创建失败的问题,请看下图
`test@bogon:/data$ /usr/share/doc/redis-tools/examples/redis-trib.rb create --replicas 1 127.0.0.1:7000 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`
# 6.2 一键创建集群
`test@bogon:/data$ redis-cli --cluster create 127.0.0.1:7000 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 --cluster-replicas 1`
查看集群状态
redis-cli -p 7000 cluster info # 集群状态
redis-cli -p 7000 cluster nodes # 等同于查看nodes-7000.conf文件节点信息
redis-cli -p 7000 cluster nodes | grep master # 集群主节点状态
redis-cli -p 7000 cluster nodes | grep slave # 集群从节点状态
集群状态
`test@bogon:/data$ redis-cli -p 7000 cluster info`
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:20
cluster_stats_messages_pong_sent:29
cluster_stats_messages_sent:49
cluster_stats_messages_ping_received:24
cluster_stats_messages_pong_received:20
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:49
测试写入集群数据
登录集群必须使用redis-cli -c -p 7000,必须加上-c参数
test@bogon:/data$ redis-cli -c -p 7000
127.0.0.1:7000> set name2 "ccc"
OK
127.0.0.1:7000> set name3 111
OK
127.0.0.1:7000> keys *
1) "name3"
2) "name2"
127.0.0.1:7000> set name "aaa"
-> Redirected to slot [5798] located at 127.0.0.1:7001 # name已经自动分配到7001节点上
OK
127.0.0.1:7001> exit