文章目录
- 安装Redis服务
- Windows下安装Redis服务
- CentOS下安装Redis服务
- Ubuntu下安装Redis服务
- Redis 单实例模式配置
- 启动方式
- 默认配置
- 启动时指定配置
- 配置文件启动
- Redis 命令行客户端
- 停止 Redis 服务
- Redis Desktop Manager 连接不上虚拟机的 Redis 服务
- Spring Boot 连接 Redis 配置
- Redis 主从架构配置
- Redis 主从从架构配置
- 主从数据同步原理
- 复制架构中出现宕机情况
- Redis 哨兵架构
- Redis 集群架构
- Redis 集群新增节点
- Redis 集群删除节点
- Redis 集群故障
- Redis 主从集群
- 使用集群需要注意的事项
- 使用 Jedis 连接到集群
安装Redis服务
Windows下安装Redis服务
解压包并在Redis根目录打开cmd窗口。
安装服务:redis-server.exe --service-install redis.windows.conf --loglevel verbose
卸载服务:redis-server.exe --service-uninstall
启动服务:redis-server.exe --service-start
关闭服务:redis-server.exe --service-stop
启动Redis客户端:redis-cli.exe -h 127.0.0.1 -p 6379
参考:
CentOS下安装Redis服务
# 下载Redis指定版本的源码压缩包到当前目录
$ wget http://download.redis.io/releases/redis-3.0.7.tar.gz
# 解压缩Redis源码压缩包
$ tar xzf redis-3.0.7.tar.gz
# 建立一个redis目录的软连接,指向redis-3.0.7。
$ ln -s redis-3.0.7 redis
# 进入redis目录
$ cd redis
# 安装gcc(操作系统已安装gcc,无需执行)
yum -y install cpp binutils glibc glibc-kernheaders glibc-common glibc-devel gcc make gcc-c++ libstdc++-devel tcl
# 编译(编译之前确保操作系统已经安装gcc)
$ make
# 安装(默认将Redis的相关运行文件放到/usr/local/bin/下)
$ make install
# 将Redis服务安装到指定目录中
$ make PREFIX=/usr/local/redis install
# 可以在任何目录执行redis-cli–v查看Redis的版本
$ redis-cli -v
编译时出现:cc1: 错误:无法识别的命令行选项“-std=c11”
错误。
Ubuntu下安装Redis服务
sudo apt-get update
sudo apt-get install redis-server
Redis 单实例模式配置
启动方式
有三种方法启动Redis:默认配置、运行配置、配置文件启动。
默认配置
这种方法会使用Redis的默认配置来启动。
启动时指定配置
# redis-server --configKey1 configValue1 --configKey2 configValue2
使用6380端口启动Redis服务:
配置文件启动
Redis目录下都会有一个redis.conf配置文件,里面就是Redis的默认配置。
# redis-server /opt/redis/redis.conf
常用配置:
# 以守护进程的方式启动Redis
# Redis服务进程的 pid 默认写入到 /var/run/redis.pid 文件中
daemonize yes
# 记录了redis服务进程的ID,如果不修改会被新端口redis服务进程的进程id覆盖掉,推荐修改
pidfile /var/run/redis-6379.pid
# 端口
port 6379
# Redis 工作目录(存放持久化文件和日志文件)
dir ./
# 日志文件名
logfile "redis-6379.log"
发现远程客户端还是连接不了,一般情况是服务器防火墙未开放 6379 端口的访问,开启放行即可访问。
Redis 命令行客户端
交互式方式:通过redis-cli-h{host}-p{port}的方式连接到Redis服务
redis-cli -h {host} -p {port}
-h 默认 127.0.0.1
-p 默认 6379
[root@yqLinux2 ~]# redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379>
redis-cli -h 127.0.0.1 -p 6379 get hello
redis-cli -h 127.0.0.1 -p 6379 shutdown
命令方式:用 redis-cli 就可以直接得到命令的返回结果
[root@yqLinux2 ~]# redis-cli -h 127.0.0.1 -p 6379 ping
PONG
[root@yqLinux2 ~]# redis-cli -h 127.0.0.1 -p 6379 set name "hello redis"
OK
[root@yqLinux2 ~]#
停止 Redis 服务
Redis提供了shutdown命令来停止Redis服务。
[root@yqLinux2 ~]# redis-cli -h 127.0.0.1 -p 6379 shutdown
日志输出如下:
# User requested shutdown... #客户端发出的shutdown命令
* Saving the final RDB snapshot before exiting.
#保存RDB持久化文件(有关Redis持久化的特性在1.2节已经进行了简单的介绍,RDB是Redis的一种
持久化方式)
* DB saved on disk #将RDB文件保存在磁盘上
# Redis is now ready to exit, bye bye... #关闭
注意:
Redis关闭的过程:断开与客户端的连接、持久化文件生成,是一种相对优雅的关闭方式。
除了可以通过shutdown命令关闭Redis服务以外,还可以通过kill进程号的方式关闭掉Redis,但是不要粗暴地使用kill-9强制杀死Redis服务,不但不会做持久化操作,还会造成缓冲区等资源不能被优雅关闭,极端情况会造成AOF和复制丢失数据的情况。
Redis Desktop Manager 连接不上虚拟机的 Redis 服务
关闭防火墙: service iptables stop
开启 redis-cli 客户端:
config set requirepass 123456
auth 123456
Spring Boot 连接 Redis 配置
spring:
redis:
host: 192.168.56.81
port: 6379
timeout: 1000
password: 123456
设置redis配置文件: 这样就可以不用配置 password 参数了
bind 192.168.56.81
Redis 主从架构配置
是一种读写分离方案,主作为写库,从作为读库,从库默认是只读的(通过设置slave-read-only no参数可修改为非只读,一般不会这样做),数据只能从主库写入。
将 Redis 分别安装在三台机器上。
ip:192.168.56.60(主)、 192.168.56.61(从)、 192.168.56.62(从)
三台机器建立主从关系后,主库历史数据会同步到从库中,并且是覆盖性质的。
缺点:
- 不保证高可用性,主库机器一挂,Redis服务就挂了。
- 主库承担了写责任和数据同步的责任,可能会导致负载过高。
查看主从信息:
[root@colony-1 redis-3.0.1]# redis-cli
127.0.0.1:6379> INFO replication
192.168.56.60主库配置:
无需配置。
[root@colony-1 redis-3.0.1]# redis-cli
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.56.62,port=6379,state=online,offset=99,lag=0
slave1:ip=192.168.56.61,port=6379,state=online,offset=99,lag=0
master_repl_offset:99
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:98
127.0.0.1:6379>
role:角色
connected_slaves:从库数量
slave0:从库信息
192.168.56.61从库配置:
[root@colony-2 redis-3.0.1]# redis-cli
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:192.168.56.60
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_repl_offset:491
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379>
192.168.56.62从库配置:
[root@yqLinux redis-3.0.1]# redis-cli
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:192.168.56.60
master_port:6379
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_repl_offset:561
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379>
配置模版:
master:6379;slave:6380;slave:6381
# redis-6379.conf
daemonize yes
port 6379
dir ./
logfile "redis-6379.log"
dbfilename "dump-6379.rdb"
pidfile "/var/run/redis-6379.pid"
# redis-6380.conf
daemonize yes
port 6380
dir ./
logfile "redis-6380.log"
dbfilename "dump-6380.rdb"
pidfile "/var/run/redis-6380.pid"
slaveof 127.0.0.1 6379
# redis-6381.conf
daemonize yes
port 6381
dir ./
logfile "redis-6381.log"
dbfilename "dump-6381.rdb"
pidfile "/var/run/redis-6381.pid"
slaveof 127.0.0.1 6379
启动3个Redis服务:
[root@yqLinux2 conf]# redis-server redis-6379.conf
[root@yqLinux2 conf]# redis-server redis-6380.conf
[root@yqLinux2 conf]# redis-server redis-6381.conf
[root@yqLinux2 conf]# ps -ef|grep redis-server | grep -v 'grep'
root 4814 1 0 23:55 ? 00:00:00 redis-server *:6379
root 4818 1 0 23:55 ? 00:00:00 redis-server *:6380
root 4822 1 0 23:55 ? 00:00:00 redis-server *:6381
[root@yqLinux2 conf]#
确认主从关系:
# 主节点视角
$ redis-cli -h 127.0.0.1 -p 6379 info replication
# Replication
role:master
490connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=281,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=281,lag=0
.................
# 从节点视角
$ redis-cli -h 127.0.0.1 -p 6380 info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
.................
使用 slaveof 建立复制关系:
[root@yqLinux2 conf]# redis-cli -p 6380
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
127.0.0.1:6380>
[root@yqLinux2 conf]# redis-cli -p 6381
127.0.0.1:6381> slaveof 127.0.0.1 6379
OK
127.0.0.1:6381>
[root@yqLinux2 conf]# redis-cli -p 6379 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=43,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=43,lag=0
master_repl_offset:43
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:42
[root@yqLinux2 conf]#
使用 config rewrite 目录重写配置文件:
[root@yqLinux2 conf]# redis-cli -p 6380 config rewrite
OK
[root@yqLinux2 conf]# redis-cli -p 6381 config rewrite
OK
[root@yqLinux2 conf]# cat redis-6380.conf
daemonize yes
port 6380
dir "/root/conf"
logfile "redis-6380.log"
# Generated by CONFIG REWRITE
slaveof 127.0.0.1 6379
[root@yqLinux2 conf]# cat redis-6381.conf
daemonize yes
port 6381
dir "/root/conf"
logfile "redis-6381.log"
# Generated by CONFIG REWRITE
slaveof 127.0.0.1 6379
[root@yqLinux2 conf]#
断开复制关系:
# 执行slaveof no one来断开与主节点复制关系。
[root@yqLinux2 conf]# redis-cli -p 6380 slaveof no one
OK
Redis 主从从架构配置
只需要配置192.168.56.62机器:
查看192.168.56.62信息:
[root@yqLinux redis-3.0.1]# redis-cli
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:192.168.56.61
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:29
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379>
查看192.168.56.61信息:
[root@colony-2 redis-3.0.1]# redis-cli
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:192.168.56.60
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:85
slave_priority:100
slave_read_only:1
connected_slaves:1
slave0:ip=192.168.56.62,port=6379,state=online,offset=1,lag=0
master_repl_offset:1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histle
主从数据同步原理
1、当从库和主库建立MS关系后,会向主数据库发送SYNC命令;
2、主库接收到SYNC命令后会开始在后台保存快照(RDB持久化过程),并将期间接收到的写命令缓存起来;
3、当快照完成后,主Redis会将快照文件和所有缓存的写命令发送给从Redis;
4、从Redis接收到后,会载入快照文件并且执行收到的缓存的命令;
之后,主Redis每当接收到写命令时就会将命令发送从Redis,从而保证数据的一致;
复制架构中出现宕机情况
如果在主从复制架构中出现宕机的情况,需要分情况看:
1、从Redis宕机
a)这个相对而言比较简单,在Redis中从库重新启动后会自动加入到主从架构中,自动完成同步数据;
b)问题? 如果从库在断开期间,主库的变化不大,从库再次启动后,主库依然会将所有的数据做RDB操作吗?还是增量更新?(从库有做持久化的前提下)
i.不会的,因为在Redis2.8版本后就实现了,主从断线后恢复的情况下实现增量复制。
2、主Redis宕机
a)这个相对而言就会复杂一些,需要以下2步才能完成
i.第一步,在从数据库中执行SLAVEOF NO ONE命令,断开主从关系并且提升为主库继续服务;
ii.第二步,将主库重新启动后,执行SLAVEOF命令,将其设置为其他库的从库,这时数据就能更新回来;
这个手动完成恢复的过程其实是比较麻烦的并且容易出错,有没有好办法解决呢?当前有的,Redis提高的哨兵(sentinel)的功能。
Redis 哨兵架构
主从复制的问题:
Redis主从复制模式下,一旦主节点出现了故障不可达,需要人工干预 进行故障转移,无论对于Redis的应用方还是运维方都带来了很大的不便。 对于应用方来说无法及时感知到主节点的变化,必然会造成一定的写数据丢失和读数据错误,甚至可能造成应用方服务不可用。对于Redis的运维方来说,整个故障转移的过程是需要人工来介入的,故障转移实时性和准确性 都无法得到保障。
- 主节点的写能力受到单机的限制。
- 主节点的存储能力受到单机的限制。
Redis Sentinel的高可用性:Redis Sentinel
是一个分布式架构,其中包含若干个Sentinel节点和Redis 数据节点,每个Sentinel节点会对数据节点和其余Sentinel节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果被标识的是主节点,它还会和其他Sentinel节点进行“协商”,当大多数Sentinel节点都认为主节点不可达时,它们会选举出一个Sentinel节点来完成自动故障转移的工作,同时会将这个变化实时通知给Redis应用方。整个过程完全是自动的,不需要人工来介入,所以这套方案很有效地解决了Redis的高可用问题。
哨兵的作用就是对Redis系统的运行情况进行监控,它是一个独立的进程。它有两个功能:
- 监控主数据库和从数据库是否运行正常;
- 主数据库出现故障后自动将从数据库转化为主数据;
优点: 保证高可用
缺点: 并没有解决master服务器写压力
配置Sentinel节点:
# redis-sentinel-26379.conf
port 26379
daemonize yes
logfile "26379.log"
dir ./
# 代表sentinel-26379节点需要监控127.0.0.1:6379这个主节点,2代表判断主节点失败至少需要2个Sentinel节
点同意,mymaster是主节点的别名。
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
# redis-sentinel-26380.conf
port 26380
daemonize yes
logfile "26380.log"
dir ./
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
# redis-sentinel-26381.conf
port 26381
daemonize yes
logfile "26381.log"
dir ./
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
启动Sentinel节点:
[root@yqLinux2 conf]# redis-sentinel redis-sentinel-26379.conf
[root@yqLinux2 conf]# redis-sentinel redis-sentinel-26380.conf
[root@yqLinux2 conf]# redis-sentinel redis-sentinel-26381.conf
[root@yqLinux2 run]# redis-cli -h 127.0.0.1 -p 26379 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3
[root@yqLinux2 run]# redis-cli -h 127.0.0.1 -p 26380 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3
[root@yqLinux2 run]#
发现配置发生了变化:
去掉了默认配置,例如parallel-syncs、failover-timeout、down-after-milliseconds参数。
port 26379
daemonize yes
logfile "26379.log"
dir "/home/yangqian/software/redis-4.0.9/sentinel_conf"
sentinel myid 5748f7e7c711aa5e1cc1f665767eef2a62c05472
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
# Generated by CONFIG REWRITE
maxclients 4064
sentinel known-slave mymaster 127.0.0.1 6381
sentinel known-slave mymaster 127.0.0.1 6380
sentinel known-sentinel mymaster 127.0.0.1 26381 570bbb1a7365fd1d55708dca748835bdb6d3f3fe
sentinel known-sentinel mymaster 127.0.0.1 26380 4c62dd03b3bea72a0f798acb4af32384eda521ae
sentinel current-epoch 0
关闭主节点:
[root@yqLinux2 conf]# redis-cli -p 6379 shutdown
[root@yqLinux2 conf]#
发现从节点6380自动切换为主节点了:
[root@yqLinux2 run]# redis-cli -h 127.0.0.1 -p 26380 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=127.0.0.1:6380,slaves=2,sentinels=3
[root@yqLinux2 run]# redis-cli -h 127.0.0.1 -p 6381 info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:17440
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
[root@yqLinux2 run]# redis-cli -h 127.0.0.1 -p 6380 info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=19183,lag=0
master_repl_offset:19449
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:19448
[root@yqLinux2 run]#
配置说明:
sentinel monitor <master-name> <ip> <port> <quorum>
master-name:监控的名字
ip、port:监控的主节点ip和port
quorum:判定主节点最终不可达所需要的票数
sentinel down-after-milliseconds <master-name> <times>
判定节点不可达的超时时间,单位:毫秒
sentinel parallel-syncs <master-name> <nums>
用来限制在一次故障转移之后,每次向新的主节点发起复制操作的从节点个数
Redis 集群架构
主从复制,每个数据库都要保存整个集群中的所有数据,容易形成木桶效应(性能取决于性能最差的那台机器)。
1、开启集群
cluster-enabled yes
2、安装 ruby 环境
# 安装ruby
yum -y install zlib ruby rubygems
rz上传redis-3.2.1.gem
# 使用 gem 目录安装redis接口,gem是ruby的一个工具包
gem install -l redis-3.2.1.gem
3、创建集群
# 进入 redis 安装包路径下的 src目录
[root@yqLinux src]# pwd
/home/redis-3.0.1/src
# 创建集群
[root@yqLinux src]# ./redis-trib.rb create --replicas 0 192.168.56.60:6379 192.168.56.61:6379 192.168.56.62:6379
>>> Creating cluster
Connecting to node 192.168.56.60:6379: OK
Connecting to node 192.168.56.61:6379: OK
Connecting to node 192.168.56.62:6379: OK
>>> Performing hash slots allocation on 3 nodes...
Using 3 masters:
192.168.56.62:6379
192.168.56.61:6379
192.168.56.60:6379
M: 6a2690f7781b1af14044c77ec01143159c0923f4 192.168.56.60:6379
slots:10923-16383 (5461 slots) master
M: fab96e689e3d261555435690862bef46db48d1ec 192.168.56.61:6379
slots:5461-10922 (5462 slots) master
M: d5dcfdbde0d5144ce8c471cd5b14ea5b78d1dce6 192.168.56.62:6379
slots:0-5460,5798 (5462 slots) master
创建集群出现的问题:
[root@yqLinux src]# ./redis-trib.rb create --replicas 0 192.168.56.60:6379 192.168.56.61:6379 192.168.56.62:6379
>>> Creating cluster
Connecting to node 192.168.56.60:6379: OK
Connecting to node 192.168.56.61:6379: OK
Connecting to node 192.168.56.62:6379: OK
[ERR] Node 192.168.56.62:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
表示创建集群中的所有数据库必须为空。
使用 FLUSHALL 命令可以情况所有数据。
Redis集群添加数据报错:
[root@colony-1 home]# redis-cli -c
127.0.0.1:6379> set name 123
(error) CLUSTERDOWN The cluster is down
127.0.0.1:6379>
原因:一般情况下是由于集群中的slots分布不正确导致的。在移除node节点或增加node节点的时候,需要重新分配slot,不然就会出现上面的问题。
集群添加数据出现错误后,发现用 check 命令检查,提示16384个slot分配不均匀。
解决方案:删除所有节点上的 dump.rdb 和 nodes.conf 文件后,重新再创建集群。
[root@yqLinux src]# ./redis-trib.rb check 192.168.56.60:6379
Connecting to node 192.168.56.60:6379: OK
>>> Performing Cluster Check (using node 192.168.56.60:6379)
M: 6a2690f7781b1af14044c77ec01143159c0923f4 192.168.56.60:6379
slots: (0 slots) master
0 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[ERR] Not all 16384 slots are covered by nodes
4、测试
# 在 192.168.56.62 节点上保存数据发现出错。
[root@yqLinux redis-3.0.1]# redis-cli
127.0.0.1:6379> set name 999
(error) MOVED 5798 192.168.56.61:6379
127.0.0.1:6379>
原因:因为 name 的 hash 槽信息在 192.168.56.61 上。
解决方案:使用 redis-cli -c 命令登录。
# 发现会自动重定向到槽所在节点的机器上。
[root@yqLinux redis-3.0.1]# redis-cli -c
127.0.0.1:6379> set name 666
-> Redirected to slot [5798] located at 192.168.56.61:6379
OK
192.168.56.61:6379>
5、集群相关命令
# 检查集群运行情况
[root@colony-2 src]# ./redis-trib.rb check 192.168.56.62:6379
# 修复集群
[root@colony-2 src]# ./redis-trib.rb fix 192.168.56.62:6379
# 重新分配 slot
[root@colony-2 src]# ./redis-trib.rb reshard 192.168.56.62:6379
# redis 命令查看插槽分布情况
[root@colony-1 src]# redis-cli
127.0.0.1:6379> cluster nodes
6663d54db59bbdc02a257b12889079c55cf6420a 192.168.56.60:6379 myself,master - 0 0 1 connected 10923-16383
0ed5ff416e96f9829162e81cbe257acc951fac90 192.168.56.61:6379 master - 0 1555092653644 2 connected 5461-10922
3449e658a263a573b31669539b1684b892ba8bea 192.168.56.62:6379 master - 0 1555092654666 3 connected 0-5460
127.0.0.1:6379>
5、插槽和 key 的关系
计算 key 的插槽值:根据 key 值使用算法计算出哈希值,再将哈希值对16384取余得到插槽值,保证 key 插槽值一定在0-16383范围内。
Redis 集群新增节点
水平扩展。
# 新增集群节点命令,第一个ip是被新增节点的ip,第二个ip是已经存在集群节点的ip
./redis-trib.rb add-node 192.168.56.63:6379 192.168.56.60:6379
出现了下面的这个错误信息。
原因:可能是当前数据库有数据了。
解决方案:清空数据库,并删除 dump.rdb 后重启 redis 服务后问题解决。
添加成功。
已添加到集群,但是未分配插槽。
#重新分配插槽
[root@yqLinux src]# ./redis-trib.rb reshard 192.168.56.62:6379
Redis 集群删除节点
第一步:将要删除节点上的插槽转移到其他节点上。
执行:[root@colony-2 src]# ./redis-trib.rb reshard 192.168.56.61:6379
输入需要删除节点上的插槽数据量
输入转到到哪个节点的节点id
输入插槽来源的节点id
输入done,开始转移
第二步:使用命令删除节点。
[root@colony-2 src]# ./redis-trib.rb del-node <被删除节点ip>:<port> <被删除节点的节点id>
Redis 集群故障
当集群中的节点超过半数认为该目标节点疑似下线,那么该节点就会被标记为下线;
当集群中的任何一个节点下线,就会导致插槽区有空档,不完整,会导致该集群不可用。
解决方案:在集群中可以使用主从模式实现某一个节点的高可用。
Redis 主从集群
当某节点(master)宕机后,集群会将该节点的从数据库(slave)转变为(master)继续完成集群服务。
三台服务器:192.168.56.60、192.168.56.61、192.168.56.62
每台服务器创建2个redis节点,端口号分别为:7000、7001
1、在192.168.56.60上创建2个redis节点
mkdir redis_cluster // 创建集群目录
mkdir 7000 7001 // 分别代表2个节点 其对应端口 7000 7001
cp redis.conf 7000 // 将redis配置文件拷贝到7000目录
cp redis.conf 7001 // 拷贝到7001目录
分别对7001,7002文件夹中的2个文件修改对应的配置
daemonize yes // redis后台运行
pidfile /var/run/redis_7000.pid // pidfile文件对应7000,7001
port 7000 // 端口7000,7001
cluster-enabled yes // 开启集群 把注释#去掉
cluster-config-file nodes_7000.conf // 集群的配置 配置文件首次启动自动生成 7000,7001
cluster-node-timeout 5000 // 请求超时 设置5秒够了
2、在61和62上创建2个redis节点,方式和第一台机器一样
3、分别启动redis节点
redis-server redis_cluster/7000/redis.conf
redis-server redis_cluster/7001/redis.conf
4、创建集群
# 创建集群,指定了从库数量为1,创建顺序为主库(3个)、从库(3个):
./redis-trib.rb create --replicas 1 192.168.56.60:7000 192.168.56.61:7000 192.168.56.60:7001 192.168.56.61:7001
5、创建完成
6、测试
# 本地连接 -c:表示在集群中会重定向,-p:端口号
[root@colony-2 redis_cluster]# redis-cli -c -p 7000
# 远程连接
[root@yqLinux redis_cluster]# redis-cli -h 192.168.56.61 -p 7001
使用集群需要注意的事项
1、多键的命令操作(如MGET、MSET),如果每个键都位于同一个节点,则可以正常支持,否则会提示错误。
2、集群中的节点只能使用0号数据库,如果执行SELECT切换数据库会提示错误。
192.168.56.62:7000> select 1
(error) ERR SELECT is not allowed in cluster mode
使用 Jedis 连接到集群
添加依赖:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.2</version>
</dependency>
示例:
public class JedisClusterTest {
public static void main(String[] args) {
Set<HostAndPort> nodes = new HashSet<HostAndPort>();
// 集群中任意节点的ip即可,因为集群都是相通的
nodes.add(new HostAndPort("192.168.56.60", 7000));
// 这里的JedisCluster不需要关闭,因为内部已经关闭连接了
JedisCluster jedisCluster = new JedisCluster(nodes);
jedisCluster.set("ddd", "66666666");
}
}