赞
踩
目录
5、Redis Sentinel(哨兵)实现 Redis 的高可用性实战
redis主从同步有两种方式(或者说两个阶段):全同步和部分同步
主从刚刚连接的时候,进行全同步;全同步结束后,进行部分同步。当然,如果有需要,slave在任何时候都可以发起全同步。
redis的策略是,无论如何,首先会尝试进行部分同步,如不成功,要求从机进行全同步,并启动BGSAVE...BGSAVE结束后,传输RDB文件,如果成功,允许从机进行部分同步,并传输积压空间中的数据。
主从同步的机制:
在主从服务器完成同步之后,主服务器每执行一个命令,它都会将被执行的写命令发送给从服务器执行,这个操作被称为“命令传播”(command propagate)
命令传播是一个持续的过程:只要复制人在继续,命令传播就会一直进行,使得主从服务器的状态可以一直保持一致
在读写分离环境下,客户端向主服务器发送写命令SET n 10086,主服务器在执行这个写命令后,向客户端返回回复,并将这个写命令传播给从服务器。
接到回复的客户端继续向从服务器发送读命令GRT n,并且因为网络状态的原因,客户端的GET命令比主服务器传播的SET命令更快到达了从服务器。
因为从服务器n的值还未被更新,所以客户端在从服务器读取到的将是一个错误(过期)的n值。
主服务器在至少有N个从服务器的情况下,才执行写操作。从redis2.8开始,为保证数据的安全性,可以通过配置,让主服务器只在有至少N个当前已连接服务器的情况下,才执行写命令。
不过,因为redis使用异步复制,所以主服务器发送的写数据并不一定被从服务器接收到,因此,数据丢失的可能性任然存在。
通过一下两个参数保证数据的安全:
- min-slaves-to-write <number of slaves>
- min-slaves-max-lag <number of seconds>
解释:
要求至少有1个slave,数据复制和同步的延迟不能超过10秒,如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒,那么这个时候,master就不会再接受任何请求了
减少异步复制的数据丢失
有了min-slaves-max-lag这个配置,就可以确保说,一旦slave复制数据和ack延迟太长,就认为可能master宕机后损失的数据太多了。那么就拒绝写请求,这样就可以吧master宕机时由于部分数据未同步到slave导致的数据丢失降低到可控的范围内
减少脑裂的数据丢失
如果一个master出现了脑裂,跟其他slave丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的slave发送数据,而且slae超过10秒没有给自己ack消息,那么直接拒绝客户端的写请求,这样脑裂后的旧master就不会接受client的新数据,也就避免了数据丢失
上面的配置就确保了,如果跟任何一个slave丢了数据,在10秒后发现没有slave给自己ack,那么就拒绝新的写请求,因此在脑裂场景下,最多就丢失10秒的数据
准备三台服务器:
master:192.168.242.144
slave-1:192.168.242.145
slave-29:12.168.242.146
三台都安装redis(yum安装)
- [root@localhost ~]# yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
- [root@localhost ~]# yum -y --enablerepo=remi install redis
-
master修改配置文件:
- [root@localhost ~]# vim /etc/redis.conf #删除原文件所有内容,输入下面的内容
- bind 192.168.242.144 127.0.0.1 #127.0.0.1写不写都可以
- protected-mode yes
- port 6379
- tcp-backlog 511
- timeout 0
- tcp-keepalive 300
- daemonize no
- supervised no
- pidfile /var/run/redis_6379.pid
- loglevel notice
- logfile /var/log/redis/redis.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 dump.rdb
- rdb-del-sync-files no
- dir /var/lib/redis
- replica-serve-stale-data yes
- replica-read-only yes
- repl-diskless-sync no
- repl-diskless-sync-delay 5
- repl-diskless-load disabled
- repl-disable-tcp-nodelay no
- replica-priority 100
- acllog-max-len 128
- requirepass redis #设置的redis的登录密码
- lazyfree-lazy-eviction no
- lazyfree-lazy-expire no
- lazyfree-lazy-server-del no
- replica-lazy-flush no
- lazyfree-lazy-user-del no
- oom-score-adj no
- oom-score-adj-values 0 200 800
- 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
- jemalloc-bg-thread yes

slave-1修改配置文件
- [root@localhost ~]# vim /etc/redis.conf #删除原文件所有内容,输入下面的内容
- bind 192.168.242.145
- protected-mode yes
- port 6379
- tcp-backlog 511
- timeout 0
- tcp-keepalive 300
- daemonize no
- supervised no
- pidfile /var/run/redis_6379.pid
- loglevel notice
- logfile /var/log/redis/redis.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 dump.rdb
- rdb-del-sync-files no
- dir /var/lib/redis
- replicaof 192.168.242.145 6379 #master的ip 端口
- masterauth redis #master的认证密码
- replica-serve-stale-data yes
- replica-read-only yes
- repl-diskless-sync no
- repl-diskless-sync-delay 5
- repl-diskless-load disabled
- repl-disable-tcp-nodelay no
- replica-priority 100
- acllog-max-len 128
- requirepass redis #本机redis的登录密码
- lazyfree-lazy-eviction no
- lazyfree-lazy-expire no
- lazyfree-lazy-server-del no
- replica-lazy-flush no
- lazyfree-lazy-user-del no
- oom-score-adj no
- oom-score-adj-values 0 200 800
- 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
- jemalloc-bg-thread yes

slave-2修改配置文件
- [root@localhost ~]# vim /etc/redis.conf #删除原文件所有内容,输入下面的内容
- bind 192.168.242.146
- protected-mode yes
- port 6379
- tcp-backlog 511
- timeout 0
- tcp-keepalive 300
- daemonize no
- supervised no
- pidfile /var/run/redis_6379.pid
- loglevel notice
- logfile /var/log/redis/redis.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 dump.rdb
- rdb-del-sync-files no
- dir /var/lib/redis
- replicaof 192.168.242.145 6379 #master的ip 端口
- masterauth redis #master的认证密码
- replica-serve-stale-data yes
- replica-read-only yes
- repl-diskless-sync no
- repl-diskless-sync-delay 5
- repl-diskless-load disabled
- repl-disable-tcp-nodelay no
- replica-priority 100
- acllog-max-len 128
- requirepass redis #本机redis的登录密码
- lazyfree-lazy-eviction no
- lazyfree-lazy-expire no
- lazyfree-lazy-server-del no
- replica-lazy-flush no
- lazyfree-lazy-user-del no
- oom-score-adj no
- oom-score-adj-values 0 200 800
- 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
- jemalloc-bg-thread yes

依次启动三台服务器的redis服务
[root@localhost ~]# systemctl start redis
验证服务
- master:
- [root@localhost ~]# redis-cli -a redis -h 192.168.242.144
- Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
- 127.0.0.1:6379> info replication
- # Replication
- role:master
- connected_slaves:2
- slave0:ip=192.168.242.145,port=6379,state=online,offset=70,lag=1
- slave1:ip=192.168.242.146,port=6379,state=online,offset=70,lag=1
- master_failover_state:no-failover
- master_replid:a9ce8d3b8be47c945730bc8599705bcc8ecf9176
- master_replid2:0000000000000000000000000000000000000000
- master_repl_offset:70
- second_repl_offset:-1
- repl_backlog_active:1
- repl_backlog_size:1048576
- repl_backlog_first_byte_offset:1
- repl_backlog_histlen:70
- 127.0.0.1:6379> set name 123
- OK
-
- slave-1:
- redis-cli -a redis -h 192.168.242.145
- Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
- 192.168.242.145:6379> get name
- "123"
- slave-2:
- 192.168.242.146:6379> get name
- "123"

Redis-Sentinel 是 Redis 官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。
Sentinel 是一个监视器,它可以根据被监视实例的身份和状态来判断应该执行何种动作。
Sentinel的主要功能包括主节点存活检测、主从运行情况检测、自动故障转移(failover)、主从切换。Redis的Sentinel最小配置是一主一从。 Redis的Sentinel系统可以用来管理多个Redis服务器,该系统可以执行以下四个任务:
由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求 。如下图:
Sentinel负责监控集群中的所有主、从Redis,当发现主故障时,Sentinel会在所有的从中选一个成为新的主。并且会把其余的从变为新主的从。同时那台有问题的旧主也会变为新主的从,也就是说当旧的主即使恢复时,并不会恢复原来的主身份,而是作为新主的一个从。
在Redis高可用架构中,Sentinel往往不是只有一个,而是有3个或者以上。目的是为了让其更加可靠,毕竟主和从切换角色这个过程还是蛮复杂的。
sentinel会与被监视的主服务器创建两个网络连接:
命令连接用于向主服务器发送命令。
订阅连接用于订阅指定的频道,从而发现监视同一主服务器的其他 Sentinel。
命令 | 描述 |
PING | 返回 PONG |
SENTINEL masters | 列出所有被监视的主服务器 |
SENTINEL slaves <master name> | 列出所有被监视的从服务器(新版本已经移除这个命令) |
SENTINEL get-master-addr-by-name <master name> | 返回给定名字的主服务器的 IP 地址和端口号。 |
SENTINEL reset <pattern> | 重置所有名字和给定模式 pattern 相匹配的主服务器 |
SENTINEL failover <master name> | 当主服务器失效时, 在不询问其他 Sentinel 意见的情况下,强制开始一次自动故障迁移。 |
在上面那个实验基础上进行,实验环境:
master:192.168.242.144 (sentinel01)
slave-1:192.168.242.145 (sentinel02)
slave-29:12.168.242.146 (sentinel03)
- [root@localhost ~]# vim /etc/redis-sentinel.conf #删除原文件所有内容,输入下面的内容
- port 26379
- daemonize no
- pidfile /var/run/redis-sentinel.pid
- logfile /var/log/redis/sentinel.log
- dir /tmp
- 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 deny-scripts-reconfig yes
-
- # 端口
- port 26379
- # 是否后台启动
- daemonize yes
- # 保护模式如果开启只接受回环地址的ipv4和ipv6地址链接,拒绝外部链接,而且正常应该配置多个哨兵,避免一个哨兵出现独裁情况,如果配置多个哨兵那如果开启也会拒绝其他sentinel的连接。导致哨兵配置无法生效。
- protected-mode no
- # pid文件路径
- pidfile /var/run/redis-sentinel.pid
- # 日志文件路径
- logfile "/var/log/redis/sentinel.log"
- # 定义工作目录
- dir /tmp
- # 定义Redis主的别名, IP, 端口,这里的2指的是需要至少2个Sentinel认为主Redis挂了才最终会采取下一步行为
- sentinel monitor mymaster 127.0.0.1 6379 2
- #如果redis配置了密码,那这里必须配置认证,否则不能自动切换
- sentinel auth-pass mymaster redispass
- # 如果mymaster 30秒内没有响应,则认为其主观失效
- sentinel down-after-milliseconds mymaster 30000
- # 如果master重新选出来后,其它slave节点能同时并行从新master同步数据的台数有多少个,显然该值越大,所有slave节点完成同步切换的整体速度越快,但如果此时正好有人在访问这些slave,可能造成读取失败,影响面会更广。最保守的设置为1,同一时间,只能有一台干这件事,这样其它slave还能继续服务,但是所有slave全部完成缓存更新同步的进程将变慢。
- sentinel parallel-syncs mymaster 1
- # 该参数指定一个时间段,在该时间段内没有实现故障转移成功,则会再一次发起故障转移的操作,单位毫秒
- sentinel failover-timeout mymaster 180000
- # 不允许使用SENTINEL SET设置notification-script和client-reconfig-script。
- sentinel deny-scripts-reconfig yes

- [root@localhost ~]# vim /etc/redis-sentinel.conf #删除原文件所有内容,输入下面的内容
- port 26379
- daemonize no
- pidfile /var/run/redis-sentinel.pid
- logfile /var/log/redis/sentinel.log
- dir /tmp
- sentinel monitor mymaster 192.168.242.144 6379 2
- sentinel auth-pass mymaster redis
- sentinel down-after-milliseconds mymaster 30000
- sentinel parallel-syncs mymaster 1
- sentinel failover-timeout mymaster 180000
- sentinel deny-scripts-reconfig yes
- [root@localhost ~]# vim /etc/redis-sentinel.conf #删除原文件所有内容,输入下面的内容
- port 26379
- daemonize no
- pidfile /var/run/redis-sentinel.pid
- logfile /var/log/redis/sentinel.log
- dir /tmp
- sentinel monitor mymaster 192.168.242.144 6379 2
- sentinel auth-pass mymaster redis
- sentinel down-after-milliseconds mymaster 30000
- sentinel parallel-syncs mymaster 1
- sentinel failover-timeout mymaster 180000
- sentinel deny-scripts-reconfig yes
在redis正常运行的前提下,依次启动sentinel01、sentinel02、sentinel03
[root@localhost ~]# systemctl restart redis-sentinel.service
- master:192.168.242.144:
- [root@localhost ~]# redis-cli -p 26379
- 127.0.0.1:26379> sentinel master mymaster
- 1) "name"
- 2) "mymaster"
- 3) "ip"
- 4) "192.168.242.144"
- 5) "port"
- 6) "6379"
- ....
-
- slave-1:192.168.242.145:
- 127.0.0.1:26379> sentinel master mymaster
- 1) "name"
- 2) "mymaster"
- 3) "ip"
- 4) "192.168.242.144"
- 5) "port"
- 6) "6379"
- ....
-
- slave-2:192.168.242.146:
- 127.0.0.1:26379> sentinel master mymaster
- 1) "name"
- 2) "mymaster"
- 3) "ip"
- 4) "192.168.242.144"
- 5) "port"
- 6) "6379"
- ....

模拟停止master上的Redis,查看Redis的主从变化,如下:
- master:192.168.242.144
- [root@localhost ~]# systemctl stop redis
-
- slave-2:192.168.242.145
- [root@localhost ~]# tailf /var/log/redis/sentinel.log
- 16759:X 19 May 2022 18:06:54.252 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
- 16759:X 19 May 2022 18:06:54.254 * Sentinel new configuration saved on disk
- 16759:X 19 May 2022 18:06:54.254 # Sentinel ID is ba4e6bd5770d4fac5284f25f491af6976756fcbe
- 16759:X 19 May 2022 18:06:54.254 # +monitor master mymaster 192.168.242.144 6379 quorum 2
- 16759:X 19 May 2022 18:06:54.258 * +slave slave 192.168.242.145:6379 192.168.242.145 6379 @ mymaster 192.168.242.144 6379
- 16759:X 19 May 2022 18:06:54.259 * Sentinel new configuration saved on disk
- 16759:X 19 May 2022 18:06:54.259 * +slave slave 192.168.242.146:6379 192.168.242.146 6379 @ mymaster 192.168.242.144 6379
- 16759:X 19 May 2022 18:06:54.260 * Sentinel new configuration saved on disk
- 16759:X 19 May 2022 18:06:57.894 * +sentinel sentinel 6e9ebf7a1cb6874e58d1f3164f996b7a0dfd2d50 192.168.242.146 26379 @ mymaster 192.168.242.144 6379
- 16759:X 19 May 2022 18:06:57.896 * Sentinel new configuration saved on disk
- 这些都是刚开始的日志文件内容,等个30秒左右
-
-
- 16759:X 19 May 2022 18:10:17.738 # +sdown master mymaster 192.168.242.144 6379
- 16759:X 19 May 2022 18:10:17.860 * Sentinel new configuration saved on disk
- 16759:X 19 May 2022 18:10:17.860 # +new-epoch 1
- 16759:X 19 May 2022 18:10:17.861 * Sentinel new configuration saved on disk
- 16759:X 19 May 2022 18:10:17.861 # +vote-for-leader 6e9ebf7a1cb6874e58d1f3164f996b7a0dfd2d50 1
- 16759:X 19 May 2022 18:10:18.762 # +config-update-from sentinel 6e9ebf7a1cb6874e58d1f3164f996b7a0dfd2d50 192.168.242.146 26379 @ mymaster 192.168.242.144 6379
- 16759:X 19 May 2022 18:10:18.762 # +switch-master mymaster 192.168.242.144 6379 192.168.242.146 6379
- 16759:X 19 May 2022 18:10:18.763 * +slave slave 192.168.242.145:6379 192.168.242.145 6379 @ mymaster 192.168.242.146 6379
- 16759:X 19 May 2022 18:10:18.763 * +slave slave 192.168.242.144:6379 192.168.242.144 6379 @ mymaster 192.168.242.146 6379
- 16759:X 19 May 2022 18:10:18.765 * Sentinel new configuration saved on disk
- 可以看到,日志内容显示,mymaster主服务器宕机了,将原来的主服务器mymaster192.168.242.144换为现在的192.168.242.146为新的主服务器

回到新的主服务器master上验证:
- 192.168.242.146:
- [root@localhost ~]# redis-cli -p 26379
- 127.0.0.1:26379> sentinel master mymaster
- 1) "name"
- 2) "mymaster"
- 3) "ip"
- 4) "192.168.242.146"
- 5) "port"
- 6) "6379"
注意:
如果旧主重新加入后数据不同步解决方案:
可能之前是主节点,没有配置从节点的连接信息 如:masterauth 连接密码,当master转变为slave后,由于他没有密码,所以他不能从新的master同步数据,随之导致 info replication 的时候,同步状态为 down ,所以只需要修改 redis.conf 中的 masterauth 为 对应的密码。
只需要在旧主服务器的redis配置文件中任意地方添加masterauth (新主服务器的redis密码)
- 旧主服务器:192.168.242.144
- [root@localhost ~]# vim /etc/redis.conf
- ...
- masterauth "redis"
- ..
- 重启redis,然后再验证数据是否能够同步
- 192.168.242.146:
- [root@localhost ~]# redis-cli -a redis -h 192.168.242.146
- Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
- 192.168.242.146:6379> set zzz 456
- OK
-
- 192.168.242.144:
- [root@localhost ~]# redis-cli -a redis -h 192.168.242.144
- Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
- 192.168.242.144:6379> get zzz
- "456"
- #数据同步成功
Redis Cluster是Redis官方提供的分布式解决方案。当遇到内存、并发、流量等瓶颈是,就可以采用Cluster架构达到负载均衡目的。官方文档:https://redis.io/topics/cluster-tutorial
1、首先redis单实例主要有单点。容量有限,流量上限的问题。
redis单点故障,可以通过主从复制replication。和自动故障转移sentinel哨兵机制。但redis单master实例提供写服务,仍然有容量和压力问题,因此需要数据分区,构建多个master实例同时提供读写服务(不仅限于从replica节点提供读服务)。
2、并发问题
redis官方声称可以达到10万/s,每秒执行10万条命令
假如业务需要每秒100万的命令执行呢?
解决方案如下
1、正确的应该是考虑分布式,加机器,把数据分布到不同的位置,分摊集中式的压力,一堆机器做一件事,还需要一定的机制保证数据分区,并且数据在各个主master节点间不能混乱,当然最好还能支持在线数据热迁移的特性。
为何要搭建Redis集群。Redis是在内存中保存数据的,而我们的电脑一般内存都不大,这也就意味着Redis不适合存储大数据,Redis更适合处理高并发,一台设备的存储能力是有限的,但是多台设备协同合作,就可以让内存增大很多倍,这就需要用到集群。
redis集群搭建的方式有多种,例如使用客户端分片、Twemproxy、Codis等,但从redis3.0之后版本支持redis-cluster集群,他是Redis官方提出的解决方案:
Redis-Cluster采用无中心化结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接,其中redis-cluster架构图如下:
1、所有的redis节点彼此互联(PING_PONG机制),内部使用二进制协议优化传输速度和宽带。
2、客户端与redis节点直连,不需要中间proxy层,客户端不需要连接集群所有节点,连接集群中任何一个节点即可。
3、节点的fail是通过及群众超过半数的节点检测失效时才生效。
rediscluster集群中有16348个哈希槽,每个redis实例负责一部分slot,集群中的所有信息通过节点数据交换而更新。一个hash slot中会有很多key和value。
3、数据分布存储原理
redis集群使用数据分片(sharding)来实现:Redis集群中内置了16384个哈希槽,当需要在redis集群中放置一个key-value时。redis先对key使用crc16算法算出一个结果,然后把结果对16384求余数(集群使用公式CRC16(key)%16384),这样每个key都会对应一个编号在0-16383之间的哈希槽,那么redis就会把这个key分配到对应范围的节点上了。同样,当连接三个节点任何一个节点想要获取这个key时,也会有这样的算法,然后内部跳转到存放这个key节点上获取数据。
例如三个节点:哈希槽分布的值如下:
cluster1:0-5460
cluster2:5461-10922
cluster3:10923-16383
这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。比如说:
因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞,所以无论是添加新节点还是移除已有节点,又或者改变某个节点包含的哈希槽数量,都不会造成集群下线。
redis cluster为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或者多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会从这个从节点选取一个来充当主节点,从而保证集群不会挂掉。
1、主从切换机制
选举过程是集群中所有master参与,如果半数以上master节点与故障点通信超过(cluster-node-timeout),认为该节点故障,自动触发故障转移操作。#故障节点对应的从节点自动升级为主节点
2、什么时候整个集群就不能用了?
如果集群任意一个主节点挂掉了,且当前主节点没有从节点,则集群无法继续,因为我们不再有办法为这个节点承担范围内的哈希槽提供服务。但是,如果这个主节点和所对应的从节点同时失败,则redis cluster无法继续运行。
4、redis cluster集群部署
环境准备:
1.准备三机器,关闭防火墙和selinux
2.制作解析并相互做解析。
注:规划架构两种方案,一种是单机多实例,这里我们采用多机器部署:
三台机器,每台机器上面两个redis实例,一个master一个slave,第一列做主库,第二列做备库
#记得选出控制节点
10.0.0.129 redis-1 7000 7001
10.0.0.130 redis-2 7002 7003
10.0.0.131 redis-3 7004 7005
三台机器做同样操作
1、安装redis
- [root@redis-1 ~]# mkdir /data
- [root@redis-1 ~]# yum -y install gcc automake autoconf libtool make
- [root@redis-1 ~]# wget https://download.redis.io/releases/redis-6.2.0.tar.gz
- [root@redis-1 ~]# tar xzvf redis-6.2.0.tar.gz -C /data/
- [root@redis-1 ~]# cd /data
- [root@redis-1 data]# mv redis-6.2.0 redis
- [root@redis-1 data]# cd redis
- [root@redis-1 redis]# make
- [root@redis-1 redis]# mkdir /data/redis/data #创建存放数据的目录
2、创建节点目录
- [root@redis-1 redis]# mkdir cluster
- [root@redis-1 redis]# cd cluster
- [root@redis-1 cluster]# mkdir 7000 7001 #目录名字自定义,不过将实例的目录名与端口对应起来方便管理
-
- [root@redis-2 redis]# mkdir cluster
- [root@redis-2 redis]# cd cluster
- [root@redis-2 cluster]# mkdir 7002 7003
-
- [root@redis-3 redis]# mkdir cluster
- [root@redis-3 redis]# cd cluster
- [root@redis-3 cluster]# mkdir 7004 7005
3、先编辑好一个配置文件,然后将这个配置文件拷贝到其他节点目录中
- [root@redis-1 cluster]# cp /data/redis/redis.conf 7000/
- [root@redis-1 cluster]# vim 7000/redis.conf
- bind 10.0.0.129 #每个实例的配置文件修改为对应节点的ip地址
- port 7000 #监听端口,运行多个实例时,需要指定规划的每个实例不同的端口号
- daemonize yes #redis后台运行
- pidfile /var/run/redis_7000.pid #pid文件,运行多个实例时,需要指定不同的pid文件
- logfile /var/log/redis_7000.log #日志文件位置,运行多实例时,需要将文件修改的不同。
- dir /data/redis/data #存放数据的目录
- appendonly yes #开启AOF持久化,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之前的状态。
- appendfilename "appendonly.aof" #AOF文件名称
- appendfsync everysec #表示对写操作进行累积,每秒同步一次
- 以下为打开注释并修改
- cluster-enabled yes #启用集群
- cluster-config-file nodes-7000.conf #集群配置文件,由redis自动更新,不需要手动配置,运行多实例时请注修改为对应端口
- cluster-node-timeout 5000 #单位毫秒。集群节点超时时间,即集群中主从节点断开连接时间阈值,超过该值则认为主节点不可以,从节点将有可能转为master
- cluster-replica-validity-factor 10 #在进行故障转移的时候全部slave都会请求申请为master,但是有些slave可能与master断开连接一段时间了导致数据过于陈旧,不应该被提升为master。该参数就是用来判断slave节点与master断线的时间是否过长。(计算方法为:cluster-node-timeout * cluster-replica-validity-factor,此处为:5000 * 10 毫秒)
- cluster-migration-barrier 1 #一个主机将保持连接的最小数量的从机,以便另一个从机迁移到不再被任何从机覆盖的主机
- cluster-require-full-coverage yes #集群中的所有slot(16384个)全部覆盖,才能提供服务
-
- #注:
- 所有节点配置文件全部修改切记需要修改的ip、端口、pid文件...避免冲突。确保所有机器都修改。

- [root@redis-1 cluster]# cp 7000/redis.conf 7001/
- [root@redis-1 cluster]# vim 7001/redis.conf
- bind 10.0.0.129 #这个手动修改,其他的使用%s/7000/7001/g
- port 7001
- daemonize yes
- pidfile /var/run/redis_7001.pid
- logfile /var/log/redis_7001.log
- cluster-config-file nodes-7001.conf
- 其他的不变
- ...
- [root@redis-1 cluster]# scp 7000/redis.conf 10.0.0.130:/data/redis/cluster/7002
- [root@redis-1 cluster]# scp 7000/redis.conf 10.0.0.130:/data/redis/cluster/7003
- [root@redis-1 cluster]# scp 7000/redis.conf 10.0.0.130:/data/redis/cluster/7004
- [root@redis-1 cluster]# scp 7000/redis.conf 10.0.0.130:/data/redis/cluster/7005
- [root@redis-2 cluster]# vim 7002/redis.conf
- bind 10.0.0.130 #这个手动修改,其他的使用%s/7000/7002/g
- port 7002
- daemonize yes
- pidfile /var/run/redis_7002.pid
- logfile /var/log/redis_7002.log
- cluster-config-file nodes-7002.conf
- 其他的不变
- ...
-
- [root@redis-2 cluster]# vim 7003/redis.conf
- bind 10.0.0.130 #这个手动修改,其他的使用%s/7000/7003/g
- port 7003
- daemonize yes
- pidfile /var/run/redis_7003.pid
- logfile /var/log/redis_7003.log
- cluster-config-file nodes-7003.conf
- 其他的不变
- ...

- [root@redis-3 cluster]# vim 7004/redis.conf
- bind 10.0.0.131 #这个手动修改,其他的使用%s/7000/7003/g
- port 7004
- daemonize yes
- pidfile /var/run/redis_7004.pid
- logfile /var/log/redis_7004.log
- cluster-config-file nodes-7004.conf
- 其他的不变
- ...
-
- [root@redis-2 cluster]# vim 7005/redis.conf
- bind 10.0.0.131 #这个手动修改,其他的使用%s/7000/7005/g
- port 7005
- daemonize yes
- pidfile /var/run/redis_7005.pid
- logfile /var/log/redis_7005.log
- cluster-config-file nodes-7005.conf
- 其他的不变
- ...

4、启动三台机器上的每个节点
- [root@redis-1 ~]# cd /data/redis/src/
- [root@redis-1 src]# ./redis-server ../cluster/7000/redis.conf &
- [root@redis-1 src]# ./redis-server ../cluster/7001/redis.conf &
-
- [root@redis-2 ~]# cd /data/redis/src/
- [root@redis-2 src]# ./redis-server ../cluster/7002/redis.conf &
- [root@redis-2 src]# ./redis-server ../cluster/7003/redis.conf &
-
- [root@redis-3 ~]# cd /data/redis/src/
- [root@redis-3 src]# ./redis-server ../cluster/7004/redis.conf &
- [root@redis-3 src]# ./redis-server ../cluster/7005/redis.conf &
查看端口
5、创建集群:在其中一个节点上操作就可以
redis节点搭建起来之后,需要完成redis cluster集群搭建,搭建集群过程中,需要保证6个redis实例都是运行状态。
redis是根据ip和port的顺序,确定master和slave,所以要排好序,再执行。
- [root@redis-1 src]# ./redis-cli --cluster create --cluster-replicas 1 10.0.0.129:7000 10.0.0.129:7001 10.0.0.130:7002 10.0.0.130:7003 10.0.0.131:7004 10.0.0.131:7005
- ...
- Can I set the above configuration? (type 'yes' to accept): yes #写yes同意
- ...
- [OK] All 16384 slots covered. 完成
-
-
6、查看集群状态可连接集群中的任一节点。此处连接了集群中的节点
- # 登录集群客户端,-c标识以集群方式登录
- [root@redis-3 src]# ./redis-cli -h 10.0.0.129 -c -p 7000
- 10.0.0.129:7000> ping
- PONG
- 10.0.0.129:7000> cluster info #查看集群信息
- ...
- 10.0.0.129:7000> cluster nodes #查看集群实例
- c6d68c418703daa99ae4e1d6508b8851551e9e21 10.0.0.130:7002@17002 slave 50891d2bbe5f228b7f22c32763fdc30a95f1aae3 0 1653912918005 14 connected
- a99f4424e6aeb4f51069a57be141a9c7b65dfec8 10.0.0.129:7001@17001 master - 0 1653912918504 15 connected 0-1364 12288-16383
- 50891d2bbe5f228b7f22c32763fdc30a95f1aae3 10.0.0.131:7005@17005 master - 0 1653912918000 14 connected 6826-12287
- b4f58fdba2d44fa02efe23b1fc3ee387c3159284 10.0.0.129:7000@17000 myself,master - 0 1653912919000 13 connected 1365-6825
- a30d771ab57c8512304e775f337d65a2a90e85e6 10.0.0.131:7004@17004 slave a99f4424e6aeb4f51069a57be141a9c7b65dfec8 0 1653912920013 15 connected
- fee769d4118fc9d7cda3f58f2bb158d2bd982c00 10.0.0.130:7003@17003 slave b4f58fdba2d44fa02efe23b1fc3ee387c3159284 0 1653912919008 13 connected
- [root@redis-1 src]# ./redis-cli -h 10.0.0.131 -c -p 7004
- 10.0.0.131:7004> set names 456
- -> Redirected to slot [6659] located at 10.0.0.129:7000
- OK
- 10.0.0.129:7000>
-
- 读
- [root@redis-1 src]# ./redis-cli -h 10.0.0.130 -c -p 7003
- 10.0.0.130:7003> get names
- -> Redirected to slot [6659] located at 10.0.0.129:7000
- "456"
-
准备一台新机器,修改主机名,做域名解析,其他3台机器添加这个机器的域名解析
- cat /etc/hosts
- 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
- ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
- 10.0.0.129 redis-1
- 10.0.0.130 redis-2
- 10.0.0.131 redis-3
- 10.0.0.132 redis-4
-
- [root@redis-4 ~]# mkdir /data
- [root@redis-4 ~]# yum -y install gcc automake autoconf libtool make
- [root@redis-4 ~]# wget https://download.redis.io/releases/redis-6.2.0.tar.gz
- [root@redis-4 ~]# tar xzvf redis-6.2.0.tar.gz -C /data/
- [root@redis-4 ~]# cd /data/
- [root@redis-4 data]# mv redis-6.2.0/ redis
- [root@redis-4 data]# cd redis/
- [root@redis-4 redis]# make #编译
- [root@redis-4 redis]# mkdir data #创建数据目录
- [root@redis-4 redis]# mkdir cluster
- [root@redis-4 redis]# mkdir cluster/{7006,7007} #创建集群节点
-
- redis-1:
- [root@redis-1 src]# scp /data/redis/cluster/7000/redis.conf 10.0.0.131:/data/redis/cluster/7006
- [root@redis-1 src]# scp /data/redis/cluster/7000/redis.conf 10.0.0.131:/data/redis/cluster/7007
-
- redis-4:
- vim /data/redis/cluster/7006/redis.conf
- vim /data/redis/cluster/7007/redis.conf
- 开始修改配置文件略...和之前一样,注意修改不一样的地方:端口、ip、pid文件...
- 启动
- [root@redis-4 src]# ./redis-server ../cluster/7006/redis.conf &
- [root@redis-4 src]# ./redis-server ../cluster/7007/redis.conf &

1、准备好之后开始添加节点,将cluster4添加到集群中
- [root@redis-1 src]# ./redis-cli --cluster add-node 10.0.0.132:7006 10.0.0.129:7000
- ...
- [OK] New node added correctly.
-
- 查看节点信息
- ./redis-cli -h 10.0.0.129 -c -p 7000
- 10.0.0.129:7000> cluster nodes
- 可以看到新增的节点
详细解释
- 详细解释:
- runid: 该行描述的节点的id。
- ip:prot: 该行描述的节点的ip和port
- flags: 逗号分隔的标记位,可能的值有:
- 1.master: 该行描述的节点是master
- 2.slave: 该行描述的节点是slave
- 3.fail?:该行描述的节点可能不可用
- 4.fail:该行描述的节点不可用(故障)
- master_runid: 该行描述的节点的master的id,如果本身是master则显示-
- ping-sent: 最近一次发送ping的Unix时间戳,0表示未发送过
- pong-recv:最近一次收到pong的Unix时间戳,0表示未收到过
- config-epoch: 主从切换的次数
- link-state: 连接状态,connnected 和 disconnected
- hash slot: 该行描述的master中存储的key的hash的范围
2、给新节点hash槽分配
需要给新节点进行hash槽分配,这样该主节才可以存储数据,(如果有数据记得提前先将数据同步然后在从其他节点迁移槽到新节点。)
- ./redis-cli --cluster reshard 10.0.0.132:7006
- ...
- How many slots do you want to move (from 1 to 16384)? 4000 #输入要分配的槽数量
- What is the receiving node ID? 0aed4a95f08a8993ade091343e0267474b4b4094 #输入接收槽的节点id,通过cluster nodes 查看新增的10.0.0.132:7006 的id
-
- Please enter all the source node IDs.
- Type 'all' to use all the nodes as source nodes for the hash slots.
- Type 'done' once you entered all the source nodes IDs.
- 输入: all
- 然后输入输入yes确认
-
- 此时再通过cluster nodes查看节点,可以看到新节点分配的槽为0-1332 5461-6794 10923-12255
3、给新添加的主节点添加对应的从节点
- [root@redis-4 src]# ./redis-cli --cluster add-node 10.0.0.132:7007 10.0.0.132:7006 --cluster-slave --cluster-master-id 0aed4a95f08a8993ade091343e0267474b4b4094 #master的id
- ...
- [OK] New node added correctly.
- 查看集群信息,可以看到新增接的从节点
4、平衡各个主节点的槽
- 任一一台机器操作
- ./redis-cli --cluster rebalance --cluster-threshold 1 10.0.0.129:7000
- ...
- ################################
- 登录测试
- ./redis-cli -h 10.0.0.132 -c -p 7007
- 10.0.0.132:7007> ping
- PONG
- 10.0.0.132:7007> get name
- -> Redirected to slot [6659] located at 10.0.0.129:7000
- "456"
#注意:这个地方需要提一下的就是:如果要下线节点6,节点7,请务必先下线从节点,并且节点6的slot的迁移到其他节点了,如果先线下节点6的话 会发产生故障切换,节点7成主节点了
在移除某个redis节点之前,首先不能在登入该节点当中,否则不能正常移除该节点。
- 退出所有链接的客户端,然后在任意一台机器执行
- [root@redis-1 src]# ./redis-cli --cluster del-node 10.0.0.132:7007 dbad32bd47cc177de61109b96447d1f1ef6db2fc #该节点的id
- ...
- >>> Sending CLUSTER RESET SOFT to the deleted node.
- [root@redis-1 src]# ./redis-cli -h 10.0.0.129 -c -p 7000
- 10.0.0.129:7000> CLUSTER NODES
- ...可以看到7007从节点被删除
删除主节点:带有槽的节点
- 需要先将该主节点的槽删除,在删除之前可以先看一下该节点的槽点有多少个,然后最好平均分到其他节点上
-
- 将6节点上面的槽迁移到其他节点:
- ip+port:要移除的节点
- cluster-from:移除节点的id
- cluster-to:接受槽主节点的id,需要将4096平均移动到不同的主节点,需要写不同接受槽的主节点id
- cluster-slots:移除槽的数量
-
- [root@redis-1 src]# ./redis-cli --cluster reshard 10.0.0.132:7006 --cluster-from 0aed4a95f08a8993ade091343e0267474b4b4094 --cluster-to 50891d2bbe5f228b7f22c32763fdc30a95f1aae3 --cluster-slots 1365 --cluster-yes
-
- [root@redis-1 src]# ./redis-cli --cluster reshard 10.0.0.132:7006 --cluster-from 0aed4a95f08a8993ade091343e0267474b4b4094 --cluster-to b4f58fdba2d44fa02efe23b1fc3ee387c3159284 --cluster-slots 1365 --cluster-yes
-
- [root@redis-1 src]# ./redis-cli --cluster reshard 10.0.0.132:7006 --cluster-from 0aed4a95f08a8993ade091343e0267474b4b4094 --cluster-to a30d771ab57c8512304e775f337d65a2a90e85e6 --cluster-slots 1366 --cluster-yes
-
- 然后查看节点信息,会发现7006节点上的槽为0
-
- 10.0.0.129:7000> CLUSTER nodes

- 如果报错:
- [root@redis-1 src]# ./redis-cli --cluster del-node 10.0.0.132:7006 0aed4a95f08a8993ade091343e0267474b4b409
- >>> Removing node 308320db4284c9b203aff1d3d9a145616856f681 from cluster 10.0.0.132:7006
- [ERR] Node 10.0.0.132:7006 is not empty! Reshard data away and try again.
-
- 需要重新查看一下槽有没有全部移动完成。如果没有需要重新指定数量移动。这是因为还有槽不能直接移除master。
删除7006master节点
- [root@redis-1 src]# ./redis-cli --cluster del-node 10.0.0.132:7006 0aed4a95f08a8993ade091343e0267474b4b409
- ...
- >>> Sending CLUSTER RESET SOFT to the deleted node.
- 在查看节点信息,会发现7006节点没有了
- 10.0.0.129:7000> CLUSTER nodes
- 可以看到变成了三主三从
- [root@redis-3 src]# ps aux |grep redis
- root 6134 0.2 0.5 164900 10084 ? Ssl 11:28 0:42 ./redis-server 10.0.0.131:7004 [cluster]
- root 6140 0.2 0.6 171044 12256 ? Ssl 11:28 0:43 ./redis-server 10.0.0.131:7005 [cluster]
- root 6808 0.0 0.0 112676 976 pts/0 R+ 15:58 0:00 grep --color=auto redis
- [root@redis-3 src]# kill -9 6134
- [root@redis-3 src]# ./redis-cli -h 10.0.0.129 -c -p 7000
- 10.0.0.129:7000> cluster nodes
可以看到这个7004端口这个redis已经失效了
- [root@redis-3 src]# ./redis-server ../cluster/7004/redis.conf &
- [1] 6818
- [root@redis-3 src]#
- [1]+ 完成 ./redis-server ../cluster/7004/redis.conf
- [root@redis-3 src]# ./redis-cli -h 10.0.0.129 -c -p 7000
- 10.0.0.129:7000> cluster nodes
可以看到该端口的redis重启后变成了7001的从节点。实现了主从切换
- 一、如何解决Redis,mysql双写一致性?
- 1.最经典的缓存+数据库读写的模式:
- 读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
- 更新的时候,先更新数据库,然后再删除缓存。
- 2.给缓存设置过期时间,这种方案下,可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,也就是说如果数据库写成功,缓存更新失败,那么只要到达过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存。
-
- 二、缓存雪崩
- 数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。
- 产生雪崩的简单过程:
- 1、redis集群大面积故障
- 2、缓存失效,但依然大量请求访问缓存服务redis
- 3、redis大量失效后,大量请求转向到mysql数据库,mysql的调用量暴增,很快就扛不住了,甚至直接宕机
- 4、由于大量的应用服务依赖mysql和redis的服务,这个时候很快会演变成各服务器集群的雪崩,最后网站彻底崩溃。
- #解决:
- 1.缓存的高可用性
- 缓存层设计成高可用,防止缓存大面积故障。即使个别节点、个别机器、甚至是机房宕掉,依然可以提供服务,例如 Redis Sentinel 和 Redis Cluster 都实现了高可用。
-
- 2.缓存降级
- 可以利用ehcache等本地缓存(暂时支持),主要还是对源服务访问进行限流、资源隔离(熔断)、降级等。
- 当访问量剧增、服务出现问题仍然需要保证服务还是可用的。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级,这里会涉及到运维的配合。
- 降级的最终目的是保证核心服务可用,即使是有损的。
- 在进行降级之前要对系统进行梳理,比如:哪些业务是核心(必须保证),哪些业务可以容许暂时不提供服务(利用静态页面替换)等,以及配合服务器核心指标,来后设置整体。
-
- 3.Redis备份和快速预热
- 1)Redis数据备份和恢复
- 2)快速缓存预热
-
- 4.提前演练
- 最后,建议还是在项目上线前,演练缓存层宕掉后,应用以及后端的负载情况以及可能出现的问题,对高可用提前预演,提前发现问题。
-
- 三、缓存穿透
- 缓存穿透是指查询一个一不存在的数据。例如:从缓存redis没有命中,需要从mysql数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
- 解决:
- 如果查询数据库也为空,直接设置一个默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。设置一个过期时间或者当有值的时候将缓存中的值替换掉即可。
-
- 四、缓存并发
- 这里的并发指的是多个redis的client同时set key引起的并发问题。其实redis自身就是单线程操作,多个client并发操作,按照先到先执行的原则,先到的先执行,其余的阻塞。
-
- 五、缓存预热
- 缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。
- 这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
- 解决:
- 1、直接写个缓存刷新页面,上线时手工操作下;
- 2、数据量不大,可以在项目启动的时候自动进行加载;
- 目的就是在系统上线前,将数据加载到缓存中。
-
- 其他面试:
- 1.Redis官方为什么不提供Windows版本?
- 因为目前Linux版本已经相当稳定,而且用户量很大,无需开发windows版本,反而会带来兼容性等问题。
- 2.一个字符串类型的值能存储最大容量是多少?
- 512M
- 3.Redis集群方案什么情况下会导致整个集群不可用?
- 有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用。
- 4.说说Redis哈希槽的概念?
- Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。
- 5.Redis集群之间是如何复制的?
- 异步复制
- 6.Redis集群最大节点个数是多少?
- 16384个。
- 7.Redis集群如何选择数据库?
- Redis集群目前无法做数据库选择,默认在0数据库。
- 8.怎么测试Redis的连通性?
- ping
- 9.如何与Redis互动?
- 安装服务器后,您可以运行redis安装提供的Redis客户端,也可以打开命令提示符并使用以下命令:
- redis-cli
- 10.使用Redis有什么好处?
- Redis非常快。
- 它支持服务器端锁定。
- 它有一个丰富的客户端库。
- 这是一个很好的反击。
- 它支持原子操作。
- 11.使用Redis有哪些缺点/限制?
- 它是单线程的。
- 它对一致哈希的客户端支持有限。
- 它具有很大的持久性开销。
- 它没有广泛部署。
- 12.Redis和RDBMS有什么区别?
- Redis是NoSQL数据库,而RDBMS是SQL数据库。
- Redis遵循键值结构,而RDBMS遵循表结构。
- Redis非常快,而RDBMS相对较慢。
- Redis将所有数据集存储在主存储器中,而RDBMS将其数据集存储在辅助存储器中。
- Redis通常用于存储小型和常用文件,而RDBMS用于存储大文件。
- Redis仅为Linux,BSD,Mac OS X,Solaris提供官方支持。它目前没有为Windows提供官方支持,而RDBMS提供对两者的支持
- 13.什么是redis的事务?
- a)事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
- b)事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
- 14.Redis单点吞吐量
- 单点TPS达到8万/秒,QPS达到10万/秒,补充下TPS和QPS的概念
- 1.QPS: 应用系统每秒钟最大能接受的用户访问量
- 每秒钟处理完请求的次数,注意这里是处理完,具体是指发出请求到服务器处理完成功返回结果。可以理解在server中有个counter,每处理一个请求加1,1秒后counter=QPS。
- 2.TPS: 每秒钟最大能处理的请求数
- 每秒钟处理完的事务次数,一个应用系统1s能完成多少事务处理,一个事务在分布式处理中,可能会对应多个请求,对于衡量单个接口服务的处理能力,用QPS比较合理。
-
- 问题2:Redis的多数据库机制,了解多少?
- 正常:Redis支持多个数据库,并且每个数据库的数据是隔离的不能共享,单机下的redis可以支持16个数据库(db0 ~ db15)
- 集群: 在Redis Cluster集群架构下只有一个数据库空间,即db0。因此,我们没有使用Redis的多数据库功能!
-
- 问题3:Redis集群机制中,你觉得有什么不足的地方吗?
- 假设我有一个key,对应的value是Hash类型的。如果Hash对象非常大,是不支持映射到不同节点的!只能映射到集群中的一个节点上!还有就是做批量操作比较麻烦!
-
- 问题4:懂Redis的批量操作么?
- 正常: 比如mset、mget操作等
- 集群: 我们在生产上采用的是Redis Cluster集群架构,不同的key会划分到不同的slot中,因此直接使用mset或者mget等操作是行不通的。
-
- 问题6:你们有对Redis做读写分离么?
- 正常:没有做
- 集群:不做读写分离。我们用的是Redis Cluster的架构,是属于分片集群的架构。而redis本身在内存上操作,不会涉及IO吞吐,即使读写分离也不会提升太多性能,Redis在生产上的主要问题是考虑容量,单机最多10-20G,key太多降低redis性能.因此采用分片集群结构,已经能保证了我们的性能。其次,用上了读写分离后,还要考虑主从一致性,主从延迟等问题,徒增业务复杂度。

- 1.ELK能做什么?
- ELK组件在海量日志系统的运维中,可用于解决:
- 分布式日志数据集中式查询和管理
- 系统监控,包含系统硬件和应用各个组件的监控
- 故障排查
- 安全信息和事件管理
- 报表功能
-
- 2.ES与关系数据库对比
- 在 ES 中,文档归属于一种 类型 (type) ,而这些类型存在于索引 (index) 中,类比传统关系型数据库
- DB -> Databases -> Tables -> Rows -> Columns
- 关系型 数据库 表 行 列
-
- ES -> Indices -> Types -> Documents -> Fields
- ES 索引 类型 文档 域(字段)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。