一、Redis Cluster去中心化集群
Redis集群是一个由多个主从节点群组成的分布式服务集群,它具有复制、高可用和分片特性。Redis集群不需要sentinel哨兵也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展,据官方文档称可以线性扩展到上万个节点(官方推荐不超过1000个节点)。redis集群的性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单。redis集群的运用主要是针对海量数据+高并发+高可用的场景。
分布式:分布式计算是分布式系统的核心思想,指的是将一个复杂的任务分解为多个子任务,并将这些子任务分配给不同的节点(服务器)进行处理。最终,所有节点的计算结果会汇总起来形成最终的结果。简单的来讲就是将一个单体应用拆分成不同单元的功能模块
1.为什么要用redis-cluster集群? 1 2 3 4 5 6 7 8 9 1.首先Redis单实例主要有单点,容量有限,流量压力上限的问题。 Redis单点故障,可以通过主从复制replication,和自动故障转移sentinel哨兵机制。但Redis单Master实例提供写服务,仍然有容量和压力问题,因此需要数据分区,构建多个Master实例同时提供读写服务(不仅限于从replica节点提供读服务)。 2.并发问题 redis官方声称可以达到 10万/s,每秒执行10万条命令 假如业务需要每秒100万的命令执行呢? 解决方案如下 1.正确的应该是考虑分布式,加机器,把数据分到不同的位置,分摊集中式的压力,一堆机器做一件事.还需要一定的机制保证数据分区,并且数据在各个主Master节点间不能混乱,当然最好还能支持在线数据热迁移的特性。
2、什么是Redis-Cluster 为何要搭建Redis集群。Redis是在内存中保存数据的,而我们的电脑一般内存都不大,这也就意味着Redis不适合存储大数据,Redis更适合处理高并发,一台设备的存储能力是很有限的,但是多台设备协同合作,就可以让内存增大很多倍,这就需要用到集群。
1 2 从redis 3.0之后版本支持redis-cluster集群,它是Redis官方提出的解决方案: Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。其Redis-cluster架构图如下:
在这个图中,每一个蓝色的圈都代表着一个redis的服务器节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他操作
2.1 redis cluster特点 1 2 3 1.所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。 2.客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。 3.节点的fail是通过集群中超过半数的节点检测失效时才生效。
2.2 redis-cluster数据分布 Redis-cluster集群中有16384 (0-16383)个哈希槽,每个redis实例负责一部分slot/槽位,集群中的所有信息通过节点数据交换而更新。一个hash slot中会有很多key和value。
2.3 数据分布存储原理 Redis 集群使用数据分片(sharding)来实现:Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value(name1: 张三) 时,redis 先对 key 使用 crc16 算法算出一个结果678698,然后把结果对 16384 求余数(集群使用公式 CRC16(key) % 16384),这样每个key 都会对应一个编号在 0-16383 之间的哈希槽,那么redis就会把这个key 分配到对应范围的节点上了。同样,当连接三个节点任何一个节点想获取这个key时,也会这样的算法,然后内部跳转到存放这个key节点上获取数据。
例如三个节点:哈希槽分布的值如下:
1 2 3 cluster1: 0-5460 cluster2: 5461-10922 cluster3: 10923-16383
这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。 比如说:
如果用户将新节点 D 添加到集群中, 那么集群只需要将节点 A 、B 、 C 中的某些槽移动到节点 D 就可以了。
如果用户要从集群中移除节点 A , 那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C , 然后再移除空白(不包含任何哈希槽)的节点 A 就可以了。
因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞, 所以无论是添加新节点还是移除已存在节点, 又或者改变某个节点包含的哈希槽数量, 都不会造成集群下线。
3、Redis Cluster主从模式 1 2 3 4 5 6 7 redis cluster 为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会有这个从节点选取一个来充当主节点,从而保证集群不会挂掉. 1.主从切换机制 选举过程是集群中所有master参与,如果半数以上master节点与故障节点通信超过(cluster-node-timeout),认为该节点故障,自动触发故障转移操作. #故障节点对应的从节点自动升级为主节点 2.什么时候整个集群就不能用了? 如果集群任意一个主节点挂掉,且当前主节点没有从节点,则集群将无法继续,因为我们不再有办法为这个节点承担范围内的哈希槽提供服务。但是,如果这个主节点和所对应的从节点同时失败,则Redis Cluster无法继续运行。
二、集群部署 1 2 3 4 5 6 7 8 9 10 环境准备: 1.准备三机器,关闭防火墙和selinux 2.制作解析并相互做解析 注:规划架构两种方案,一种是单机多实例,这里我们采用多机器部署 三台机器,每台机器上面两个redis实例,一个master一个slave,第一列做主库,第二列做备库 # 记得选出控制节点 redis-cluster1 192.168.116.172 7000、7001 redis-cluster2 192.168.116.173 7002、7003 redis-cluster3 192.168.116.174 7004、7005
1.三台机器相同操作 1 2 3 4 5 6 7 8 9 10 1.安装redis [root@redis-cluster1 ~]# mkdir /data [root@redis-cluster1 ~]# yum -y install gcc automake autoconf libtool make [root@redis-cluster1 ~]# wget https://download.redis.io/releases/redis-6.2.0.tar.gz [root@redis-cluster1 ~]# tar xzvf redis-6.2.0.tar.gz -C /data/ [root@redis-cluster1 ~]# cd /data/ [root@redis-cluster1 data]# mv redis-6.2.0/ redis [root@redis-cluster1 data]# cd redis/ [root@redis-cluster1 redis]# make #编译 [root@redis-cluster1 redis]# mkdir /data/redis/data #创建存放数据的目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 2.创建节点目录:按照规划在每台redis节点的安装目录中创建对应的目录(以端口号命名) [root@redis-cluster1 redis]# pwd /data/redis [root@redis-cluster1 redis]# mkdir cluster #创建集群目录 [root@redis-cluster1 redis]# cd cluster/ [root@redis-cluster1 cluster]# mkdir 7000 7001 #创建节点目录 [root@redis-cluster2 redis]# mkdir cluster [root@redis-cluster2 redis]# cd cluster/ [root@redis-cluster2 cluster]# mkdir 7002 7003 [root@redis-cluster3 redis]# mkdir cluster [root@redis-cluster3 redis]# cd cluster/ [root@redis-cluster3 cluster]# mkdir 7004 7005
1 2 3 4 5 6 7 8 9 3.拷贝配置文件到节点目录中,#三台机器相同操作 [root@redis-cluster1 cluster]# cp /data/redis/redis.conf 7000/ [root@redis-cluster1 cluster]# cp /data/redis/redis.conf 7001/ [root@redis-cluster2 cluster]# cp /data/redis/redis.conf 7002/ [root@redis-cluster2 cluster]# cp /data/redis/redis.conf 7003/ [root@redis-cluster3 cluster]# cp /data/redis/redis.conf 7004/ [root@redis-cluster3 cluster]# cp /data/redis/redis.conf 7005/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 4.修改集群每个redis配置文件。(主要是端口、ip、pid文件,三台机器相同操作),修改如下: [root@redis-cluster1 cluster]# cd 7000/ [root@redis-cluster1 7000]# vim redis.conf #修改如下 bind 192.168.116.172 #每个实例的配置文件修改为对应节点的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文件...避免冲突。确保所有机器都修改。
1 2 3 4 5 6 7 8 9 10 11 12 5.启动三台机器上面的每个节点(三台机器相同操作) [root@redis-cluster1 ~]# cd /data/redis/src/ [root@redis-cluster1 src]# nohup ./redis-server ../cluster/7000/redis.conf & [root@redis-cluster1 src]# nohup ./redis-server ../cluster/7001/redis.conf & [root@redis-cluster2 7003]# cd /data/redis/src/ [root@redis-cluster2 src]# nohup ./redis-server ../cluster/7002/redis.conf & [root@redis-cluster2 src]# nohup ./redis-server ../cluster/7003/redis.conf & [root@redis-cluster3 7005]# cd /data/redis/src/ [root@redis-cluster3 src]# nohup ./redis-server ../cluster/7004/redis.conf & [root@redis-cluster3 src]# nohup ./redis-server ../cluster/7005/redis.conf &
查看端口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 6.创建redis-cluster集群:在其中一个节点操作就可以 redis节点搭建起来后,需要完成redis cluster集群搭建,搭建集群过程中,需要保证6个redis实例都是运行状态。 Redis是根据IP和Port的顺序,确定master和slave的,所以要排好序,再执行。 参数: --cluster-replicas 1:表示为集群中的每个主节点创建一个从节点.书写流程:主节点ip+port 对应一个从节点ip+port(注意:若节点在不同的机器上,注意主节点的书写位置,要避免主节点在同一台机器上,影响性能。正常是前面三个节点为主节点,后面的为从节点) [root@redis-cluster1 src]# cd /data/redis/src/ [root@redis-cluster1 src]# ./redis-cli --cluster create --cluster-replicas 1 192.168.174.130:6379 192.168.174.131:6379 192.168.174.132:6379 192.168.174.133:6379 192.168.174.134:6379 192.168.174.135:6379 192.168.116.172:7000 192.168.116.172:7001 192.168.116.173:7002 192.168.116.173:7003 192.168.116.174:7004 192.168.116.174:7005 > >> 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.116.173:7003 to 192.168.116.172:7000 Adding replica 192.168.116.174:7005 to 192.168.116.173:7002 Adding replica 192.168.116.172:7001 to 192.168.116.174:7004 M: de5b4b2f6a559362ed56d4de1e3994fd529917b5 192.168.116.172:7000 slots:[0-5460] (5461 slots) master S: 2e8c1caa63ac4a1b9a6eea4f0fd5eab4c6b73c21 192.168.116.172:7001 replicates 60e3755761c9cbdacb183f59e3d6205da5335e86 M: e0370608cd33ddf5bb6de48b5627799e181de3b6 192.168.116.173:7002 slots:[5461-10922] (5462 slots) master S: 4035841f20f07674671e6bff5d4c6db99c00626b 192.168.116.173:7003 replicates de5b4b2f6a559362ed56d4de1e3994fd529917b5 M: 60e3755761c9cbdacb183f59e3d6205da5335e86 192.168.116.174:7004 slots:[10923-16383] (5461 slots) master S: e200afc33b10bd6975160bfeda7277d02371981a 192.168.116.174:7005 replicates e0370608cd33ddf5bb6de48b5627799e181de3b6 Can I set the above configuration? (type 'yes' to accept): yes #写yes同意 > >> Nodes configuration updated > >> Assign a different config epoch to each node > >> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join . > >> Performing Cluster Check (using node 192.168.116.172:7000) M: de5b4b2f6a559362ed56d4de1e3994fd529917b5 192.168.116.172:7000 slots:[0-5460] (5461 slots) master 1 additional replica(s) M: e0370608cd33ddf5bb6de48b5627799e181de3b6 192.168.116.173:7002 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: 2e8c1caa63ac4a1b9a6eea4f0fd5eab4c6b73c21 192.168.116.172:7001 slots: (0 slots) slave replicates 60e3755761c9cbdacb183f59e3d6205da5335e86 M: 60e3755761c9cbdacb183f59e3d6205da5335e86 192.168.116.174:7004 slots:[10923-16383] (5461 slots) master 1 additional replica(s) S: 4035841f20f07674671e6bff5d4c6db99c00626b 192.168.116.173:7003 slots: (0 slots) slave replicates de5b4b2f6a559362ed56d4de1e3994fd529917b5 S: e200afc33b10bd6975160bfeda7277d02371981a 192.168.116.174:7005 slots: (0 slots) slave replicates e0370608cd33ddf5bb6de48b5627799e181de3b6 [OK] All nodes agree about slots configuration. > >> Check for open slots... > >> Check slots coverage... [OK] All 16384 slots covered.
1 2 3 4 5 6 7 8 7.查看集群状态可连接集群中的任一节点,此处连接了集群中的节点192.168.116.172:7000 # >登录集群客户端,-c标识以集群方式登录 [root@redis-cluster1 src]# ./redis-cli -h 192.168.116.172 -c -p 7000 192.168.116.172:7000> ping PONG # >>> 查看集群信息 192.168.116.173:7002> cluster info
cluster_state:ok :
集群的当前状态。ok 表示集群正常运行。如果为 fail,表示集群出现问题(例如某个节点不可达或有故障)。
cluster_slots_assigned:16384 :
集群中已分配的哈希槽数量。Redis 集群的哈希槽总数是 16384,表示所有槽都已分配。
cluster_slots_ok:16384 :
集群中正常工作的哈希槽数量。这里为 16384,表示所有槽都正常。
cluster_slots_pfail:0 :
处于 pfail(潜在故障)状态的哈希槽数量。pfail 表示集群认为某些节点可能有问题,但尚未完全确认。这里为 0,表示没有节点处于潜在故障状态。
cluster_slots_fail:0 :
处于 fail 状态的哈希槽数量。fail 表示有节点被标记为已故障,并且集群确认它们无法工作。这里为 0,表示没有节点发生故障。
cluster_known_nodes:8 :
集群中已知的节点数量。这里为 8,表示集群中有 8 个节点,这些节点包括主节点和从节点。
cluster_size:4 :
集群的大小,即主节点的数量。这里为 4,表示集群中有 4 个主节点。
cluster_current_epoch:8 :
当前集群的 epoch(纪元)。epoch 用于处理集群的重新分片或节点选举。在集群中,每次重新选主或分配槽时,epoch 会递增。
cluster_stats_messages_ping_sent:1923 :
该节点向集群中其他节点发送的 ping 消息数量。这里为 1923,表示该节点已经发送了 1923 条 ping 消息来监控集群中的其他节点状态。
cluster_stats_messages_pong_sent:1955 :
该节点向集群中其他节点发送的 pong 消息数量。这里为 1955,表示该节点响应了 1955 次其他节点发送的 ping 消息。
cluster_stats_messages_sent:3878 :
该节点发送的所有类型的消息总数,包括 ping、pong等消息类型。这里总计为 3878 条消息。
cluster_stats_messages_ping_received:1955 :
该节点接收到的 ping 消息数量。这里为 1955,表示该节点接收了 1955 条来自其他节点的 ping 消息。
cluster_stats_messages_pong_received:1923 :
该节点接收到的 pong 消息数量。这里为 1923,表示该节点接收了 1923 条来自其他节点的 pong 消息。
cluster_stats_messages_received:3878 :
该节点接收到的所有类型的消息总数。包括 ping、pong 等消息类型。
1 2 192.168.174.50:6379> CLUSTER nodes
1 05a613685a2f0e49c5be0603ad5a867ac64bd601 192.168.174.54:6379@16379 master - 0 1723698435000 8 connected 1333-5460
05a613685a2f0e49c5be0603ad5a867ac64bd601 :
节点的唯一标识符 (Node ID),用于唯一标识 Redis 集群中的每个节点。
192.168.174.54:6379@16379 :
节点的 IP 地址和端口号。192.168.174.54 是 IP 地址,6379 是 Redis 的服务端口,16379 是集群端口。
master :
节点的角色。在此行中,该节点是 master 节点,表示它是集群中的主节点,负责管理指定范围的哈希槽。
- :
此字段用于标记节点的状态或者对某些节点的关系。在此处显示为 -,表示该节点没有故障。
0 :
这是节点的延迟时间(ping-sent),即上次向该节点发送 ping 的时间。0 表示当前未发送 ping。
1723698435000 :
上次接收到节点 pong 响应的时间戳,单位为毫秒。
8 :
connected :
节点的连接状态。connected 意味节点目前在线且正常连接到集群。
1333-5460 :
1 18ede67545805ff44b1183bdeb3be6a513ded867 192.168.174.55:6379@16379 slave e473d8099e960ce1e5cd44807efd10f80706dfff 0 1723698435170 2 connected
18ede67545805ff44b1183bdeb3be6a513ded867 :
192.168.174.55:6379@16379 :
节点的 IP 地址和端口号。192.168.174.55 是 IP 地址,6379 是 Redis 的服务端口,16379 是集群端口。
slave :
e473d8099e960ce1e5cd44807efd10f80706dfff :
slave 节点所属的主节点的 ID。该从节点在从主节点复制数据。
0 :
节点的延迟时间(ping-sent),即上次向该节点发送 ping 的时间。这里的 0 表示当前未发送 ping。
1723698435170 :
这是上次接收到节点 pong 响应的时间戳,单位为毫秒。
2 :
connected :
节点的连接状态。connected 意味着该节点目前在线且正常连接到集群。
三、集群操作 1、客户端登陆 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 测试链接redis,存取数据(链接集群中任意一台机器就可以。) 存: [root@redis-cluster1 src]# ./redis-cli -h 192.168.116.172 -c -p 7000 192.168.116.172:7000> ping PONG 192.168.116.172:7000> set name qianfeng -> Redirected to slot [5798] located at 192.168.116.173:7002 OK 192.168.116.173:7002> 读 [root@redis-cluster3 src]# ./redis-cli -h 192.168.116.173 -c -p 7002 192.168.116.173:7002> ping PONG 192.168.116.173:7002> get name "qianfeng" 192.168.116.173:7002> exists name #查看某一个key是否存在 (integer) 1
2、Redis Cluster 添加节点
环境准备
1 2 192.168.174.56 redis07 192.168.174.57 redis08
两台服务器安装redis实例
略
添加的master节点操作
1 2 3 4 5 [root@redis07 ~] [root@redis07 ~]
参数解释:
192.168.174.56:6379 当前需要加入集群的master地址
192.168.174.51:6379 加入的集群中存在的任意master地址
登录集群任意节点查看
1 2 [root@redis01 redis] 192.168.174.50:6379> cluster nodes
给新节点分配Hash槽
需要给新节点进行hash槽分配,这样该主节才可以存储数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@redis01 redis] >>> Performing Cluster Check (using node 192.168.116.175:7006) ...... [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. How many slots do you want to move (from 1 to 16384)? 4000 What is the receiving node ID? 828c48dc72d52ff5be972512d3d87b70236af87c 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确认
查看集群节点分配的槽位
1 192.168.174.52:6379> cluster nodes
给master添加slave
参数解释:
192.168.174.57:6379 添加的slave节点ip+端口
192.168.174.56:6379 需要添加slave的master节点ip+端口
d9a270610aad049ab23045f6ed9098c58591c7b3 需要添加slave的master节点的标识码
平衡各个主节点的槽
测试
1 2 3 4 5 6 7 192.168.174.52:6379> set ccc ddd -> Redirected to slot [135] located at 192.168.174.56:6379 OK 192.168.174.56:6379> keys * 1) "name" 2) "name02" 3) "ccc"
3、Redis Cluster移除节点 如果要下线节点6,节点7,请务必先下线从节点,并且节点6的slot的迁移到其他节点了,如果先线下节点6的话 会发产生故障切换,节点7成主节点了。在移除某个redis节点之前,首先不能在登入该节点当中,否则不能正常移除该节点。
移除从节点
查看集群节点
1 192.168.174.56:6379> cluster nodes
查看每个节点槽的数量
要删除的当前主节点哈希槽状态:0-1364 5461-6826 10923-12287 共有哈希槽=1365 + 1366 + 1365 = 4096个
将redis06节点上面的槽迁移到其他节点
1 2 3 4 5 6 7 8 9 10 redis-cli --cluster reshard 192.168.174.56:6379 --cluster-from d9a270610aad049ab23045f6ed9098c58591c7b3 --cluster-to 788f2fbe060a59449a31da7a0c8afc384007387b --cluster-slots 1365 --cluster-yes redis-cli --cluster reshard 192.168.174.56:6379 --cluster-from d9a270610aad049ab23045f6ed9098c58591c7b3 --cluster-to 98a4ff6a6533f30a2c3211f28f4c5a709949d44e --cluster-slots 1366 --cluster-yes redis-cli --cluster reshard 192.168.174.56:6379 --cluster-from d9a270610aad049ab23045f6ed9098c58591c7b3 --cluster-to 58fa947712a4a3af5fde37982f4ea02126655e02 --cluster-slots 1365 --cluster-yes
查看集群节点信息
1 192.168.174.56:6379> cluster nodes
删除节点
1 redis-cli --cluster del-node 192.168.174.56:6379 d9a270610aad049ab23045f6ed9098c58591c7b3
参数解释:
192.168.174.56:6379 需要删除的节点IP+端口
d9a270610aad049ab23045f6ed9098c58591c7b3 节点标识码
查看集群节点信息
1 192.168.174.51:6379> cluster nodes
四、主从切换 1 2 3 4 5 6 7 8 9 10 测试: 1.将节点cluster1的主节点7000端口的redis关掉 [root@redis-cluster1 src]# ps -ef |grep redis root 15991 1 0 01:04 ? 00:02:24 ./redis-server 192.168.116.172:7000 [cluster] root 16016 1 0 01:04 ? 00:02:00 ./redis-server 192.168.116.172:7001 [cluster] root 16930 1595 0 08:04 pts/0 00:00:00 grep --color=auto redis [root@redis-cluster1 src]# kill -9 15991 查看集群信息: 192.168.116.173:7002> CLUSTER nodes
可以看到7000端口这个redis已经是fail失败的了。
1 2 3 4 5 6 2.将该节点的7000端口redis启动在查看 [root@redis-cluster1 log]# cd /data/redis/src/ [root@redis-cluster1 src]# ./redis-server ../cluster/7000/redis.conf 查看节点信息: 192.168.116.173:7002> CLUSTER nodes
redis面试问题整理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 一、如何解决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性能.因此采用分片集群结构,已经能保证了我们的性能。其次,用上了读写分离后,还要考虑主从一致性,主从延迟等问题,徒增业务复杂度。
elk相关面试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1.ELK能做什么? ELK组件在海量日志系统的运维中,可用于解决: 分布式日志数据集中式查询和管理 系统监控,包含系统硬件和应用各个组件的监控 故障排查 安全信息和事件管理 报表功能 2.ES与关系数据库对比 在 ES 中,文档归属于一种 类型 (type) ,而这些类型存在于索引 (index) 中,类比传统关系型数据库 DB -> Databases -> Tables -> Rows -> Columns 关系型 数据库 表 行 列 ES -> Indices -> Types -> Documents -> Fields ES 索引 类型 文档 域(字段)