Redis: 集群测试和集群原理

news/2024/10/4 17:43:19/

集群测试


1 ) SET/GET 命令

  • 测试 set 和 get 因为其他命令也基本相似,
  • 我们在 101 节点上尝试连接 103 $ /usr/local/redis/bin/redis-cli -c -a 123456 -h 192.168.10.103 -p 6376
  • 我们在插入或读取一个 key的时候,会对这个key做一个hash运算,运算完以后会得到对应槽的索引值
  • 之后,就会把key插入槽里,当执行 $ set username zhangsan,username 这个key就会被hash运算
    - > Reddirecte to slot [14315] located at 192.168.10.103:6375
    
  • 可见 username 的 槽是 14315,在 103:6375 这个实例上
  • 并且,我现在如果执行 set 的时候主机是 6376,命令行会重定向到 6375,这是内部的一个转向
  • 这是它内部在做的一个转向操作,之后,执行 $ set age 18 这个 age 运算完后插入 741槽
  • 这里又有了一个转向,741 这个槽在 6371的实例范围之内, 这些范围在 $ cluster nodes 返回可见


  • 执行 $ set address sh 发现并没有做转向,原因肯定是 address 运算之后,在 6371 实例槽的范围之内


  • 注意,get 也一样,会转向, 不再演示

2 ) 开启从节点只读模式

  • 关于从节点的只读模式,通过上面的例子,可以看出,所有的操作都是转发到主节点上去的
  • 目前从节点只起到备份容灾的角色,而非读的角色分担压力,目前还没有开启从节点的读功能
  • 我现在要释放压力,把读的压力给从节点,我只需要在从节点中执行一个 $ READONLY 命令即可
  • 注意,这个 $ READONLY 命令只支持自己主节点的key的范围
    • 就是如果获取的 key 不在这个从节点复制的主节点中
    • 它是没有办法给你直接返回的,它还是会去做转发,这是必然的

单节点和集群模式的性能测试

  • 我们对性能进行一个测试,通过 Redis 自带的 redis-benchmark 命令
  • Redis 是通过同时执行多个命令实现的
  • 把集群和单机分别执行一百万的get和set,看一下谁的性能更高,其实单机的性能是比较高的
  • 在集群环境测试的时候,get/set 它内部会去做一个转向的处理, 单机没有这个过程

1 )语法

  • $ redis-benchmark [option] [option value]

  • 参数

    选项描述
    -h指定服务器主机名
    -p指定服务器端口
    -s指定服务器 socket 方式连接
    -c指定并发连接数
    -n指定请求数
    -d以字节的形式指定SET/GET值的数据大小
    -k1=keep alive 0=reconnect
    -rSET/GET/INCR 使用随机 Key
    -P通过管道传输请求
    -q指定强制退出 Redis
    –csv以CsV格式输出
    -l生成循环,永久执行测试
    -t仅运行以逗号分隔的测试命令列表

2 ) 单机测试

# 随机set/get1000000条命令1000个并发
bin/redis-benchmark -a 123456 -h 192.168.10.101 -p 6379 -t set,get -r 1000000 -n 1000000 -c 1000

3 ) 集群测试

# 随机set/get1000000条命令1000个并发
bin/redis-benchmark -a 123456 -h 192.168.10.101 -p 6371 -t set, get -r 1000000 -n 1000000 -c 1000

4 ) 对比结果

  • 综合上述单机和集群跑出来的数据结果,单机要更快!

集群原理

  • 我们之前用到的单机,主从,哨兵这几种模式数据都是存在单个节点上
    • 如果说是主从的话,会有从节点,从节点也只是对主节点的数据进行复制
    • 而我们单个节点它存储是有上限的,而且我们说它还有写压力等
  • 集群其实就是把请求包括数据的存储都分在了不同的节点上,就是把数据进行了分片存储
    • 当一个分片的数量达到上限的时候,还可以给它分成多个分片

1 ) 哈希槽

  • 集群的原理是什么? 它的本质是哈希槽
    • Redis 集群,它并没有选用一致性哈希,一致性哈希它是一个圆环,它的节点是分配在这个圆环上
    • 当我们插入和删除节点的时候,它是会影响响临近的节点,对其他的节点没有影响,这是它的优点
    • 但是缺点就是在节点比较少的情况下,当你插入一个新的节点的时候,它影响到数据会比较多
    • 因为我们要做数据迁移,除非你有上千个节点,这个时候添加一个节点影响的就微乎其微了
    • 所以说它不太适合那种节点比较少的分布式的缓存
    • 一般我们公司里的集群不可能达到上千个节点,因为它性能本身就很高
    • 所以说 Redis 的集群它并没有选择一致性哈希算法
    • 它采用的是哈希槽的这种概念,主要原因就是一致性哈希它对于数据的分布
    • 节点的位置的控制并不是很友好
  • 哈希槽其实是两个概念
    • 第一个概念就是哈希算法,Redis Cluster 的 hash算法,它不是简单的 hash()
      • 而是内部的一个crc16的算法, 是一种校验算法
    • 第二个就是槽位的一个概念,就是空间分配的规则
      • 其实哈希槽的本质和一致性哈希算法是非常相似的
      • 不同点就是对于哈希空间的定义
        • 一致性哈希的空间是一个圆环,节点分布是基于圆环的
          • 没有办法很好的就是控制数据的分布
          • 圆环节点分布在圆环上,你节点比较少的时候,插入一个节点
          • 对临近的节点有影响,数据迁移就会比较多
          • 除非现在这个环上有上千个节点,在添加一个节点的时候,它的影响就非常非常小了
          • 所以它不适合少量数据节点的分布式方案
        • 而 Redis Cluster 槽位空间,它是可以自定义分配的
          • 就类似于像windows 盘符分区, 这种分区可以自定义大小,自定义位置
          • 就很好的可以去方便的管理,比如说我现在在D盘上右键扩展卷
          • 我就把D盘的一部分分出去变成一个E盘,对E盘还可以合并其他盘或删除E盘
          • 这样来回操作都没有什么问题,非常方便管理
  • 注意,对于槽位的转移和分派,Redis集群是不会自动进行的,而是需要人工配置的
    • 所以,Redis集群的高可用是依赖于节点的主从复制和主从间的故障转移。
  • Redis Cluster 它内部的哈希槽是 16384 个,通过 之前 check 检查的命令可以看出
    • 对于主节点的槽位的分配还是非常平均的
    • 这默认是Redis Cluster 自己去做的,当然我们人为的也可以去做这样的分配
    • 每个key 通过计算都会落在一个具体的槽位上,这个槽位,比如说属于哪个节点的
    • 然后这个我们自己在添加槽的时候,就可以自己来定义了
    • 比如说你的这个机器硬盘比较小,我们给它分配少一点
  • 哈希槽的这种概念就很好的解决了一致性哈希的一个缺点,而且它在容错和扩展上也非常的方便
  • 虽然说它表象跟一致性哈希一样,都是对受影响的数据进行转移
  • 但哈希槽本质其实是对槽位的转移
    • 就是它会把故障的节点负责的这个槽位转到其他正常的节点上
    • 扩展节点也是一样的, 比如说我现在新加了一个节点
    • 我可以把其他节点上的槽再转移到这个新的节点上,就非常的方便,影响很低的
    • 因为它固定了聚集在这些槽的某一个节点

2 ) 16384 个 slots (槽位)

  • Redis Cluster 没有单机那种 16个数据库 (0 - 15) 数据库的概念了,就是我们已经看不到数据库

  • 而是分成了 16384 个 slots (槽位) ,每个节点负责其中一部分槽位,槽位的信息存储于每个节点中

  • 那我们客户端这边是怎么来操作集群的呢?

    • 当客户端连接集群的时候,首先它会得到一份集群的槽位配置信息
    • 然后把它缓存到客户端本地,这样客户端要查找某个key的时候,就可以直接定位到目标节点
    • 同时因为槽位的信息可能会存在客户端服务器不一致的情况
    • 那这个里边还会有纠错机制来实现槽位信息的一个调整
    • 客户端,随便找一台都能连上,对吧?都能连上,然后连上之后看到的效果都是一样的

3 )槽位定位算法

  • Redis Cluster 默认会对key值使用CRC16算法进行hash得到一个整数值
  • 再把这个整数对 16384 取余,取完余以后会得到一个具体的槽位
  • 这个就是槽位的计算公式: HASH_SLOT = CRC16(key) mod 16384
  • 不管是 SET/GET 都是用这个方式
  • 基于此,Redis Cluster 它提供了灵活的节点的扩容和缩容的方案
    • 而且可以在不影响集群对外提供服务的情况下,为我们的集群添加节点进行扩容
    • 也可以下线部分节点进行缩容
  • 这里的槽其实就是 Redis Cluster 管理数据的基本单位
    • 集群的伸缩,其实就是咱们的槽和对应的数据在节点之间的移动
    • 对于这个槽位算法,简单的理解就扩容缩容之后槽需要重新分配,数据也需要重新迁移
    • 但是服务不需要下线,而且他对于数据和节点的影响非常的小
  • 为什么是 16834 个槽,而不是别的数字呢?
    • https://github.com/redis/redis/issues/2576
    • 这里考虑心跳消息头的一个大小, 会达到 8k,过于庞大,比较占带宽
    • 还有就是关于节点,数量不可能到达1000的,16834 足够
    • 第三个就是就是槽位越小节点少的情况下压缩率越高
      • 哈希槽的存储是通过 bitmap 形式来进行保存的
      • 传输的过程中会对 bitmap 进行压缩
      • 如果哈希槽越多,压缩率就会很低,而 16834 / 8 约等于 2kb 这个压缩率会很高

http://www.ppmy.cn/news/1534537.html

相关文章

C语言-指针

0.引入 int a; //定义了一个整型变量 名为a a 100; // a作为左值, 把100存放到a所对应的存储单元中 int b a; // a作为右值, 取a所对应的存储单元(变量本身)的值, 然后再把这个值存放到变量b对应的空间中 在C语言中, 任何一个变量名 都有两层含义: …

Mac通过ssh连接工具远程登录服务器( Royal TSX安装及使用)

一、Royal TSX软件下载地址 Royal Apps 二、Royal TSX 汉化 汉化包地址:GitCode - 全球开发者的开源社区,开源代码托管平台 三、基础配置 Royal TSX 是一款基于插件的应用,刚安装时还不具备使用条件,需要进行一些基础配置 1 安装基础插件…

JVM 基础、GC 算法与 JProfiler 监控工具详解

目录 1、引言 1.1 JVM内存与本地内存 1.2 JVM与JDK的关系 2、JVM基础 2.1 JVM(Java Virtual Machine) 2.2 Java与JVM的关系 2.3 JVM的内存结构 2.3.1 堆内存 2.3.2 栈内存 2.3.3 方法区 2.3.4 本地方法栈 2.3.5 程序计数器(PC寄存…

【深度学习】交叉熵

交叉熵(Cross-Entropy)是信息论中的一个重要概念,也是在机器学习和深度学习中用于分类任务的常见损失函数。它衡量的是两个概率分布之间的差异,特别是模型的预测概率分布与真实分布的差异。 交叉熵最初是从信息论引入的&#xff0…

Nginx性能优化全攻略:打造高性能Web服务器

Nginx作为一款高性能的Web服务器和反向代理服务器,以其轻量级、高并发处理能力而闻名。然而,要充分发挥Nginx的潜力,需要进行全面而细致的优化。本文将深入探讨Nginx的性能优化策略,从基础配置到高级技巧,全方位提升您的Nginx服务器性能。 © ivwdcwso (ID: u012172506) 基…

Spring Cloud全解析:服务调用之OpenFeign集成OkHttp

文章目录 OpenFeign集成OkHttp添加依赖配置连接池yml配置 OpenFeign集成OkHttp OpenFeign本质是HTTP来进行服务调用的,也就是需要集成一个Http客户端。 使用的是Client接口来进行请求的 public interface Client {// request是封装的请求方式、参数、返回值类型/…

Linux编译部署PHP环境

1.准备工作 安装前我们需要设置防护墙,开放端口,更新yum源 # 1.防火墙 systemctl status firewalld 看到active(running)就意味着防火墙打开了 systemctl stop firewalld 看到inactive(dead)就意味着防火墙关闭了 systemctl start fire…

Java中的对象生命周期管理:从Spring Bean到JVM对象的深度解析

Java中的对象生命周期管理:从Spring Bean到JVM对象的深度解析 大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!今天我们来聊聊Java中的对象生命周期管理,尤其是从Spring Be…