# Redis基操



## Redis 介绍

一、Redis和同类产品的比较，本职工作还是**高速缓存**

* Ehcache
  * 是一个Java开源项目，使用的方式就是引入一个jar包，非常方便
* Memcached
  * 如果开启多线程模式，读取速度将有极大的提高
  * 数据只会存储在内存中，挂掉后数据不可恢复
* Redis
  * 数据结构非常丰富，字符串、hash列表、list、Set等等
  * 支持主从，Sentinal，分片等多种高级特性，用于负载均衡和容灾，具有高可用性
  * 几乎支持所有语言的客户端

二、做为消息队列比较及选择 <如果能用Kafka就用Kafka，对于数据不敏感的一般场景也是可以应用Redis的。>

* Redis
  * 只能说具备发布订阅功能，一个或多个消费者订阅一个频道
* Kafka
  * 高级特性一应俱全，集群、负载均衡、动态扩容、数据备份等

## Redis与Memcached的详细区别

| Type  | Memcached                       | Redis                                     |
| ----- | ------------------------------- | ----------------------------------------- |
| 线程模型  | 多线程                             | 单线程                                       |
| 数据结构  | 仅支持string、value最大1M、过期时间不能超过30天 | string、list、hash、set、zset、geo、hyperLogLog |
| 淘汰策略  | LRU                             | LRU、LFU、随机等多种策略                           |
| 管道与事务 | 不支持                             | 支持                                        |
| 持久化   | 不支持                             | 支持                                        |
| 高可用   | 不支持                             | 主从复制+哨兵                                   |
| 集群化   | 客户端一致性哈希算法                      | 主从复制+哨兵+固定哈希槽位                            |

* 整体来说，Redis提供了非常丰富的功能，而且性能基本上与Memcached相差无几，这也是它最近这几年占领内存数据库鳌头的原因。
* 如果你的业务需要各种数据结构给予支撑，同时要求数据的高可用保障，那么选择Redis是比较合适的。
* 如果你的业务非常简单，只是简单的set/get，并且对于内存使用并不高，那么使用简单的Memcached足够。

## Redis 运维优化最佳实践

* 不同业务线部署不同的实例，各自独立，避免混用，推荐不同业务线使用不同的机器，根据业务重要程度划分不同的分组来部署，避免某一个业务线出现问题影响其他业务线
* 保证机器有足够的CPU、内存、带宽、磁盘资源，防止负载过高影响Redis性能
* 以master-slave集群方式部署实例，并分布在不同机器上，避免单点，slave必须设置为readonly
* master和slave节点所在机器，各自独立，不要交叉部署实例，通常备份工作会在slave上做，做备份时会消耗机器资源，交叉部署会影响到master的性能
* 推荐部署哨兵节点增加可用性，节点数量至少3个，并分布在不同机器上，实现故障自动故障转移
* 提前做好容量规划，一台机器部署实例的内存上限，最好是机器内存的一半，主从全量同步时会占用最多额外一倍的内存空间，防止网络大面积故障引发所有master-slave的全量同步导致机器内存被吃光
* 做好机器的CPU、内存、带宽、磁盘监控，在资源不足时及时报警处理，Redis使用Swap后性能急剧下降，网络带宽负载过高访问延迟明显增大，磁盘IO过高时开启AOF会拖慢Redis的性能
* 设置最大连接数上限，防止过多的客户端连接导致服务负载过高
* 单个实例的使用内存建议控制在20G以下，过大的实例会导致备份时间久、资源消耗多，主从全量同步数据时间阻塞时间更长
* 设置合理的slowlog阈值，推荐10毫秒，并对其进行监控，产生过多的慢日志需要及时报警 设置合理的复制缓冲区repl-backlog大小，适当调大repl-backlog可以降低主从全量复制的概率
* 设置合理的slave节点client-output-buffer-limit大小，对于写入量很大的实例，适当调大可以避免主从复制中断问题
* 备份时推荐在slave节点上做，不影响master性能
* 不开启AOF或开启AOF配置为每秒刷盘，避免磁盘IO消耗降低Redis性能
* 当实例设置了内存上限，需要调大内存上限时，先调整slave再调整master，否则会导致主从节点数据不一致
* 对Redis增加监控，监控采集info信息时，使用长连接，频繁的短连接也会影响Redis性能，[redis性能监控指标](http://mp.weixin.qq.com/s?__biz=MzI0MDQ4MTM5NQ==\&mid=2247495171\&idx=2\&sn=b1097b73768ae4fb5c2b7e8747e2fae7\&chksm=e9188b1fde6f0209e70af9066722e097941ac30214b02e6ad4fdb88ddc62c39d4f203ae9d610\&scene=21#wechat_redirect)，参考这个文章
* 线上扫描整个实例数时，记得设置休眠时间，避免扫描时QPS突增对Redis产生性能抖
* 做好Redis的运行时监控，尤其是expired\_keys、evicted\_keys、latest\_fork\_usec指标，短时间内这些指标值突增可能会阻塞整个实例，引发性能问题

## Redis集群搭建的三种方式

1. 主从模式（master/slaver） 或 一主多从

```
# 主要修改：
slaveof IP PORT 指明master的ip和端口号就可以了主从了！

作用：
主写从查，默认master可读写，slave只读！ 如果故障方便恢复，但是主挂，无法写入，只能读，
```

注意： 生产坏境是不会单单只有主从模式的

1. sentinel模式， < 哨兵模式 >

```
工作原理： sentinel模式是建立在主从模式的基础上，如果只有一个Redis节点，sentinel就没有任何意义
当master节点挂了以后，sentinel会在slave中选择一个做为master，并修改它们的配置文件，其他slave的配置文件也会被修改，比如slaveof属性会指向新的master
当master节点重新启动后，它将不再是master而是做为slave接收新的master节点的同步数据

缺点： 在哨兵模式中，只有一个Master节点具有写能力。当并发写请求较大时，哨兵模式并不能缓解写压力。
```

功能：

```
监控：能持续监控Redis的主从实例是否正常工作；
通知：当被监控的Redis实例出问题时，能通过API通知系统管理员或其他程序；
自动故障恢复：如果主实例无法正常工作，Sentinel将启动故障恢复机制把一个从实例提升为主实例，其他的从实例将会被重新配置到新的主实例，且应用程序会得到一个更换新地址的通知。
配置提供：因为sentinel保存着Redis主从的信息，所以Redis可以从sentinel那获得所有的配置信息。
```

由于：sentinel也是一个进程有挂掉的可能，所以sentinel也会启动多个形成一个sentinel集群， 最好不要和Redis部署在同一台机器

优缺点：sentinel模式基本可以满足一般生产的需求，具备高可用性。但是当数据量过大到一台服务器存放不下的情况时，主从模式或sentinel模式就不能满足需求了

1. cluster模式

> cluster的出现是为了解决单机Redis容量有限的问题，将Redis的数据根据一定的规则分配到多台机器 cluster可以说是sentinel和主从模式的结合体，通过cluster可以实现主从和master重选功能，所以如果配置两个副本三个分片的话，就需要六个Redis实例。 因为Redis的数据是根据一定规则分配到cluster的不同机器的，当数据量过大时，可以新增机器进行扩容

注意： 这种模式适合数据量巨大的缓存要求，当数据量不是很大使用sentinel即可。

### 单机版

**Redis源码安装**

```bash
# 已验证：复制粘贴即可

export REDIS_VERSION=4.0.10
export REDIS_DIR=/home/redis
export REDIS_PASS=123456

yum install gcc gcc-c++ tcl -y

curl -O http://download.redis.io/releases/redis-${REDIS_VERSION}.tar.gz
tar -zxf redis-${REDIS_VERSION}.tar.gz
cd redis-${REDIS_VERSION}
make 

# 安装到指定目录,，默认在/usr/local/bin ; 并创建存放配置文件的目录 ; 修改为后台启动；设置密码；启动redis服务端
make PREFIX=${REDIS_DIR} install
mkdir ${REDIS_DIR}/config
cp redis.conf ${REDIS_DIR}/config/
sed -i 's/^daemonize no/daemonize yes/g' ${REDIS_DIR}/config/redis.conf
sed -i "s/^# requirepass foobared/requirepass ${REDIS_PASS}/g" ${REDIS_DIR}/config/redis.conf
cd ${REDIS_DIR}/bin/ && ./redis-server ../config/redis.conf
```

**Redis客户端测试**

```bash
[root@localhost bin]# ./redis-cli 
127.0.0.1:6379> ping
(error) NOAUTH Authentication required.
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set name test
OK
127.0.0.1:6379> get name
"test"

# 停止 redis 服务
./redis-cli shutdown
or
./redis-cli -a '123456' shutdown 2>/dev/null
or
./redis-cli -h 127.0.0.1 -p 6379 -a "123456" shutdown 2>/dev/null
```

**Systemctl 守护**

```bash
vi /lib/systemd/system/redis.service
//将以下复制进redis.service，注意目录信息

[Unit]
Description=Redis
After=network.target

[Service]
Type=forking
PIDFile=/var/run/redis_6379.pid
ExecStart=/home/redis/bin/redis-server /home/redis/config/redis.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

//重载系统服务
systemctl daemon-reload

systemctl start redis
systemctl enable redis
```

**redis.conf 基本配置解释**

```bash
//使redis能在后台运行，启用守护进程
daemonize yes
//指定pid文件保存路径
pidfile /data/redisdata/6379/redis_6379.pid
//日志级别，学习阶段设为debug
loglevel debug
//绑定主机地址，未绑定端口
bind 127.0.0.1
//指定日志文件目录
logfile /data/redisdata/6379/redis.log
//指定数据持久化RDB数据文件和AOF日志文件存放路径
dir /data/redisdata/6379/dbdata/
//启动数据持久化AOF日志文件
appendonly yes
//每秒钟执行一次AOF同步（默认）
appendfsync everysec
//启用AOF同步重写，当AOF日志文件过大时执行重写（默认）
no-appendfsync-on-rewrite no
//当AOF文件超过1GB的100%时即2GB时自动启动日志文件重写（默认）
//允许重写的最小AOF日志文件
auto-aof-rewrite-min-size 1Gb
//配置最大内存（根据本机物理内存考量）
maxmemory 3GB
//内存不足的缓存淘汰算法，我选的是——从所有配置了过期时间的键中驱逐使用频率最少的键
maxmemory-policy volatile-lfu
//从淘汰算法选出的列表中随机选择的样本数量
maxmemory-samples 5

//设置连接密码，客户端连接Redis时需要通过auth <password>命令提供密码（默认关闭，可选不设）
requirepass "密码"
```

**常见错误**

```bash
zmalloc.h:50:31: 致命错误：jemalloc/jemalloc.h：没有那个文件或目录
make 改变 ---> make MALLOC=libc


make clean 清除
```

### Redis Cluster 集群安装(部署一)

**环境：**

> Centos7 系统 < 单机集群 | 多台服务器集群>

**安装 ruby 环境，管理 redis 接口**

> < 仅启动集群 redis 服务器安装即可，不需要所有都安装 >

```bash
yum -y install ruby ruby-devel rubygems rpm-build
gem install redis

# 也许会出现错误，要高于 2.3.0 版本
    ERROR:  Error installing redis:
            redis requires Ruby version >= 2.3.0

curl -L get.rvm.io | bash -s stable

# 也许会提示：把提示的命令执行一遍，再往下执行
    command curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -
    command curl -sSL https://rvm.io/pkuczynski.asc | gpg2 --import -3


source /usr/local/rvm/scripts/rvm
rvm install 2.4.1
rvm use 2.4.1
gem install redis
```

**所有的 redis 服务器都执行**

```bash
# 6个 redis 节点、节点起始端口、绑定地址、Redis版本、安装目录、是否开启持久化、是否后台运行
export REDIS_NODE=6
export REDIS_PORT=7001
export REDIS_HOST=0.0.0.0
export REDIS_VERSION=4.0.10
export REDIS_DIR=/home/redis
export APPENDONLY_ENABLE=yes
export DAEMON_ENABLE=yes

# export REDIS_PASS=123456


yum install gcc gcc-c++ tcl -y
curl -O http://download.redis.io/releases/redis-${REDIS_VERSION}.tar.gz
tar -zxf redis-${REDIS_VERSION}.tar.gz
cd redis-${REDIS_VERSION}
make && make test && make PREFIX=${REDIS_DIR} install

mkdir ${REDIS_DIR}/run
mkdir ${REDIS_DIR}/conf
mkdir ${REDIS_DIR}/log
mkdir ${REDIS_DIR}/redis-cluster/{7001..7006} -p
mkdir ${REDIS_DIR}/dbdata/{7001..7006} -p 
cp src/redis-trib.rb ${REDIS_DIR}/bin/
```

**来到启动集群的服务器**

> < 已安装 ruby 环境的服务器 >

```bash
cp redis.conf ${REDIS_DIR}/conf/redis.conf.bak
cd ${REDIS_DIR}/conf/ && cp redis.conf.bak redis-${REDIS_PORT}.conf


# 修改节点端口、绑定地址、 开启cluster集群模式、设置超时、设置集群节点配置文件路径、设置pid文件位置、设置数据存储位置、设置日志位置、设置数据备份方式

sed -i "s%^port 6379%port ${REDIS_PORT}%g" redis-${REDIS_PORT}.conf
sed -i "s/^bind 127.0.0.1/bind ${REDIS_HOST}/g" redis-${REDIS_PORT}.conf
sed -i "s/^daemonize no/daemonize ${DAEMON_ENABLE}/g" redis-${REDIS_PORT}.conf
sed -i 's/^# cluster-enabled yes/cluster-enabled yes/g' redis-${REDIS_PORT}.conf
sed -i 's/# cluster-node-timeout 15000/cluster-node-timeout 5000/g' redis-${REDIS_PORT}.conf
sed -i "s%^# cluster-config-file nodes-6379.conf%cluster-config-file ${REDIS_DIR}/redis-cluster/${REDIS_PORT}/node-${REDIS_PORT}.conf%g" redis-${REDIS_PORT}.conf
sed -i "s%/var/run/redis_6379.pid%${REDIS_DIR}/run/redis_${REDIS_PORT}.pid%g" redis-${REDIS_PORT}.conf
sed -i "s%dir ./%dir ${REDIS_DIR}/dbdata/${REDIS_PORT}%g" redis-${REDIS_PORT}.conf
sed -i "s%^logfile \"\"%logfile \"${REDIS_DIR}/log/${REDIS_PORT}.log\"%g" redis-${REDIS_PORT}.conf
sed -i "s%^appendonly no%appendonly ${APPENDONLY_ENABLE}%g" redis-${REDIS_PORT}.conf

# sed -i "s/^# requirepass foobared/requirepass ${REDIS_PASS}/g" redis-${REDIS_PORT}.conf


# 查看是否成功 
sed -n "/^\s*[^#\t].*/p" redis-${REDIS_PORT}.conf


# 复制每个节点的配置文件，并修改
for ((i=1;i<${REDIS_NODE};i++));do other_port=`expr ${REDIS_PORT} + $i`; cp redis-${REDIS_PORT}.conf redis-${other_port}.conf; done
for ((i=1;i<${REDIS_NODE};i++));do other_port=`expr ${REDIS_PORT} + $i`; sed -i "s/${REDIS_PORT}/${other_port}/g" redis-${other_port}.conf; done
```

**选择一：单机版，不适合生产环境**

> 一个服务器启动 6 个 redis 节点

```bash
export LOCALHOST_IP=192.168.1.45


# 启动集群
cd ${REDIS_DIR}/bin
for ((i=0;i<${REDIS_NODE};i++));do other_port=`expr ${REDIS_PORT} + $i`; ./redis-server ../conf/redis-${other_port}.conf; done


＃ 创建集群： --replicas 1　设置每个 master 有几个 slave
arrs=''
mynode=$(ps -A -ostat,cmd |grep -v grep |grep redis|awk '{print $3}' |awk -F':' '{print $2}'| while read line; do  arrs="$arrs $LOCALHOST_IP:$line"; echo $arrs;done |tail -n 1)
./redis-trib.rb create --replicas 1 $mynode


# 询问分配是否ｏｋ：　输入ｙｅｓ即可； 最后检查集群状态
./redis-trib.rb check ${LOCALHOST_IP}:${REDIS_PORT}


# 设为开机自启动
for ((i=1;i<${REDIS_NODE};i++));do other_port=`expr ${REDIS_PORT} + $i`; echo "${REDIS_DIR}/bin/redis-server ${REDIS_DIR}/conf/redis-${other_port}.conf" >> /etc/rc.local; done
chmod +x /etc/rc.local

完成安装！
```

**选择二：生产环境**

> 多服务器，考虑到成本和资源最大化，这里使用三台服务器启动6个redis节点

```bash
# 例如
节点一： 172.17.0.2     < 已安装 ruby 环境，是启动集群节点 >
节点二： 172.17.0.3
节点二： 172.17.0.4
```

```bash
# 配置文件传给另外两个节点
scp -r /home/redis/conf/* root@172.17.0.3:/home/redis/conf
scp -r /home/redis/conf/* root@172.17.0.4:/home/redis/conf


# 启动每个节点 redis 
# 172.17.0.2
cd /home/redis/bin/ && ./redis-server ../conf/redis-7002.conf
cd /home/redis/bin/ && ./redis-server ../conf/redis-7001.conf

# 172.17.0.2
cd /home/redis/bin/ && ./redis-server ../conf/redis-7003.conf
cd /home/redis/bin/ && ./redis-server ../conf/redis-7004.conf

# 172.17.0.4
cd /home/redis/bin/ && ./redis-server ../conf/redis-7005.conf
cd /home/redis/bin/ && ./redis-server ../conf/redis-7006.conf


###################  开机自启动
# 172.17.0.2
echo "/home/redis/bin/redis-server /home/redis/conf/redis-7002.conf" >> /etc/rc.d/rc.local
echo "/home/redis/bin/redis-server /home/redis/conf/redis-7001.conf" >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local

# 172.17.0.3
echo "/home/redis/bin/redis-server /home/redis/conf/redis-7003.conf" >> /etc/rc.local
echo "/home/redis/bin/redis-server /home/redis/conf/redis-7004.conf" >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local

# 172.17.0.4
echo "/home/redis/bin/redis-server /home/redis/conf/redis-7005.conf" >> /etc/rc.d/rc.local
echo "/home/redis/bin/redis-server /home/redis/conf/redis-7006.conf" >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local



# 启动集群
cd /home/redis/bin/ 

./redis-trib.rb create --replicas 1 \
172.17.0.2:7001 \
172.17.0.2:7002 \
172.17.0.3:7003 \
172.17.0.3:7004 \
172.17.0.4:7005 \
172.17.0.4:7006


# 输入 yes, 进入节点中查看集群状态
./redis-cli -c -p 7002
cluster info 
cluster nodes
```

***

**Nginx 负责转发**

```bash
# tcp 转发
upstream redis {
    server 172.17.0.2:7001;
    server 172.17.0.2:7002;
    server 172.17.0.3:7003;
    server 172.17.0.3:7004;
    server 172.17.0.3:7005;
    server 172.17.0.3:7006;
    check interval=3000 rise=2 fall=5 timeout=5000 default_down=true type=tcp;
}
server {
    listen 51001;
    allow 192.168.0.0/16;
    deny all;
    proxy_connect_timeout 600s;
    proxy_timeout 600s;
    proxy_pass redis;
}
```

### Redis Cluster 集群安装(部署二)

端口号：7000-7005

本次分布式分片集群在一台LInux系统即可，只需要安装多个实例作为集群配置。

**安装ruby环境支持：**

> yum安装2.0.0版本，但是gem需要2.2.2版本以上，所以选择编译

**下载并安装ruby环境：**

```bash
wget https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.1.tar.gz
tar xf ruby-2.6.1.tar.gz && cd ruby-2.6.1/
./configure --prefix=/usr/local/ruby
make && make install && echo $?
echo 'export PATH=$PATH:/usr/local/ruby/bin' >> /etc/profile
source /etc/profile
```

**修改gem工具国内源：**

```bash
# 查看gem工具源地址
gem sources -l
# 添加一个阿里云的gem工具源
gem sources -a http://mirrors.aliyun.com/rubygems/
# 删除gem工具默认国外源
gem sources --remove https://rubygems.org/
# 下载当前最新版本集群插件
gem install redis -v 4.1.0
```

**集群节点准备：**

```bash
mkdir /data/700{0..5}
```

**配置7000端口实例：**

```bash
vim /data/7000/redis.conf
port 7000
daemonize yes
pidfile /data/7000/redis.pid
loglevel notice
logfile "/data/7000/redis.log"
dbfilename dump.rdb
dir /data/7000
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
```

**拷贝其他端口实例：**

```bash
# 拷贝配置文件
cp /data/7000/redis.conf /data/7001/
cp /data/7000/redis.conf /data/7002/
cp /data/7000/redis.conf /data/7003/
cp /data/7000/redis.conf /data/7004/
cp /data/7000/redis.conf /data/7005/

# 修改配置文件内容
sed -i 's#7000#7001#g' /data/7001/redis.conf
sed -i 's#7000#7002#g' /data/7002/redis.conf
sed -i 's#7000#7003#g' /data/7003/redis.conf
sed -i 's#7000#7004#g' /data/7004/redis.conf
sed -i 's#7000#7005#g' /data/7005/redis.conf
```

**启动所有实例：**

```bash
redis-server /data/7000/redis.conf
redis-server /data/7001/redis.conf
redis-server /data/7002/redis.conf
redis-server /data/7003/redis.conf
redis-server /data/7004/redis.conf
redis-server /data/7005/redis.conf
```

**创建命令软链接：**

（这个命令过期了，现在使用redis-cli命令）（可选执行命令）

```bash
ln -s /usr/local/redis-5.0.2/src/redis-trib.rb /usr/sbin/
```

**查看进程：**

```bash
ps -ef |grep redis-server
```

![](https://2134947750-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvILwbD2PrkBCkSitM3m4%2Fuploads%2FnQVWBczNwwKqWDh9riAd%2F1460000039832618.png?alt=media\&token=5c9f06a0-98bd-4344-b826-a544d1ece7c6)

**加入所有实例节点到集群管理：**

```bash
# --replicas 1",1是代表每一个主有一个从,后面的是所有节点的地址与端口信息
redis-cli --cluster create --cluster-replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
```

分布式主从规则为，前三个实例节点是主，对应的后面三个实例节点为从节点，如果replicas 2，那就多加3个实例节点

**查看主节点状态：**

```bash
redis-cli -p 7000 cluster nodes|grep master
```

![](https://2134947750-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvILwbD2PrkBCkSitM3m4%2Fuploads%2FmfPKfqhh523CoDKgHc9k%2F1460000039832619.png?alt=media\&token=1e495b10-899b-4a2d-9b9e-87dc133f7bd7)

**查看从节点状态：**

```bash
redis-cli -p 7000 cluster nodes|grep slave
```

![](https://2134947750-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvILwbD2PrkBCkSitM3m4%2Fuploads%2FHTJuVY2N7NhvuxsRF6UM%2F1460000039832620.png?alt=media\&token=d5d0fcde-c0f4-453d-96ac-9e14384644a3)

**Redis-分布式集群（管理）**

**集群节点增加准备：**

```bash
mkdir /data/700{6..7}

拷贝其他端口实例：

# 拷贝配置文件
cp /data/7000/redis.conf /data/7006/
cp /data/7000/redis.conf /data/7007/

# 修改配置文件内容
sed -i 's#7000#7006#g' /data/7006/redis.conf
sed -i 's#7000#7007#g' /data/7007/redis.conf
```

启动新节点实例：

```bash
redis-server /data/7006/redis.conf
redis-server /data/7007/redis.conf
```

**查看进程：**

```bash
ps -ef |grep redis-server
```

![](https://2134947750-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvILwbD2PrkBCkSitM3m4%2Fuploads%2Fdsb8pszeXzENth7Kd906%2F1460000039832622.png?alt=media\&token=566f5bfa-771d-4fbe-9d7b-54719749479b)

**添加主节点：（7000实例是管理节点）**

```bash
#'把7006实例添加到7000实例这个主节点所在集群内(此时已经有了4个主节点)
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000
```

**查看主节点状态：**

```bash
redis-cli -p 7000 cluster nodes|grep master
```

![](https://2134947750-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvILwbD2PrkBCkSitM3m4%2Fuploads%2F7PHKk5vg3DlVYpL5MVHx%2F1460000039832624.png?alt=media\&token=e254bb43-b3e6-47a0-82f4-71a269224903)

**转移slot（重新分片）：**

```bash
#'操作集群管理节点从新分配，并在交互界面指定分片大小、选择接收分片的节点ID
redis-cli --cluster reshard 127.0.0.1:7000

How many slots do you want to move (from 1 to 16384)? 4096
#通过人工手动计算数据分片总大小除以主节点后的数字

What is the receiving node ID? 2129d28f0a86fc89571e49a59a0739812cff7953
#选择接收数据分片的节点ID，（这是新增节点7006实例的ID号）

Source node #1: all
#选择从哪些源主节点重新分片给新主节点）（all是所有节点）

Do you want to proceed with the proposed reshard plan (yes/no)? yes           
#确认修改以上的操作
```

**重新查看主节点状态：（可以看到集群数据的重新分片）**

```bash
redis-cli -p 7000 cluster nodes|grep master
```

![](https://2134947750-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvILwbD2PrkBCkSitM3m4%2Fuploads%2FD9HirvKbM8TggyN9tDNa%2F1460000039832625.png?alt=media\&token=ef23283d-215a-48e2-bb50-e7736650fb3e)

**添加从节点：**

```bash
#'把7007实例节点添加到7006实例主节点内，并指定对应7006实例主节点坐在集群的管理节点
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7000 --cluster-slave --cluster-master-id 2129d28f0a86fc89571e49a59a0739812cff7953
```

**查看从节点状态：**

```bash
redis-cli -p 7000 cluster nodes|grep slave
```

![](https://2134947750-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvILwbD2PrkBCkSitM3m4%2Fuploads%2FJkdrb4Y5XcYPzm16dAq7%2F1460000039832623.png?alt=media\&token=5ab13568-61b3-4618-8ebf-00656f76ceaf)

**集群节点删除准备：**

**移动要删除节点的数据分片：**

```bash
#'操作集群管理节点从新分配，并在交互界面指定分片大小、选择接收分片的节点ID
redis-cli --cluster reshard 127.0.0.1:7000

#方法是根据要删除master节点的分片位置，然后一个组分一个节点 ， 也可以直接移动所有数据片到一个节点

How many slots do you want to move (from 1 to 16384)? 1365                    
#通过人工手动查看数据分片总大小

What is the receiving node ID? e64f9074a3733fff7baa9a4848190e56831d5447
#选择接收数据分片的节点ID，（这是新增节点7006实例的ID号）

Source node #1: 2129d28f0a86fc89571e49a59a0739812cff7953
#选择从哪些源主节点重新分片给新主节点（这是要删除的主节点的ID号）

Source node #2: done
#这是结束命令

Do you want to proceed with the proposed reshard plan (yes/no)? yes           
#确认修改以上的操作
```

**重新查看主节点状态：（可以看到集群数据的重新分片）**

```bash
redis-cli -p 7000 cluster nodes|grep master
```

![](https://2134947750-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvILwbD2PrkBCkSitM3m4%2Fuploads%2FAoHFcoEnoEAmhsv3UpG9%2F1460000039832626.png?alt=media\&token=caeb6e4f-69ae-4e4d-98be-489c04483589)

**继续移动数据片：**

```bash
#'操作集群管理节点从新分配，并在交互界面指定分片大小、选择接收分片的节点ID
redis-cli --cluster reshard 127.0.0.1:7000

# 方法是根据要删除master节点的分片位置，然后一个组分一个节点 ， 也可以直接移动所有数据片到一个节点

How many slots do you want to move (from 1 to 16384)? 1366                    #通过人工手动查看数据分片总大小

What is the receiving node ID? f6c1aaea3a8c56e0c7dee8ad7ae17e26dd04244c
#选择接收数据分片的节点ID，（这是新增节点7006实例的ID号）

Source node #1: 2129d28f0a86fc89571e49a59a0739812cff7953
#选择从哪些源主节点重新分片给新主节点（这是要删除的主节点的ID号）

Source node #2: done
#这是结束命令

Do you want to proceed with the proposed reshard plan (yes/no)? yes           
#确认修改以上的操作
```

**重新查看主节点状态：（可以看到集群数据的重新分片）**

```bash
redis-cli -p 7000 cluster nodes|grep master
```

![](https://2134947750-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvILwbD2PrkBCkSitM3m4%2Fuploads%2FclKeQdc1IwbREqa0tT40%2F1460000039832627.png?alt=media\&token=009e0176-d495-40cd-b316-1edab9337da9)

**最后一次移动数据片：**

```bash
#'操作集群管理节点从新分配，并在交互界面指定分片大小、选择接收分片的节点ID
redis-cli --cluster reshard 127.0.0.1:7000

#方法是根据要删除master节点的分片位置，然后一个组分一个节点 ， 也可以直接移动所有数据片到一个节点

How many slots do you want to move (from 1 to 16384)? 1365                    
#通过人工手动查看数据分片总大小

What is the receiving node ID? 5a0df4ea0af5f35c1248e45e88d44c3f2e10169f
Source node #1: 2129d28f0a86fc89571e49a59a0739812cff7953
Source node #2: done                
```

**重新查看主节点状态：（可以看到集群数据的重新分片）**

```bash
redis-cli -p 7000 cluster nodes|grep master
```

![](https://2134947750-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvILwbD2PrkBCkSitM3m4%2Fuploads%2FINT2nLle9M7evPBGStVy%2F1460000039832629.png?alt=media\&token=c98be7ee-c29f-4b1c-a5f8-ab392d190dd6)

**删除清空数据片的主节点：**

```bash
#'删除已经清空数据的7006实例
redis-cli --cluster del-node 127.0.0.1:7006 2129d28f0a86fc89571e49a59a0739812cff7953

#删除没有主库的7007实例
redis-cli --cluster del-node 127.0.0.1:7007 821bcf78c5e4c0b08aa7a5d514214b657ebec4ab
```

![](https://2134947750-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvILwbD2PrkBCkSitM3m4%2Fuploads%2FxyWbYlB0hZIG4XX3dWNh%2F1460000039832628.png?alt=media\&token=2b5dd2be-39f8-43fa-ab97-a70de18ceb04)

**其他配置管理：**

```bash
#内存信息查看
redis-cli -p 6382 -a redhat info memory

#设置最大只能使用100MB的内存
redis-cli -p 6382 -a redhat config set maxmemory 102400000
```
