阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Redis集群之Redis Cluster

268次阅读
没有评论

共计 6074 个字符,预计需要花费 16 分钟才能阅读完成。

1. Linux 系统配置

1.1. vm.overcommit_memory 设置

overcommit_memory 文件指定了内核针对内存分配的策略,其值可以是 0、1、2。

0,表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1,表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2,表示内核允许分配超过所有物理内存和交换空间总和的内存

jenkins_service@jenkinsservice:~/Redis-3.0.1$ sudo sysctl vm.overcommit_memory=1

vm.overcommit_memory = 1

1.2. Transparent Huge Pages 开启

THP(Transparent Huge Pages)是一个使管理 Huge Pages 自动化的抽象层。

目前需要注意的是,由于实现方式问题,THP 会造成内存锁影响性能,尤其是在程序不是专门为大内内存页开发的时候,简单介绍如下:

操作系统后台有一个叫做 khugepaged 的进程,它会一直扫描所有进程占用的内存,在可能的情况下会把 4kpage 交换为 Huge Pages,在这个过程中,对于操作的内存的各种分配活动都需要各种内存锁,直接影响程序的内存访问性能,并且,这个过程对于应用是透明的,在应用层面不可控制, 对于专门为 4k page 优化的程序来说,可能会造成随机的性能下降现象。

Redis Cluster 命令行

 // 集群(cluster) 

  1. CLUSTER INFO 打印集群的信息 
  2. CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。
  3.  
  4. // 节点(node) 
  5. CLUSTER MEET <ip> <port> 将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
  6. CLUSTER FORGET <node_id> 从集群中移除 node_id 指定的节点。
  7. CLUSTER REPLICATE <node_id> 将当前节点设置为 node_id 指定的节点的从节点。
  8. CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面。
  9.  
  10. // 槽(slot) 
  11. CLUSTER ADDSLOTS <slot> [slot …] 将一个或多个槽(slot)指派(assign)给当前节点。
  12. CLUSTER DELSLOTS <slot> [slot …] 移除一个或多个槽对当前节点的指派。
  13. CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
  14. CLUSTER SETSLOT <slot> NODE <node_id> 将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽 >,然后再进行指派。
  15. CLUSTER SETSLOT <slot> MIGRATING <node_id> 将本节点的槽 slot 迁移到 node_id 指定的节点中。
  16. CLUSTER SETSLOT <slot> IMPORTING <node_id> 从 node_id 指定的节点中导入槽 slot 到本节点。
  17. CLUSTER SETSLOT <slot> STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。
  18.  
  19. // 键 (key) 
  20. CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。
  21. CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量。
  22. CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键。

 

2. 配置文件

开启 cluster 的 redis 必须是空服务器

修改 redis.conf 开启 cluster

 Redis 集群之 Redis Cluster

设置 3 个 cluster

10.24.6.7:6379

10.24.6.4:6379

10.24.6.6:6379

3. 查看初始 redis 集群状态

启动三个节点上的 Redis 服务器。此时,三个 Redis 服务器节点均会以 Redis Cluster 的方式开始运行,但并没有自动构建集群,因为三者还处于“我不认识你,你不属于我”的状态,它们每个都是孤零零的 Redis 节点,或者是只包含了一个节点的集群。我们可以通过 Redis 客户端连接到服务器查看它们的状态,图一给出了状态查询方法和查询结果,其中 cluster nodes 命令用于查看当前 Redis 节点所属的 Redis 集群中的所有节点,而 cluster info 则用于查看当前 Redis 节点所属的 Redis 集群的整体状态。由图中我们可以看到,Redis 集群中仅包含一个 Redis 节点,也就是当前节点,整个集群的状态是 fail。

 Redis 集群之 Redis Cluster

4. 分配 hash slot

通过上面的操作,我们已经将三个各自为政的 Redis 节点规划到一个相同的集群中,那么我们现在是否就已经完成了集群搭建的所有工作了呢?非也!通过图二中对集群状态的查看我们可以知道,当前集群的状态还是 fail,此时的 Redis 集群是不工作的,无法处理任何 Redis 命令。那么集群的状态为什么还是 fail 呢?本博主通过查看官方文档说明找到了原因所在,现摘录原文如下:

The FAIL state for the cluster happens in two cases.

1) If at least one hash slot is not served as the node serving it currently is in FAIL state.

2) If we are not able to reach the majority of masters (that is, if the majorify of masters are simply in PFAIL state, it is enough for the node to enter FAIL mode).

很明显,导致我们的集群处于 fail 状态的原因不是第二个条,也就是说至少有一个 hash slot 没有被服务!稍微考虑一下,可不是!何止有一个 hash slot 没有被服务,压根儿就没有 Redis 节点为任何 hash slot 服务!众所周知,Redis Cluster 通过 hash slot 将数据根据主键来分区,所以一条 key-value 数据会根据算法自动映射到一个 hash slot,但是一个 hash slot 存储在哪个 Redis 节点上并不是自动映射的,是需要集群管理者自行分配的。那么我们需要为多少个 hash slot 分配 Redis 节点呢?根据源码可知是 16384 个,即我们要将 16384 个 hash slot 分配到集群内的三个节点上。Redis 中用于分配 hash slot 的命令有很多,其中包括 cluster addslots、cluster delslots 和 cluster setslot。鉴于我们现在是集群的初始化阶段,所以我们可以选择 cluster addslots 来分配 hash slot,该命令的语法为 cluster addslots slot1 [slot2] … [slotN]。

4.1. nodes-6379.conf 分配

每个 redis 客户端单独分配自己负责的部分

修改内容如下:cda76a0a094d2ce624e33bed7f3c75689a4128fd :0 myself,master – 0 0 connected 0-5000(注意是在自身节点的描述,也就是包含了 myself 那一行的后面追加 hash slot 的范围)。类似的,Redis Cluster Node2 上 nodes-6379.conf 文件中追加5001-10000,Redis Cluster Node3 上 nodes-6379.conf 文件中追加10001-16383。经过这样的配置后,Redis Cluster Node1 负责存储 0 至 5000 之间的所有 hash slots,Redis Cluster Node2 负责存储 5001 至 10000 之间的所有 hash slots,Redis Cluster Node3 负责存储 10001 至 16383 的所有 hash slots。

 Redis 集群之 Redis Cluster

4.2. Redis cluster 命令分配

 Redis 集群之 Redis Cluster

5. 搭建 Redis 集群

这里所谓的搭建集群,说白了就是让之前启动的三个 Redis 节点彼此连通,意识到彼此的存在,那么如何做到这一点呢?答案就是 cluster meet 命令。该命令的作用就是将当前节点主动介绍给另外一个节点认识,图二给出了 cluster meet 命令的执行方法和执行效果,由图中可知我们使用 cluster meet 命令分别将 Redis Cluster Node1 介绍给了 Redis Cluster Node2(节点 IP 地址为 192.168.32.3,运行端口为 6379)和 Redis Cluster Node3(节点 IP 地址为 192.168.32.4,运行端口为 6379),之后我们再次查看集群节点和集群状态就可以知道,三个节点已经成功合并到了同一个集群中。

 Redis 集群之 Redis Cluster

这里找到了 3 个节点

查看 10.24.6.6 客户端

 Redis 集群之 Redis Cluster

至此,3 个结点

 Redis 集群之 Redis Cluster

搭建完成标识:

 Redis 集群之 Redis Cluster

在集群状态显示为 ok 之后,我们就可以像在 Redis 单机版上一样执行 Redis 命令了。

 

6. 测试

6.1. 非集群模式

6.1.1.  Redis-cli

 Redis 集群之 Redis Cluster

Redis 集群之 Redis Cluster

非集群模式客户端在 cluster 跳转时会提示 MOVED 错误

6.1.2.  Redis 客户端库

from redis.sentinel import Sentinel
sentinel = Sentinel([(
‘10.24.6.7’, 26379)], socket_timeout=0.1)
master = sentinel.master_for(
‘10.24.6.5master’, socket_timeout=0.1)
print master
master.set(
‘aaaaaaaaaaaaaaa’, ‘bar’)
master.set(
‘bbbbbbbbbbbbbbbb’, ‘bar’)
print master.get(‘aaaaaaaaaaaaaaa’)
print master.get(‘bbbbbbbbbbbbbbbb’)

Traceback (most recent call last):

  File “E:/HomeInternet/server/utest_workspace/utest_utils/utest_unit/__init__.py”, line 23, in <module>

    master.set(‘bbbbbbbbbbbbbbbb’, ‘bar’)

  File “build\bdist.win32\egg\redis\client.py”, line 1055, in set

  File “build\bdist.win32\egg\redis\client.py”, line 565, in execute_command

  File “build\bdist.win32\egg\redis\client.py”, line 577, in parse_response

  File “build\bdist.win32\egg\redis\sentinel.py”, line 55, in read_response

  File “build\bdist.win32\egg\redis\connection.py”, line 574, in read_response

redis.exceptions.ResponseError: MOVED 9577 10.24.6.6:6379

6.2. 集群模式(-C)

6.2.1.  Redis-cli

 Redis 集群之 Redis Cluster

集群模式客户端在跳转时会自动进行结点转向

6.2.2. Redis Cluster

https://github.com/Grokzen/redis-py-cluster

 

from rediscluster import StrictRedisCluster
startup_nodes = [{
“host”: “10.24.6.7”, “port”: “6379”}]
rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)
print rc.set(“bbbbbbbbbbbbbbbb”, “bar”)
True
print rc.get(“bbbbbbbbbbbbbbbb”)

 Redis 集群之 Redis Cluster

6.2.3. Redis Sentinel + Cluster

from redis.sentinel import Sentinel
from redisclusterimport StrictRedisCluster
sentinel = Sentinel([(
‘10.24.6.7’, 26379)], socket_timeout=0.1)
ip, port = sentinel.discover_master(
‘10.24.6.5master’)
rc = StrictRedisCluster(host=ip, port=port, decode_responses=True)
print rc.set(“bbbbbbbbbbbbbbbb”, “bar”)
print rc.get(“bbbbbbbbbbbbbbbb”)

Redis 集群之 Redis Cluster

下面关于 Redis 的文章您也可能喜欢,不妨参考下:

Ubuntu 14.04 下 Redis 安装及简单测试 http://www.linuxidc.com/Linux/2014-05/101544.htm

Redis 主从复制基本配置 http://www.linuxidc.com/Linux/2015-03/115610.htm

Redis 集群明细文档 http://www.linuxidc.com/Linux/2013-09/90118.htm

Ubuntu 12.10 下安装 Redis(图文详解)+ Jedis 连接 Redis http://www.linuxidc.com/Linux/2013-06/85816.htm

Redis 系列 - 安装部署维护篇 http://www.linuxidc.com/Linux/2012-12/75627.htm

CentOS 6.3 安装 Redis http://www.linuxidc.com/Linux/2012-12/75314.htm

Redis 安装部署学习笔记 http://www.linuxidc.com/Linux/2014-07/104306.htm

Redis 配置文件 redis.conf 详解 http://www.linuxidc.com/Linux/2013-11/92524.htm

Redis 的详细介绍:请点这里
Redis 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-04/130155.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计6074字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中