Redis 认识
redis 开源 c语言编写 支持网络 基于内存也可以持久化的日志型 k-v Nosql数据库
多用作缓存 消息中间件
支持多种数据结构 字符串(string) 哈希(hashe) 列表(list) 集合(set) 有序集合(zset)
内置了复制 LUA脚本 LRU驱动事件 事务 和不同级别的磁盘持久化
可通过redis哨兵和自动分区 提供高可用性
redis性能主要决定于内存和网络带宽
Redis 安装
# windows(redis3.2)
下载地址:https://github.com/microsoftarchive/redis/releases/download/win-3.2.100/Redis-x64-3.2.100.msi
# 直接下载压缩包
https://github.com/microsoftarchive/redis/releases/download/win-3.2.100/Redis-x64-3.2.100.zip
# 常规文件
redis-server:服务端
redis-cli:客户端
redis-check-dump: rdb文件修复工具
redis-check-aof: aof文件修复工具
redis.window.conf: redis常规配置文件
redis.windows-service.conf: redis系统服务配置文件
# 配置系统环境变量path= xx/redis路径
# 测试
redis-server -v
redis-cli -v
# window-GUI/ redis-desktop-manager
下载地址:https://wws.lanzous.com/iSan7hgo4xe
# linux
wget https://download.redis.io/releases/redis-6.0.9.tar.gz
tar xzvf redis-6.0.9.tar.gz
cd redis-6.0.9.tar.gz
make test # 测试编译是否有问题
make install
# 可能出现的问题:
# fatal error: sys/types.h
sudo apt-get install libc6-dev
# fatal error:jemalloc/jemalloc.h
sduo make MALLOC=libc
# ubuntu
sudo apt update
sudo apt install redis-server
# 卸载redis
sudo apt-get purge --auto-remove redis-server
Redis 配置
# linux-ubuntu
sudo vi /etc/redis/redis.conf
-------------------------------------------
daemonize yes # 开启后台运行
bind # 绑定的ip 允许远程访问
supervised systemd # 修改信息|vi通过/搜索supervised no
dbfilename dump.rdb # 数据文件
dir /var/lib/redis # 数据文件存储路径
logfile /var/log/redis/redis-server.log # 日志文件
database 16 # 数据库数量
-------------------------------------------
# 服务端
sudo service redis start # 启动服务
sudo service redis restart # 重启服务
sudo systemctl status redis || sudo service redis-server status # 查看redis状态
dpkg -l | grep redis # 查看redis安装的包
# 客户端
$redis-cli
redis>info # 查看redis所有信息[server client memory cpu ...]
redis>ping # 运行测试
redis>select 数据库(0~15) # 切换数据库
redis>auth psw # 校验密码
redis>quit # 退出
Redis常用命令
# 版本
redis-cli -v # 客户端
redis-server -v # 服务端
# 连接
redis-cli # 本地
redis-cli -h host -p port -a password # 远程
# 数据库
select 0~15 # 切换数据库
flushdb # 清空当前数据库
flushall # 清空所有数据库
# 通用键操作
keys * # 当前数据库所有键
dbsize # 当前数据库所有键总数
exists key # 是否存在key
del key # 删除特定key
expire key 1 # 设置key有效期[s]
ttl key # 查看key有效期时长[s](-1:没有设置过期时间; -2:不存在)
rename key newkey_name # 重命名key
type key # key的类型
# 数据备份|恢复(可通过修改配置文件更改备份目录 备份文件名)
redis>config get dir # 获取备份的目录
redis>config get dbfilename # 获取备份文件名[默认dump.rdbf]
redis>save # 数据备份(阻塞)
redis>bgsave # 数据备份(后台)
# 通过复制备份文件到备份目录
# 重启redis服务恢复数据
Redis 数据类型
string(二进制安全字符串 可存储字符串 图片 视频等类型 最大支持512M)
set k v: set class c1 # 添加key
get k: get class # 获取key值
mset k1 v1 k2 v2: mset name fsh age 223 job python # 添加多个key
mget k1 k2: mget name age job # 获取多个key值
append k v: append class 2 # 追加拼接key的值
strlen k: strlen class # 获取key值长度
incr k: incr age # 增值+1 针对integer整形
incrby k number: incrby age 25 # 增加特定值 针对integer
decr/decrby k number # 减少k值
hash(map(file:value)-file&&value都是字符串类型)
hset k f v: hset city province shanghai # 添加key
hsetnx k f v: hsetnx class cls_teacher libai # 添加key对应新的f v
hget k f: hget city province # 获取key对应的f值
hmset k f1 v1 f2 v2: hmset class cls_name c1 cls_no 1 cls_stus 65 # 添加key对应的多个f v
hmget k f1 f2: hmget class cls_name cls_no cls_stus # 获取k对应的多个f v
hlen k: hlen class # key对应的f个数
hgetall k: hgetall class # 获取key对应的所有f v
hkeys k: hkeys class # 获取key对应的所有f
hvals k: hvals class # 获取可以对应的所有v
hexists k f: hexists class cls_no # 判断k对应的f是否存在
hdel k f1 f2: hdel class cls_teacher # 删除key对应的f1 f2
list(一个插入顺序排序的字符串元素集合 基于双链表实现)
lpush k v1 v2: lpush class c3 c4 # 从左添加
rpush k v1 v2: rpush class c1 c2 # 从右添加
linsert k before|after w_v v: linsert class before c4 c99 # 往指定w_v 前|后添加
lrange k start stop: larnge class 0 -1 # 从左查询所有v
lindex class index_n: lindex class 1 # 获取指定index对应的v
lset k index_n v: lset class 0 c100 # 修改指定indx对应的v
lpop k: lpop class # 删除获取最左边的v
rpop k: rpopp class # 删除获取最右边的v
lrem k v_count v: lrem class 3 c1 # 删除指定个数的v[0:所有v; >0从左到右删除指定个数v; <0:从右往左删除指定个数v]
ltrim k start stop: ltrim class 2 4 # 截取指定区间的数据 其他部分删除
llen k: llen class # 输出k长度
set(无顺序集合 集合元素没有顺序且唯一)
sadd k v1 v2: sadd m 1 5 10 20 # 添加集合元素
scard k: scard m # 获取集合元素总数
smembers k: smembers m2 # 获取集合所有元素
sdiff k1 k2: sdiff m m2 # 获取集合1与集合2的差集
sinter k1 k2: sinter m m2 # 获取集合1与集合2的交集
sunion k1 k2: sunion m m2 # 获取集合1与集合2的并集
sunionstore dest_k k1 k2: sunionstore m3 m m2 # 集合k1与k2的并集元素存储覆盖dest_k集合
smove source_k dest_k v: smove m2 m 23 # 把集合source_k的23移动到dest_k集合
spop k: spop m2 # 随机删除集合中一个值
srem k v1 v2: srem m 1 5 # 删除特定集合的值
sismember k v: sismember m2 5 # 判断v是否是k的元素
zset(有序集合 每个元素关联一个double类型的分数权值 通过权值为集合中成员进行从小到大排序)
zadd set_name v1 k1 v2 k2: zadd num 60 chinese 70 english # 添加数据
zrange set_name start stop: zrange num 0 -1 # 查看集合所有k
zrange set_name start stop withscores: zrange num 0 -1 withscore # 查看集合所有k-v
zcard set_name: zcard num # 输出k个数
zscore set_name k: zscore num chinese # 输出指定k的值
zrank set_name k: zrank num math # 输出指定k的下标
zcount set_name min max: zcount num 70 80 # 输出set_name集合v值在min-max个数
zrem set_name k: zrem num chinese # 删除指定k

事务
# 事务
watch key # 监控特定键值 unwatch
multi # 开启事务
exec # 事务提交
discard # 事务回滚
# 实质:multi开启事务后 操作指令被redis记录在队列queued中 等待exec命令一起执行|discard回滚命令
# watch监控的key 实际是redis使用多线程CAS(比较+交换)执行->乐观锁原理 key不变exec执行所有事务队列中的命令 否则回滚


发布订阅
pub/sub 是一种消息通讯模式
pub发送消息 sub接收消息 channel:渠道匹配消息
redis客户端可以订阅任意数量的频道
命令:publish/subscribe/psubscribe/unsub

Python-Redis
#$pip install redis
import redis
# 创建redis连接
r = redis.StrictRedis(host='localhost', port=6379, db=0)
# string操作
r.set('key', 'value')
print(r.get('key'))
import redis
# 创建redis的连接池
Pool = redis.ConnectionPool(host='127.0.0.1', port=6379, max_connections=10)
# 获取一个redis连接
conn = redis.Redis(connection_pool=Pool, decode_responses=True)
# 添加数据
conn.set('key', 'value')
# 获取数据
print(conn)
print(conn.get('key').decode())

Redis 持久化
RDB
redis内存中的数据生成快照定时备份到磁盘特定文件 文件后缀为rdb
实际是调用fork进程 将数据写入临时快照文件 写入成功后替换之前的文件 可再进行二进制压缩(LZF算法压缩 耗时但减少了文件大小[实质支队字符串达到20字节的数据压缩并非对文件本身])存储并删除原文件
# 自动开启(修改配置文件)
-----------redis.conf
# redis-rdb持久化配置(在限定时间内key发生变化 则进行持久化存储)
# after 900 sec (15 min) if at least 1 key changed
# after 300 sec (5 min) if at least 10 keys changed
# after 60 sec if at least 10000 keys changed
save 900 1
save 300 10
save 60 10000
# 持久化的文件名
# The filename where to dump the DB
dbfilename dump.rdb
# rdb持久化出现错误 是否继续
stop-writes-on-bgsave-error yes
# rdb文本是否进行LZF压缩
rdbcompression yes
# 是否检验rdb文本
rdbchecksum yes
# 持久化的文件目录
# The working directory.
# Note that you must specify a directory here, not a file name.
dir ./
# 手动开启(使用命令)
# 阻塞redis主进程 客户端无法连接redis 直到将所有数据快照以rdb文件形式保存到磁盘
redis>save
# 创建子进程负责数据保存到磁盘 主进程管理客户端请求 不影响其他redis请求
redis>bgsave
# 动态修改rdb存储路径
redis>config set dir dir_name
# 动态修改rdb文件名
redis>config set dbfilename file_name
# 动态开启|关闭rdb文件默认压缩方式(LZF)
redis>config set rdbcompression no
# 动态开启rdb文件校验(写入&读取文件机型数据检测是否异常)
redis> config set rdbchecksum yes
# 动态开启bgsave恢复数据写入磁盘时 对磁盘的检测机制
stop-writes-on-bgsave-error yes
# ps:默认不同数据库key修改符合rdb持久化操作时 dump.rdb会相互覆盖 只执行最后一次文件覆盖的数据恢复|备份
# 数据恢复-将dump.rdb 放置到redis备份目录(config get dir) 重启redis服务
# 自动触发rdb快照机制:
1.主从复制场景 从节点执行全量复制 主机点会执行bgsave 并将rdb文件发送到从节点
2.redis执行shutdown操作 自动执行rdb持久化
3.flushall操作
4.满足save策略 save m n
# 默认aof优先级高于rdb 且只有aof关闭 redis才会检测rdb文件
rdb快照持久化原理:
1. serverCron函数->周期性运行函数 检查是否满足save m n 配置条件 执行bgsave
2. dirty计数器->记录上次bgsave/save后 redis数据状态进行的修改(增删改) 记录结束后 重置为0
3. lastsave事件戳->记录上次成功执行bgsave/save时间 当前时间-lastsave > m 执行bgsave

AOF
redis以日志形式记录数据操作 只记录写入 删除 且记录为追加不可修改 类似MySQL binlog 也是为了弥补rdb恢复可能导致的数据不一致 优先级高于rdb
aof备份过程
1.redis命令发送到aof程序
2.aof程序将命令内容追加到服务器的aof缓存
3.aof缓存的内容写入到aof文件末尾 满足aof保存条件 则写入内容到磁盘
aof持久化策略
1.appendfsync no[不保存]: redis关闭 aof关闭 系统写缓存刷新
2.appendfsync everysec[每秒保存]
3.appendfsync always[每个命令保存]: save write
# -------------redis.conf
# AOF and RDB persistence can be enabled at the same time without problems.
# 开启aof
appendonly yes
# 指定aof文件
# The name of the append only file (default: "appendonly.aof")
appendfilename appendonly.aof
# Redis supports three different modes:
# appendfsync always # 每次写入都执行fsync 保证数据同步到磁盘
appendfsync everysec
# appendfsync no
# 重写aof过程中新写入日志的处理策略
# aof重写过程 fsync会造成阻塞 选择no 保证了数据完整同步 但会延长阻塞 yes表示重写期间的新写入操作不进行fsync 暂存内存 直到重写完毕后再写入
no-appendfsync-no-rewrite no
# aof自动重写策略 当前aof文件大小超过上一次重写的aof文件大小的多少占比进行重写
auto-aof-rewrite-percentage 50 # 一倍
# 设置重写的最小aof文件大小
auto-aof-rewrite-min-size 18mb
# 指定备份文件rdb&aof&数据库数据的路径
dir ./
# 实际aof持久化操作
# 开启aof持久化
appendonly yes # 开启持久化
appendfilename 'appendonly.aof' # 保存记录的文件
appendfsync everysec # 持久化策略
no-appendfsync-on-rewrite no # 重写aof过程中新写入日志的处理策略
# 关闭服务
redis>shutdown
# 检测aof文本有效性
redis-check-aof appendonly.aof
# 修复aof文本
redis-check-aof --fix appendonly.aof
# 重启服务
redis-server xx/redis.conf
----redis-aof/
--------redis.conf
--------data/
# ----redis.conf
port 16379
dir /redis/data
logfile /redis/log/redis.log
# 不使用rdb
save ""
# 开启aof
appendonly yes
appendfilename "redis.aof"
appendfsync everysec
daemonize yes
# ----shell
docker run -itd --name redis-aof -p 16379:16379 -v C:/Users/FSH/Desktop/redis/redis-aof/redis.conf:/redis/conf/redis.conf -v C:/Users/FSH/Desktop/redis/redis-aof/data:/redis/data redis:latest
docker exec -it redis-aof bash
>redis-server /redis/conf/redis.conf
# 已挂载宿主机目录修改aof文本最后的flushdb指定后校验aof文本后重启服务恢复数据

Redis主从
主从
redis主从服务
是由一台master(主要进行写入数据操作)和多台slave(读数据 可设置为只读模式slave-read-only=yes)构成 同时保证数据复制的单向性
作用:
1.读写分离 提高了读写负载能力
2.故障宕机数据恢复
3.高可用->保证redis服务使用
依赖:
redis的持久化功能aof rdb redis-replication
# 问题:redis重启 宕机导致数据丢失 通过持久化功能 主从可以同步数据 避免丢失数据(少量丢失) 单节点redis服务可用性不高 主服务宕机 需要手动切换从服务为主服务
# 方式
1.slaveof masterip masterport
2.redis-server -slaveof masterip masterport
3.vim redis.conf
slave of masterip masterport
# 主从连接流程
1.slave:slaveof masterip masterport 保存master信息 并发送ping周期性命令
2.master:身份鉴权 保存slave端口信息
实例
### 主从连接相关流程
# 启动redis服务
redis-server ./redis-master.conf
redis-server ./redis-slave.conf
# 主从建立socket连接
# 方式一
redis-slave>slaveof masterip masterport
redis>info replication # 查看信息
# 方式二
redis-server ./redis-slave.conf --slaveof masterip masterport
# 方式三
vim redis-slave.conf
slaveof masterip masterport
redis-server ./redis-slave.conf # 启动slave服务
redis-cli -p slaveport # 启动slave客户端
### 主从断连
redis-slave>slaveof no one
###主从鉴权访问
redis-master>requirepass password
redis-master>config set requirepass new_password
redis-master>config get requirepass
redis-slave>auth password
redis-slave>masterauth password
redis-server -a password -p slaveport # 启动从服务器需要携带密码校验
###数据同步
1.全量复制
初始化主从的数据都是全量复制
slave发送数据同步指令 master执行bgsave生成rdb文件并发送给slave
slave接收rdb文件 清空数据并执行rdb文件恢复数据
ps:数据同步时需注意复制缓冲区[FIFO队列 存储服务器执行的命令]的大小且可设置
repl-backlog-size 1mb
2.增量复制(部分复制)
执行于全量复制后
ps:避免数据不同步和服务响应阻塞 可以关闭对外服务操作
slave-server-stale-data yes|no
----redis-master-slave
--------redis-master.conf
--------redis-slave.conf
# -----redis-master.conf
port 16379
dbfilename dump_master.rdb
logfile "redi_master.log"
daemonize yes
requirepass master
# -----redis-slave.conf
# 端口
port 16380
# 持久化快照数据文件名
dbfilename dump_slave.rdb
# 日志目录
logfile "redis_slave.log"
# 主服务的IP和端口 当前实例成为(ip&port的副本)
slaveof 172.17.0.2 16379 # docker inspect redis-master
# 是否后台运行
daemonize yes
# 默认从服务只有只读权限
# slave-read-only yes
# 登录客户端密码
requirepass slave
# 从服务访问主服务密码
masterauth master
# 启动redis服务(详细步骤)
docker run -itd --name redis-master -p 16379:16379 -v C:\\Users\\FSH\\Desktop\\redis\\redis-master-slave\\redis-master.conf:/redis/redis.conf -w /redis redis:latest
docker run -itd --name redis-slave -p 16380:16380 -v C:\\Users\\FSH\\Desktop\\redis\\redis-master-slave\\redis-slave.conf:/redis/redis.conf -w /redis redis:latest
docker exec -it redis-master bash
>redis-server redis.conf
docker exec -it redis-slave bash
>redis-server redis.conf


Redis 哨兵机制
哨兵
sentinel(哨兵)作用:
1. 监控:主数据库与从数据库运行状况
2. 故障转移:redis集群出现故障 自动进行故障转移
3. 通知: 检测到redis实例问题 通过api通知用户
4. 提供配置: 用户可通过命令查看 redis集群相关信息
集群角色:
· 1.master 源数据存储
2.slave 数据复制同步
3.sentinel 监听管理master/slave
备注:
哨兵以独立的进程运行 基于主从模式 通过发送命令 等待redis集群内部服务的响应 达到监控redis服务是否正常效果
流程:
1. 哨兵发送命令 监听redis(主|从)服务的运行情况
2. 哨兵检测到主服务宕机 自动切换从服务到主服务 通过sub/pub模式通知其他从服务 修改配置文件 连接新主服务
----流程转载于https://zhuanlan.zhihu.com/p/145186839
启动:
---sentinel.conf
sentinel monitor redis-master 172.17.0.2 16379 1
$ redis-sentinel sentinel.conf
官方推荐:
一主二从三哨兵
实例
# 配置主从模型
vim sentinel.conf # 创建哨兵配置文件
sentinel monitor [master_name] [master_ip] [master_port] sentinel_number # 监听的服务器信息
redis-sentinel ./sentinel.conf # 启动哨兵进程
ps:
sentinel_number: 用于master节点故障判定的基准数 表示哨兵监控master节点出现异常投出的票数
# 目录结构
----redis-sentinel
--------master.conf
--------slave1.conf
--------slave2.conf
--------sentinel1.conf
--------sentinel2.conf
--------sentinel3.conf
# 文本内容
----master.conf
port 16379
dir /redis/data
logfile /redis/log/master.log
daemonize yes
----slave.conf
port 16380
dir /redis/data
logfile /redis/log/slave1.log
replicaof 172.17.0.2 16379
daemonize yes
----sentinel.conf
port 26379
sentinel monitor sm 172.17.0.2 16379 1
logfile "sentinel1.log"
dir "/redis/log"
daemonize yes
# 启动命令
1. 配置主从
docker run -itd --name master -v C:/Users/FSH/Desktop/redis/redis-sentinel/master.conf:/redis/conf/redis.conf -v C:/Users/FSH/Desktop/redis/redis-sentinel/log/master.log:/redis/log/master.log -p 16379:16379 redis:latest bash
docker run -itd --name slave1 -v C:/Users/FSH/Desktop/redis/redis-sentinel/slave1.conf:/redis/conf/redis.conf -v C:/Users/FSH/Desktop/redis/redis-sentinel/log/slave1.log:/redis/log/slave1.log -p 16380:16380 redis:latest bash
docker run -itd --name slave2 -v C:/Users/FSH/Desktop/redis/redis-sentinel/slave2.conf:/redis/conf/redis.conf -v C:/Users/FSH/Desktop/redis/redis-sentinel/log/slave2.log:/redis/log/slave2.log -p 16381:16381 redis:latest bash
2. 启动哨兵进程
docker run -itd --name sn1 -v C:/Users/FSH/Desktop/redis/redis-sentinel/sentinel1.conf:/redis/sn.conf -v C:/Users/FSH/Desktop/redis/redis-sentinel/log/sentinel1.log:/redis/log/sentinel1.log --link master:master -p 26379:26379 redis:latest bash
docker run -itd --name sn2 -v C:/Users/FSH/Desktop/redis/redis-sentinel/sentinel2.conf:/redis/sn.conf -v C:/Users/FSH/Desktop/redis/redis-sentinel/log/sentinel2.log:/redis/log/sentinel2.log --link master:master -p 26380:26380 redis:latest bash
docker run -itd --name sn3 -v C:/Users/FSH/Desktop/redis/redis-sentinel/sentinel3.conf:/redis/sn.conf -v C:/Users/FSH/Desktop/redis/redis-sentinel/log/sentinel3.log:/redis/log/sentinel3.log --link master:master -p 26381:26381 redis:latest bash
3. 模拟master 宕机
docker stop master
4. 查看哨兵机制(宿主机与容器日志目录已挂载)
备注:
哨兵服务可与redis服务一起启动
docker run -itd --name master -p 16379:16379 -p 26379:26379 redis:latest bash
docker exec -it master bash
> redis-server redis.conf
> redis-sentinel sentinel1.conf



Redis 集群
集群
Redis Cluster是一种服务器 Sharding 技术 3.0版本开始正式提供
Redis 的哨兵模式基本上实现了高可用 读写分离 但是在这种模式下每台 Redis 服务器都存储相同的数据 浪费内存 redis3.0加入 Cluster 集群模式 实现了 Redis 的分布式存储 也就是说每台 Redis 节点上存储不同的内容
所有redis节点采用[ping-pong]机制互联
节点的失败是通过判断是否集群中有超过半数的对此节点检测失败进行的
官方推荐搭建环境使用三主三从
---详见于https://zhuanlan.zhihu.com/p/145186839
----redis.conf 集群配置部分
# 是否开启集群 默认no
cluster-enabled yes
# 指定节点集群配置文件名 持久化保存集群信息 配置文件由redis实例生成
cluster-config-file node_xxx.conf
# 集群节点互连超时阙值(ms)
cluster-node-timeout 1000
# 进行故障迁移 更换主从时 判断slave节点与master节点断连时长
cluster-replica-validity-factor 5
# 进行故障迁移 更换主从时 只有slave值大于该值才会进行主从更换
cluster-migration-barrier 2
# 是否保证集群所有slot由节点负责
cluster-require-full-coverage yes
----启动&搭建集群
redis-cli --cluster create host_ip:port1 host_ip:port2 host_ip:port3 ... --cluster-replicas 2
ps:
--cluster-replicas
主从数量占比(master:slave=1:2)
为0则表示所有节点均为master节点
slave数量比例不足则直接异常创建集群失败
----集群节点数据操作
redis-cli -p [node_port] -c
>cluster nodes # 查看集群节点信息
实例
# 目录结果
----redis-cluster
--------rc_9001.conf
--------rc_9002.conf
--------rc_9003.conf
--------rc_9004.conf
--------rc_9005.conf
--------rc_9006.conf
# 配置文件
----rc.conf
port 9001
cluster-enabled yes
cluster-config-file n_9001.conf
cluster-node-timeout 5000
dir "/redis"
logfile "redis.log"
appendonly yes
appendfsync everysec
daemonize yes
# 启动服务(细化流程)
docker network create vm-net
docker run -itd --name rc1 -w /redis --net vm-net -p 9001:9001 -v C:/Users/FSH/Desktop/redis/redis-cluster/rc_9001.conf:/redis/redis.conf redis:latest bash
docker run -itd --name rc2 -w /redis --net vm-net -p 9002:9002 -v C:/Users/FSH/Desktop/redis/redis-cluster/rc_9002.conf:/redis/redis.conf redis:latest bash
docker run -itd --name rc3 -w /redis --net vm-net -p 9003:9003 -v C:/Users/FSH/Desktop/redis/redis-cluster/rc_9003.conf:/redis/redis.conf redis:latest bash
docker run -itd --name rc4 -w /redis --net vm-net -p 9004:9004 -v C:/Users/FSH/Desktop/redis/redis-cluster/rc_9004.conf:/redis/redis.conf redis:latest bash
docker run -itd --name rc5 -w /redis --net vm-net -p 9005:9005 -v C:/Users/FSH/Desktop/redis/redis-cluster/rc_9005.conf:/redis/redis.conf redis:latest bash
docker run -itd --name rc6 -w /redis --net vm-net -p 9006:9006 -v C:/Users/FSH/Desktop/redis/redis-cluster/rc_9006.conf:/redis/redis.conf redis:latest bash
docker exec -it rc1 redis-server redis.conf # rc2类同
ps:可优化流程-使用宿主机网络
docker create --name rc1 --port 9001 --cluster-enabled yes --cluster-config-file n_9001.conf --net host redis:latest
docker start rc1
>redis-cli --cluster create 宿主机IP:9001 宿主机IP:9002 ... --cluster-replicas 1
# 创建集群
docker exec -it rc1 bash
redis-cli --cluster create 172.19.0.2:9001 172.19.0.3:9002 172.19.0.4:9003 172.19.0.5:9004 172.19.0.6:9005 172.19.0.7:9006 --cluster-replicas 1
# 查看集群信息
172.19.0.2:9001>cluster nodes
# 校验-数据分布式存储到不同节点
root@cfb9d4dedb13:/redis# redis-cli -c -p 9001
127.0.0.1:9001> set name fsh
-> Redirected to slot [5798] located at 172.19.0.3:9002
OK
172.19.0.3:9002> get name
"fsh"
172.19.0.3:9002> set level p11
-> Redirected to slot [1085] located at 172.19.0.2:9001
OK
172.19.0.2:9001> keys *
1) "level"
172.19.0.2:9001> get level
"p11"
172.19.0.2:9001> get name
-> Redirected to slot [5798] located at 172.19.0.3:9002
"fsh"
172.19.0.3:9002> keys *
1) "name"

Redis常见问题
redis内存穿透
问题:redis获取key 由于key不存在 redis找不到 从而向db进行获取
原因:第一次访问 | 访问不存在key | key过期
解决:服务器启动时 提前写入 | 规范key命令 通过中间件拦截 | 对高频访问的key 设置合理的有效期
redis缓存雪崩
问题1:同一时刻缓存(redis)中数据量大量到期时 引起的redis数据库压力增大甚至宕机
问题2: Redis缓存层由于某种原因宕机后,所有的请求会涌向存储层,短时间内的高并发请求可能会导致存储层挂机
原因:短时间高并发访问 | 短时间key大量到期
解决: redis集群 | 设置过期时间随机值 | 限流
Redis应用场景
String: 缓存 计数器 分布式锁 ...
List: 队列 ...
Hash: 用户信息 hash表 ...
Set: 去重 点赞 共同好友 ...
Zset: 排行榜 ...
帮助文档
[4] redis启动模式https://zhuanlan.zhihu.com/p/145186839
[5]redis配置文件详解https://blog.csdn.net/suprezheng/article/details/90679790