NOSQL

NOSQL

什么是nosql?

NoSQL(Not Only SQL):非关系型数据库;

包括:

  • Redis:基于内存的KV结构的数据库;
  • MongoDB:文档型数据库,擅长存储JSON(BSON)数据;
  • HBase:列存储数据库,大数据存储;

特点:

  • 存储半结构化、非结构化数据;
  • 海量存储;
  • 高并发场景;

Redis

Redis(Remote Dictionary Server )远程字典服务。

内存型数据库:数据存储到内存中的,读写速度快(GB级);

支持高并发,查询11万次 / 秒,写入8万次 / 秒。

支持持久化(将数据定期存储到磁盘中);

常用于缓存,存储热点数据、临时数据;

通过加缓存,可以提高并发,减少成本。

Redis常用的数据类型:

  • 字符串
  • hash
  • 集合
  • 列表
  • 有序集合
  • 空间结构

Redis安装

1.编译安装脚本

#1.编译安装脚本
vim redis_install.sh

#内容如下:
#!/bin/bash

# 检查系统类型
if [ -f /etc/os-release ]; then
    . /etc/os-release
    OS_NAME=$NAME
    OS_VERSION=$VERSION_ID
else
    echo "无法识别操作系统"
    exit 1
fi

echo "当前操作系统: $OS_NAME $OS_VERSION"

# 根据操作系统选择安装命令
if [[ "$OS_NAME" == "Ubuntu" ]]; then
    # 更新包列表并安装依赖
    apt update
    apt -y install build-essential tcl wget

elif [[ "$OS_NAME" == "CentOS Linux" ]] || [[ "$OS_NAME" == "Red Hat" ]]; then
    yum -y install gcc gcc-c++ make tcl wget
else
    echo "不支持的操作系统"
    exit 1
fi

cd /usr/local/src

# 下载Redis源码包
if [ -f redis-6.2.14.tar.gz ]; then
    echo "redis-6.2.14.tar.gz已存在不需要下载!"
else
    # wget http://download.redis.io/releases/redis-6.2.14.tar.gz
    wget http://192.168.56.200/Software/redis-6.2.14.tar.gz
fi

# 解压源码包
tar -xvf redis-6.2.14.tar.gz

# 进入解压后的目录
cd redis-6.2.14

# Redis编译安装
make
make PREFIX=/usr/local/redis install

# Redis基础配置
mkdir -p /usr/local/redis/{etc,logs,data}
egrep -v "^$|^#" redis.conf > /usr/local/redis/etc/redis.conf

sed -i "s/bind 127.0.0.1/bind 0.0.0.0/g" /usr/local/redis/etc/redis.conf
sed -i "s/protected-mode yes/protected-mode no/g" /usr/local/redis/etc/redis.conf
sed -i "s/daemonize no/daemonize yes/g" /usr/local/redis/etc/redis.conf
sed -i "s/pidfile \/var\/run\/redis_6379.pid/pidfile \/usr\/local\/redis\/redis.pid/g" /usr/local/redis/etc/redis.conf
sed -i "s/dir \.\//dir \/usr\/local\/redis\/data/g" /usr/local/redis/etc/redis.conf
sed -i "s/logfile \"\"/logfile \"\/usr\/local\/redis\/logs\/redis.log\"/g" /usr/local/redis/etc/redis.conf

# 将配置文件复制到/etc下
mkdir -p /etc/redis/
cp /usr/local/redis/etc/redis.conf /etc/redis/

# 启动redis
/usr/local/redis/bin/redis-server /etc/redis/redis.conf

# 更新PATH环境变量
echo 'export PATH=$PATH:/usr/local/redis/bin/' >> /etc/profile
. /etc/profile

# 查看redis监听端口
echo "查看redis监听端口:"
netstat -tanp | grep redis

-----------------------------------------------------
#给脚本一个执行权限
chmod +x redis_install.sh

#执行脚本,进行安装
bash redis_install.sh

#2.编写一个Redis启动、关闭和重启的Shell脚本

vim redis.sh
#内容如下

#!/bin/bash

REDIS_PATH="/usr/local/redis"
REDIS_CONF="/etc/redis/redis.conf"
PID_FILE="$REDIS_PATH/redis.pid"

start() {
    if [ -f $PID_FILE ]; then
        echo "Redis is already running."
        exit 1
    fi

    echo "Starting Redis..."
    $REDIS_PATH/bin/redis-server $REDIS_CONF &
    echo $! > $PID_FILE
    echo "Redis started."
}

stop() {
    if [ ! -f $PID_FILE ]; then
        echo "Redis is not running."
        exit 1
    fi

    echo "Stopping Redis..."
    kill $(cat $PID_FILE)
    rm $PID_FILE
    echo "Redis stopped."
}

restart() {
    stop
    sleep 1
    start
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        restart
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
        ;;
esac
------------------------------------------------------

#给脚本一个执行权限
chmod +x redis.sh

#使用方法

/etc/init.d/redis start             # 启动Redis服务器
/etc/init.d/redis stop              # 停止Redis服务器
/etc/init.d/redis restart           # 重启Redis服务器

## 习惯上会把启动脚本放置在/etc/init.d/目录下,方便使用
cp redis.sh /etc/init.d/redis

#配置文件在 //etc/init.d/redis

#启动redis端
redis-cli

缓存失败问题:

  • 缓存击穿:一个热点的key失效,直接访问到数据库,导致数据库访问量激增。
    • 加锁,从数据库中读取数据写入缓存后,返回给用户;
    • 通过异步的⽅式不断的刷新过期时间;
  • 缓存穿透:大量用户访问不存在的数据,导致请求直接访问数据库,占用数据库大量的资源;
    • 缓存空值/默认值;
    • 布隆过滤器做一层过滤;
  • 缓存雪崩:最严重的缓存问题,缓存自身崩溃或者有大量的key都过期,后端数据库压力剧增,或直接崩溃。
    • 缓存增加备份、高可用;
    • 缓存集群;
    • 过期时间设置均匀一些;
    • 多级缓存;

Redis基础配置

配置项名称 配置项值范围 说明
daemonize yes、no yes表示启用守护进程,默认是no即不以守护进程方式运行。其中Windows系统下不支持启用守护进程方式运行
port 指定 Redis 监听端口,默认端口为 6379
bind 绑定的主机地址,如果需要设置远程访问则直接将这个属性备注下或者改为bind * 即可,这个属性和下面的protected-mode控制了是否可以远程访问
protected-mode yes 、no 保护模式,该模式控制外部网是否可以连接redis服务,默认是yes,所以默认我们外网是无法访问的,如需外网连接rendis服务则需要将此属性改为no
loglevel debug、verbose、notice、warning 日志级别,默认为 notice
databases 16 设置数据库的数量,默认的数据库是0。整个通过客户端工具可以看得到
rdbcompression yes、no 指定存储至本地数据库时是否压缩数据,默认为 yes,Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变得巨大
dbfilename dump.rdb 指定本地数据库文件名,默认值为 dump.rdb
dir 指定本地数据库存放目录
requirepass 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH命令提供密码,默认关闭
maxclients 0 设置同一时间最大客户端连接数,默认无限制,Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息
maxmemory XXX 指定 Redis 最大内存限制,Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis 新的 vm 机制,会把 Key 存放内存,Value 会存放在 swap 区。配置项值范围列里XXX为数值
#服务器端
#查看是否启动
[root@localhost redis]# ps -ef|grep redis
或
[root@localhost redis]# ./bin/redis-cli ping

#前台启动
[root@localhost redis]# ./bin/redis-server

#后台启动
#修改/usr/local/redis/etc/redis.conf文件
daemonize yes  #前台启动,改后台启动

#指定配置文件,启动
[root@localhost redis]# ./bin/redis-server ./etc/redis.conf

#关闭
[root@localhost redis]# ./bin/redis-cli shutdown


#客户端
#启动
[root@localhost redis]# ./bin/redis-cli
127.0.0.1:6379>

#关闭
方式一:指令ctrl+c
方式二:执行指令quit
方式三:执行指令exit

#设置远程访问
修改/usr/local/redis/etc/redis.conf文件
#bind 127.0.0.1  #注释掉允许本地连接
protected-mode no  #允许远程访问

Redis客户端应用

#下载地址:
(局域网)http://192.168.56.200/Software/RedisDesktopManager.exe

#安装
next -> IAgree -> 选择安装路径 -> Install -> next -> √ Finssh

Redis基础命令

1.连接命令

ping 通常用于测试与服务器的连接是否仍然生效,或者用于测量延迟值。

127.0.0.1:6379> ping
PONG

echo m 打印一个特定的信息 m ,测试时使用。

127.0.0.1:6379> echo 'hello world'
"hello world"

select i 切换到指定的数据库,数据库索引号 i 用数字值指定,以 0 作为起始索引值。默认使用 0号数据库。Redis 默认包含 16 个独立的数据库(编号 0-15)

127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> 

set 存储键值对

SET 键名(Key) 键值(Value)
127.0.0.1:6379> set a 'hello world'
OK
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> get a
(nil)

get 读取键值对

GET 键名(Key)
# 读取存在的 Key(0 号库中你存储的 a)
127.0.0.1:6379> GET a
"hello world"  # 返回存储的 Value

# 读取不存在的 Key(比如 Key = "x")
127.0.0.1:6379> GET x
(nil)  # 无此 Key,返回空

# 切换到 1 号库后读取 a(你之前的操作)
127.0.0.1:6379[1]> GET a
(nil)  # 1 号库中未存储 a,返回空

auth pword

​ 开启了密码保护,在每次连接 Redis 服务器之后,就要使用auth命令解锁,解锁之后才能使用其他 Redis 命令。密码匹配时返回 OK ,否则返回一个错误。

设置密码

127.0.0.1:6379> config set requirepass redis123456
OK   #requirepass的值就是密码
127.0.0.1:6379> quit

在次登录

[root@localhost redis]# ./src/redis-cli
127.0.0.1:6379> ping
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth redis123456
OK
127.0.0.1:6379> ping
PONG

清空密码

127.0.0.1:6379> config set requirepass “”
OK   #requirepass的值就是密码
127.0.0.1:6379> quit

quit

请求服务器关闭与当前客户端的连接。总是返回 OK (但是不会被打印显示,因为当时 Redis-cli 已经退出)。

127.0.0.1:6379[1]> quit
[root@localhost redis]# 

2.键命令

set key value

将字符串值 value关联到 key 。

127.0.0.1:6379> set key1 1  #传入的都是字符串
OK

get key

返回 key所关联的字符串值。如果 key 不存在那么返回特殊值 nil 。

127.0.0.1:6379> get key1
"1"

del key1 [key2 … keyn]

删除给定的一个或多个 key 。没有的key忽略,返回被删除 key 的数量。

127.0.0.1:6379> del key1
(integer) 1

案例:

声明key1,key2,key3,删除key1,key2,key4

127.0.0.1:6379> set key1 1
OK
127.0.0.1:6379> set key2 1
OK
127.0.0.1:6379> set key3 1
OK
127.0.0.1:6379> del key1 key2 key4
(integer) 2

exists key

检查给定 key 是否存在。若 key 存在,返回 1 ,否则返回 0 。

127.0.0.1:6379> exists key3
(integer) 1

type key

返回 key 所储存的值的类型。none (key不存在)、string (字符串)、list (列表)、set (集合)、zset (有序集)、hash (哈希表)

127.0.0.1:6379> type key1
string

expire key seconds

为给定 key 设置生存时间,以秒为单位,当 key 过期时(生存时间为 0 ),它会被自动删除。设置成功返回 1 。其他为0。

127.0.0.1:6379> expire key3 30
(integer) 1
127.0.0.1:6379> ttl key3  #查看有效时间
(integer) 24
127.0.0.1:6379> exists key3 #验证是否存在
(integer) 0

pexpire key mseconds

这个命令和 EXPIRE 命令的作用类似,但是它以毫秒为单位设置 key 的生存时间,而不像 EXPIRE 命令那样,以秒为单位。设置成功,返回 1。key不存在或设置失败,返回0

127.0.0.1:6379> set key1 abc
OK
127.0.0.1:6379> pexpire key1 10000
(integer) 1
127.0.0.1:6379> ttl key1
(integer) 5
127.0.0.1:6379> pttl key1
(integer) 746

persist key

移除给定 key 的生存时间,将这个 key 从易失的转换成持久的。当生存时间移除成功时,返回 1 .如果 key 不存在或 key 没有设置生存时间,返回 0 。

127.0.0.1:6379> set zhangwu 1
OK
127.0.0.1:6379> persist zhangwu
(integer) 0
127.0.0.1:6379> expire zhangwu 30
(integer) 1
127.0.0.1:6379> persist zhangwu
(integer) 1
127.0.0.1:6379> ttl zhangwu
(integer) -1

ttl key

以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。当 key 不存在时,返回 -2 。当 key 存在但没有设置剩余生存时间时,返回 -1 。

127.0.0.1:6379> set key1 helloworld
OK
127.0.0.1:6379> ttl key1
(integer) -1
127.0.0.1:6379> expire key1 50
(integer) 1
127.0.0.1:6379> ttl key1
(integer) 44
127.0.0.1:6379> ttl key1
(integer) -2

pttl key

这个命令类似于 TTL 命令,但它以毫秒为单位返回 key 的剩余生存时间,而不是像 TTL 命令那样,以秒为单位。当 key 不存在时,返回 -2 。当 key 存在但没有设置剩余生存时间时,返回 -1 。

127.0.0.1:6379> pttl key1
(integer) -2
127.0.0.1:6379> set key1 abc
OK
127.0.0.1:6379> pexpire key1 30000
(integer) 1
127.0.0.1:6379> pttl key1
(integer) 27345

keys pattern

查找所有符合给定模式 pattern 的 key 。符合给定模式的 key 列表。

通配符

* 表示多个字符
? 表示一个字符
[] 表示只能是[]里面的字符
\ 表示指定特殊字符
127.0.0.1:6379> mset zhangsan 1 zhangsi 2 zhangwu 3
OK
127.0.0.1:6379> keys *
1) "zhangwu"
2) "zhangsan"
3) "zhangsi"
127.0.0.1:6379> keys ng*
(empty list or set)
127.0.0.1:6379> keys *ng*
1) "zhangwu"
2) "zhangsan"
3) "zhangsi"
127.0.0.1:6379> keys zhang??
1) "zhangwu"
2) "zhangsi"
127.0.0.1:6379> keys zha[ng]si
(empty list or set)
127.0.0.1:6379> keys zhan[ng]si
1) "zhangsi"

move key db

将当前数据库的 key 移动到给定的数据库 db 当中。移动成功返回 1 ,失败则返回 0 。

127.0.0.1:6379> keys *
1) "zhangwu"
2) "zhangsan"
3) "zhangsi"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> move zhangsan 1
(integer) 1
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "zhangsan"
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> keys *
1) "zhangwu"
2) "zhangsi"

注意:

key不存在时,移动失败

key移动到1库时,1库中出现同名的key,移动失败

random key

从当前数据库中随机返回(不删除)一个 key 。当数据库不为空时,返回一个 key 。当数据库为空时,返回 nil 。

127.0.0.1:6379> randomkey
"zhangwu"
127.0.0.1:6379> randomkey
"key"
127.0.0.1:6379> randomkey
"key"
127.0.0.1:6379> randomkey
"zhangwu"

rename key newkey

将 key 改名为 newkey 。改名成功时提示 OK ,失败时候返回一个错误。

127.0.0.1:6379> rename key key1
OK
127.0.0.1:6379> keys *
1) "key1"
2) "zhangwu"
3) "zhangsi"

注意:

当 key 和 newkey 相同,或者 key 不存在时,返回一个错误。

当 newkey 已经存在时, RENAME 命令将覆盖旧值。

renamenx key newkey

当且仅当 newkey 不存在时,将 key 改名为 newkey 。修改成功时,返回 1 。如果 newkey 已经存在,返回 0 。

127.0.0.1:6379> renamenx zhangsi zhangwu
(integer) 0
127.0.0.1:6379> renamenx zhangsi zhangsan
(integer) 1
127.0.0.1:6379> keys *
1) "zhangsan"
2) "key1"
3) "zhangwu"

Redis数据类型

Redis常用的数据类型:

  • 字符串

Redis 最基础的数据类型,以 “键值对(Key-Value)” 形式存储,Value 可以是字符串、数字(整数 / 浮点数)或二进制数据(如图片),最大容量 512MB。

**核心命令**:
  • SET key value:存储键值对(覆盖旧值);
  • GET key:获取值;
  • INCR key:对数值型 Value 自增 1(如计数器);
  • APPEND key value:在原有 Value 后追加字符串。
    应用场景
  • 缓存(如用户信息、商品详情);
  • 计数器(如文章阅读量、接口调用次数);
  • 分布式锁(利用 SET key value NX EX 命令);
  • 存储二进制数据(如短链接映射、Token)
  • 哈希hash

类似 “字典” 或 “对象”,Value 是一个键值对集合(field-value),适合存储结构化数据(如用户信息、商品属性)。

  • HSET key field value:设置哈希中某个字段的值;
  • HGET key field:获取哈希中某个字段的值;
  • HGETALL key:获取哈希中所有字段和值;
  • HDEL key field:删除哈希中的某个字段。
    应用场景
  • 存储对象(如 user:1001 作为 key,name/age/email 作为 field);
  • 精简键名(避免 user:1001:name 这类冗余键);
  • 部分更新(只需修改某个字段,无需操作整个对象)。
  • 集合

无序、唯一的字符串集合(不允许重复元素),支持交集、并集、差集等集合运算。

核心命令

  • SADD key member1 member2:向集合添加元素;
  • SMEMBERS key:获取集合中所有元素;
  • SISMEMBER key member:判断元素是否在集合中;
  • SINTER key1 key2:求两个集合的交集(如共同好友);
  • SUNION key1 key2:求两个集合的并集。
    应用场景
  • 去重存储(如用户标签、商品分类);
  • 关系计算(如共同好友、粉丝交集);
  • 抽奖系统(SRANDMEMBER key 随机取元素)
  • 列表

有序、可重复的字符串列表(类似链表),支持从两端插入 / 删除元素,底层是 “双向链表” 结构,适合高频的首尾操作。

核心命令

  • LPUSH key value:从列表左侧(头部)添加元素;
  • RPUSH key value:从列表右侧(尾部)添加元素;
  • LPOP key:移除并返回列表左侧第一个元素;
  • RPOP key:移除并返回列表右侧第一个元素;
  • LRANGE key start end:获取列表中指定范围的元素(如 LRANGE list 0 9 取前 10 个)。
    应用场景
  • 消息队列(LPUSH 生产消息,RPOP 消费消息);
  • 最新列表(如 “最近浏览商品”“最新评论”,用 LPUSHLRANGE 取前 N 条);
  • 栈 / 队列模拟(LPUSH+LPOP 实现栈,LPUSH+RPOP 实现队列)。
  • 有序集合

类似 “带分数的集合”,每个元素(member)关联一个分数(score,浮点数),元素唯一,但分数可重复;集合按分数自动排序(升序 / 降序)。

核心命令

  • ZADD key score1 member1 score2 member2:添加元素及分数;
  • ZRANGE key start end [WITHSCORES]:按分数升序取指定范围的元素(带 WITHSCORES 显示分数);
  • ZREVRANGE key start end:按分数降序取元素(如排行榜);
  • ZSCORE key member:获取元素的分数;
  • ZINCRBY key increment member:给元素的分数增加指定值(如投票加 1 分)。
    应用场景
  • 排行榜(如 “游戏得分榜”“销量排行榜”,用 ZREVRANGE 取前 N 名);
  • 范围查询(如 “分数在 80-100 之间的用户”);
  • 延迟队列(用时间戳作为分数,按分数顺序消费)。
  • 空间结构

专门用于存储地理位置信息(经纬度),支持距离计算、范围查询等地理空间操作,底层基于有序集合(Sorted Set)实现。

核心命令

  • GEOADD key longitude latitude member:添加地理位置(经度、纬度、名称);
  • GEODIST key member1 member2 [unit]:计算两个位置的距离(单位:m/km/mi/ft);
  • GEORADIUS key longitude latitude radius unit:查询指定经纬度范围内的位置(如 “附近 1km 的商店”);
  • GEOPOS key member:获取位置的经纬度。
    应用场景
  • LBS 服务(如 “附近的人”“周边商家”);
  • 地理位置排序(如按距离远近展示门店);
  • 地理围栏(如 “用户进入某区域时触发通知”)。

总结

Redis 不同数据类型的核心区别在于 存储结构和适用场景

  • 简单键值用 String
  • 结构化对象用 Hash
  • 无序去重用 Set
  • 有序可重用 List
  • 带排序需求用 Sorted Set
  • 地理信息用 Geo

Redis数据持久化

数据持久化:将内存中的数据保持到磁盘中。

作用:让redis服务重启后可以恢复之前的数据。

  • Redis数据持久化的方式:
    • RDB(快照):将内存中Redis缓存的所有数据,都以二进制字符串的方式保存为一个 .rdb 文件。特点:占用存储小,当恢复所有数据时,速度快。不建议频繁生成快照。每次重启自动加载快照。
    • AOF(追加日志):将每次增、删、改的操作添加到 .aof 日志中,默认明文存储(可压缩),占据更大的存储空间,保存数据时,运行资源占用少。追加日志可以实时添加。

RDB的触发

  • 手动触发:save 【前台保存,使 Redis 处于阻塞状态】和 bgsave【后台保存,整个过程中只有在 fork() 子进程时有短暂的阻塞】
  • 自动触发:save m n 在配置文件中修改 /etc/redis/redis.conf
    • 表示的是在 m 秒内,如果有 n 个键发生改变,则自动触发持久化。
vim /etc/redis/redis.conf

#RDB持久化自动触发条件
save 900 1
save 300 10
save 60 10000
#bgsave持久化失败,是否停止持久化数据到磁盘,yes 表示停止持久化,no 表示忽略错误继续写文件
stop-writes-on-bgsave-error yes
#rdb文件是否压缩
rdbcompression yes
#写入文件和读取文件时是否开启rdb文件检查,检查是否有无损坏,如果在启动是检查发现损坏,则停止启动。
rdbchecksum yes
#rdb持久化后存放的文件名
dbfilename dump.rdb
#rdb持久化后文件的存放路径
dir ./

AOF持久化

#修改配置
#修改配置文件/usr/local/redis/redis.conf
appendonly yes #表示开启AOF持久化,默认是no表示关闭
appendfilename "appendonly.aof" #AOF持久化文件名
appendfsync everysec #缓冲同步策略,默认值
no-appendfsync-on-rewrite no  #是否重写,默认不重写

#开启之后,Redis每执行一条写命令就会将该命令写入硬盘中的AOF文件。AOF文件保存路径和RDB文件路径是一致的,都是通过dir参数配置 , 默 认文 件 名 是 : appendonly.aof
AOF重写

为什么要重写:

随着aof文件越来越大,需要定期对aof文件进行重写,达到压缩的目的。

重写方式

AOF重写过程可以手动触发和自动触发:

手动触发:直接调用bgrewriteaof命令。

#直接在命令行输入
127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started

自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。

#修改配置文件/etc/redis/redis.conf

auto-aof-rewrite-percentage 100 #AOF文件增长率(当前AOF文件大小超过上一次重写的AOF文件大小的百分之多少才会重写)
auto-aof-rewrite-min-size 64mb #表示运行AOF重写时文件最小体积,默认为64MB。

aof文件恢复

在写入aof日志文件时,如果Redis服务器宕机,则aof日志文件文件会出格式错误,在重启Redis服务器时,Redis服务器会拒绝载入这个aof文件,可以通过以下步骤修复aof并恢复数据。

备份现在aof文件,以防万一。

出现以下提示:

(https://img2024.cnblogs.com/blog/3672404/202508/3672404-20250826143358495-1372562543.png)

使用redis-check-aof命令修复aof文件,该命令格式如下:

# 修复aof日志文件
$ redis-check-aof -fix file.aof

重启Redis服务器,加载已经修复的aof文件,恢复数据。

Redis集群

  • redis 主从模式:一主一从或一主多从,自带读写分离,负载均衡。
  • redis 哨兵模式:高可用,主服务器宕机,从服务器变为主服务器。
  • redis 集群模式(分片):将数据拆分存储到多个Redis 主从集群中;从而实现高扩展。

Redis主从模式

原理:第一次同步时,使用RDB(快照),在同步时,主服务器产生的数据,会记录偏移量,在同步完成后,再进行偏移量的同步。

​ 全量复制完成后,主从节点进入增量复制阶段,此时的数据同步依赖于 “命令传播” 机制。

  • 当slave启动后,主动向master发送SYNC命令;
  • master接受到SYNC命令后在后台保存快照(RDB持久化)和缓存保存快照这段时间的命令;
  • 然后将保存的快照文件和缓存的命令发送给slave;
  • slave收到快照文件和命令后加载快照文件和缓存的执行命令;
  • 复制初始化后,master每次收到的写命令都会同步发送给slave,保证主从数据一致性;

缺点:只有主服务器能写入数据,从服务器只能读,主服务器一但宕机,导致无法写入数据。

Redis哨兵模式

  • 1.监控所有Redis 服务器,重点监控主服务器,1秒ping一次主;
  • 2.主服务器宕机主观下线,10秒后未恢复,客观下线,选举新的主服务器,根据条件(数据完整性,服务器性能);
  • 3.通知其他从服务器,主从变更,让其他从服务器连接新的主服务器;

多哨兵模式:

  • 哨兵监控主从的同时,也监控其他哨兵;
  • 当主服务器宕机,哨兵中选出一个哨兵,这个哨兵再从其他从服务器中选出新的主服务器;

Cluster模式

​ cluster可以说是sentinal和主从模式的结合体,通过=可以实现主从和master重选功能,所以如果配置两个副本三个分片的话,就需要六个Redis实例。因为Redis的数据是根据一定规则分配到cluster的不同机器的,当数据量过大时,可以新增机器进行扩容。

​ 使用集群,只要将redis配置文件中的cluster-enable配置打开即可。每个集群中至少需要3个主数据库才能正常运行,新增节点非常方便。

实验:一主两从三哨兵
  • 192.168.25.26 redis(主)
  • 192.168.25.27 redis(从)
  • 192.168.25.28 redis(从)
#1.在三台服务器上都安装好redis
#包含一件安装脚本和启动脚本

#2.修改从服务器配置文件
vim /etc/redis/redis.conf
#           主服务器ip   端口
replicaof 192.168.25.26 6379

#3.分别启动三台redis服务器
redis-cli

#4.查看主从信息
info replication

手动临时修改主从

#从服务器上输入 让当前 Redis 节点从 “从节点(slave/replica)” 变为 “主节点(master)
slaveof no one

#从服务器切换主节点   
#        新主服务器ip   端口
slaveof 192.168.25.27 6379
配置哨兵
#在主服务器上先配置哨兵配置文件
#1.把模板复制出来
#复制或替换 sentinel.conf
grep -Ev "^$|^#" /usr/local/src/redis-6.2.14/sentinel.conf > /etc/redis/sentinel.conf

#修改配置文件 /etc/redis/sentinel.conf
-------------------------------------------------------
#指定哨兵进程的 PID 文件路径,用于记录哨兵进程的 ID,方便管理
pidfile "/var/run/redis-sentinel.pid"
#设置哨兵的日志文件路径
logfile "/usr/local/redis/logs/sentinel.log"
#指定哨兵的工作目录,用于存储临时文件
dir "/usr/local/redis/data"
# 两个哨兵主观下线,才能客观下线 
#单哨兵后面数字是1,三哨兵后面数字是2,哨兵数量是单数  
sentinel monitor mymaster 192.168.8.11 6379 2
#“主观下线” 的判断时间 10秒
sentinel down-after-milliseconds mymaster 10000
#故障转移的超时时间 15秒
sentinel failover-timeout mymaster 15000

--------------------------------------------------------

#2.把修改后的哨兵配置文件发给从服务器
scp /etc/redis/sentinel.conf root@192.168.25.27://etc/redis/sentinel.conf
scp /etc/redis/sentinel.conf root@192.168.25.28://etc/redis/sentinel.conf

#3.重新启动服务器上的redis
/etc/init.d/redis restart

#再启动哨兵日志
redis-sentinel /etc/redis/sentinel.conf

#主服务器上查看哨兵日志 是否有误
 cd /usr/local/redis/logs
#实时监控 日志
tail -f sentinel.log

#4.进行测哨兵
#手动关闭主服务器,查看是否会切换

搭建集群

单机搭建集群

#集群搭建:至少要三个master 三对主从
#1.创建一个文件夹redis-cluster,然后在其下面分别创建6个文件夹

[root@zuolaoshi /]# cd /usr/local/redis
[root@zuolaoshi redis]# mkdir redis-cluster
[root@zuolaoshi redis]# cd redis-cluster/
[root@zuolaoshi redis-cluster]# mkdir 7001
[root@zuolaoshi redis-cluster]# mkdir 7002
[root@zuolaoshi redis-cluster]# mkdir 7003
[root@zuolaoshi redis-cluster]# mkdir 7004
[root@zuolaoshi redis-cluster]# mkdir 7005
[root@zuolaoshi redis-cluster]# mkdir 7006

#把之前的redis.conf配置文件分别copy到700*下

[root@zuolaoshi redis]# cp ./etc/redis.conf ./redis-cluster/7001/redis.conf
[root@zuolaoshi redis]# cp ./etc/redis.conf ./redis-cluster/7002/redis.conf
[root@zuolaoshi redis]# cp ./etc/redis.conf ./redis-cluster/7003/redis.conf
[root@zuolaoshi redis]# cp ./etc/redis.conf ./redis-cluster/7004/redis.conf
[root@zuolaoshi redis]# cp ./etc/redis.conf ./redis-cluster/7005/redis.conf
[root@zuolaoshi redis]# cp ./etc/redis.conf ./redis-cluster/7006/redis.conf
------------------------------------------------------
#2. Redis 5.0 及以上版本:无需依赖 Ruby,直接用 redis-cli --cluster 管理集群  可直接跳过这一步
#查看redis版本
redis-server --version

#5.0 以下旧版本:必须安装 Ruby 及 redis gem
# CentOS7
yum install ruby
yum install rubygems
gem install redis   #(安装redis和ruby的接口)
---------------------------------------------------------
#3.修改每个节点的配置文件
[root@zuolaoshi redis]# vim ./redis-cluster/7001/redis.conf
#需要修改的配置
daemonize yes
port 700* #(分别对每个机器的端口号进行设置)
bind 192.168.25.26 #(必须要绑定当前机器的ip,不然会无限悲剧下去哇..深坑勿入!!!)
dir /usr/local/redis-cluster/700*/ #(指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据,深坑勿入!!!)
pidfile /usr/local/redis/redis_700*.pid
appendonly yes
cluster-enabled yes  #(启动集群模式,开始玩耍)
cluster-config-file nodes700*.conf#(这里700x最好和port对应上)
cluster-node-timeout 5000  #redis节点宕机被发现的时间 
--------------------------------------------------------
#配置文件写好后需要手动创建没有的目录dir /usr/local/redis-cluster/700*/
cd /usr/local
mkdir redis-cluster
cd redis-cluster
mkdir 7001-6

#4.启动redis服务
[root@zuolaoshi redis]# ./bin/redis-server ./redis-cluster/7001/redis.conf
[root@zuolaoshi redis]# ./bin/redis-server ./redis-cluster/7002/redis.conf
[root@zuolaoshi redis]# ./bin/redis-server ./redis-cluster/7003/redis.conf
[root@zuolaoshi redis]# ./bin/redis-server ./redis-cluster/7004/redis.conf
[root@zuolaoshi redis]# ./bin/redis-server ./redis-cluster/7005/redis.conf
[root@zuolaoshi redis]# ./bin/redis-server ./redis-cluster/7006/redis.conf
---------------------------------------------------------
#5.创建集群
#执行redis-cli --cluster create命令

[root@zuolaoshi redis]# ./bin/redis-cli --cluster create 192.168.25.26:7001 192.168.25.26:7002 192.168.25.26:7003 192.168.25.26:7004 192.168.25.26:7005 192.168.25.26:7006 --cluster-replicas 1

#说明
#create
#表示创建一个redis集群。
#--cluster-replicas 1
#表示为集群中的每一个主节点指定一个从节点,即一比一的复制。

image20200311021844778.png

#6.集群搭建完成后,查看redis服务状态

[root@zuolaoshi redis]# ps -ef|grep redis
---------------------------------------------------------
#7.进入一个节点
[root@zuolaoshi redis]# ./bin/redis-cli -c -h 192.168.25.26 -p 7001
192.168.25.26:7001> info cluster
# Cluster
cluster_enabled:1 #节点是否为cluster模式 。1是0否
---------------------------------------------------------
#8.进行测试集群功能是否成功
[root@zuolaoshi redis]# ./bin/redis-cli -c -h 192.168.25.26 -p 7005
192.168.25.26:7005> set b fdfsfsd
-> Redirected to slot [3300] located at 192.168.25.26:7001
OK
192.168.25.26:7001> get b
"fdfsfsd"
192.168.25.26:7001> set c fdsfdfdsfds
-> Redirected to slot [7365] located at 192.168.25.26:7002
OK
192.168.25.26:7002> get c
"fdsfdfdsfds"
192.168.25.26:7002> set x fdsfdsfsdf
-> Redirected to slot [16287] located at 192.168.25.26:7003
OK
192.168.25.26:7003> keys *
1) "x"
2) "a"
192.168.25.26:7003> get b
-> Redirected to slot [3300] located at 192.168.25.26:7001
"fdfsfsd"
192.168.25.26:7001> keys *
1) "b"
192.168.25.26:7001> set d fdsfdsfsd
-> Redirected to slot [11298] located at 192.168.25.26:7003
OK
192.168.25.26:7003> get d
"fdsfdsfsd"
192.168.25.26:7003> set x zhangsan
OK
192.168.25.26:7003> get x
"zhangsan"

添加新的主节点

#将7007设置为7006的主节点
#保证7007服务是启动的

[root@zuolaoshi redis]# ./bin/redis-cli --cluster add-node 192.168.1.121:7007 192.168.1.121:7006

#查看节点信息,未分配槽位不能存储数据

[root@zuolaoshi redis]# ./bin/redis-cli -c -h 192.168.1.121 -p 7005
192.168.1.121:7005> cluster nodes

#如果有未分配槽位的主节点,则重新分配槽位

[root@zuolaoshi redis]# ./bin/redis-cli --cluster reshard 192.168.1.121:7007

#查看节点信息
[root@zuolaoshi redis]# ./bin/redis-cli -c -h 192.168.1.121 -p 7005
192.168.1.121:7005> cluster nodes

给主节点加从节点

#准备一个新的Redis,7008

[root@zuolaoshi redis]#cd redis-cluster/
[root@zuolaoshi redis-cluster]# ls
7001  7002  7003  7004  7005  7006  7007
[root@zuolaoshi redis-cluster]# mkdir 7008
[root@zuolaoshi redis-cluster]# cp ./7007/redis.conf ./7008/redis.conf
[root@zuolaoshi redis-cluster]# vim ./7008/redis.conf
[root@zuolaoshi redis-cluster]# cd ..
[root@zuolaoshi redis]# ./bin/redis-server ./redis-cluster/7008/redis.conf 
[root@zuolaoshi local]#cd redis-cluster
[root@zuolaoshi redis-cluster]# mkdir 7008

#为7007添加从节点7008
[root@zuolaoshi redis]# ./bin/redis-cli --cluster add-node 192.168.1.121:7008 192.168.1.121:7007 --cluster-slave

#查看节点信息
[root@zuolaoshi redis]# ./bin/redis-cli -c -h 192.168.1.121 -p 7005
192.168.1.121:7005> cluster nodes

删除节点

#删除从节点

[root@zuolaoshi redis]# ./bin/redis-cli --cluster del-node 192.168.1.121:7008 8e52c94dafa72df26b1eddf94363a4780bed9339
>>> Removing node 8e52c94dafa72df26b1eddf94363a4780bed9339 from cluster 192.168.1.121:7008
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

#移动数据将7007移动到7001节点
[root@zuolaoshi redis]# ./bin/redis-cli --cluster reshard 192.168.1.121:7007

#查看节点信息
[root@zuolaoshi redis]# ./bin/redis-cli -c -h 192.168.1.121 -p 7005
192.168.1.121:7005> cluster nodes

#删除主节点

[root@zuolaoshi redis]# ./bin/redis-cli --cluster del-node 192.168.1.121:7007 d7a3e48cd142dce6566023fce21e31669e9fa3d5
>>> Removing node d7a3e48cd142dce6566023fce21e31669e9fa3d5 from cluster 192.168.1.121:7007
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

#查看节点信息
[root@zuolaoshi redis]# ./bin/redis-cli -c -h 192.168.1.121 -p 7005
192.168.1.121:7005> cluster nodes
posted @ 2025-08-26 12:08  落无一  阅读(17)  评论(0)    收藏  举报