文章目录
1. 介绍
1.1 功能介绍
- 数据类型丰富
- 支持持久化
- 多种内存分配及回收策略
- 支持事务
- 消息队列、消息订阅
- 支持高可用(原生态高可用)
- 支持分布式分片集群(原生态分布式)
- 缓存穿透/雪崩
- Redis API
1.2 企业缓存产品介绍
- Memcached
优点:高性能读写、单一数据类型、支持客户端分布式集群、一致性hash、多核结构、多线程读写性能高
缺点:无持久化、节点故障可能出现缓存穿透、分布式需要客户端实现、跨机房数据同步困难、架构扩容复杂度高
- Redis
优点:高性能读写、多数据类型支持、数据持久化、高可用架构、支持自定义虚拟内存、支持分布式分片集群、单线程读写性能极高
缺点:多线程读写较memcached慢
- 读写性能对比
多核:memcached适合,多用户访问,每个用户少量的rw
单核:redis适合,少用户访问,每个用户大量rw
2. Redis安装–单机
官网:点击跳转
下载地址:点击跳转
- redis-5.0.9
[root@node01 ~]# yum install gcc gcc-c++ kernel-devel automake autoconf libtool make wget -y
[root@node01 ~]# wget https://download.redis.io/releases/redis-5.0.9.tar.gz
[root@node01 ~]# tar -xf redis-5.0.9.tar.gz -C /usr/local/
[root@node01 ~]# ln -sv /usr/local/redis-5.0.9 /usr/local/redis
[root@node01 ~]# cd /usr/local/redis/
[root@node01 redis]# make
[root@node01 redis]# make PREFIX=/usr/local/redis install
[root@node01 redis]# mkdir -p /data/redis/6379
[root@node01 redis]# cp redis.conf /data/redis/6379/
[root@node01 ~]# vim /data/redis/6379/redis.conf
# 监听所有ip地址,外网可以访问
#bind 127.0.0.1
bind 0.0.0.0
# 是否开启保护模式,默认开启。要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问。要是开启了密码和bind,可以开启。否则最好关闭设置为no
protected-mode yes
# 端口
port 6379
# 允许后台启动
daemonize yes
# pid存放位置
pidfile /data/redis/6379/redis_6379.pid
# 日志级别,可用的级别有debug.verbose.notice.warning
loglevel verbose
# 错误日志存放位置
logfile "/data/redis/6379/redis_err_6379.log"
# dump
dbfilename dump6379.rdb
# dir
dir /data/redis/6379/
# 密码
requirepass 123456
[root@node01 ~]# useradd -s /sbin/nologin redis
[root@node01 ~]# chown -R redis.redis /data/redis
[root@node01 ~]# cat > /usr/lib/systemd/system/redis.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /data/redis/6379/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
[root@node01 ~]# systemctl enable redis
[root@node01 ~]# systemctl start redis
[root@node01 ~]# vim /etc/profile.d/redis.sh
export REDIS_HOME=/usr/local/redis
export PATH=$PATH:$REDIS_HOME/bin
[root@node01 ~]# source /etc/profile.d/redis.sh
[root@node01 ~]# redis-cli -a 123456
3. Redis基本命令
- 本地登陆
# 方式一:通过密码直接登陆
[root@node01 ~]# redis-cli -a 123456
#方式二:先连接,再通过密码登陆
[root@node01 ~]# redis-cli
127.0.0.1:6379> auth 123456
- 远程连接
[root@node01 ~]# redis-cli -h 192.168.1.161 -a 123456 -p 6379
- 插入数据、获取数据
# 方式一:进去redis,执行命令
192.168.1.161:6379> set key1 value1
192.168.1.161:6379> get key1
# 方式二:在redis外直接执行命令。相当于mysql -e
[root@node01 ~]# redis-cli -a 123456 set key2 value2
[root@node01 ~]# redis-cli -a 123456 get key2
- 获取redis信息
# 获取全部信息
192.168.1.161:6379> info
# 获取cpu相关信息
192.168.1.161:6379> info cpu
# 获取主从相关信息
192.168.1.161:6379> info replication
- 获取键
# 列出所有键
192.168.1.161:6379> keys * #不建议使用
192.168.1.161:6379> keys a* #支持模糊查询
# 查询当前库下键值对的数量
192.168.1.161:6379> dbsize
- 清空数据
# 清空0-15所有库的数据
192.168.1.161:6379> flushall
# 清空当前所在库的所有数据
192.168.1.161:6379> flushdb
- 切换库
#redis中也有库的概念,一共是0-15号共16个库,默认使用的是0库
192.168.1.161:6379> select 1
OK
192.168.1.161:6379[1]>
- 查看当前连接的客户端数量
192.168.1.161:6379> client list #一条就是一个连接
- 手动关闭某个客户端的连接
192.168.1.161:6379> client kill 127.0.0.1:34548
- 返回键所储存值的类型
type key
- 键值对存活时间
# 以秒/毫秒设定生存时间
expire/pexpire
# 以秒/毫秒为单位返回生存时间
ttl/pttl #如果返回的是-2,代表这个key已经不存在了;如果返回的是-1,代表这个key存在但没有设置存活时间
# 取消生存时间设置
persist
- 关于key操作
# 删除key
del key
# 查看是否存在
exists key
# 变更key名称
rename oldkey newkey
4. 持久化
4.1 RDB持久化
可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)
优点:速度快,适合于用作备份,主从复制也是基于RDB持久化功能实现的
缺点:会有数据丢失
配置文件
vim /data/redis/6379/redis.conf
dir /data/redis/6379/
dbfilename dump6379.rdb
save 900 1
save 300 10
save 60 10000
## 参数解读:创建快照的策略
900秒(15分钟)内有1个更改(累计)
300秒(5分钟)内有10个更改(累计)
60秒内有10000个更改(累计)
####如上配置,最短创建一次快照的时间是60s,加入现在redis down,那么就是丢失了60s的数据
4.2 AOF持久化
append-only log file ,相当于MySQL里的binlog
记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集
AOF文件中的命令全部以Redis协议的格式来保存,新命令会被追加到文件的末尾
优点:可以最大程度保证数据不丢失
缺点:日志记录量级比较大
配置文件
vim /data/redis/6379/redis.conf
appendonly yes # 开启AOF
appendfsync always # 不管什么情况都记录
appendfsync everysec # 每秒记录一次
appendfsync no # 系统决定(已经决定开启AOF,所以就不需要让系统决定了)
5. 发布与订阅
发布/订阅(pub/sub)是一种消息通信模式:发布者(pub)发送消息,订阅者(sub)接收消息
pub即publish,出版、发布;publisher,发布者
sub即subscribe,订阅;subscriber,订阅者
PS:订阅者只能接收到订阅者在线时期间发布者发布的消息。订阅者重新上线后,也不会接收到历史消息
# 订阅频道
PSUBSCRIBE fm1039
# 发布
PUBLISH fm1039 helloworld
6. 事务
Redis的事务是基于队列实现的。是乐观锁
Redis中的事务是一组命令的集合。事务同命令一样都是Redis最小的执行单位,一个事务中的命令要么都执行,要么都不执行。Redis事务的实现需要用到
MULTI
MULTI和EXEC
两个命令,事务开始的时候先向Redis服务器发送MULTI命令,然后依次发送需要在本次事务中处理的命令,最后再发送EXEC命令表示事务结束。Redis的事务是下面4个命令来实现
# 开启Redis事务,置客户端为事务状态
multi
# 这4条命令是放在一个队列里的,并没有真正执行
command1
command2
command3
command4
# 提交事务,执行从multi到exec结束的所有命令队列里的命令,置客户端为非事务状态
exec
#取消该队列,就是不执行了
discard
# 监视键值对,作用是如果事务提交exec的时候发现监视的键值对发生变化,事务将被取消
watch
示例
192.168.1.161:6379> set a aa # 执行执行
OK
192.168.1.161:6379> MULTI
OK
192.168.1.161:6379> set b bb
QUEUED
192.168.1.161:6379> set c cc
QUEUED
192.168.1.161:6379> exec # 提交后才执行
1) OK
2) OK
应用:商品秒杀系统【存在问题:商品数量一定,但是所有人都可以购买成功,甚至出现商品数量为负值,不符合逻辑】
7. Redis乐观锁
Redis有乐观锁和悲观锁
-
悲观锁
当我们要对一个数据库中的一条数据进行修改时,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发。这种借助数据库锁机制,在修改数据之前先锁定,再修改的方式成为悲观并发控制(又名“悲观锁”,缩写“PCC”)
-
乐观锁
乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况下不会发生冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发生冲突了,则返回给用户错误的信息,让用户均订如何去做
案例:买票(执行顺序:1–>2–>3–>4)
# 1.创建1张票
192.168.1.161:6379> set ticket 1
# 2.用户1:查询剩余票的数量,开启“买票事务”,但未付款(即未提交事务)
192.168.1.161:6379> get ticket
"1"
192.168.1.161:6379> watch ticket
OK
192.168.1.161:6379> multi
OK
192.168.1.161:6379> decr ticket
QUEUED
# 4.提交事务(付款):乐观锁(watch)机制发现剩余数量未0,因此,不执行该事务(即不购买)
192.168.1.161:6379> exec
(nil)
# 3.用户2:查询剩余票的数量,启“买票”事务,直接付款(即未提交事务)
127.0.0.1:6379> get ticket
"1"
127.0.0.1:6379> watch ticket
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decr ticket
QUEUED
127.0.0.1:6379> exec
1) (integer) 0
8. Redis主从复制
8.1 主从复制原理
# slaveof 相当 MySQL中change master to
1. 副本库通过slaveof 192.168.1.161 6380 命令连接主库,发送SYNC给主库;
2. 主库收到SYNC,会立即触发BGSAVE,后台保存RDB,发送给副本库;
3. 副本库接收后会立即应用RDB快照;
4. 主库会陆续将中间产生的新的操作,保存并发送给副本库;
5. 至此,主从复制集正常工作;
6. 后续,主库只有发生新的操作,都会以广播的形式自动发送给副本库;
7. 所有复制相关信息,从info信息中都可以查到。即使重启任何节点,主从关系依然存在;
8. 如果主从关系断裂,从库数据没有任何损坏,在下次重连后,从库发送PSYNC给主库;
9. 主库只会将从库缺失部分的数据同步给从库应用,达到快速恢复主从的目的。
主从数据一致性保护
min-slaves-to-write 1
min-slaves-max-lag 3
8.2 主从复制搭建–基础
- 架构:单节点多实例
- 主机:192.168.1.161
- 实例:
- 6380:主
- 6381:从1
- 6382:从2
- 主从搭建(配置文件已简化)
[root@node01 ~]# yum install gcc gcc-c++ kernel-devel automake autoconf libtool make wget -y
[root@node01 ~]# wget https://download.redis.io/releases/redis-5.0.9.tar.gz
[root@node01 ~]# tar -xf redis-5.0.9.tar.gz -C /usr/local/
[root@node01 ~]# ln -sv /usr/local/redis-5.0.9 /usr/local/redis
[root@node01 ~]# cd /usr/local/redis/
[root@node01 redis]# make
[root@node01 redis]# make PREFIX=/usr/local/redis install
# 创建目录
[root@node01 ~]# mkdir -p /data/redis/638{0..2}
# 写入配置文件【配置文件模板:/usr/local/redis/redis.conf】
[root@node01 ~]# cat >> /data/redis/6380/redis.conf <<EOF
bind 0.0.0.0
port 6380
daemonize yes
pidfile /data/redis/6380/redis.pid
loglevel notice
logfile "/data/redis/6380/redis.log"
dbfilename dump.rdb
dir /data/redis/6380
requirepass 123
masterauth 123
EOF
[root@node01 ~]# cat >> /data/redis/6381/redis.conf <<EOF
bind 0.0.0.0
port 6381
daemonize yes
pidfile /data/redis/6381/redis.pid
loglevel notice
logfile "/data/redis/6381/redis.log"
dbfilename dump.rdb
dir /data/redis/6381
requirepass 123
masterauth 123
#主从复制的从需要此配置,指定主库的IP+port
slaveof 127.0.0.1 6380
EOF
[root@node01 ~]# cat >> /data/redis/6382/redis.conf <<EOF
bind 0.0.0.0
port 6382
daemonize yes
pidfile /data/redis/6382/redis.pid
loglevel notice
logfile "/data/redis/6382/redis.log"
dbfilename dump.rdb
dir /data/redis/6382
requirepass 123
masterauth 123
#主从复制的从需要此配置
slaveof 127.0.0.1 6380
EOF
#创建用户并授权
[root@node01 ~]# useradd -s /sbin/nologin redis
[root@node01 ~]# chown -R redis.redis /data/redis
# 创建服务启动配置文件
[root@node01 ~]# cat > /usr/lib/systemd/system/redis6380.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /data/redis/6380/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
[root@node01 ~]# cat > /usr/lib/systemd/system/redis6381.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /data/redis/6381//redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
[root@node01 ~]# cat > /usr/lib/systemd/system/redis6382.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /data/redis/6382/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
[root@node01 ~]# systemctl enable redis6380 redis6381 redis6382
[root@node01 ~]# systemctl start redis6380 redis6381 redis6382
[root@node01 ~]# vim /etc/profile.d/redis.sh
export REDIS_HOME=/usr/local/redis
export PATH=$PATH:$REDIS_HOME/bin
[root@node01 ~]# source /etc/profile.d/redis.sh
- 验证
# 查看主从关系及运行状态
[root@node01 ~]# redis-cli -a 123 -p 6380 info replication
[root@node01 ~]# redis-cli -a 123 -p 6381 info replication
[root@node01 ~]# redis-cli -a 123 -p 6382 info replication
# 创建数据验证
[root@node01 ~]# redis-cli -a 123 -p 6380 set a aa
[root@node01 ~]# redis-cli -a 123 -p 6381 get a
[root@node01 ~]# redis-cli -a 123 -p 6382 get a
PS:主从关系搭建完成后,只能主库写,从库读,从库无法写
PS:5.0.9版本完整的redis.conf配置文件如下
bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /data/redis/6379/redis_6379.pid
loglevel verbose
logfile "/data/redis/6379/redis_err_6379.log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump6379.rdb
dir /data/redis/6379/
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
requirepass 123456
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
8.3 主从复制搭建–哨兵
-
功能
- 监控
- 自动选主,切换
- 应用透明
- 自动处理故障节点
-
搭建
- 基于基础主从复制
# 创建目录
[root@node01 ~]# mkdir -p /data/sentinel/26380
# 写入配置文件【模板路径:/usr/local/redis/sentinel.conf】
[root@node01 ~]# cat >> /data/sentinel/26380/sentinel.conf <<EOF
port 26380
dir "/data/sentinel/26380"
sentinel monitor mymaster 127.0.0.1 6380 1
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel auth-pass mymaster 123
logfile "sentinel.log"
EOF
#写入服务启动配置文件
[root@node01 ~]# cat > /usr/lib/systemd/system/sentinel.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-sentinel /data/sentinel/26380/sentinel.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=simple
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
#授权
[root@node01 ~]# chown -R redis.redis /data/sentinel
# 启动
[root@node01 ~]# systemctl enable sentinel
[root@node01 ~]# systemctl start sentinel
- 配置文件解读
#sentinel monitor mymastert 127.0.0.1 6380 1
mymaster sentinel的名称
127.0.0.1 当前主库IP
6380 当前主库端口
1 投票数
#sentinel down-after-milliseconds mymaster 5000
5000 5000ms,心跳检测在5000ms后才认为主库宕机
#sentinel auth-pass mymaster 123
123 sentinel的密码
### 如果想监控多套集群,可在配置文件末尾新增以下:以sentinel的名称(mymastert1)进行区分
sentinel monitor mymastert 127.0.0.1 6380 1
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel auth-pass mymaster 123
- 模拟主库宕机验证
# 模拟主库宕机
[root@node01 ~]# systemctl stop redis6380
# 查看主从当前状态
[root@node01 ~]# redis-cli -a 123 -p 6381 info replication
[root@node01 ~]# redis-cli -a 123 -p 6382 info replication
# 恢复原主库,查看状态:作为从加入
[root@node01 ~]# systemctl start redis6380
[root@node01 ~]# redis-cli -a 123 -p 6380 info replication
- sentinel管理命令
# 连接sentinel
redis-cli -p 26380
# 连通性检测
ping
# 列出所有被监视的主库信息
sentinel masters
# 列出指定sentinel下的从库信息(使用master name进行区分sentinel)
sentinel slaves mymaster
# 返回给定名字的主库的IP和端口号
sentinel get-master-addr-by-name mymaster
# 重置所有名字和给定模式 pattern 相匹配的主库
sentinel reset <pattern>
# 当主库失效时,在不询问其他sentinel意见的情况下,强制开始一次自动故障转移
sentinel failover mymaster
8.4 主从复制搭建–集群
-
高性能
- 在多分片节点中,将 16384 个槽位均匀分布到多个分片节点
- 存数据时,对每个key按照CRC16规则进行hash运算,然后把结果和16384进行取模,得出槽位值(0-16383之间)
- 根据计算得出的槽位值,找到相对应的分片节点的主节点,存储到相应槽位上
- 如果客户端当时连接的节点不是将来要存储的分片节点,分片集群会将客户端连接切换至真正存储节点进行数据存储
-
高可用
在搭建集群时,会为每一个分片的主节点,对应一个从节点,实现slaveof的功能,同时当主节点down,实现类似于sentinel的自动failover的功能
- redis由多组分片构成(3组)
- redis cluster 使用固定个数的slot存储数据(共16384个slot)
- 每组分片分得 1/3 slot 个数
- 基于CRC16(key) % 16384 = 值 = 槽位号
-
搭建
- 192.168.161
- 7001 主A
- 7002 从
- 192.168.1.162
- 7001 主B
- 7002 从
- 192.168.1.163
- 7001 主C
- 7002 从
8.4.1 基础实例搭建
yum install gcc-c++ wget -y
mkdir -p /data/redis/700{1,2}
useradd -s /sbin/nologin redis
wget https://download.redis.io/releases/redis-5.0.9.tar.gz
tar -xf redis-5.0.9.tar.gz -C /usr/local/
ln -sv /usr/local/redis-5.0.9 /usr/local/redis
cd /usr/local/redis/
make
make PREFIX=/usr/local/redis install
#192.168.161
cat >> /data/redis/7001/redis.conf <<EOF
bind 0.0.0.0
port 7001
daemonize yes
pidfile /data/redis/7001/redis.pid
loglevel notice
logfile "/data/redis/7001/redis.log"
dbfilename dump.rdb
dir /data/redis/7001
protected-mode no
requirepass 123
masterauth 123
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat >> /data/redis/7002/redis.conf <<EOF
bind 0.0.0.0
port 7002
daemonize yes
pidfile /data/redis/7002/redis.pid
loglevel notice
logfile "/data/redis/7002/redis.log"
dbfilename dump.rdb
dir /data/redis/7002
protected-mode no
requirepass 123
masterauth 123
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat > /usr/lib/systemd/system/redis7001.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /data/redis/7001/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
cat > /usr/lib/systemd/system/redis7002.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /data/redis/7002/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
#192.168.162
cat >> /data/redis/7001/redis.conf <<EOF
bind 0.0.0.0
port 7001
daemonize yes
pidfile /data/redis/7001/redis.pid
loglevel notice
logfile "/data/redis/7001/redis.log"
dbfilename dump.rdb
dir /data/redis/7001
protected-mode no
requirepass 123
masterauth 123
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat >> /data/redis/7002/redis.conf <<EOF
bind 0.0.0.0
port 7002
daemonize yes
pidfile /data/redis/7002/redis.pid
loglevel notice
logfile "/data/redis/7002/redis.log"
dbfilename dump.rdb
dir /data/redis/7002
protected-mode no
requirepass 123
masterauth 123
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat > /usr/lib/systemd/system/redis7001.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /data/redis/7001/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
cat > /usr/lib/systemd/system/redis7002.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /data/redis/7002/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
#192.168.163
cat >> /data/redis/7001/redis.conf <<EOF
bind 0.0.0.0
port 7001
daemonize yes
pidfile /data/redis/7001/redis.pid
loglevel notice
logfile "/data/redis/7001/redis.log"
dbfilename dump.rdb
dir /data/redis/7001
protected-mode no
requirepass 123
masterauth 123
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat >> /data/redis/7002/redis.conf <<EOF
bind 0.0.0.0
port 7002
daemonize yes
pidfile /data/redis/7002/redis.pid
loglevel notice
logfile "/data/redis/7002/redis.log"
dbfilename dump.rdb
dir /data/redis/7002
protected-mode no
requirepass 123
masterauth 123
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat > /usr/lib/systemd/system/redis7001.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /data/redis/7001/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
cat > /usr/lib/systemd/system/redis7002.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /data/redis/7002/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
##所有节点均执行
chown -R redis.redis /data/redis
systemctl daemon-reload
systemctl start redis7001
systemctl start redis7002
systemctl enable redis7001
systemctl enable redis7002
vim /etc/profile.d/redis.sh
export REDIS_HOME=/usr/local/redis
export PATH=$PATH:$REDIS_HOME/bin
source /etc/profile.d/redis.sh
8.4.2 创建集群
redis-cli -a 123 --cluster create 192.168.1.161:7001 192.168.1.162:7001 192.168.1.163:7001 192.168.1.162:7002 192.168.1.163:7002 192.168.1.161:7002 --cluster-replicas 1
检查集群
redis-cli -a 123 --cluster check 192.168.1.161:7001
存取数据测试
redis-cli -c -a 123 -h 192.168.1.161 -p 7001
# -c 指定集群模式
# -a 指定密码
查看集群节点及slot分配信息
redis-cli -a 123 -p 7001 cluster nodes # 带有“myself”的是集群的主控节点
8.4.3 增加节点
- 192.168.1.104
- 7001 主
- 7002 从
- 运行基础实例
yum install gcc-c++ wget -y
mkdir -p /data/redis/700{1,2}
useradd -s /sbin/nologin redis
wget https://download.redis.io/releases/redis-5.0.9.tar.gz
tar -xf redis-5.0.9.tar.gz -C /usr/local/
ln -sv /usr/local/redis-5.0.9 /usr/local/redis
cd /usr/local/redis/
make
make PREFIX=/usr/local/redis install
cat >> /data/redis/7001/redis.conf <<EOF
bind 0.0.0.0
port 7001
daemonize yes
pidfile /data/redis/7001/redis.pid
loglevel notice
logfile "/data/redis/7001/redis.log"
dbfilename dump.rdb
dir /data/redis/7001
protected-mode no
requirepass 123
masterauth 123
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat >> /data/redis/7002/redis.conf <<EOF
bind 0.0.0.0
port 7002
daemonize yes
pidfile /data/redis/7002/redis.pid
loglevel notice
logfile "/data/redis/7002/redis.log"
dbfilename dump.rdb
dir /data/redis/7002
protected-mode no
requirepass 123
masterauth 123
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat > /usr/lib/systemd/system/redis7001.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /data/redis/7001/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
cat > /usr/lib/systemd/system/redis7002.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /data/redis/7002/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
chown -R redis.redis /data/redis
systemctl daemon-reload
systemctl start redis7001
systemctl start redis7002
systemctl enable redis7001
systemctl enable redis7002
vim /etc/profile.d/redis.sh
export REDIS_HOME=/usr/local/redis
export PATH=$PATH:$REDIS_HOME/bin
source /etc/profile.d/redis.sh
- 将192.168.1.164:7001以主库身份加入集群
redis-cli -h 192.168.1.161 -a 123 -p 7001 --cluster add-node 192.168.1.164:7001 192.168.1.161:7001
##参数
#192.168.1.164:7001 新增的主库
#192.168.1.161:7001 集群主控节点
redis-cli -h 192.168.1.161 -a 123 -p 7001 cluster nodes # 查看当前节点信息,并记录新增节点的 node id
- 新节点分配slot(4节点就是每个节点4096)
redis-cli -h 192.168.1.161 -a 123 -p 7001 --cluster reshard 192.168.1.164:7001
How many slots do you want to move (from 1 to 16384)? 4096 # 总共分配 4096 slot
What is the receiving node ID? 82f6b409ea836ed9c3b2e2a53170d3dc0e37193d # 接收槽位节点的 node id
Source node #1: all #从所有节点分配槽位
Do you want to proceed with the proposed reshard plan (yes/no)? yes
#再次查看,可发现新增节点有了槽位:0-1364 5461-6826 10923-12287
redis-cli -h 192.168.1.161 -a 123 -p 7001 cluster nodes
- 将192.168.1.164:7002以从库身份加入集群
redis-cli -h 192.168.1.161 -a 123 -p 7001 --cluster add-node 192.168.1.164:7002 --cluster-slave --cluster-master-id 82f6b409ea836ed9c3b2e2a53170d3dc0e37193d 192.168.1.161:7001
###
#192.168.1.164:7002 新增的节点
#192.168.1.161:7001 集群主控节点
#82f6b409ea836ed9c3b2e2a53170d3dc0e37193d 新增节点的主的node id
- 查看集群节点
redis-cli -h 192.168.1.161 -a 123 -p 7001 cluster nodes
8.4.4 删除节点
- 分配 slot
# 目前新增节点(192.168.1.164:7001,node_id:82f6b409ea836ed9c3b2e2a53170d3dc0e37193d)上面有3段分配来的solt(0-1364 5461-6826 10923-12287),首先将这些slot再分配给其他3个主库
#1.给主1(node_id:88fa60a65885cc3f2124e5bfdda30c52a41f6be7)1364-0+1=1365 个
redis-cli -h 192.168.1.161 -a 123 -p 7001 --cluster reshard 192.168.1.164:7001 --cluster-from 82f6b409ea836ed9c3b2e2a53170d3dc0e37193d --cluster-to 88fa60a65885cc3f2124e5bfdda30c52a41f6be7 --cluster-slots 1365 --cluster-yes
#2.给主2(node_id:72b0f0ddc9bdeed1cff66598b1f54ff864d81237) 6826-5461+1=1366 个
redis-cli -h 192.168.1.161 -a 123 -p 7001 --cluster reshard 192.168.1.164:7001 --cluster-from 82f6b409ea836ed9c3b2e2a53170d3dc0e37193d --cluster-to 72b0f0ddc9bdeed1cff66598b1f54ff864d81237 --cluster-slots 1366 --cluster-yes
#3.给主3(node_id:a31f09c9f72892e7403df6e17c41c0fe6c20fc1c) 12287-10923+1=1365 个
redis-cli -h 192.168.1.161 -a 123 -p 7001 --cluster reshard 192.168.1.164:7001 --cluster-from 82f6b409ea836ed9c3b2e2a53170d3dc0e37193d --cluster-to a31f09c9f72892e7403df6e17c41c0fe6c20fc1c --cluster-slots 1366 --cluster-yes
# 查看:192.168.1.164:7001 slot为空
redis-cli -h 192.168.1.161 -a 123 -p 7001 cluster nodes
- 删除主节点(192.168.1.164:7001,node_id:82f6b409ea836ed9c3b2e2a53170d3dc0e37193d)
# 指定删除节点的node id:82f6b409ea836ed9c3b2e2a53170d3dc0e37193d
# 指定集群主控节点(集群任意节点即可):192.168.1.161:7001
redis-cli -h 192.168.1.161 -a 123 -p 7001 --cluster del-node 192.168.1.161:7001 82f6b409ea836ed9c3b2e2a53170d3dc0e37193d
- 删除从节点(192.168.1.164:7002,node_id:0051a40f48a624deb1277c4dbb32bd7fa3c06336)
# 指定删除节点的node id:0051a40f48a624deb1277c4dbb32bd7fa3c06336
# 指定集群主控节点(集群任意节点即可):192.168.1.161:7001
redis-cli -h 192.168.1.161 -a 123 -p 7001 --cluster del-node 192.168.1.161:7001 0051a40f48a624deb1277c4dbb32bd7fa3c06336