分布式缓存之redis介绍、安装、主从、集群实例

本文详细介绍了Redis的体系架构、数据类型、持久化、安装配置、主从复制和Sentinel高可用方案,以及集群搭建。Redis作为高性能的Key-Value数据库,支持丰富的数据类型,如字符串、哈希、列表、集合和有序集合。文章还探讨了Redis的持久化机制,包括快照和AOF文件,以及如何调优和进行故障转移。此外,文章涵盖了哨兵系统和集群部署,确保高可用性和数据分片。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录

1. redis介绍

开源的c语言编写,支持网络,基于内存亦可持久化的日志型、高性能的key-value数据库,并提供多种语言的apl,通常被称为数据结构服务器,因为值(value)可以是字符串,哈希,列表,集合和有序集合等类型
redis与其他key-value缓存产品的特点

  • 支持数据持久化,可以将内存放入数据保存在磁盘中,启动时再次加载进行使用
  • 支持多种数据结构的存储,丰富的数据类型-redix支持二进制案例strings,list,hashes,set以及oredred set数据类型的操作
  • 支持数据备份,即master-slave模式的数据备份
  • 所有操作都是原子性的,溶蚀redis还支持几个操作合并后的原子执行
  • 性能极高,redis的读的速度为110000次/s。写的速度为81000次/s

1.1 体系架构

(1) redis结构

在这里插入图片描述
互联网数据目前基本使用两种方式存储,关系数据库或者key value,但是这些互联网业务本身并不属于这两种数据类型,比如用户在社会化平台的关系,就是一个列表,如果用关系数据库存储就需要转换成一种多行记录的形式,这种形式存在很多冗余数据,每一行都需要存储一些重复的信息。如果用key value存储则修改和删除比较麻烦,需要讲所有数据读出再写入。
redis在内存中设计了各种数据类型,让业务能够高速原子的访问这些数据结构,并且不需要关心持久存储的问题,从架构解决了前面两种存储需要走一些弯路的问题。

(2)备份模式

AOF文件比RDB文件大,切恢复速度慢,这样导致违背高可用行性的本意。在redis中还有另一种方法来达到目的:replication。由于redis的高性能,复制基本没有延迟,这样达到了防止单点故障且实现了高可用。
在这里插入图片描述

(3)容灾模式

在这里插入图片描述

1.2 数据类型

redis支持五中数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)

(1)string(字符串)

是redis最基本的数据类型,可以理解成与memcache一模一样的类型。一个key对应一个value。意思是redis的string可以包含任何数据,比如jpg图片或序列化对象。
一个键最大存储512MB

127.0.0.1:6379> set var 123   # set赋值
OK
127.0.0.1:6636> get var	#get取值
"123"

(2)hash(哈希)

是一个键值对集合,一个string类型的field和value的映射表。hash特别适合用于存储对象

127.0.0.1:6379> HSET set1 name "zhangsan"
(integer) 1
127.0.0.1:6379> HSET set1 score "100"
(integer) 1
127.0.0.1:6379> HSET set2 name "lisi"
(integer) 1
127.0.0.1:6379> HSET set2 score "99"
(integer) 1
127.0.0.1:6379> HGET set1 name
"zhangsan"
127.0.0.1:6379> HGET set1 score
"100"
127.0.0.1:6379> HGET set2 name
"lisi"
127.0.0.1:6379> HGET set2 score
"99"
  • hset&hget一次只能往哈希结构里面插入一个键值对,如果插入多个可以用hmset&hmget
127.0.0.1:6379> HMSET var:1 name zhangsan wanger lisi
OK
127.0.0.1:6379> HGETALL var:1
1) "name"
2) "zhangsan"
3) "wanger"
4) "lisi"
# 说明:var:1是键值,每个hash可以存储232-1键值对
hmset用于建立hash对象,hgetall用于获取hash对象
  • hset和hmset操作对比
127.0.0.1:6379> hset test1 name1 zhangsan name2 wanger name3 lisi name4 mazi
(integer) 4
127.0.0.1:6379> HMGET test2 name1 zhangsi name2 wangsan name3 liwu name4 mazi
1) (nil)
2) (nil)
3) (nil)
4) (nil)
5) (nil)
6) (nil)
7) (nil)
8) (nil)
127.0.0.1:6379> HGETALL test1
1) "name1"
2) "zhangsan"
3) "name2"
4) "wanger"
5) "name3"
6) "lisi"
7) "name4"
8) "mazi"
127.0.0.1:6379> HGETALL test2
(empty list or set)
127.0.0.1:6379> hget test1 name1
"zhangsan"
127.0.0.1:6379> hget test2 name1
(nil)

(3)list(列表)

127.0.0.1:6379> lpush lvar 1
(integer) 1
127.0.0.1:6379> lpush lvar a
(integer) 2
127.0.0.1:6379> lpush lvar ab
(integer) 3
127.0.0.1:6379> lrange lvar 0 1
1) "ab"
2) "a"
127.0.0.1:6379> lrange lvar 0 10
1) "ab"
2) "a"
3) "1"
127.0.0.1:6379> lrange lvar 2 2
1) "1"

说明:lpush往列表的前面插入;lrange后面的数字是范围(闭区间)
列表最多可存储232-1元素(4294967295,每个列表可存储40多亿)

(4)set(集合)

redis的set是string类型的无序集合。
集合是通过哈希表实现的,

127.0.0.1:6379> sadd setvar redis
(integer) 1
127.0.0.1:6379> sadd setvar kongkong
(integer) 1
127.0.0.1:6379> sadd setvar kongkong
(integer) 0
127.0.0.1:6379> sadd setvar kongkongruye
(integer) 1
127.0.0.1:6379> SMEMBERS setvar
1) "kongkong"
2) "redis"
3) "kongkongruye"

说明:set往集合中插入元素,smembers列举出集合中的元素
成功插入返回1;错误插入返回0

(5)zset(sorted set:有序集合)

zset和set一样也是string类型的集合,且不允许有重复的元素;不同指出在于zset关联一个double类型的分数,redis通过分数在对集合中的元素排序;zset的元素是唯一的,但分数可以是重复的

127.0.0.1:6379> ZADD zvar 1 redis
(integer) 1
127.0.0.1:6379> ZADD zvar 1 kongkong
(integer) 1
127.0.0.1:6379> ZADD zvar 1 kongkong
(integer) 0
127.0.0.1:6379> ZADD zvar 1 kongkongruye
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE zvar 0 2
1) "kongkong"
2) "kongkongruye"
3) "redis"
127.0.0.1:6379> ZRANGEBYSCORE zvar 0 4
1) "kongkong"
2) "kongkongruye"
3) "redis"

127.0.0.1:6379> ZRANGEBYSCORE zvar  -3
(error) ERR wrong number of arguments for 'zrangebyscore' command
127.0.0.1:6379> ZRANGEBYSCORE zvar  -3 10
1) "kongkong"
2) "kongkongruye"
3) "redis"
127.0.0.1:6379> ZRANGEBYSCORE zvar  -3 1
1) "kongkong"
2) "kongkongruye"
3) "redis"
127.0.0.1:6379> ZRANGEBYSCORE zvar  -1 0
(empty list or set)
分数为float(可正,负,0)

说明:成功插入返回1,否则返回0

1.3 应用场景

  • 缓存系统:与memcached类似
  • 计数器:例如转发数,评论数,有了原子递增,可以加上计数,用getset重置或者让其过期
  • 消息队列系统:类似于kafka,运行稳定并且快速,支持模式匹配,能够实时订阅与取消频道
  • 社交网络:redis可以非常好的与社交网络结合,用户和状态消息将会聚焦很多有用的信息,很多交互,如实时聊天就是通过redis来实现的
  • 过期项目处理:通过系统时间为关键词,用来保持列表能够按时间排序,对currenttime和timeto_live进行检索,完成查找过期项目的艰巨任务。
  • 实时系统:使用位图来布隆过滤器,例如实现垃圾邮件过滤系统的开发变得非常容易

2. redis持久化

2.1 方式

  • snapshotting
  • append-only file
  • 虚拟内存
  • diskstore

2.2 snapshotting

快照是默认的持久化方式,将内存中的数据以快照的方式写入二进制文件中,默认的文件名为dump.rdb。可以通过配置设置自动做快照持久化的方式,可以配置redis在n秒内如果超过m个key被修改就自动做快照。

save 900 1 #900秒内如果超过1个key被修改,则发起快照保存
save 300 10 #300秒内容如超过10个key被修改,则发起快照保存
save 60 10000

在这里插入图片描述
client也可以用save或者bgsave命令通知redis做一次快照持久化,save操作是在主线程中保存快照的。由于redis使用一个主线程来处理所有client的请求,这种方式会阻塞所有的client请求,所以不推荐使用,另一点需要注意的事,每次快照持久化都是将内存数据完全写入到磁盘一次,并不是增量的只同步脏数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘io操作,可能会严重影响性能

另外由于快照方式是一定时间间隔做一次的,如果redis意外down掉的话,就会丢失最后一次快照后的所有修改,如果应用要求不能丢失任何修改的话,可以采用aof持久化方式。

2.3 append-only file

使用aof持久化方式时,redis会将每一个收到的写命令通过write函数追加到文件中(默认时appendonly.aof)。当redis重启时会通过重新执行文件中的保存的写命令来在内存中重建整个数据库的内容。由于os会在内核中缓存write做的修改,所以可能不是立即写到磁盘上。这样的aof方式的持久化也有可能会丢失部分修改。可以通过修改配置文件告诉redis,我们想要通过fsync函数强制os写入到磁盘的时机。有三种方式

appendonly yes  #启用aof持久化方式
# appendfsync always # 每次收到写命令就立即强制写入磁盘,速度最慢,但是保证了完全的持久哈,不推荐使用
appendfsync eversec  #每秒强制写入磁盘一次,在性能和持久化方面做了很好的折中。推荐
# appendfsync no # 完全依赖os,性能最好,持久化没保证

aof的方式同时带来了另一个问题,持久化文件会变的越来越大。例如:调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为恢复数据库的状态只需要保存一条set test100 就够了。为了压缩aof的持久化文件,redis提供了bgrewriteaof命令,接收到此命令。redis将使用与快照类似的方式将内存的数据以命令的方式保存在临时文件中,最后替换原来的文件。如下
在这里插入图片描述
需要注意的时重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据内容用命令的方式重写了一个新的aof文件,这点和快照有点类似

2.4 数据持久化对比

RDB方式AOF方式
描述默认方式,实现方式是定时将内存的快照持久化到硬盘aof即append only file,再写入内存数据的同时将操作命令保存到日志文件中
优点使用单独的子进程进行持久化,主进程不会进行任何的io操作,保证redis的高性能保证了数据的可靠性及高安全性,保证更高的数据完整性
缺点RDB是件个月i段时间进行持久化,如果持久化之间redis发生故障,数据会丢失在并发更改上万的系统上。命令日志是一个分场庞大的数据,管理维护成本非常高,回复创建时间会非常长;AOF文件比RDB文件大,且恢复速度慢
应用场景更适合数据要求不严谨的时候适合数据完整性要求高的场景

3. redis安装配置及运用

3.1 安装

[root@redis1 ~]# yum install gcc gcc-c++ make
[root@redis1 ~]# wget http://download.redis.io/releases/redis-5.0.4.tar.gz
[root@redis1 ~]# tar xf redis-5.0.4.tar.gz -C /usr/local/src/
[root@redis1 ~]# cd /usr/local/
[root@redis1 local]# ln -s /usr/local/src/redis-5.0.4 ./redis
[root@redis1 redis]# cd redis/
[root@redis1 redis]# make
[root@redis1 redis]# echo $?
0
[root@redis1 redis]# mkdir -p /data/redis
[root@redis1 redis]# make PREFIX=/data/redis install
[root@redis1 redis]# echo $?
0
[root@redis1 redis]# mkdir /data/redis/conf
[root@redis1 redis]# cp -p redis.conf /data/redis/conf/

3.2 生成指令

[root@redis1 ~]# cd /data/redis/bin/
[root@redis1 bin]# ll
总用量 32700
-rwxr-xr-x. 1 root root 4366640 8月  21 14:45 redis-benchmark
-rwxr-xr-x. 1 root root 8101288 8月  21 14:45 redis-check-aof
-rwxr-xr-x. 1 root root 8101288 8月  21 14:45 redis-check-rdb
-rwxr-xr-x. 1 root root 4806864 8月  21 14:45 redis-cli
lrwxrwxrwx. 1 root root      12 8月  21 14:45 redis-sentinel -> redis-server
-rwxr-xr-x. 1 root root 8101288 8月  21 14:45 redis-server

3.3 启动

[root@redis1 ~]# /data/redis/bin/redis-server /data/redis/conf/redis.conf
12516:C 21 Aug 2020 14:47:41.864 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
12516:C 21 Aug 2020 14:47:41.864 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=12516, just started
12516:C 21 Aug 2020 14:47:41.864 # Configuration loaded
12516:M 21 Aug 2020 14:47:41.865 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 5.0.4 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 12516
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

12516:M 21 Aug 2020 14:47:41.868 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
12516:M 21 Aug 2020 14:47:41.868 # Server initialized
12516:M 21 Aug 2020 14:47:41.868 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
12516:M 21 Aug 2020 14:47:41.868 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
12516:M 21 Aug 2020 14:47:41.868 * Ready to accept connections

# 重新打开一个终端进行测试
[root@redis1 ~]# ps -ef | grep redis
root      12516   7956  0 14:47 pts/0    00:00:00 /data/redis/bin/redis-server 127.0.0.1:6379
root      12553  12528  0 14:48 pts/1    00:00:00 grep --color=auto redis

# 关闭服务
[root@redis1 ~]# /data/redis/bin/redis-cli shutdown

3.4 调优(此时我们发现启动时的时候有三个警告)

net.core.somaxconn  表示socket监听的backlog上限,backlog就是socket的监听队列,当一个请求尚未被处理或建立时,会进入backlog。而socket server可以一次性处理backlog的所有请求。处理后的请求不在位于监听队列中,当server处理请求较慢,以至于监听队列被填满后,新来的请求会被拒绝,linux的参数此默认值为128.当服务端繁忙时,128是远远不够的。需要调大backlog

overcommit_memory  时一个内核对内存分配的一种策略,
		当此值为0时表示内核将检查是否有足够的可用内存共应用进程使用;如果足够使用,则允许内存申请,否则,则内存申请失败,并把错误返回给应用进程。
		当此值为1时,表示内核允许分配所有的物理内存,而不管当前的内存状态如何。		当此值为2时,表示内核允许分配超过所有物理内存和交换空间总和的内存

hugepage  hugepage动态分配

优化三个警告

(1) 12516:M 21 Aug 2020 14:47:41.868 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
[root@redis1 ~]# cat /proc/sys/net/core/somaxconn
128
# 临时修改
[root@redis1 ~]# echo 1024 > /proc/sys/net/core/somaxconn

(2) 12516:M 21 Aug 2020 14:47:41.868 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
[root@redis1 ~]# cat /proc/sys/vm/overcommit_memory
0
[root@redis1 ~]# echo 1 >  /proc/sys/vm/overcommit_memory

(3)12516:M 21 Aug 2020 14:47:41.868 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
[root@redis1 ~]# cat  /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
[root@redis1 ~]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
[root@redis1 ~]# cat  /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]

3.5 客户端连接

(1)本地连接

# 开启服务(此时并没有警告了)
[root@redis1 ~]# /data/redis/bin/redis-server /data/redis/conf/redis.conf
# 另一台终端进行测试
[root@redis1 ~]# /data/redis/bin/redis-cli
127.0.0.1:6379> set test 123
OK
127.0.0.1:6379> get test
"123"
127.0.0.1:6379> set IP 192.168.10.11
OK
127.0.0.1:6379> get IP
"192.168.10.11"

(2)远程链接

需要已经安装redis可以使用redis-cli命令的
安装方法上面有,此处略

# 注意:修改配置文件的时候是修改启动的时指定的配置文件,可以用netstat -tunlap查看监听端口是否开放测试的ip
[root@redis1 ~]# vim /data/redis/conf/redis.conf
# 修改69行
bind 0.0.0.0
# 修改507行
requirepass 123456
# 验证密码是否正确

127.0.0.1:6379> auth 123456
OK

# 另一台连接
[root@test ~]# /data/redis/bin/redis-cli -h 192.168.10.11 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.10.11:6379> get test
"123"
192.168.10.11:6379> get IP
"192.168.10.11"

(3)命令别名

[root@redis1 ~]# vim /data/redis/conf/redis.conf  #大概520行左右
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
rename-command set settest  #注意,此处用纯数字好像会报错
# 重启服务端测试
pe -ef| grep redis
kill #进程号
# 测试
192.168.10.11:6379> set 123 456
(error) ERR unknown command `set`, with args beginning with: `123`, `456`,
192.168.10.11:6379> settest qwe 111
OK
192.168.10.11:6379> get qwe
"111"

(4)设置启动日志

[root@redis1 ~]# mkdir /data/redis/log
[root@redis1 ~]# vim /data/redis/conf/redis.conf  #大概 172 行左右
 logfile "/data/redis/log/logs"

(5)设置redis自启动脚本

[root@redis1 ~]# cat redserver.sh
#!/bin/bash
password=123456
redstop(){
    # redis-cli stop
    /data/redis/bin/redis-cli -a $password shutdown
}

redstart(){
    # redis start
    /data/redis/bin/redis-server /data/redis/conf/redis.conf &
}

case $1 in
    start)
        redstart
        ;;
    stop)
        redstop
        ;;
    restart)
        redstop
        redstart
        ;;
    *)
        echo "Usage:$0 (start|stop|restart)"
esac

[root@redis1 ~]# chmod +x redserver.sh
[root@redis1 ~]# mv redserver.sh /data/redis/
[root@redis1 profile.d]# vim redserver.sh
export PATH=/data/redis/:$PATH

(6)退出

# 本地退出
[root@test ~]# /data/redis/bin/redis-cli shutdown
# 远程退出就需要加上ip 端口登信息
[root@test ~]# /data/redis/bin/redis-cli -h 192.168.10.11 -p 6379 -a 123456 shutdown
# 退出客户端
192.168.10.11:6379> exit

3.6 查看redis-server统计信息

INFO

127.0.0.1:6379> INFO
# Server
redis_version:5.0.4
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:e279380029e91390
redis_mode:standalone
os:Linux 3.10.0-957.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:4.8.5
process_id:13059
run_id:f3a7938c9d2e36d3a388803813cda3d9c8416446
tcp_port:6379
uptime_in_seconds:12286
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:4181588
executable:/data/redis/bin/redis-server
config_file:/data/redis/conf/redis.conf

# Clients
connected_clients:1
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0

# Memory
used_memory:855920
used_memory_human:835.86K
used_memory_rss:3772416
used_memory_rss_human:3.60M
used_memory_peak:875336
used_memory_peak_human:854.82K
used_memory_peak_perc:97.78%
used_memory_overhead:841510
used_memory_startup:791136
used_memory_dataset:14410
used_memory_dataset_perc:22.24%
allocator_allocated:1260536
allocator_active:1552384
allocator_resident:10383360
total_system_memory:952262656
total_system_memory_human:908.15M
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.23
allocator_frag_bytes:291848
allocator_rss_ratio:6.69
allocator_rss_bytes:8830976
rss_overhead_ratio:0.36
rss_overhead_bytes:-6610944
mem_fragmentation_ratio:4.63
mem_fragmentation_bytes:2958496
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:49694
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1598006541
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:360448
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:0

# Stats
total_connections_received:14
total_commands_processed:69
instantaneous_ops_per_sec:0
total_net_input_bytes:3720
total_net_output_bytes:94189
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:23
keyspace_misses:4
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:180
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0

# Replication
role:master
connected_slaves:0
master_replid:64f887c9de46eaa7653ce9357e90ae7eb955b647
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:10.949295
used_cpu_user:10.860994
used_cpu_sys_children:0.004137
used_cpu_user_children:0.000000

# Cluster
cluster_enabled:0

# Keyspace
db0:keys=13,expires=0,avg_ttl=0

3.7 配置文件详解

# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
daemonize yes
# 默认情况下 redis 不是作为守护进程运行的,如果你想让它在后台运行,你就把它改成 yes。
# nothing bad happens, the server will start and run normally.
pidfile /var/run/redis_6379.pid
# 当redis作为守护进程运行的时候,它会把 pid 默认写到 /var/run/redis.pid 文件里面,你也可以指定写入的位置
# in order to get the desired effect.
tcp-backlog 511
# TCP 监听的最大容纳数量
# 在高并发的环境下,你需要把这个值调高以避免客户端连接缓慢的问题。
# Examples:
bind 127.0.0.1 ::1  192.168.1.100
# 默认情况下,redis 在 server 上所有有效的网络接口上监听客户端连接。
# 你如果只想让它在一个网络接口上监听,那你就绑定一个IP或者多个IP。
# Close the connection after a client is idle for N seconds (0 to disable)
timeout 0
# 指定在一个 client 空闲多少秒之后关闭连接(0 就是不管它)
# Redis default starting with Redis 3.2.1.
tcp-keepalive 0
# tcp 心跳包
# 如果设置为非零,则在与客户端缺乏通讯的时候使用 SO_KEEPALIVE 发送 tcp acks 给客户端。
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice
# 定义日志级别(debug,verbose,notice,warning)
# output for logging but daemonize, logs will be sent to /dev/null
logfile ""
# 指定日志文件的位置
# Set the number of databases. The default database is DB 0, you can select
# a different one on a per-connection basis using SELECT <dbid> where
# dbid is a number between 0 and 'databases'-1
databases 16
# 设置数据库的数目。
# 默认数据库是 DB 0,你可以在每个连接上使用 select 命令选择一个不同的数据库,
# 但是 dbid 必须是一个介于 0 到 databasees - 1 之间的值
# However if you have setup your proper monitoring of the Redis server
# and persistence, you may want to disable this feature so that Redis will
# continue to work as usual even if there are problems with disk,
# permissions, and so forth.
stop-writes-on-bgsave-error yes
# 默认情况下,如果 redis 最后一次的后台保存失败,redis 将停止接受写操作,
# 这样以一种强硬的方式让用户知道数据不能正确的持久化到磁盘,
# 否则就会没人注意到灾难的发生。
# 如果后台保存进程重新启动工作了,redis 也将自动的允许写操作。
# the dataset will likely be bigger if you have compressible values or keys.
rdbcompression yes
# 是否在 dump .rdb 数据库的时候使用 LZF 压缩字符串
# 默认都设为 yes
# 如果你希望保存子进程节省点 cpu ,你就设置它为 no ,
# 不过这个数据集可能就会比较大
# tell the loading code to skip the check.
rdbchecksum yes
# 是否校验rdb文件
# The filename where to dump the DB
dbfilename dump.rdb
# 设置 dump 的文件位置
# Note that you must specify a directory here, not a file name.
dir ./
#指定本地数据库存放目录
slaveof <masterip> <masterport>
#设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
masterauth <master-password>
#当master服务设置了密码保护时,slave服务连接master的密码
equirepass foobared
#设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭
maxclients 10000
#设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息
maxmemory <bytes>
#指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区
appendonly no
指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的
数据会在一段时间内只存在于内存中。默认为no
appendfilename "appendonly.aof"
#指定更新日志文件名,默认为appendonly.aof
appendfsync everysec
#指定更新日志条件,共有3个可选值:
no:表示等操作系统进行数据缓存同步到磁盘()
always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
everysec:表示每秒同步一次(折衷,默认值)
activerehashing yes
指定是否激活重置哈希,默认为开启
include /path/to/local.conf
#指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件。

3.8 发布订阅

redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接受消息
redis剋短可以订阅任意数量的频道
原理:下图展示了三个客户端client1,client2,clent5订阅了channel1
在这里插入图片描述
当有新消息通过publish发送给channel1时,这时候channel1就会把消息同事发布给订阅者
在这里插入图片描述
例子创建订阅频道redisChat

127.0.0.1:6379> subscribe redisChat
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1
# 多打开几个客户端,订阅 channel redisChat
[root@redis1 ~]# /data/redis/bin/redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> subscribe redisChat
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1
1) "message"
2) "redisChat"
3) "hello world"

客户端接收到消息

192.168.10.11:6379> psubscribe redisChat
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "redisChat"
3) (integer) 1
1) "pmessage"
2) "redisChat"
3) "redisChat"
4) "hello world"

3.9 事务

保证多个操作同事成功执行,在一个事务中,任何一个操作发生error,所有操作都会回滚。

192.168.10.11:6379> MULTI
OK
192.168.10.11:6379> set a 10
QUEUED
192.168.10.11:6379> INCR a
QUEUED
192.168.10.11:6379> INCR a
QUEUED
192.168.10.11:6379> INCR a 12
(error) ERR wrong number of arguments for 'incr' command
192.168.10.11:6379> get a
QUEUED
192.168.10.11:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
192.168.10.11:6379> EXEC
(error) ERR EXEC without MULTI
192.168.10.11:6379> set a 10
OK
192.168.10.11:6379> MULTI
OK
192.168.10.11:6379> INCR a
QUEUED
192.168.10.11:6379> INCR a
QUEUED
192.168.10.11:6379> EXEC
1) (integer) 11
2) (integer) 12

4. 主从复制企业级方案

4.1 概述

(1)redis的复制功能是支持多个数据库之间的数据同步。一类是主数据库(master)一类是从数据库(slave),主数据库可以进行读写操作,当发生写操作的时候自动将数据同步从数据库,而从数据库一般是只读的,并接收主数据库同步过来的数据,一个主数据可以的有多个从数据库,而一个从数据库只能有一个主数据库。
(2)通过redis的复制功能可以很好的实现数据库的读写分离,提高服务器的负载能力,主数据库主要进行写操作,而从数据库负责读操作。

4.2 主从复制过程

主从复制过程:见下图
在这里插入图片描述
(1)当一个从数据库启动时,会向主数据库发送sync命令
(2)主数据库接收到sync命令后会开始在后台保存快照(执行rdb操作),并将保存期间接收到的命令缓存起来
(3)当快照完成后,redis会将快照文件和所有缓存的命令发送给从数据库
(4)从数据库接收到后,会载入快照文件并执行收到的缓存的命令。
注意“redis2.8之前的版本,当主从数据库同步的时间从数据库因为网络原因断开重连后会重新执行上述操作,不支持断点续传。redis2.8之后支持断点续传

4.3 配置

(1)主从复制replication

  • 一个redis服务可以有多个该服务的复制品,这个redis服务成为master,其他的复制品成为slave
  • 只有网络连接正常,master会一直将自己的数据库更新同步给slave,保持主从同步
  • 只有master可以执行写命令,slave只能执行读命令
  • 客户端可以连接slaves执行读请求,来降低master的读压力

在这里插入图片描述
在这里插入图片描述

(2)主从复制的创建

方法1:redis-server --slave of,配置当前服务称为某个redis服务的slave
实例1

目前有两个redis实例,一个基于当前主机的6379端口,一个基于当前主机的6380端口,将6379端口机器设置成6380的slave

[root@redis1 conf]# /data/redis/bin/redis-server /data/redis/conf/redis.conf &
[1] 8144
[root@redis1 conf]# /data/redis/bin/redis-server --port 6380 --slaveof 127.0.0.1 6379 &
[2] 8148

在这里插入图片描述

验证
127.0.0.1:6379> set cat 123
OK

127.0.0.1:6380> get cat
"123"
加一台远程从库测试
[root@test ~]# /data/redis/bin/redis-server /data/redis/conf/redis.conf --slaveof 192.168.10.11 6379

在这里插入图片描述

验证
127.0.0.1:6379> set see 123
OK
[root@redis1 ~]# /data/redis/bin/redis-cli -p 6380
127.0.0.1:6380> get see
"123"
[root@test ~]# /data/redis/bin/redis-cli
127.0.0.1:6379> get see
"123"

#注,从库此时只能读,不能写

方法2:Slaveof host port命令,将当前服务状态从master修改为别的服务的slave
redis > SLAVEOF 192.168.42.201 6379 ,将服务器转换为Slave
redis > SLAVEOF NO ONE ,将服务器重新恢复到Master,不会丢弃已经同步的数据
实例2

1)先启动一台master

# 启动6379
[root@redis1 ~]# /data/redis/bin/redis-server /data/redis/conf/redis.conf &

2)启动一个redis客户端和上面那台监听6379端口的redis实例连接

[root@redis1 ~]# /data/redis/bin/redis-cli -p 6379
127.0.0.1:6379> set mse look
OK
127.0.0.1:6379> get mse
"look"

此时模拟这样一个场景:
有一台master实例master,master已经处于正常工作状态,接收读写请求,这个时候master的压力过大,我们想在启动一个redis实例来分带master的读压力,假设我们启动的这个实例是slave。
已知master的IP为127.0.0.1,端口为6379
首先我们先启动一个redis的slave实例,同时启动一个客户端连接这个实例(此处直接做远程的)

[root@test ~]# /data/redis/bin/redis-server /data/redis/conf/redis.conf &
[1] 7885

# 再起终端连接
[root@test ~]# /data/redis/bin/redis-cli
127.0.0.1:6379>
# 此时两端没有联系,故取不到上面设定的值
127.0.0.1:6379> get mes
(nil)

# 设置连接
127.0.0.1:6379> SLAVEOF 192.168.10.11 6379
OK
127.0.0.1:6379> get mse
"look"
方法3:启动时,服务器读取配置文件,并自动成指定服务器的从服务器
实例3

redis主从结构支持一主多从

主节点:192.168.10.11
从节点:192.168.10.12

注意:所有节点的配置都一样
只需要额外修改从节点中redis的配置文件中的slaveof属性即可
1) 配置文件修改如下(/data/redis/conf/redis.conf)
在这里插入图片描述
2) 启动服务

[root@redis1 ~]# /data/redis/bin/redis-server /data/redis/conf/redis.conf  &
[2] 8272
[root@test ~]# /data/redis/bin/redis-server /data/redis/conf/redis.conf &           [1] 7919
# 主库插入
[root@redis1 ~]# /data/redis/bin/redis-cli
127.0.0.1:6379> set name lisan
OK
# 从库查询
[root@test ~]# /data/redis/bin/redis-cli
127.0.0.1:6379> get name
"lisan"

4.4 主从复制问题

(1)一个master可以有多个slave
(2)slave下线,只是读请求的处理能力下降
(3)master下线,写请求无法执行
(4)其中一台slave使用slaveof no one 命令成为master,其他slave执行slaveof命令指向这台新的master,从这里同步数据
以上过程都是手动的,能够实现自动,就需要sentinel哨兵,实现故障转移failover操作。

5. 手动节点故障转移

(1)节点环境

master  6379
slave1   6380
slave2   6381

(2)开启三个实例

[root@redis1 ~]# /data/redis/bin/redis-server /data/redis/conf/redis.conf &
[1] 8498
[root@redis1 ~]# /data/redis/bin/redis-server /data/redis/conf/redis1.conf &
[2] 8503
[root@redis1 ~]# /data/redis/bin/redis-server /data/redis/conf/redis2.conf &
[3] 8507

(3)连接三个客户端

[root@redis1 ~]# /data/redis/bin/redis-cli -p 6379
127.0.0.1:6379>
[root@redis1 ~]# /data/redis/bin/redis-cli -p 6380
127.0.0.1:6380>
[root@redis1 ~]# /data/redis/bin/redis-cli -p 6381
127.0.0.1:6381>

(4)设置主从(主:6379,从:6380,6381)

127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK

(5)验证

127.0.0.1:6379> set test1 hello
OK
127.0.0.1:6380> get test1
"hello"
127.0.0.1:6381> get test1
"hello"

(6)宕掉6379

[root@redis1 ~]# ps -ef | grep redis
root       8498   7935  0 15:31 pts/0    00:00:01 /data/redis/bin/redis-server 0.0.0.0:6379
root       8503   7935  0 15:31 pts/0    00:00:01 /data/redis/bin/redis-server 0.0.0.0:6380
root       8507   7935  0 15:31 pts/0    00:00:01 /data/redis/bin/redis-server 0.0.0.0:6381
root       8527   7990  0 15:42 pts/1    00:00:00 /data/redis/bin/redis-cli -p 6379
root       8592   8536  0 15:43 pts/2    00:00:00 /data/redis/bin/redis-cli -p 6380
root       8593   8568  0 15:43 pts/3    00:00:00 /data/redis/bin/redis-cli -p 6381
root       8607   7935  0 15:47 pts/0    00:00:00 grep --color=auto redis
[root@redis1 ~]# kill 8498
[root@redis1 ~]# ps -ef | grep redis
root       8503   7935  0 15:31 pts/0    00:00:01 /data/redis/bin/redis-server 0.0.0.0:6380
root       8507   7935  0 15:31 pts/0    00:00:01 /data/redis/bin/redis-server 0.0.0.0:6381
root       8527   7990  0 15:42 pts/1    00:00:00 /data/redis/bin/redis-cli -p 6379
root       8592   8536  0 15:43 pts/2    00:00:00 /data/redis/bin/redis-cli -p 6380
root       8593   8568  0 15:43 pts/3    00:00:00 /data/redis/bin/redis-cli -p 6381
root       8609   7935  0 15:48 pts/0    00:00:00 grep --color=auto redis
[1]   完成                  /data/redis/bin/redis-server /data/redis/conf/redis.conf

在这里插入图片描述
(7)将6380改为master,6381改为slave指向6380

127.0.0.1:6380> SLAVEOF no one
OK
127.0.0.1:6381> SLAVEOF 127.0.0.1 6380
OK

(8)验证

127.0.0.1:6380> set test2 world
OK
127.0.0.1:6381> get test2
"world"

在这里插入图片描述
以上实例是通过手动方式实现的一个故障的切换,为了保证靠可用,我们可以使用一个监控机制来完成该操作,当有节点故障时,故障自动转移,我们可用哨兵模式来处理该需求。

6. sentinel介绍

6.1 sentinel高可用

(1)官方提供的高可用方案,可以用它管理多个redis服务实例
(2)编译后产生redis-sentinel程序文件
(3)redis sentinel是一个分布式系统,可以在一个架构中运行多个sentinel进程

6.2 sentinel启动方式

(1)将src目录下产生的redis-sentinel程序文件复制到¥REDIS_HOME/bin
(2)启动一个运行在sentinel模式下的redis服务实例
redis-sentinel
redis-server /path/to/sentinel.conf --sentinel

6.3 监控monitoring

(1)sentinel会不断检查master和slaves是否正常
(2)每一个sentinel可以监控任意多个master和该master下的slaves
在这里插入图片描述

6.4 sentinel网络

监控同一个master的sentinel会自动连接,组成分布式的sentinel网络,互相通信并交换彼此关于被监视服务器信息
在这里插入图片描述
服务器下线
当一个sentinel认为被监控的服务器已经下线时,他会像网络中的其他sentinel进行确认,判断是否真的已经下线
如果下线的服务器为主服务器,那么sentinel网络将对下线主机服务器进行自动故障转移,通过将下线主服务器的某个从服务器提升为新的主服务器,并将其从服务器指向新的主服务器,让系统回复到上线状态
在这里插入图片描述
服务器下线后重新上线,将会成为从服务器

6.5 sentinel配置文件

(1)至少包含一个监控配置选项,用户指定被监控master的相关信息
(2)sentinel monitor
例如:sentinel monitor mymaster 127.0.0.1 6379 2
监视mymaster的主服务器,服务器端口为6379,将这台服务区判断为下线状态至少需要两个sentinel同意,才会执行故障转移
(3)sentinel会根据master配置自动发现master的slaves
(4)sentinel默认端口为 26379

6.6 sentinel配置实例

(1)实例架构

在这里插入图片描述

(2)节点规划

主机名ipredis说明
redis1192.168.10.11127.0.0.1:6379(主) 127.0.0.1:6380(从) 127.0.0.1:6381(从)

(3)启动实例

[root@redis1 ~]# nohup /data/redis/bin/redis-server /data/redis/conf/redis.conf >> /data/redis/log/6379.log &
[5] 8658
[root@redis1 ~]# nohup /data/redis/bin/redis-server /data/redis/conf/redis1.conf >> /data/redis/log/6380.log 2>&1 &
[6] 8666
[root@redis1 ~]# nohup /data/redis/bin/redis-server /data/redis/conf/redis2.conf >> /data/redis/log/6381.log 2>&1 &

(4)连接客户端并设置主从

[root@redis1 ~]# /data/redis/bin/redis-cli -p 6379
127.0.0.1:6379>
[root@redis1 ~]# /data/redis/bin/redis-cli -p 6380
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
OK
[root@redis1 ~]# /data/redis/bin/redis-cli -p 6381
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK

(5)验证

127.0.0.1:6379> set test3 abc
OK
127.0.0.1:6380> get test3
"abc"
127.0.0.1:6381> get test3
"abc"

(6)哨兵模式集群的搭建

1)创建sentinel.conf文件

[root@redis1 conf]# vim sentinel1.conf
port 26379
sentinel monitor s1 127.0.0.1 6379 2
[root@redis1 conf]# cat sentinel2.conf
port 26380
sentinel monitor s1 127.0.0.1 6379 2


port :指定启动服务的端口号;
Sentinel monitor <name> <ip> <port> <quorum>
name :redis主服务名称,可以自行命名,但是在一个sentinel网络中,一个redis主服务只能有一个名称;
ip和port :redis主服务的IP地址和端口号;
quorum :表示要将这个主服务器判断为失效并下线至少需要2个sentinel同意;
protected-mode :关闭保护模式(默认情况下,redis node和sentinel的protected-mode都是yes,在搭建集群时,若想从远程连接redis集群,需要将redis node和sentinel的protected-mode修改为no,若只修改redis node,从远程连接sentinel后,依然是无法正常使用的,且sentinel的配置文件中没有protected-mode配置项,需要手工添加。依据redis文档的说明,若protected-mode设置为no后,需要增加密码证或是IP限制等保护机制,否则是极度危险的。

2)启动sentinel

[root@redis1 ~]# nohup /data/redis/bin/redis-sentinel /data/redis/conf/sentinel1.conf  >> /data/redis/log/sentinel1.log 2>&1 &
[1] 8730
[root@redis1 ~]# nohup /data/redis/bin/redis-sentinel /data/redis/conf/sentinel2.conf  >> /data/redis/log/sentinel2.log 2>&1 &

# 查看
[root@redis1 ~]# ps -ef | grep sentinel
root       8730   8693  0 16:20 pts/4    00:00:00 /data/redis/bin/redis-sentinel *:26379 [sentinel]
root       8735   8693  1 16:20 pts/4    00:00:00 /data/redis/bin/redis-sentinel *:26380 [sentinel]
root       8743   8693  0 16:21 pts/4    00:00:00 grep --color=auto sentinel

到此简单的哨兵模式搭建完成
在这里插入图片描述
3) 结果测试

  • 模拟master破坏
[root@redis1 ~]# ps -ef| grep redis
root       8658   7935  0 16:10 pts/0    00:00:01 /data/redis/bin/redis-server 0.0.0.0:6379
root       8666   7935  0 16:11 pts/0    00:00:01 /data/redis/bin/redis-server 0.0.0.0:6380
root       8671   7935  0 16:11 pts/0    00:00:01 /data/redis/bin/redis-server 0.0.0.0:6381
root       8677   7990  0 16:12 pts/1    00:00:00 /data/redis/bin/redis-cli -p 6379
root       8678   8536  0 16:12 pts/2    00:00:00 /data/redis/bin/redis-cli -p 6380
root       8681   8568  0 16:12 pts/3    00:00:00 /data/redis/bin/redis-cli -p 6381
root       8730      1  0 16:20 ?        00:00:01 /data/redis/bin/redis-sentinel *:26379 [sentinel]
root       8735      1  0 16:20 ?        00:00:01 /data/redis/bin/redis-sentinel *:26380 [sentinel]
root       8793   8767  0 16:25 pts/4    00:00:00 grep --color=auto redis
[root@redis1 ~]# kill 8658
  • 查看日志
    在这里插入图片描述
  • 再次启动6379
[root@redis1 ~]# nohup /data/redis/bin/redis-server /data/redis/conf/redis.conf >> /data/redis/log/6379.log 2>&1  &
[9] 8805
  • 查看日志
    在这里插入图片描述
  • 实验表明:此时数据是从6381上同步的。
127.0.0.1:6379> set test4 aaa
(error) READONLY You can't write against a read only replica.
127.0.0.1:6379> get test4
"aaa"
127.0.0.1:6380> set test4 aaa
(error) READONLY You can't write against a read only replica.
127.0.0.1:6380> get test4
"aaa"
127.0.0.1:6381> set test4 aaa
OK
127.0.0.1:6381> get test4
"aaa"

7. 集群

7.1 集群介绍

redis3.0版本以上,提供集群功能
redis集群cluster

  • redis集群是一个提供在多个redis节点的共享数据
  • redis集群通过分区share来提供一定程度的可用行,在实际环境中当一个节点宕机或者不可达的情况下继续处理命令

redis集群的优势

  • 自动分割数据到不同的节点上
  • 整个集群的部分节点失败或者不可达的情况下能够继续处理命令

7.2 redis集群的数据分片

redis使用hash槽,每个key通过CRC16校验后对16384去模来决定放置那个槽,集群的每一个节点来负责一部分hash槽
例如
节点A:包含0-5500号的hash槽
节点B:包含5501-11000号hash槽
节点C:包含11000-16384号hash槽
数据究竟存放在那个槽上,数据hash运算除以16384取余

7.3 集群的主存服复制模型

redis的一致性保证
redis并不能保证数据的强一致性,这意味着在实际中集群在特定条件下操作可能丢失一些数据。
集群是用来异步复制,写操作过程

7.4 集群搭建过程

(1)参数修改

搭建并使用redis集群,需要启动集群模式的实例

cluster-enabled yes  启动集群模式
cluster-config-file nodes.conf 指定集群文件(自动生成)
cluster-note-timeout 5000  集群超时时间(毫秒)
appendonly yes

(2)集群搭建

1)节点规划

192.168.10.11  6379 6380 6381
192.168.10.12  6390 6391 6392

2)同步时间

yum -y install ntp ntpdate
ntpdate cn.pool.ntp.org
hwclock --w

3)关闭防火墙

systemctl stop firewalld
systemctl disable firewalld
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0

4)卸载数据库

rpm -e mariadb-libs postfix

5)分别在两个节点安装redis(上面安装过,此处省略)
6)为了方便使用创建集群命令,将其复制到/usr/local/bin

[root@redis1 src]# cp -p redis-trib.rb /usr/local/bin/
[root@redis1 src]# pwd
/usr/local/redis/src
[root@test ~]# cd /usr/local/redis/src/
[root@test src]# cp -p redis-trib.rb /usr/local/bin/

# 添加系统路径
[root@redis1 ~]# vim /etc/profile.d/redis.sh
export PATH=$PATH:/data/redis/bin
[root@redis1 ~]# source /etc/profile.d/redis.sh
[root@test ~]# vim /etc/profile.d/redis.sh
export PATH=$PATH:/data/redis/bin
[root@test ~]# source /etc/profile.d/redis.sh

7)修改配置文件(实例的配置文件都需修改,根据实例修改)

[root@redis1 ~]# vim /data/redis/conf/redis.conf  #修改下面几项
bind 192.168.10.11  #主机ip
port 6379 	#实例端口
daemonize yes
pidfile "/var/run/redis_6379.pid"
logfile "/data/redis/log/logs"
appendonly yes
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 5000

8)启动实例

[root@redis1 ~]# /data/redis/bin/redis-server /data/redis/conf/redis.conf &
[1] 8052
[root@redis1 ~]# /data/redis/bin/redis-server /data/redis/conf/redis1.conf &
[1] 8069
[root@redis1 ~]# /data/redis/bin/redis-server /data/redis/conf/redis2.conf &
[2] 8074
[root@redis1 ~]# ps -ef |grep redis
root       8053      1  0 18:06 ?        00:00:00 /data/redis/bin/redis-server 192.168.10.11:6379 [cluster]
root       8070      1  0 18:06 ?        00:00:00 /data/redis/bin/redis-server 192.168.10.11:6380 [cluster]
root       8075      1  0 18:06 ?        00:00:00 /data/redis/bin/redis-server 192.168.10.11:6381 [cluster]
root       8080   7679  0 18:06 pts/1    00:00:00 grep --color=auto redis

[root@test ~]# /data/redis/bin/redis-server /data/redis/conf/redis.conf &
[root@test ~]# /data/redis/bin/redis-server /data/redis/conf/redis1.conf &
[root@test ~]# /data/redis/bin/redis-server /data/redis/conf/redis2.conf &
[root@test ~]# ps -ef|grep redis
root       8287   7831  0 18:02 pts/1    00:00:00 /data/redis/bin/redis-server 0.0.0.0:6390 [cluster]
root       8291   7831  0 18:02 pts/1    00:00:00 /data/redis/bin/redis-server 0.0.0.0:6391 [cluster]
root       8295   7831  0 18:02 pts/1    00:00:00 /data/redis/bin/redis-server 0.0.0.0:6392 [cluster]
root       8300   7831  0 18:02 pts/1    00:00:00 grep --color=auto redis

9)创建集群

[root@test ~]# /data/redis/bin/redis-cli --cluster create 192.168.10.11:6379 192.168.10.11:6380 192.168.10.11:6381 192.168.10.12:6390 192.168.10.12:6391 192.168.10.12:6392 --cluster-replicas 1

>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.10.12:6392 to 192.168.10.11:6379
Adding replica 192.168.10.11:6381 to 192.168.10.12:6390
Adding replica 192.168.10.12:6391 to 192.168.10.11:6380
M: 6ae3296a49d7fb3408765fd05d081159f9bc1993 192.168.10.11:6379
   slots:[0-5460] (5461 slots) master
M: ac4101aa44e19eb1995a3ca38ba394a114d5cd0c 192.168.10.11:6380
   slots:[10923-16383] (5461 slots) master
S: 0a9e967f0fbad50cb5a264bb922be61a068337fc 192.168.10.11:6381
   replicates beecd5ca72f4b23007ad28b46c81ec6b4d8760f3
M: beecd5ca72f4b23007ad28b46c81ec6b4d8760f3 192.168.10.12:6390
   slots:[5461-10922] (5462 slots) master
S: f3b96c03e53ef95e0deed466be2559aa66b25abd 192.168.10.12:6391
   replicates ac4101aa44e19eb1995a3ca38ba394a114d5cd0c
S: 797952ac748a30a26516fe19973d555b7154abe3 192.168.10.12:6392
   replicates 6ae3296a49d7fb3408765fd05d081159f9bc1993
Can I set the above configuration? (type 'yes' to accept): yes

。。。
8317:M 22 Aug 2020 18:11:07.318 # Cluster state changed: ok
8321:S 22 Aug 2020 18:11:07.319 * Background AOF rewrite terminated with success
8321:S 22 Aug 2020 18:11:07.319 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
8321:S 22 Aug 2020 18:11:07.319 * Background AOF rewrite finished successfully

10) 向集群中存储数据

[root@test ~]# /data/redis/bin/redis-cli -h 192.168.10.11 -p 6379 -c
192.168.10.11:6379> set Test1 123
-> Redirected to slot [6676] located at 192.168.10.12:6390
OK
192.168.10.12:6390> set Test1 456
OK
192.168.10.12:6390>

[root@test ~]# /data/redis/bin/redis-cli -h 192.168.10.11 -p 6380 -c
192.168.10.11:6380> get Test1
-> Redirected to slot [5798] located at 192.168.10.12:6390
"456"
[root@test ~]# /data/redis/bin/redis-cli -h 192.168.10.11 -p 6381 -c
192.168.10.11:6381> get Test1
-> Redirected to slot [6676] located at 192.168.10.12:6390
"456"

注:集群中分配了写和读取的实例,当执行相关操作会自动跳转。

------------------------------------------------------------------------------------------------------- 返回目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值