一、单机Redis
Redis:是一个key-value结构的NoSQL,为了进一步提升性能,Redis把数据存储到内存里。所以Redis有极高的读写速度。官方数据 读11万次/秒, 写8.1万次/秒
在实际开发中,Redis通常作为缓存使用
之前我们在使用Redis的时候,全部使用的是Redis的单机模式。因为单机模式Redis搭建简单、使用方便,利于学习入门。但是在实际使用中,单机Redis存在一些问题需要解决:
持久化存储问题
Redis为了提高性能,数据是在内存中存储的。而内存不能持久化存储数据,所以Redis提供了持久化机制
并发能力问题
单机Redis的并发能力有限,可以通过主从集群来实现读写分离,从而提高并发能力
故障恢复问题
在Redis集群中,一旦某个节点宕机,就必须要手动进行故障转换与恢复。Redis提供了哨兵模式来实现自动故障恢复
存储能力问题
无论是主从模式的集群,还是哨兵模式的集群,都没有解决存储能力的扩展问题。Redis提供了分片集群模式,可以很方便的动态扩容
下载 解压 安装Redis
下载地址:Download | Redis
#1. 安装Redis需要的依赖程序包
yum install -y gcc tcl
#2. 切换到root用户的家目录
cd ~
#3. 解压Redis程序包
tar -xvf redis-6.2.4.tar.gz
#4. 切换到Redis目录里
cd ~/redis-6.2.4/
#5. 编译并安装Redis。如果此命令不出错,通常就表示安装成功了
make && make install
配置Redis
#1. 在root家目录里创建文件夹
mkdir ~/01standalone
#2. 把Redis配置文件拷贝进来
cp ~/redis-6.2.4/redis.conf ~/01standalone/
#3. 切换到~/01standalone/目录里
cd ~/01standalone/
#4. 使用vi编辑redis.conf
vi redis.conf
使用vi修改redis.conf的如下内容: n命令 搜索名
# 绑定地址,默认是127.0.0.1,只能在本机访问Redis服务。修改为0.0.0.0则可以在任意IP访问Redis服务
bind 0.0.0.0
# 数据库数量,设置为1
databases 1
启动Redis
所有单机问题,我们全在~/01standalone/目录里操作,使用这个目录里的配置文件
首先:cd ~/01standalone/
启动Redis服务:redis-server redis.conf
使用Redis:redis-cli,然后就可以使用Redis的命令了
关闭Redis服务:redis-cli shutdown
💡Redis服务安装好以后,可以同时启动多个实例,只要加载不同的配置文件,使用不同的端口即可
小结:
1. 请介绍一下Redis
Redis是key-value结构的NoSQL,为了提升数据的读写速度,把数据存储到了内存中
Redis在实际开发中,通常作为缓存来使用2. 单机Redis有哪些问题
数据持久化存储的问题:因为Redis的数据在内存中,当Redis服务关闭时要避免数据被清空释放掉
单机Redis并发能力有限:可以搭建Redis主从集群,实现读写分离
要解决故障恢复的问题:要能够实现主节点故障后自动恢复
要解决存储容量的问题:可以搭建分片集群提升存储容量
二、Redis主从模式
单节点的Redis服务支持的并发是有限的:
所有客户端的请求全部冲击到仅有的一台服务器上,
服务器可能因为压力过大而阻塞不能及时响应。
这时候可以采用主从架构
做到读写分离:
多个Redis节点共同提供服务,所有写数据的操作都请求到主服务器,
所有读数据的操作都请求到从服务器。读写分离,提升并发能力
2. 搭建Redis主从架构
我们搭建的Redis主从集群结构,共包含三个节点。其中一个主节点,两个从节点
我们将会在同一个虚拟机里开启三个Redis实例,模拟主从集群,信息如下:
角色ip端口
角色 ip 端口
master 192.168.126.120 6380
slave 192.168.126.120 6381
slave 192.168.126.120 6382#1. 准备一个文件夹02master,把主从集群所有相关的配置全放到这个文件夹里
mkdir ~/02master
#2. 在02master里准备三个文件夹,作为三个redis实例的工作目录
cd ~/02master/
mkdir 6380 6381 6382
#3. 把Redis的配置文件,分别拷贝到6380,6381,6382三个文件夹里。
echo 6380 6381 6382 | xargs -t -n 1 cp ~/redis-6.2.4/redis.conf
#4. 分别修改6380、6381、6382三个文件夹里的配置文件
# 把端口分别修改为6380、6381、6382
# 把配置文件里的dir,全部修改为各自的工作目录
cd ~/02master
sed -i -e 's/6379/6380/g' -e 's/dir .\//dir \/root\/02master\/6380\//g' -e 's/bind 127.0.0.1 -::1/bind 0.0.0.0/g' 6380/redis.conf
sed -i -e 's/6379/6381/g' -e 's/dir .\//dir \/root\/02master\/6381\//g' -e 's/bind 127.0.0.1 -::1/bind 0.0.0.0/g' 6381/redis.conf
sed -i -e 's/6379/6382/g' -e 's/dir .\//dir \/root\/02master\/6382\//g' -e 's/bind 127.0.0.1 -::1/bind 0.0.0.0/g' 6382/redis.conf
#5. 修改每个Redis实例的ip
# 虚拟机本身有多个虚拟网卡,有多个ip地址。为了防止地址混乱,我们直接在配置文件里指定要绑定的ip地址
# 6380、6381、6382三个文件夹里的配置文件都要修改,执行以下命令
cd ~/02master
printf '%s\n' 6380 6381 6382 | xargs -I{} -t sed -i '1a replica-announce-ip 192.168.200.136' {}/redis.conf
启动集群
为了方便查看每个Redis实例的日志,我们开启三个ssh容器,分别启动3个redis实例。
命令如下:
# 第一个Redis实例
redis-server ~/02master/6380/redis.conf
# 第二个Redis实例
redis-server ~/02master/6381/redis.conf
# 第三个Redis实例
redis-server ~/02master/6382/redis.conf
附加:如果想要一键停止所有Redis实例,可以执行以下命令:
printf '%s\n' 6380 6381 6382 | xargs -I{} -t redis-cli -p {} shutdown
开启主从关系
到目前为止,三个Redis实例之间还没有任何关系。
要配置主从关系,可以使用Redis提供的replicaof命令(Redis5.0开始)或者slaveof命令(Redis5.0以前),两个命令效果一致。
主从关系的配置有临时配置和永久配置两种
永久生效:修改配置文件,然后重启所有Redis服务
在redis.conf中增加一行配置:slaveof masterIp masterPort
临时生效:使用redis-cli连接Redis服务,执行slaveof命令(Redis实例重启后失效)
slaveof masterIp masterPort
#连接6381实例
redis-cli -p 6381
#设置为6380的从节点
slaveof 192.168.200.123 380
#连接6382实例
redis-cli -p 6382
#设置为6380的从节点
slaveof 192.168.200.123 6380
#连接6380实例
redis-cli -p 6380
#查看集群状态
info replication
测试
按顺序执行以下操作:
使用redis-cli连接6380,执行
set sum 100
使用redis-cli连接6381,执行
get num
, 然后再执行set num 101
使用redis-cli连接6382,执行
get num
,然后再执行set num 102
结果发现:
只有6380这个节点上可以进行写操作
6381和6382两个节点上只能进行读操作
三、Redis分片集群
1. 介绍
主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:
海量数据存储问题
高并发写的问题
使用分片集群可以解决上述问题
2. 分片集群的架构
分片集群特征:
集群中有多个master,每个master保存不同数据
每个master都可以有多个slave节点
master之间通过ping监测彼此健康状态
客户端请求可以访问集群任意节点,最终都会被转发到正确节点
3. 搭建分片集群
架构说明
分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个master包含一个slave节点,结构如下:这里我们会在同一台虚拟机中开启6个redis实例,模拟分片集群,信息如下:
ip 端口 角色
192.168.126.121 7380 master
192.168.126.121 7381 master
192.168.126.121 7382 master
192.168.126.121 8380 slave
192.168.126.121 8381 slave
192.168.126.121 8382 slave
准备实例和配置
准备文件夹
创建04cluster文件夹,并在文件夹里准备7380 7381 7382 8380 8381 8382六个文件夹
mkdir ~/04cluster
cd ~/04cluster/
mkdir 7380 7381 7382 8380 8381 8382准备配置文件
准备7380的配置
切换到7380目录:
cd ~/04cluster/7380
使用vi编辑文件:
vi redis.conf
, 内容如下port 7380 # 开启集群功能 cluster-enabled yes # 集群的配置文件名称,不需要我们创建,由redis自己维护 cluster-config-file /root/04cluster/7380/nodes.conf # 节点心跳失败的超时时间 cluster-node-timeout 5000 # 持久化文件存放目录 dir /root/04cluster/7380 # 绑定地址 bind 0.0.0.0 # 让redis后台运行 daemonize yes # 注册的实例ip replica-announce-ip 192.168.126.121 # 保护模式 protected-mode no # 数据库数量 databases 1 # 日志 logfile /root/04cluster/7380/run.log
准备其它实例的配置
#修改每个目录下的redis.conf,修改其端口: cd ~/04cluster # 执行修改 printf '%s\n' 7381 7382 8380 8381 8382 | xargs -I{} -t sed -i 's/7380/{}/g' {}/redis.conf
启动
#因为已经配置了Redis后台运行,所以可以直接启动,不需要开多个shell端口。执行以下命令: cd ~/04cluster #启动7380 7381 7382 8380 8381 8382 六个Redis服务 printf '%s\n' 7380 7381 7382 8380 8381 8382 | xargs -I{} -t redis-server {}/redis.conf #查看是否成功启动,执行命令:`ps -ef | grep redis`。如果看到以下结果,说明6个redis实例都启动成功
如果要关闭所有进程,可以执行命令:
方式一:ps -ef | grep redis | awk '{print $2}' | xargs kill
方式二:printf '%s\n' 7380 7381 7382 8380 8381 8382 | xargs -I{} -t redis-cli -p {} shutdown
创建集群
虽然服务已经成功启动,但目前6个Redis实例还是独立的,它们之间没有任何关系。
我们需要执行命令来创建集群。在Redis5.0之前创建集群比较麻烦,5.0之后集群管理命令都集成到了redis-cli中
命令说明
redis5.0之前
Redis5.0之前集群命令都是用redis安装包下的src/redis-trib.rb来实现的。因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境:
# 安装依赖
yum -y install zlib ruby rubygems
gem install redis
然后通过命令管理集群:# 进入redis的src目录
cd ~/redis-6.2.4/src
# 创建集群
./redis-trib.rb create --replicas 1 192.168.126.121:7380 192.168.126.121:7381 192.168.126.121:7382 192.168.126.121:8380 192.168.126.121:8381 192.168.126.129:8381
redis5.0开始我们使用的是Redis6.2.4版本,集群管理以及集成到了redis-cli中,格式如下:
redis-cli --cluster create --cluster-replicas 1 192.168.126.129:7380 192.168.126.121:7381 192.168.126.121:7382 192.168.126.121:8380 192.168.126.129:8381 192.168.126.121:8382
命令说明:
redis-cli --cluster或者./redis-trib.rb:表示要操作redis集群
create:表示要创建集群
--cluster-replicas 1或者--replicas:指令集群中每个master的副本个数为1。这样:
master节点的数量:节点总数 / (replicas + 1),得到的就是master节点的数量
节点列表中前n个就是master节点,其它是slave节点。这些slave随机分配给不同的master
创建集群
如果在执行下面的命令创建集群时报错:[ERR] Node 192.168.126.129:7380 is not empty. Either the node already knows other nodes
主要原因可能是:该节点默认生成的配置与历史存储的数据不一致导致的
解决的方法是:
关闭所有redis实例:
printf '%s\n' 7380 7381 7382 8380 8381 8382|xargs -I{} -t redis-cli -p {} shutdown
清除对应节点的dump.rdb、nodes.conf等文件find / -name nodes.conf | xargs rm -rf
find / -name dump.rdb | xargs rm -rf
然后重启redis实例,再执行创建集群的命令cd ~/04cluster
#启动7380 7381 7382 8380 8381 8382 六个Redis服务
printf '%s\n' 7380 7381 7382 8380 8381 8382 | xargs -I{} -t redis-server {}/redis.conf
执行以下的命令,创建集群redis-cli --cluster create --cluster-replicas 1 192.168.126.121:7380 192.168.126.121:7381 192.168.126.121:7382 192.168.126.121:8380 192.168.126.121:8381 192.168.126.121:8382
测试
使用命令连接7380节点:redis-cli -c -p 7380,做如下操作:存储数据:set num 10
获取数据:get num
再次存储:set a 1
在使用redis-cli连接分片集群时,必须加上参数-c,否则操作时可能会出错。示例:
尝试连接7380节点:redis-cli -p 7380,做如下操作:
存储数据:set num 10
获取数据:get num
再次存储:set a 1
发现会报错