https://blog.csdn.net/houxian1103/article/details/108270768
===============RedisCluster5的安装包
wget http://download.redis.io/releases/redis-5.0.3.tar.gz
tar -zxvf redis-5.0.3.tar.gz
cd redis-5.0.3
make
# 安装到 /usr/local/redis 目录中 安装的文件只有一个bin目录
make install PREFIX=/usr/local/redis/
# 创建配置文件和data存放目录
mkdir /usr/local/redis/conf /usr/local/redis/data
# 可以查看所有这个命令和子命令的帮助信息
/data/server/redis-cluster/redis-5.0.5/src/redis-cli --cluster help
# 重置所有节点
CLUSTER RESET
# 创建cluster
/data/server/redis-cluster/redis-5.0.5/src/redis-cli --cluster create 192.168.64.15:8051 192.168.64.15:8052 \
192.168.64.169:8053 192.168.64.169:8054 192.168.64.169:8056 192.168.64.169:8057 \
--cluster-replicas 1
# 检查集群状态
/data/server/redis-cluster/redis-5.0.5/src/redis-cli --cluster check 192.168.64.15:8051
# 检查集群,查看所有节点信息
/data/server/redis-cluster/redis-5.0.5/src/redis-cli -c -h 192.168.64.15 -p 8051 cluster nodes
# 默认是master平均分了0-16383的所有虚拟slot
# 可以进行调整,部分节点放多一点slot(槽或者位置)。
/data/server/redis-cluster/redis-5.0.5/src/redis-cli --cluster reshard <host>:<port> --cluster-from <node-id> --cluster-to <node-id> --cluster-slots <number of slots> --cluster-yes
===============测试自动故障转移
# cluster集群不保证数据一致,数据也可能丢失
# 首先是运行客户端不断的写入或读取数据,以便能够发现问题
# 然后是模拟节点故障:找一个主节点关闭,主从故障切换的过程中,这个时间端的操作,客户端而言,只能是失败
# 官方描述 https://redis.io/topics/cluster-spec
There is always a window of time when it is possible to lose writes during partitions.
分区的时间窗口内总是有可能丢失写操作。
==============手动故障转移
# 可能某个节点需要维护(机器下线、硬件升级、系统版本调整等等场景),需要手动的实现转移
# 在slave节点上执行命令
CLUSTER FAILOVER
# 注:CLUSTER help 可以看到帮助文档和简介。 相对安全的做法
===============扩容操作
# 1、 启动新节点
/usr/local/redis/bin/redis-server /usr/local/redis/conf/6387.conf
# 2、 加入到已经存在的集群作为master
/usr/local/redis/bin/redis-cli --cluster add-node 192.168.100.242:6387 192.168.100.242:6382
# 本质就是发送一个新节点通过 CLUSTER MEET命令加入集群
# 新节点没有分配hash槽
# 3、 加入到已经存在的集群作为slave
/usr/local/redis/bin/redis-cli --cluster add-node 192.168.100.242:7006 192.168.100.242:7000 --cluster-slave
# 可以手工指定master,否则就是选择一个slave数量较少的master
/usr/local/redis/bin/redis-cli --cluster add-node 192.168.100.242:7006 192.168.100.242:7000 --cluster-slave --cluster-master-id <node-id>
# 还可以将空master,转换为slave
cluster replicate <master-node-id>
# 4、 检查集群
/usr/local/redis/bin/redis-cli --cluster check 192.168.100.242:6382
================缩容操作
# 注意:删除master的时候要把数据清空或者分配给其他主节点
/usr/local/redis/bin/redis-cli --cluster del-node 192.168.100.242:6381 <node-id>
================集群关心的问题
# 1、 增加了slot槽的计算,是不是比单机性能差?
共16384个槽,slots槽计算方式公开的,java客户端中就使用了:HASH_SLOT = CRC16(key) mod 16384
为了避免每次都需要服务器计算重定向,优秀的java客户端都实现了本地计算,和服务器slots分配进行映射,有变动时再更新本地内容。
# 2、 redis集群大小
理论是可以做到16384个槽,但是redis官方建议是最大1000个实例
# 3、 批量操作或者
# 4、cluster meet命令中的bus-port是什么?
MEET <ip> <port> [bus-port]
每个Redis群集节点都有一个额外的TCP端口,用于接收来自其他Redis群集节点的传入连接
# 5、集群节点间的通信方式
每个节点使用TCP连接与每个其他节点连接。
# 6、ask和moved重定向的区别
重定向包括两种情况
如果是确定slot不属于当前节点,redis会返回moved
如果当前redis节点正在处理slot迁移,则代表此处请求对应的key暂时不在此节点,返回ask,告诉客户端本次请求重定向
# 7、数据倾斜和访问倾斜的问题
解决办法 调整key的策略 + slot迁移
迁移过程如下,完整的迁移流程:
在迁移目的节点执行cluster setslot <slot> IMPORTING <node ID>命令,指明需要迁移的slot和迁移源节点。
在迁移源节点执行cluster setslot <slot> MIGRATING <node ID>命令,指明需要迁移的slot和迁移目的节点。
在迁移源节点执行cluster getkeysinslot获取该slot的key列表。
在迁移源节点执行对每个key执行migrate命令,该命令会同步把该key迁移到目的节点。
在迁移源节点反复执行cluster getkeysinslot命令,直到该slot的列表为空。
在迁移源节点和目的节点执行cluster setslot <slot> NODE <node ID>,完成迁移操作。
==============批量操作
删除
redis-cli -h 10.10.45.5 -p 12161 --scan --pattern "ops-coffee-*" | xargs -L 10 redis-cli -h 10.10.45.5 -p 12161 unlink
查询
redis-cli -h 10.10.45.5 -p 12161 --scan --pattern "ops-coffee-*" | xargs -L 1 redis-cli -h 10.10.45.5 -p 12161 get
===========对应查看链接相关的Linux
# ss的结果证明了链接已经建立了
ss -ant
# 将目的端口为 8051 的请求丢弃
iptables -A INPUT -p tcp --dport 18052 -j DROP
iptables -A INPUT -p tcp --dport 8052 -j DROP
# 加上拒绝策略的参数
iptables -A INPUT -p tcp --dport 5555 -j REJECT --reject-with tcp-reset
# tcpkill的原理和刚才的iptables相似, 也是发送了一个链接重置的R标志报文, 迫使对方关闭断开连接, 只是相对而言会比较智能一点, 因为它会自动构造报文并发送.
tcpkill -1 -i eth0 port 5555
# 清空规则缓冲区
iptables -F
# 查看规则
iptables -nL
==========tcpdump进行网络抓包
模拟server启动:nc -l -p 5555
模拟client连接:nc 10.10.200.30 5555 -p 6666
tcpdump -i en3 -xnn -S |grep 192.168.64.15
iptables的DROP行为, 能够阻止链接的建立, 但是对于已经建立起来的链接, 顶多只能阻止数据的传输, 但是不能断开链接, 链接的断开应该只有下面几种可能:
socket 的主动close, 也就是发送 fin报文 ( 应用层程序或者内核 )
TCP链接的超时自动断开 ( 这个过程可能会比较耗时 )
伪造报文发送RST
在某些情况下, 哪怕对方关闭了, 但是自己也是无法感知的, 还是需要send一次, 通信一次, 触发了socket的错误, 例如 Connection reset by peer. 或者 Broken pipe等等, 才能知道自己可以关闭, 否则大家都不通信, 这样有心无力, 只能听天由命了!