初识Redis

1. 介绍

1.1 功能介绍

  • 数据类型丰富
  • 支持持久化
  • 多种内存分配及回收策略
  • 支持事务
  • 消息队列、消息订阅
  • 支持高可用(原生态高可用)
  • 支持分布式分片集群(原生态分布式)
  • 缓存穿透/雪崩
  • Redis API

1.2 企业缓存产品介绍

  1. Memcached
优点:高性能读写、单一数据类型、支持客户端分布式集群、一致性hash、多核结构、多线程读写性能高

缺点:无持久化、节点故障可能出现缓存穿透、分布式需要客户端实现、跨机房数据同步困难、架构扩容复杂度高
  1. Redis
优点:高性能读写、多数据类型支持、数据持久化、高可用架构、支持自定义虚拟内存、支持分布式分片集群、单线程读写性能极高

缺点:多线程读写较memcached慢
  1. 读写性能对比

多核: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基本命令

  1. 本地登陆
# 方式一:通过密码直接登陆
[root@node01 ~]# redis-cli -a 123456

#方式二:先连接,再通过密码登陆
[root@node01 ~]# redis-cli
127.0.0.1:6379> auth 123456
  1. 远程连接
[root@node01 ~]# redis-cli -h 192.168.1.161 -a 123456 -p 6379
  1. 插入数据、获取数据
# 方式一:进去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
  1. 获取redis信息
# 获取全部信息
192.168.1.161:6379> info

# 获取cpu相关信息
192.168.1.161:6379> info cpu

# 获取主从相关信息
192.168.1.161:6379> info replication
  1. 获取键
# 列出所有键
192.168.1.161:6379> keys *		#不建议使用
192.168.1.161:6379> keys a*		#支持模糊查询

# 查询当前库下键值对的数量
192.168.1.161:6379> dbsize
  1. 清空数据
# 清空0-15所有库的数据
192.168.1.161:6379> flushall

# 清空当前所在库的所有数据
192.168.1.161:6379> flushdb
  1. 切换库
#redis中也有库的概念,一共是0-15号共16个库,默认使用的是0库
192.168.1.161:6379> select 1
OK
192.168.1.161:6379[1]>
  1. 查看当前连接的客户端数量
192.168.1.161:6379> client list		#一条就是一个连接
  1. 手动关闭某个客户端的连接
192.168.1.161:6379> client kill 127.0.0.1:34548
  1. 返回键所储存值的类型
type key
  1. 键值对存活时间
# 以秒/毫秒设定生存时间
expire/pexpire

# 以秒/毫秒为单位返回生存时间
ttl/pttl		#如果返回的是-2,代表这个key已经不存在了;如果返回的是-1,代表这个key存在但没有设置存活时间

# 取消生存时间设置
persist
  1. 关于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有乐观锁和悲观锁

  1. 悲观锁

    当我们要对一个数据库中的一条数据进行修改时,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发。这种借助数据库锁机制,在修改数据之前先锁定,再修改的方式成为悲观并发控制(又名“悲观锁”,缩写“PCC”)

  2. 乐观锁

    乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况下不会发生冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发生冲突了,则返回给用户错误的信息,让用户均订如何去做

案例:买票(执行顺序: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 主从复制搭建–基础

  1. 架构:单节点多实例
  • 主机:192.168.1.161
  • 实例:
    • 6380:主
    • 6381:从1
    • 6382:从2
  1. 主从搭建(配置文件已简化)
[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
  1. 验证
# 查看主从关系及运行状态
[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 主从复制搭建–哨兵

  1. 功能

    • 监控
    • 自动选主,切换
    • 应用透明
    • 自动处理故障节点
  2. 搭建

  • 基于基础主从复制
# 创建目录
[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
  1. 配置文件解读
#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
  1. 模拟主库宕机验证
# 模拟主库宕机
[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
  1. 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 主从复制搭建–集群

  1. 高性能

    1. 在多分片节点中,将 16384 个槽位均匀分布到多个分片节点
    2. 存数据时,对每个key按照CRC16规则进行hash运算,然后把结果和16384进行取模,得出槽位值(0-16383之间)
    3. 根据计算得出的槽位值,找到相对应的分片节点的主节点,存储到相应槽位上
    4. 如果客户端当时连接的节点不是将来要存储的分片节点,分片集群会将客户端连接切换至真正存储节点进行数据存储
  2. 高可用

    在搭建集群时,会为每一个分片的主节点,对应一个从节点,实现slaveof的功能,同时当主节点down,实现类似于sentinel的自动failover的功能

    1. redis由多组分片构成(3组)
    2. redis cluster 使用固定个数的slot存储数据(共16384个slot)
    3. 每组分片分得 1/3 slot 个数
    4. 基于CRC16(key) % 16384 = 值 = 槽位号
  3. 搭建

  • 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 从
  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


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
  1. 将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
  1. 新节点分配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
  1. 将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
  1. 查看集群节点
redis-cli -h 192.168.1.161 -a 123 -p 7001 cluster nodes

8.4.4 删除节点

  1. 分配 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
  1. 删除主节点(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
  1. 删除从节点(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 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值