Redis cluster

呼唤集群

1.10w/没秒 正常上万是没有问题的,业务需要并发量100w/s
2.机器内存16~256G,业务需要500G
3.网络流量等
解决方案:强悍的机器,超大内存等
分布式:加机器

即,数量量和并发量引出集群。

数据分布

常用两种分区:
顺序分区: 1~100—>1-33(部署第一个结点) 34-66—>(部署第二个结点) 67-100–>(分布在第三个结点)
哈希分布:(例如节点取模)hash(key)%3..

分布方式 特点 典型产品
哈希分布 数据分散度高、键值分布业务无关、无法顺序访问 一致性哈希Memcache,Redis Cluster
顺序分布 数据分散度易倾斜、键值业务相关、可顺序操作 BIG Table, Hbase

哈希分布方式:
①节点取余方式 如 hash(key)%3…
问题:对节点伸缩时候,整个数据迁移比较大。【尝试多陪扩容,迁移数据量为50%】
②一致性哈希:(一个环中)顺时针去查找最近的node
客户端分片:哈希+顺时针
节点伸缩:影响的节点数量特别少(同样是缓存的场景,不能改变原有node 上数据的转移)翻陪扩容:实现负载均衡
③ 虚拟槽分区
槽范围:0-16383 每个节点一个分配部分槽范围(每一个rediscluster 知道其余节点槽范围)
key;CRC16(key) &16383,发送给任意一个节点。 节点对于对应真正节点的反馈。

搭建集群

服务端多个节点,每个节点负责一部分槽。通常返回给客户端对应存储数据的节点。(通常命中率不高)智能客户端,知道数据对应的槽节点。

redis cluster 架构:
节点:每个节点都可以读写 #cluster-enabled:yes
meet:用于通信 A:–meetb->B
指派槽:负责本槽内的数据存写
复制:主从赋值(并不是通过sentinel)

特性:复制、高可用、分片的

安装

原生命令安装(理解架构):
1.配置开启节点
port
daemonize yes
dir “/opt/redis/redis/data”
dabfilename “dump-{port}.rdb”
logfile “{port}.log”
cluster-enable yes //代表当前节点是cluster节点
cluster-node-timeout 1500//主观下线的时间,ping时间
cluster-require-full-coverage yes//有节点出现问题,集群不可用 No
2.meet
cluster meet ip port
redis-cli -h 127.0.0.1 -p 7000 cluster meet 127.0.0.1 7001
3.分配槽
cluster addslots slot[slot…]
redis-cli -h 127.0.0.1 -p 7000 cluster addslots {0…5461}
4.设置主从
cluster replicate node-id(不等同于runid conf 文件中)
redis-cli -h 127.0.0.1 -p 7003 cluster replicate node-id-7000

官方工具安装
1.Ruby 环境准备
下载、编译、安装Ruby
2.安装rubygem redis (redis ruby 客户端)
3.安装redis-tirb.rb
redis-trib.rb create –replicas 1 127.0.0.1:8000 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003

集群伸缩

1.伸缩原理

槽和数据在节点之间的移动

2.扩容节点

PART ONE:
准备新节点
加入集群
迁移槽和数据
官方工具实现:redis-trib.rb add-node new_host:new_port existing_host:existing_port –salve –master-id
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PART TWO:迁移槽计划,迁移数据:
1.对目标节点 cluster setslot{slot} importing {sourceNodeId} 目标节点准备入槽数据
2.对源节点:cluster setslot{slot} migrating {targetNodeId} 源节点准备迁出槽的数据
3.源节点循环执行 cluster getkeysinslot{slot} {count} #获取槽下面的count 键
4.在源节点执行 migrate {targetIp} {targetPort} key 0 {timeout} 指定key 迁移
5.重复3~4
6.向集群所有主节点发送 cluster setlot {slot} node {targetNode},通知所有主节点槽分配给目标节点。

3.收缩节点

PART:下线迁移槽
和迁移槽相似
PART TWO:忘记节点(先从后主)
redis -cli>cluster forget{downNodeID}
reids-trib.rb del-node host:port. nodeID…
PARTTHREE:关闭节点

客户端路由

moved 重定向

1.发送键命令
2.计算槽和对应的节点
3.不是自身 回复moved异常 ,否则执行命令
4.重定向发送命令

redis -cli -c -p 7000
set key value #不会返回moved ,自己去处理

redis-cli -p 7000
set key value// 可能出现error moved 异常

ask 重定向

槽迁移产生的问题(客户端记录的槽在源节点,去访问时后发现以及迁移走路)。
1.发送键命令
2.回复ask转向
3.asking 发送命令
4.响应结果

都是客户端重定向:
movde:槽以及确定迁移
ask:槽还在迁移中

smart 客户端

JedisCluster
1.从集群中选一个可运行节点,使用cluster slots 初始化槽和节点映射
2.将cluster slots 的结果映射本地,为每个节点创建一个JedisPool
3.准备执行命令
出现连接出错,随机发送命令,返回moved,重新初始化 slot-node 缓存,如果命令发送五次任未成功 –>Too many cluster redirection!

基本使用:
Set nodeList = new HashSet();
JedisCluster redisCLuster = new JedisCluster(nodeList,timeOut,poolConfig);

1.单列模式
2.无需手动借还
3.合理设置commons-pool

多节点命令实现:
1.获取所有节点上的jedispool
2.获取每个节点的jedis 连接
3.执行相关命令

批量操作?mget mset 都需要在一个槽上

串行mget:key次网咯时间
串行IO :node次网络时间,提高并发量
hash_tag:增加tag 维护成本

故障转移

自身实现故障转移,没使用sentinel。
1.故障发现
ping/pong 消息实现故障发现(不仅仅是槽的信息,也包含故障信息)
主观下线:一个节点的认知
客观下线:过半以上持有槽的主节点都标记某节点主观下线。
2.故障恢复
资格检查:每个从节点检查与故障主节点的断线时间(超过太久的不具有资格)
准备选举时间:保证偏移量最大的从节点获取足够时间用于更新。
选举投票:偏移量最大的获取最多票数。
替换主节点:

1.slaveof no one
2撤销主节点负责槽,分配给自己
3.向集群广播自己pong消息,表明自己替换主节点。

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jcsyl_mshot/article/details/80322589
个人分类: 数据库
上一篇Redis Sentinel 常见问题
下一篇java序列化与反序列化系列问题
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭