缓存服务器 Memcached&Redis

文章目录

    • 一、前言
      • 1、NoSQL的优点/缺点
      • 2、关系型数据库与非关系型数据库的区别
        • (1)关系型数据库
        • (2)非关系型数据库
    • 二、Memcached
        • 1、特点
        • 2、服务框架
        • 3、配置安装Memcached
    • 三、Redis服务
      • 1、介绍
      • 2、特点
      • 3、优势
      • 4、区别
      • 5、安装Redis
      • 6、Redis命令行工具
    • 四、数据持久化
      • 1、redis持久化 – 两种方式
      • 2、持久化配置
      • 3、拓展RDB快照备份恢复
    • 五、Redis主从配置
      • 1、主从简介
        • (1)主从 – 用法
        • (2)主从同步原理
      • 2、部署三台机器Redis---主从同步
    • 六、Redis-sentinel---哨兵模式
      • 1、哨兵简介:Redis Sentinel
      • 2、作用
      • 3、工作模式
      • 4、主观下线和客观下线
      • 5、配置哨兵模式
      • 6、扩展:php安装redis的模块
    • 七、Redis Cluster集群
      • 1、为什么要用redis-cluster集群?
      • 2、什么是Redis-Cluster
        • (1)redis cluster特点
        • (2)redis-cluster数据分布
        • (3)数据分布存储原理
      • 3、Redis Cluster主从模式
      • 4、集群部署
      • 5、集群操作
      • 6、主从切换
    • 七、面试

一、前言

许多Web应用都将数据保存到关系型数据库( RDBMS)中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、 网站显示延迟等重大影响。Memcached/redis是高性能的分布式内存缓存服务器,通过缓存数据库查询结果,减少关系型数据库访问次数,以提高动态Web等应用的速度、 提高可扩展性。

NOSQL名词解释:非关系型数据库
nosql产品: redis,mongodb,memcached.

  • 以键值对的方式存储数据—(Key-Value)的形式

  • 缓存数据库

1、NoSQL的优点/缺点

优点:
- 高可扩展性
- 分布式计算
- 低成本
- 架构的灵活性
- 没有复杂的关系

缺点:
- 没有标准化
- 有限的查询功能(到目前为止)
- 最终一致是不直观的程序

缓存服务器作用: 加快访问速度 ,缓解数据库压力

2、关系型数据库与非关系型数据库的区别

(1)关系型数据库

关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织。

优点:

  • 易于维护:都是使用表结构,格式一致;
  • 使用方便:SQL语言通用,可用于复杂查询;
  • 复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。

缺点:

  • 读写性能比较差,尤其是海量数据的高效率读写;
  • 固定的表结构,灵活度稍欠;
  • 高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈;
(2)非关系型数据库

非关系型数据是一种数据结构化存储方法的集合,可以是文档或者键值对等

优点:

  • 格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。
  • 速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;
  • 高扩展性;
  • 成本低:nosql数据库部署简单,基本都是开源软件。

缺点:

  • 不提供sql支持,学习和使用成本较高;
  • 无事务处理;
  • 数据结构相对复杂,复杂查询方面稍欠。

二、Memcached

1、特点
  • 内置内存存储方式-----------为了提高性能,memcached中保存的数据都存储在memcache内置的内存存储空间中。由于数据仅存在于内存中,重启操作系统会导致全部数据消失
  • 简单key/value存储---------------服务器不关心数据本身的意义及结构,只要是可序列化数据即可。存储项由“键、过期时间、可选的标志及数据”四个部分组成;

缓存服务器 Memcached&Redis_第1张图片

2、服务框架

缓存服务器 Memcached&Redis_第2张图片

原理

  • 检查客户端的请求数据是否在memcached中,如有,直接把请求数据返回,不再对数据库进行任何操作,路径操作为①②③⑦。

  • 如果请求的数据不在memcached中,就去查数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到memcached中(memcached客户端不负责,需要程序明确实现),路径操作为①②④⑤⑦⑥。

  • 保持缓存的“新鲜性”,每当数据发生变化的时候(比如,数据有被修改,或被删除的情况下),要同步更新的缓存信息,确保用户不会在缓存取到旧的数据。

3、配置安装Memcached

memcache能存放多少数据,取决于服务器本身的内存有多大。

1.安装----准备一台服务器
[root@memcached ~]# yum install memcached -y
[root@memcached ~]# systemctl start memcached  #启动

2.修改配置文件
[root@memcached ~]# vim /etc/sysconfig/memcached
PORT="11211"    ---监听的端口,默认11211.可以修改
USER="memcached"  -----用户
MAXCONN="1024"   -----默认并发,可以修改
CACHESIZE="64"    ------给的内存。默认是M
OPTIONS=""       ----监听的网络地址
然后把ip地址发给开发人员,开发的会使用api接口连接memcached.
测试:
[root@memcached ~]# yum install -y telnet   #安装telent
[root@memcached ~]# telnet 192.168.246.188 11211
Trying 192.168.246.188...
Connected to 192.168.246.188.
Escape character is '^]'.
set name 0 60 9    #设置名称为name的key      key   标记位(id号)   过期时间 大小
helloword        #给name的值
STORED         #出现stoped表示已经存储成功。
get name       #查询key值
VALUE name 0 9
helloword
END
quit   ---退出
参数解释:
name:key的名字 自己定义
0:key的id号,需要和其他的key不一样
60:缓存过期时间,单位为秒,0为永远
9:字符串最大长度

不用它的原因:存储的数据类型单一,而且数据只能存储在内存中。无法实现数据的持久化,服务器重启,数据将消失。
=================================================================
扩展:安装php支持memcached的扩展模块:
安装php7.0
[root@memcached ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm
[root@memcached ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
[root@memcached ~]# yum install php70w.x86_64 php70w-cli.x86_64 php70w-common.x86_64 php70w-gd.x86_64 php70w-ldap.x86_64 php70w-mbstring.x86_64 php70w-mcrypt.x86_64 php70w-mysql.x86_64 php70w-pdo.x86_64 php70w-devel zlib-devel  -y
[root@memcached ~]# yum -y install php70w-fpm
[root@memcached ~]# yum install -y make gcc zlib-devel libmemcached-devel git
下载PHP Memcache 扩展包
[root@memcached ~]# yum install libmemcached -y
[root@memcached ~]# yum install php70w-pecl-memcached -y
安装nginx略,配置nginx的yum源。测试访问php的页面。
[root@memcached ~]# yum -y install nginx
[root@memcached ~]# vim /etc/nginx/conf.d/nginx.conf
server {
    listen       80;
    server_name  localhost;

    location ~ \.php$ {
        root           /usr/share/nginx/html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}
编辑php页面
[root@memcached ~]# cd /usr/share/nginx/html/
[root@memcached html]# vi index.php
<?php
phpinfo();
?>
启动nginx与php-fpm即可
浏览器访问

缓存服务器 Memcached&Redis_第3张图片

三、Redis服务

1、介绍

Redis 是完全开源免费的,遵守 BSD 协议,是一个高性能的 key-value 数据库。

它通常被称为数据结构服务器,因为值(value)可以是字符串(String),哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。

2、特点

与其他缓存服务器相比,redis具备三个特点

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。
  • 支持事务 ---------------事务是指“一个完整的动作,要么全部执行,要么什么也没有做”。

3、优势

redis在缓存服务器中具备的优势

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型 –支持string(字符串),hash(哈希),list(列表),set(集合)及 zset(有序集合) 等
  • 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
  • 丰富的特性 – 可用于缓存,消息,按 key 设置过期时间,过期后将会自动删除

4、区别

redis和memcache比较 

1).Redis不仅仅支持简单的k/v类型的数据,同时还提供了list,set,zset,hash等数据结构的存储 
2).Redis支持master-slave(主-从)模式应用 
3).Redis支持数据的持久化

5、安装Redis

[root@redis-master ~]# mkdir -p /data/application     ---创建工作目录
[root@redis-master ~]# wget http://download.redis.io/releases/redis-4.0.9.tar.gz   ---下载redis
[root@redis-master ~]# tar xzf redis-4.0.9.tar.gz -C /data/application/    ---解压
[root@redis-master ~]# cd /data/application/
[root@redis-master application]# mv redis-4.0.9/ redis
[root@redis-master application]# cd redis/
[root@redis-master redis]# yum install -y gcc make  #安装编译工具
[root@redis-master redis]# make
注:如果报错请将刚才解压的安装包删除掉,再次重新解压并进行make安装即可。
[root@redis-master redis]# mv redis.conf redis.conf.bak
[root@redis-master redis]# vim redis.conf     ---修改如下
bind 192.168.246.202  #只监听内网IP
daemonize yes     #开启后台模式将on改为yes
port 6379                      #端口号
dir /data/application/redis/data  #本地数据库存放持久化数据的目录该目录-----需要存在
创建存放数据的目录
[root@redis-master redis]# mkdir /data/application/redis/data
配置redis为systemctl启动
[root@redis-master redis]# cd /usr/lib/systemd/system
[root@redis-master system]# vim redis.service
[Unit]
Description=Redis
After=network.target

[Service]
ExecStart=/data/application/redis/src/redis-server /data/application/redis/redis.conf  --daemonize no
ExecStop=/data/application/redis/src/redis-cli -h 127.0.0.1 -p 6379 shutdown

[Install]
WantedBy=multi-user.target

参数详解:

  • [Unit] 表示这是基础信息

  • Description 是描述

  • After 是在那个服务后面启动,一般是网络服务启动后启动

  • [Service] 表示这里是服务信息

  • ExecStart 是启动服务的命令

  • ExecStop 是停止服务的指令

  • [Install] 表示这是是安装相关信息

  • WantedBy 是以哪种方式启动:multi-user.target表明当系统以多用户方式(默认的运行级别)启动时,这个服务需要被自动运行。

启动服务

[root@redis-master system]# systemctl daemon-reload  #重新加载
[root@redis-master system]# systemctl start redis.service

缓存服务器 Memcached&Redis_第4张图片

6、Redis命令行工具

缓存服务器 Memcached&Redis_第5张图片

登陆redis
[root@redis-master system]# cd /data/application/redis/src/
[root@redis-master src]# ./redis-cli -h 192.168.246.202 -p 6379
192.168.246.202:6379> ping     ---测试redis是否可以用
PONG
192.168.246.202:6379> set name xiaoming    #设置key--name,并设置值
OK
192.168.246.202:6379> get name    #获取到key
"xiaoming"
192.168.246.202:6379>
单机版redis已经部署完成。将ip和端口发给开发就可以了。

192.168.246.202:6379> set key value [EX seconds] [PX milliseconds] [NX|XX]
EX seconds : 将键的过期时间设置为 seconds 秒。 执行 SET key value EX seconds 的效果等同于执行 SETEX key seconds value。
PX milliseconds : 将键的过期时间设置为 milliseconds 毫秒。 执行 SET key value PX milliseconds 的效果等同于执行 PSETEX key milliseconds value。
NX : 只在键不存在时, 才对键进行设置操作。
XX : 只在键已经存在时, 才对键进行设置操作。

使用 EX 选项:
[root@localhost src]# ./redis-cli -h 192.168.62.231 -p 6379
192.168.62.231:6379> set name1 xiaohong EX 10
OK
192.168.62.231:6379> get name1
"xiaohong"
等待10s,再次查看
192.168.62.231:6379> get name1
(nil)

使用 PX 选项:
192.168.62.231:6379> set name2 xiaohong PX 3233
OK
192.168.62.231:6379> get name2
"xiaohong"
等待3s,再次查看
192.168.62.231:6379> get name2
(nil)

使用 NX 选项:
192.168.62.231:6379> set class 1901 NX
OK # 键不存在,设置成功
192.168.62.231:6379> get class
"1901"
192.168.62.231:6379> set class 1901 NX
(nil)  # 键已经存在,设置失败
192.168.62.231:6379> get class
"1901"  # 维持原值不变

使用 XX 选项:
192.168.62.231:6379> set home taikang XX
(nil)  # 因为键不存在,设置失败
192.168.62.231:6379> set home taikang
OK # 先给键设置一个值
192.168.62.231:6379> set home zhengzhou XX
OK # 设置新值成功
192.168.62.231:6379> get home
"zhengzhou"

删除:
192.168.62.231:6379> del class
(integer) 1
192.168.62.231:6379> get class
(nil)

redis的相关工具

./redis-cli           #redis的客户端
./redis-server        #redis的服务端
./redis-check-aof     #用于修复出问题的AOF文件
./redis-sentinel      #用于集群管理

四、数据持久化

即把数据保存到可永久保存的存储设备中(如磁盘)。

1、redis持久化 – 两种方式

一、redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。
======================================================================================
RDB(Redis DataBase):是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上;
特点:
1.周期性
2.不影响数据写入  #RDB会启动子进程,备份所有数据。当前进程,继续提供数据的读写。当备份完成,才替换老的备份文件。
3.高效     #一次性还原所有数据
4.完整性较差 #故障点到上一次备份,之间的数据无法恢复。
======================================================================================
AOF(Append Only File)则是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
特点:
1.实时性
2.完整性较好
3.体积大  #记录数据的指令,删除数据的指令都会被记录下来。
=======================================================================================
二、RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。
三、如何选择方式?
缓存:不用开启任何持久方式
双开:因RDB数据不实时,但同时使用两者时服务器只会找AOF文件,所以RDB留作以防万一的手段。
官方的建议是两个同时使用。这样可以提供更可靠的持久化方案。
写入速度快 ------------AOF
写入速度慢 ------------RDB

2、持久化配置

1、RDB默认开启:
[root@redis-master src]# cd ..
[root@redis-master redis]# vim redis.conf
#dbfilename:持久化数据存储在本地的文件
dbfilename dump.rdb
#dir:持久化数据存储在本地的路径
dir /data/application/redis/data
##snapshot触发的时机,save   
##如下为900秒后,至少有一个变更操作,才会snapshot  
##对于此值的设置,需要谨慎,评估系统的变更操作密集程度  
##可以通过save “”来关闭snapshot功能  
#save时间,以下分别表示更改了1个key时间隔900s进行持久化存储;更改了10个key300s进行存储;更改10000个key60s进行存储。
save 900 1
save 300 10
save 60 10000 
##yes代表当使用bgsave命令持久化出错时候停止写RDB快照文件,no表明忽略错误继续写文件,“错误”可能因为磁盘已满/磁盘故障/OS级别异常等
stop-writes-on-bgsave-error yes
##是否启用rdb文件压缩,默认为“yes”,压缩往往意味着“额外的cpu消耗”,同时也意味着较短的网络传输时间  
rdbcompression yes 
注意:每次快照持久化都是将内存数据完整写入到磁盘一次,如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘io操作,可能会严重影响性能。
3、AOF默认关闭--开启
[root@redis-master src]# cd ..
[root@redis-master redis]# vim redis.conf
修改如下:

缓存服务器 Memcached&Redis_第6张图片

1、此选项为aof功能的开关,默认为“no”,可以通过“yes”来开启aof功能,只有在“yes”下,aof重写/文件同步等特性才会生效
====================================
2、指定aof文件名称
appendfilename appendonly.aof  
====================================
3、指定aof操作中文件同步策略,有三个合法值:always everysec no,默认为everysec
appendfsync everysec
always     #每次有数据修改发生时都会写入AOF文件
everysec   #每秒钟同步一次,该策略为AOF的缺省策略/默认策略
no         #从不同步。高效但是数据不会被持久化

开启持久化功能后,重启redis后,数据会自动通过持久化文件恢复

3、拓展RDB快照备份恢复

redis数据库备份与恢复(dump.rdb快照方式),两台机器

做备份机器的redis.conf配置文件内容:
bind 0.0.0.0
dbfilename dump.rdb
dir /data/application/redis/data
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
备份数据:
[root@redis-slave-1 redis]# src/redis-cli 
127.0.0.1:6379> set name3 qianfeng
OK
127.0.0.1:6379> set name4 tianyun
OK
127.0.0.1:6379> BGSAVE   执行备份,或者敲SAVE
[root@redis-slave-1 redis]# ls data/
dump.rdb

[root@redis-slave-1 redis]# scp data/dump.rdb 192.168.62.135:/usr/local/redis/data/

恢复数据的机器:
修改redis.conf配置文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QMB3fonv-1631796370075)(assets/image-20210202173657496.png)]

缓存服务器 Memcached&Redis_第7张图片

将dump.rdb数据文件存放到配置文件制定的目录下,直接启动即可
[root@redis-master redis]# src/redis-server redis.conf &
[root@redis-master redis]# src/redis-cli
[root@redis-master redis]#
127.0.0.1:6379> get name3
"qianfeng"
127.0.0.1:6379> get name4
"tianyun"

五、Redis主从配置

1、主从简介

(1)主从 – 用法

像MySQL一样,redis是支持主从同步的,而且也支持一主多从以及多级从结构。

主从结构,一是为了纯粹的冗余备份,二是为了提升读性能,比如很消耗性能的操作就可以由从服务器来承担。
redis的主从同步是异步进行的,这意味着主从同步不会影响主逻辑,也不会降低redis的处理性能。
主从架构中,可以考虑关闭主服务器的数据持久化功能,只让从服务器进行持久化,这样可以提高主服务器的处理性能。

(2)主从同步原理
  • 如果我们给master配置了一个slave,不管这个slave是否是第一次连接上Master,它都会发送一个PSYNC命令给master请求复制数据。

  • master收到PSYNC命令后,会在后台进行数据持久化通过bgsave生成最新的rdb快照文件,持久化期间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。

  • 当持久化进行完毕以后,master会把这份rdb文件数据集发送给slave,slave会把接收到的数据进行持久化生成rdb,然后再加载到内存中。然后,master再将之前缓存在内存中的命令发送给slave。

  • 当master与slave之间的连接由于某些原因而断开时,slave能够自动重连Master,如果master收到了多个slave并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送给多个并发连接的slave。

了解

BGSAVE指令:
在后台异步(Asynchronously)保存当前数据库的数据到磁盘。
BGSAVE 命令执行之后立即返回 OK ,然后 Redis fork 出一个新子进程,原来的 Redis 进程(父进程)继续处理客户端请求,而子进程则负责将数据保存到磁盘,然后退出。

2、部署三台机器Redis—主从同步

redis-master----192.168.246.202
redis-slave-1-----192.168.246.203
redis-slave-2-----192.168.246.204
1.首先三台服务器将redis部署完成。
2.编辑master的redis配置文件:
[root@redis-master ~]# cd /data/application/redis/
[root@redis-master redis]# vim redis.conf

缓存服务器 Memcached&Redis_第8张图片

关闭protected-mode模式,此时外部网络可以直接访问

开启protected-mode保护模式,需配置bind ip或者设置访问密码

3.启动主节点redis服务
[root@redis-master src]# cd /data/application/redis/src
[root@redis-master src]# ./redis-server ../redis.conf &   会加载此文件中的配置信息
4.修改slave1的配置文件:
[root@redis-slave-1 ~]# cd /data/application/redis/
[root@redis-slave-1 redis]# vim redis.conf      ---修改如下:

缓存服务器 Memcached&Redis_第9张图片

缓存服务器 Memcached&Redis_第10张图片

5.启动从节点1的redis服务
[root@redis-slave-1 ~]# cd /data/application/redis/src/
[root@redis-slave-1 src]# ./redis-server ../redis.conf &
6.修改slave2的配置文件
[root@redis-slave-2 ~]# cd /data/application/redis/
[root@redis-slave-2 redis]# vim redis.conf       ---修改如下

缓存服务器 Memcached&Redis_第11张图片

缓存服务器 Memcached&Redis_第12张图片

7.启动从节点2的redis服务
[root@ansible-web2 ~]# cd /data/application/redis/src/
[root@ansible-web2 src]# ./redis-server ../redis.conf &
或者,配置到了系统管理工具里面直接可以以下操作
8.重启三台redis
[root@redis-master redis]# systemctl restart redis.service
[root@redis-slave-1 ~]# systemctl restart redis.service
[root@redis-slave-2 ~]# systemctl restart redis.service

缓存服务器 Memcached&Redis_第13张图片

9.测试主从
1.在master上面执行
[root@redis-master redis]# cd src/
[root@redis-master src]# ./redis-cli 
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set name jack
OK
127.0.0.1:6379> get name
"jack"
127.0.0.1:6379>

2.分别在slave-1和slave-2上面执行:
[root@redis-slave-1 redis]# cd src/
[root@redis-slave-1 src]# ./redis-cli 
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> get name
"jack"
127.0.0.1:6379>
[root@redis-slave-2 src]# ./redis-cli 
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> get name
"jack"
127.0.0.1:6379>
查看复制状态
master执行:
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.246.203,port=6379,state=online,offset=490,lag=0
slave1:ip=192.168.246.204,port=6379,state=online,offset=490,lag=1
==============================================================================
slave上面执行:
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.246.202
master_port:6379
master_link_status:up

注意:从服务器一般默认禁止写入操作:slave-read-only yes

主从同步部署完成!

六、Redis-sentinel—哨兵模式

1、哨兵简介:Redis Sentinel

Sentinel(哨兵)是用于监控Redis集群中Master状态的工具,其已经被集成在redis2.4+的版本中是Redis官方推荐的高可用性(HA)解决方案。

2、作用

  • Master状态检测
  • 如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave
  • Master-Slave切换后,sentinel.conf的监控目标会随之调换

3、工作模式

1):每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令

2):如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。

3):如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。

4):当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线 。

4、主观下线和客观下线

主观下线:Subjectively Down,简称 SDOWN,指的是当前 一个Sentinel 实例对某个redis服务器做出的下线判断。
客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在对Master Server做出 SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,然后开启failover/故障转移

5、配置哨兵模式

1.每台机器上修改redis主配置文件redis.conf文件设置:bind 0.0.0.0   ---已经操作
2.每台机器上修改sentinel.conf配置文件:修改如下配置
[root@redis-master src]# cd ..
[root@redis-master redis]# vim sentinel.conf
sentinel monitor mymaster 10.0.0.137 6379 2 #当集群中有2个sentinel认为master死了时,才能真正认为该master已经不可用了。 (slave上面写的是master的ip,master写自己ip)
sentinel down-after-milliseconds mymaster 3000   #单位毫秒
sentinel failover-timeout mymaster 10000   #若sentinel在该配置值内未能完成failover(故障转移)操作(即故障时master/slave自动切换),则认为本次failover失败。
protected-mode no  #关闭加密模式--新添加到sentinel配置文件中
3.每台机器启动哨兵服务:
[root@redis-master redis]# ./src/redis-sentinel sentinel.conf 
注意:在生产环境下将哨兵模式启动放到后台执行:     ./src/redis-sentinel sentinel.conf &

缓存服务器 Memcached&Redis_第14张图片

将master的哨兵模式退出(Crtl+c),再将redis服务stop了,在两台slave上面查看其中一台是否切换为master:(没有优先级,为随机切换)

^C4854:signal-handler (1564349039) Received SIGINT scheduling shutdown...
4854:X 29 Jul 05:23:59.592 # User requested shutdown...
4854:X 29 Jul 05:23:59.592 # Sentinel is now ready to exit, bye bye...
[root@redis-master redis]# systemctl stop redis.service
或者用kill命令杀死

在slave机器上面查看:

缓存服务器 Memcached&Redis_第15张图片

缓存服务器 Memcached&Redis_第16张图片

6、扩展:php安装redis的模块

1.安装php7.0
[root@redis ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm
[root@redis ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
[root@redis ~]# yum install php70w.x86_64 php70w-cli.x86_64 php70w-common.x86_64 php70w-gd.x86_64 php70w-ldap.x86_64 php70w-mbstring.x86_64 php70w-mcrypt.x86_64 php70w-mysql.x86_64 php70w-pdo.x86_64 php70w-devel zlib-devel  -y
[root@redis ~]# yum -y install php70w-fpm
[root@redis ~]# yum install -y make gcc zlib-devel libmemcached-devel gi
=================================================================================
[root@redis ~]# wget http://pecl.php.net/get/redis-4.0.0RC2.tgz #下载扩展
[root@redis ~]# tar xzf redis-4.0.0RC2.tgz
[root@redis ~]# cd redis-4.0.0RC2
[root@redis redis-4.0.0RC2]# /usr/bin/phpize   #---生成./configure 这个配置文件
[root@redis redis-4.0.0RC2]# ./configure -with-php-config=/usr/bin/php-config
...
configure: creating ./config.status
config.status: creating config.h
config.status: executing libtool commands
[root@ansible-web3 redis-4.0.0RC2]# make && make install  #编译,最后显示如下表示成功
Build complete.
Don't forget to run 'make test'.
Installing shared extensions:     /usr/lib64/php/modules/
=======================================
[root@redis ~]# vim /etc/php.ini #添加扩展
搜索: \.so

缓存服务器 Memcached&Redis_第17张图片

2.安装nginx,配置nginx的yum源--略
配置nginx连接php
[root@redis ~]# vim /etc/nginx/conf.d/nginx.conf
server {
    listen       80;
    server_name  localhost;

    location ~ \.php$ {
        root           /usr/share/nginx/html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

}
编辑php页面
[root@redis ~]# cd /usr/share/nginx/html/
[root@redis html]# vi index.php
<?php
phpinfo();
?>
启动nginx与php
[root@redis ~]# systemctl start nginx
[root@redis ~]# systemctl start php-fpm

访问:

缓存服务器 Memcached&Redis_第18张图片

安装扩展完成!

七、Redis Cluster集群

Redis Cluster是Redis官方提供的分布式解决方案。当遇到内存、并发、流量等瓶颈时,就可以采用Cluster架构达到负载均衡目的。官方文档:https://redis.io/topics/cluster-tutoria

1、为什么要用redis-cluster集群?

首先Redis单实例主要有单点,容量有限,流量压力上限的问题。 Redis单点故障,可以通过主从复制replication,和自动故障转移sentinel哨兵机制。但Redis单Master实例提供读写服务,仍然有容量和压力问题,因此需要数据分区,构建多个Master实例同时提供读写服务(不仅限于从replica节点提供读服务)。

并发问题

redis官方声称可以达到 10万/s,每秒执行10万条命令 假如业务需要每秒100万的命令执行呢?

解决方案

正确的应该是考虑分布式,加机器,把数据分到不同的位置,分摊集中式的压力,一堆机器做一件事.还需要一定的机制保证数据分区,并且数据在各个主Master节点间不能混乱,当然最好还能支持在线数据热迁移的特性。

2、什么是Redis-Cluster

为何要搭建Redis集群。Redis是在内存中保存数据的,而我们的电脑一般内存都不大,这也就意味着Redis不适合存储大数据,Redis更适合处理高并发,一台设备的存储能力是很有限的,但是多台设备协同合作,就可以让内存增大很多倍,这就需要用到集群。

Redis集群搭建的方式有多种,例如使用客户端分片、Twemproxy、Codis等,但从redis 3.0之后版本支持redis-cluster集群,它是Redis官方提出的解决方案:

Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。其Redis-cluster架构图如下:

缓存服务器 Memcached&Redis_第19张图片

(1)redis cluster特点
  • 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
  • 客户端与redis节点直连,不需要中间proxy层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
  • 节点的fail是通过集群中超过半数的节点检测失效时才生效。
(2)redis-cluster数据分布

Redis集群中有16384个哈希槽,每个redis实例负责一部分slot,集群中的所有信息通过节点数据交换而更新。一个hash slot中会有很多key和value。

(3)数据分布存储原理

Redis 集群使用数据分片(sharding)来实现:Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数(集群使用公式 CRC16(key) % 16384),这样每个key 都会对应一个编号在 0-16384 之间的哈希槽,那么redis就会把这个key 分配到对应范围的节点上了。同样,当连接三个节点任何一个节点想获取这个key时,也会这样的算法,然后内部跳转到存放这个key节点上获取数据。

例如三个节点:哈希槽分布的值如下:

cluster1:  0-5460
cluster2:  5461-10922
cluster3:  10923-16383  

这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。 比如说:

  • 如果用户将新节点 D 添加到集群中, 那么集群只需要将节点 A 、B 、 C 中的某些槽移动到节点 D 就可以了。
  • 如果用户要从集群中移除节点 A , 那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C , 然后再移除空白(不包含任何哈希槽)的节点 A 就可以了。

因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞, 所以无论是添加新节点还是移除已存在节点, 又或者改变某个节点包含的哈希槽数量, 都不会造成集群下线。

3、Redis Cluster主从模式

redis cluster 为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会有这个从节点选取一个来充当主节点,从而保证集群不会挂掉.

1.主从切换机制

选举过程是集群中所有master参与,如果半数以上master节点与故障节点通信超过(cluster-node-timeout),认为该节点故障,自动触发故障转移操作. #故障节点对应的从节点自动升级为主节点

2.什么时候整个集群就不能用了?

如果集群任意一个主节点挂掉,且当前主节点没有从节点,则集群将无法继续,因为我们不再有办法为这个节点承担范围内的哈希槽提供服务。但是,如果这个主节点和所对应的从节点同时失败,则Redis Cluster无法继续运行。

4、集群部署

环境准备:
1.准备三机器,关闭防火墙和selinux
2.制作解析并相互做解析。
注:规划架构两种方案,一种是单机多实例,这里我们采用多机器部署:
三台机器,每台机器上面两个redis实例,一个master一个slave,第一列做主库,第二列做备库
#记得选出控制节点

redis-cluster1 192.168.116.172   7000、7001
redis-cluster2 192.168.116.173   7002、7003
redis-cluster3 192.168.116.174   7004、7005

1.三台机器相同操作

1.安装redis
[root@redis-cluster1 ~]# mkdir /data
[root@redis-cluster1 ~]# yum -y install gcc automake autoconf libtool make
[root@redis-cluster1 ~]# wget https://download.redis.io/releases/redis-6.2.0.tar.gz
[root@redis-cluster1 ~]# tar xzvf redis-6.2.0.tar.gz -C /data/
[root@redis-cluster1 ~]# cd /data/
[root@redis-cluster1 data]# mv redis-6.2.0/ redis
[root@redis-cluster1 data]# cd redis/
[root@redis-cluster1 redis]# make    #编译
[root@redis-cluster1 redis]# mkdir /data/redis/data #创建存放数据的目录
2.创建节点目录:按照规划在每台redis节点的安装目录中创建对应的目录(以端口号命名)
[root@redis-cluster1 redis]# pwd
/data/redis
[root@redis-cluster1 redis]# mkdir cluster #创建集群目录
[root@redis-cluster1 redis]# cd cluster/
[root@redis-cluster1 cluster]# mkdir 7000 7001 #创建节点目录

[root@redis-cluster2 redis]# mkdir cluster
[root@redis-cluster2 redis]# cd cluster/
[root@redis-cluster2 cluster]# mkdir 7002 7003

[root@redis-cluster3 redis]# mkdir cluster
[root@redis-cluster3 redis]# cd cluster/
[root@redis-cluster3 cluster]# mkdir 7004 7005
3.拷贝配置文件到节点目录中,#三台机器相同操作
[root@redis-cluster1 cluster]# cp /data/redis/redis.conf 7000/
[root@redis-cluster1 cluster]# cp /data/redis/redis.conf 7001/

[root@redis-cluster2 cluster]# cp /data/redis/redis.conf 7002/
[root@redis-cluster2 cluster]# cp /data/redis/redis.conf 7003/

[root@redis-cluster3 cluster]# cp /data/redis/redis.conf 7004/
[root@redis-cluster3 cluster]# cp /data/redis/redis.conf 7005/
4.修改集群每个redis配置文件。(主要是端口、ip、pid文件,三台机器相同操作),修改如下:
[root@redis-cluster1 cluster]# cd 7000/
[root@redis-cluster1 7000]# vim redis.conf #修改如下
bind 192.168.116.172  #每个实例的配置文件修改为对应节点的ip地址
port 7000   #监听端口,运行多个实例时,需要指定规划的每个实例不同的端口号
daemonize yes #redis后台运行
pidfile /var/run/redis_7000.pid #pid文件,运行多个实例时,需要指定不同的pid文件
logfile /var/log/redis_7000.log #日志文件位置,运行多实例时,需要将文件修改的不同。
dir /data/redis/data #存放数据的目录
appendonly yes #开启AOF持久化,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之前的状态。
appendfilename "appendonly.aof"  #AOF文件名称
appendfsync everysec #表示对写操作进行累积,每秒同步一次
以下为打开注释并修改
cluster-enabled yes #启用集群
cluster-config-file nodes-7000.conf #集群配置文件,由redis自动更新,不需要手动配置,运行多实例时请注修改为对应端口
cluster-node-timeout 5000 #单位毫秒。集群节点超时时间,即集群中主从节点断开连接时间阈值,超过该值则认为主节点不可以,从节点将有可能转为master
cluster-replica-validity-factor 10 #在进行故障转移的时候全部slave都会请求申请为master,但是有些slave可能与master断开连接一段时间了导致数据过于陈旧,不应该被提升为master。该参数就是用来判断slave节点与master断线的时间是否过长。(计算方法为:cluster-node-timeout * cluster-replica-validity-factor,此处为:5000 * 10 毫秒)
cluster-migration-barrier 1 #一个主机将保持连接的最小数量的从机,以便另一个从机迁移到不再被任何从机覆盖的主机
cluster-require-full-coverage yes #集群中的所有slot(16384个)全部覆盖,才能提供服务

#注:
所有节点配置文件全部修改切记需要修改的ip、端口、pid文件...避免冲突。确保所有机器都修改。
5.启动三台机器上面的每个节点(三台机器相同操作)
[root@redis-cluster1 ~]# cd /data/redis/src/
[root@redis-cluster1 src]# ./redis-server ../cluster/7000/redis.conf 
[root@redis-cluster1 src]# ./redis-server ../cluster/7001/redis.conf

[root@redis-cluster2 7003]# cd /data/redis/src/
[root@redis-cluster2 src]# ./redis-server ../cluster/7002/redis.conf 
[root@redis-cluster2 src]# ./redis-server ../cluster/7003/redis.conf

[root@redis-cluster3 7005]# cd /data/redis/src/
[root@redis-cluster3 src]# ./redis-server ../cluster/7004/redis.conf 
[root@redis-cluster3 src]# ./redis-server ../cluster/7005/redis.conf

查看端口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PcZmzPvE-1633482678060)(assets/image-20210227170755994.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uJ5kL4Ig-1633482678062)(assets/image-20210227171013509.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-abP6C67D-1633482678064)(assets/image-20210227171119590.png)]

6.创建集群:在其中一个节点操作就可以
redis节点搭建起来后,需要完成redis cluster集群搭建,搭建集群过程中,需要保证6个redis实例都是运行状态。
Redis是根据IP和Port的顺序,确定master和slave的,所以要排好序,再执行。

参数:
--cluster-replicas 1:表示为集群中的每个主节点创建一个从节点.书写流程:主节点ip+port 对应一个从节点ip+port(注意:若节点在不同的机器上,注意主节点的书写位置,要避免主节点在同一台机器上,影响性能。正常是前面三个节点为主节点,后面的为从节点)

[root@redis-cluster1 src]# cd /data/redis/src/
[root@redis-cluster1 src]# ./redis-cli --cluster create --cluster-replicas 1 192.168.116.172:7000 192.168.116.172:7001 192.168.116.173:7002 192.168.116.173:7003 192.168.116.174:7004 192.168.116.174:7005
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.116.173:7003 to 192.168.116.172:7000
Adding replica 192.168.116.174:7005 to 192.168.116.173:7002
Adding replica 192.168.116.172:7001 to 192.168.116.174:7004
M: de5b4b2f6a559362ed56d4de1e3994fd529917b5 192.168.116.172:7000
   slots:[0-5460] (5461 slots) master
S: 2e8c1caa63ac4a1b9a6eea4f0fd5eab4c6b73c21 192.168.116.172:7001
   replicates 60e3755761c9cbdacb183f59e3d6205da5335e86
M: e0370608cd33ddf5bb6de48b5627799e181de3b6 192.168.116.173:7002
   slots:[5461-10922] (5462 slots) master
S: 4035841f20f07674671e6bff5d4c6db99c00626b 192.168.116.173:7003
   replicates de5b4b2f6a559362ed56d4de1e3994fd529917b5
M: 60e3755761c9cbdacb183f59e3d6205da5335e86 192.168.116.174:7004
   slots:[10923-16383] (5461 slots) master
S: e200afc33b10bd6975160bfeda7277d02371981a 192.168.116.174:7005
   replicates e0370608cd33ddf5bb6de48b5627799e181de3b6
Can I set the above configuration? (type 'yes' to accept): yes  #写yes同意
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 192.168.116.172:7000)
M: de5b4b2f6a559362ed56d4de1e3994fd529917b5 192.168.116.172:7000
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: e0370608cd33ddf5bb6de48b5627799e181de3b6 192.168.116.173:7002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 2e8c1caa63ac4a1b9a6eea4f0fd5eab4c6b73c21 192.168.116.172:7001
   slots: (0 slots) slave
   replicates 60e3755761c9cbdacb183f59e3d6205da5335e86
M: 60e3755761c9cbdacb183f59e3d6205da5335e86 192.168.116.174:7004
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 4035841f20f07674671e6bff5d4c6db99c00626b 192.168.116.173:7003
   slots: (0 slots) slave
   replicates de5b4b2f6a559362ed56d4de1e3994fd529917b5
S: e200afc33b10bd6975160bfeda7277d02371981a 192.168.116.174:7005
   slots: (0 slots) slave
   replicates e0370608cd33ddf5bb6de48b5627799e181de3b6
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

缓存服务器 Memcached&Redis_第20张图片

7.查看集群状态可连接集群中的任一节点,此处连接了集群中的节点192.168.116.172:7000
# 登录集群客户端,-c标识以集群方式登录
[root@redis-cluster1 src]# ./redis-cli -h 192.168.116.172 -c -p 7000
192.168.116.172:7000> ping
PONG
192.168.116.173:7002> 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 #集群实例数
......

192.168.116.172:7000> cluster nodes  #查看集群实例

5、集群操作

1、客户端登陆

测试链接redis,存取数据(链接集群中任意一台机器就可以。)
存:
[root@redis-cluster1 src]# ./redis-cli -h 192.168.116.172 -c -p 7000
192.168.116.172:7000> ping
PONG
192.168.116.172:7000> set name qianfeng
-> Redirected to slot [5798] located at 192.168.116.173:7002
OK
192.168.116.173:7002>[root@redis-cluster3 src]# ./redis-cli -h 192.168.116.173 -c -p 7002
192.168.116.173:7002> ping
PONG
192.168.116.173:7002> get name
"qianfeng"
192.168.116.173:7002> exists name  #查看某一个key是否存在
(integer) 1

2、集群添加节点

准备工作:
1.新准备一台机器,修改主机名,关闭防火墙和selinux。
2.安装相同版本redis,单机多实例。配置主从端口配置文件。
新准备cluster4,第一列为master第二列为slave。
192.168.116.175 redis-cluster4  7006 7007
[root@redis-cluster4 ~]# mkdir /data
[root@redis-cluster4 ~]# yum -y install gcc automake autoconf libtool make
[root@redis-cluster4 ~]# wget https://download.redis.io/releases/redis-6.2.0.tar.gz
[root@redis-cluster4 ~]# tar xzvf redis-6.2.0.tar.gz -C /data/
[root@redis-cluster4 ~]# cd /data/
[root@redis-cluster4 data]# mv redis-6.2.0/ redis
[root@redis-cluster4 data]# cd redis/
[root@redis-cluster4 redis]# make    #编译
[root@redis-cluster4 redis]# mkdir data  #创建数据目录
[root@redis-cluster4 redis]# mkdir cluster
[root@redis-cluster4 redis]# mkdir cluster/{7006,7007}  #创建集群节点
[root@redis-cluster4 redis]# cp redis.conf cluster/7006/
[root@redis-cluster4 redis]# cp redis.conf cluster/7007/
开始修改配置文件略...和之前一样,注意修改不一样的地方:端口、ip、pid文件...
启动
[root@redis-cluster4 src]# ./redis-server ../cluster/7006/redis.conf 
[root@redis-cluster4 src]# ./redis-server ../cluster/7007/redis.conf

1.都准备好之后,开始添加节点:将cluster4添加到集群中
[root@redis-cluster4 src]# ./redis-cli --cluster add-node 192.168.116.175:7006 192.168.116.172:7000
>>> Adding node 192.168.116.175:7006 to cluster 192.168.116.172:7000
......
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 192.168.116.175:7006 to make it join the cluster.
[OK] New node added correctly.

查看集群节点信息(随便登陆一个客户端即可)
[root@redis-cluster1 src]# ./redis-cli -h 192.168.116.172 -c -p 7000
192.168.116.172:7000> CLUSTER nodes

缓存服务器 Memcached&Redis_第21张图片

详细解释:
runid: 该行描述的节点的id。
ip:prot: 该行描述的节点的ip和port
flags: 逗号分隔的标记位,可能的值有:
1.master: 该行描述的节点是master
2.slave: 该行描述的节点是slave
3.fail?:该行描述的节点可能不可用
4.fail:该行描述的节点不可用(故障)
master_runid: 该行描述的节点的master的id,如果本身是master则显示-
ping-sent: 最近一次发送ping的Unix时间戳,0表示未发送过
pong-recv:最近一次收到pong的Unix时间戳,0表示未收到过
config-epoch: 主从切换的次数
link-state: 连接状态,connnected 和 disconnected
hash slot: 该行描述的master中存储的key的hash的范围
2.给新节点hash槽分配
需要给新节点进行hash槽分配,这样该主节才可以存储数据,(如果有数据记得提前先将数据同步然后在从其他节点迁移槽到新节点。)
[root@redis-cluster1 src]# ./redis-cli --cluster reshard 192.168.116.175:7006
>>> Performing Cluster Check (using node 192.168.116.175:7006)
......
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 4000 #输入要分配的槽数量 
What is the receiving node ID?  828c48dc72d52ff5be972512d3d87b70236af87c #输入接收槽的节点id,通过cluster nodes 查看新增的192.168.116.175:7006 的id

Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
输入: all
然后输入输入yes确认

此时再通过cluster nodes查看节点,可以看到新节点分配的槽为0-1332 5461-6794 10923-12255
[root@redis-cluster1 src]# ./redis-cli -h 192.168.116.172 -c -p 7000
192.168.116.172:7000> CLUSTER nodes

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jQT2OwFN-1633482678068)(assets/image-20210227211624203.png)]

3.给新添加的主节点添加对应的从节点:
[root@redis-cluster4 src]# ./redis-cli --cluster add-node 192.168.116.175:7007 192.168.116.175:7006 --cluster-slave --cluster-master-id 308320db4284c9b203aff1d3d9a145616856f681 #master的id
>>> Adding node 192.168.116.175:7007 to cluster 192.168.116.175:7006
>>> Performing Cluster Check (using node 192.168.116.175:7006)
......
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 192.168.116.175:7007 to make it join the cluster.
Waiting for the cluster to join

>>> Configure node as replica of 192.168.116.175:7006.
[OK] New node added correctly.

查看集群信息
192.168.116.172:7000> CLUSTER nodes

缓存服务器 Memcached&Redis_第22张图片

4.平衡各个主节点的槽:
[root@redis-cluster1 src]# ./redis-cli --cluster rebalance --cluster-threshold 1 192.168.116.172:7000
>>> Performing Cluster Check (using node 192.168.116.172:7000)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Rebalancing across 4 nodes. Total weight = 4.00
Moving 32 slots from 192.168.116.174:7004 to 192.168.116.175:7006
################################
Moving 32 slots from 192.168.116.173:7002 to 192.168.116.175:7006
################################
Moving 32 slots from 192.168.116.172:7000 to 192.168.116.175:7006
################################

登陆测试:
[root@redis-cluster1 src]# ./redis-cli -h 192.168.116.175 -c -p 7007
192.168.116.175:7007> ping
PONG
192.168.116.175:7007> get name 
-> Redirected to slot [5798] located at 192.168.116.175:7006
"qianfeng"

3、删除节点

#注意:这个地方需要提一下的就是
如果要下线节点6,节点7,请务必先下线从节点,并且节点6的slot的迁移到其他节点了,如果先线下节点6的话 会发产生故障切换,节点7成主节点了
在移除某个redis节点之前,首先不能在登入该节点当中,否则不能正常移除该节点.

1.退出所有链接的客户端,然后在任意一台机器执行
[root@redis-cluster1 src]# ./redis-cli --cluster del-node 192.168.116.175:7007 dbad32bd47cc177de61109b96447d1f1ef6db2fc #该节点的id
>>> Removing node dbad32bd47cc177de61109b96447d1f1ef6db2fc from cluster 192.168.116.175:7007
>>> Sending CLUSTER FORGET messages to the cluster...
>>> Sending CLUSTER RESET SOFT to the deleted node.

[root@redis-cluster1 src]# ./redis-cli -h 192.168.116.172 -c -p 7000
192.168.116.172:7000> CLUSTER NODES

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DVn6ofg1-1633482678069)(assets/image-20210227222435355.png)]

2.删除主节点:带有槽的节点
查看每个节点槽的数量
[root@redis-cluster1 src]# ./redis-cli --cluster info 192.168.116.172:7000
192.168.116.172:7000 (de5b4b2f...) -> 0 keys | 4096 slots | 1 slaves.
192.168.116.173:7002 (e0370608...) -> 0 keys | 4096 slots | 1 slaves.
192.168.116.174:7004 (60e37557...) -> 0 keys | 4096 slots | 1 slaves.
192.168.116.175:7006 (308320db...) -> 2 keys | 4096 slots | 0 slaves.
[OK] 2 keys in 4 masters.

要删除的当前主节点哈希槽状态:0-1364 5461-6826 10923-12287
共有哈希槽=1365 + 1366 + 1365 = 40961.将6节点上面的槽迁移到其他节点:
ip+port:要移除的节点
cluster-from:移除节点的id
cluster-to:接受槽主节点的id,需要将4096平均移动到不同的主节点,需要写不同接受槽的主节点id
cluster-slots:移除槽的数量
[root@redis-cluster1 src]# ./redis-cli --cluster reshard 192.168.116.175:7006 --cluster-from 308320db4284c9b203aff1d3d9a145616856f681 --cluster-to e0370608cd33ddf5bb6de48b5627799e181de3b6 --cluster-slots 1365 --cluster-yes

[root@redis-cluster1 src]# ./redis-cli --cluster reshard 192.168.116.175:7006 --cluster-from 308320db4284c9b203aff1d3d9a145616856f681 --cluster-to de5b4b2f6a559362ed56d4de1e3994fd529917b5 --cluster-slots 1366 --cluster-yes

[root@redis-cluster1 src]# ./redis-cli --cluster reshard 192.168.116.175:7006 --cluster-from 308320db4284c9b203aff1d3d9a145616856f681 --cluster-to 60e3755761c9cbdacb183f59e3d6205da5335e86 --cluster-slots 1365 --cluster-yes

查看节点信息
192.168.116.173:7002> CLUSTER nodes

缓存服务器 Memcached&Redis_第23张图片

可以看到已经没有槽了。

如果报错:
[root@redis-cluster1 src]# ./redis-cli --cluster del-node 192.168.116.175:7006 308320db4284c9b203aff1d3d9a145616856f681
>>> Removing node 308320db4284c9b203aff1d3d9a145616856f681 from cluster 192.168.116.175:7006
[ERR] Node 192.168.116.175:7006 is not empty! Reshard data away and try again.

需要重新查看一下槽有没有全部移动完成。如果没有需要重新指定数量移动。这是因为还有槽不能直接移除master。
3.删除master节点
[root@redis-cluster1 src]# ./redis-cli --cluster del-node 192.168.116.175:7006 308320db4284c9b203aff1d3d9a145616856f681
>>> Removing node 308320db4284c9b203aff1d3d9a145616856f681 from cluster 192.168.116.175:7006
>>> Sending CLUSTER FORGET messages to the cluster...
>>> Sending CLUSTER RESET SOFT to the deleted node.

查看集群信息:
192.168.116.173:7002> CLUSTER nodes

缓存服务器 Memcached&Redis_第24张图片

可以看到变成了3主3从

6、主从切换

测试:
1.将节点cluster1的主节点7000端口的redis关掉
[root@redis-cluster1 src]# ps -ef |grep redis 
root      15991      1  0 01:04 ?        00:02:24 ./redis-server 192.168.116.172:7000 [cluster]
root      16016      1  0 01:04 ?        00:02:00 ./redis-server 192.168.116.172:7001 [cluster]
root      16930   1595  0 08:04 pts/0    00:00:00 grep --color=auto redis
[root@redis-cluster1 src]# kill -9 15991

查看集群信息:
192.168.116.173:7002> CLUSTER nodes

缓存服务器 Memcached&Redis_第25张图片

可以看到7000端口这个redis已经是fail失败的了。

2.将该节点的7000端口redis启动在查看
[root@redis-cluster1 log]# cd /data/redis/src/
[root@redis-cluster1 src]# ./redis-server ../cluster/7000/redis.conf

查看节点信息:
192.168.116.173:7002> CLUSTER nodes

缓存服务器 Memcached&Redis_第26张图片

可以看到已经主从切换了

七、面试

redis有哪些优点
(1) 速度快,因为数据存在内存中。
(2) 支持丰富数据类型,支持string,list,set,hash等
(3) 支持事务,操作都是原子性,就是对数据的更改要么全部执行,要么全部不执行
(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

redis相比memcached有哪些优势
(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
(2) redis可以持久化其数据

redis常见性能问题和解决方案
(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
(4) 尽量避免在压力很大的主库上增加从库
(5) 主从复制不要用树状结构,用单向链表结构更为稳定,即:Master(写) <- Slave1(读) <- Slave2(读) <- Slave3(读)...
这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。
redis集群的工作原理
主多从+哨兵模式

了解:

redis–快照

快照,主要涉及的是redis的RDB持久化相关的配置

用如下的指令来让数据保存到磁盘上,即控制RDB快照功能:

save <seconds> <changes>

举例
save 900 1 //表示每15分钟且至少有1个key改变,就触发一次持久化
save 300 10 //表示每5分钟且至少有10个key改变,就触发一次持久化
save 60 10000 //表示每60秒至少有10000个key改变,就触发一次持久化

如果想禁用RDB持久化的策略,只要不设置任何save指令就可以,或者给save传入一个空字符串参数也可以达到相同效果,就像这样:

save ""

安全:为redis加密:

可以要求redis客户端在向redis-server发送请求之前,先进行密码验证。当你的redis-server处于一个不太可信的网络环境中时,相信你会用上这个功能。由于redis性能非常高,所以每秒钟可以完成多达15万次的密码尝试,所以你最好设置一个足够复杂的密码,否则很容易被黑客破解。

requirepass 1122334

这里我们通过requirepass将密码设置成“1122334”。

你可能感兴趣的:(Redis,memcached,redis,缓存)