百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Redis集群.note

bigegpt 2024-08-12 14:29 3 浏览

Redis集群

1、Redis集群方案比较

  • 哨兵模式

在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态,如果master节点异常,则会做主从切换,将某一台slave作为master,哨兵的配置略微复杂,并且性能和高可用性等各方面表现一般,特别是在主从切换的瞬间存在访问瞬断的情况,而且哨兵模式只有一个主节点对外提供服务,没法支持很高的并发,且单个主节点内存也·不宜设置得过大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率。

无法满足的需求?: 大并发,高可用,大内存

  • 高可用集群模式

redis集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。Redis集群不需要sentinel哨兵也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展,据官方文档称可以线性扩展到上万个节点(官方推荐不超过1000个节点)。redis集群的性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单

高并发:通过横向拓展实现,通过 --cluster add-node 添加新机器到集群 执行 reshard 命令,重新分配slot ,将相对均摊了 slot 的分布,缓冲了 其他机器的并发压力,从而应对 百万,甚至上千万的并发。

复制:每个小集群都是一个主从复制的架构,从而保证了 主节点挂掉的时候,不至于丢失全部数据,当选举产生新的master节点后,继续对外进行服务,在主备切换过程中,部分key会有影响,但是其他分片上的key不会有任何影响,从而保证了高可用的场景。

分片:每个不同的主从架构小集群,数据是不一致的,客户端通过哈希函数,将数据路由到不同的数据节点,从而实现了数据的分片。这样技术内存不够用的时候,只需要添加新的集群节点进来,重新分配一下slot 就可以了。

c 语言版获取 slot

def HASH_SLOT(key)
 s = key.index "{"
 if s
 e = key.index "}",s+1
 if e && e != s+1
 key = key[s+1..e-1]
 end
 end
 crc16(key) % 16384
end

java 版获取 slot

public static int getSlot(byte[] key) {
 int s = -1;
 int e = -1;
 boolean sFound = false;
 for (int i = 0; i < key.length; i++) {
 if (key[i] == '{' && !sFound) {
 s = i;
 sFound = true;
 }
 if (key[i] == '}' && sFound) {
 e = i;
 break;
 }
 }
 if (s > -1 && e > -1 && e != s + 1) {
 return getCRC16(key, s + 1, e) & (16384 - 1);
 }
 return getCRC16(key) & (16384 - 1);
}

2、Redis高可用集群搭建

  • redis安装

下载地址:http://redis.io/download

安装步骤:

# 安装gcc

yum install gcc

# 把下载好的redis-5.0.2.tar.gz放在/usr/local文件夹下,并解压

wget http://download.redis.io/releases/redis-5.0.2.tar.gz

tar xzf redis-5.0.2.tar.gz

cd redis-5.0.2

# 进入到解压好的redis-5.0.2目录下,进行编译与安装

make & make install

# 启动并指定配置文件

src/redis-server redis.conf(注意要使用后台启动,所以修改redis.conf里的daemonize改为yes)

# 验证启动是否成功

ps -ef | grep redis

# 进入redis客户端

/usr/local/redis/bin/redis-cli

# 退出客户端

quit

# 退出redis服务:

(1)pkill redis-server

(2)kill 进程号

(3)src/redis-cli shutdown

  • redis集群搭建

redis集群需要至少要三个master节点,我们这里搭建三个master节点,并且给每个master再搭建一个slave节点,总共6个redis节点,这里用一台机器部署6个redis实例,一共三组一主一从集群,搭建集群的步骤如下:

第一步:在机器的/usr/local下创建文件夹redis-cluster,然后在其下面分别创建1个文件夾如下

(1)mkdir -p /usr/local/redis-cluster

(2)mkdir 8001

第一步:把之前的redis.conf配置文件copy到8001下,修改如下内容:

(1)daemonize yes

(2)port 8001(分别对每个机器的端口号进行设置)

(3)dir /usr/local/redis-cluster/8001/(指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据)

(4)cluster-enabled yes(启动集群模式)

(5)cluster-config-file nodes-8001.conf(集群节点信息文件,这里800x最好和port对应上,注意这里不是用户可编辑的文件,而是Redis群集节点每次发生更改时自动保留群集配置)

(6)cluster-node-timeout 5000

(7) # bind 127.0.0.1(去掉bind绑定访问ip信息)

(8) protected-mode no (关闭保护模式)

(9)appendonly yes

如果要设置密码需要增加如下配置:

(10)requirepass 111111 (设置redis访问密码)

(11)masterauth 111111 (设置集群节点间访问密码,跟上面一致)

第三步:copy 配置好的文件夹 8001 到8002,8003,8004,8005,8006 ,

第四步:修改复制后的配置文件 redis.conf 第2、3、5项里的端口号,可以用批量替换:

:%s/源字符串/目的字符串/g

第五步:分别启动6个redis实例,然后检查是否启动成功

(1)/usr/local/redis-5.0.2/src/redis-server /usr/local/redis-cluster/800*/redis.conf

(2)ps -ef | grep redis 查看是否启动成功

第六步:用redis-cli创建整个redis集群(redis5以前的版本集群是依靠ruby脚本redis-trib.rb实现)

(1)/usr/local/redis-5.0.2/src/redis-cli -a 111111 --cluster create --cluster-replicas 1 192.168.6.132:8001 192.168.6.132:8002 192.168.6.132:8003 192.168.6.132:8004 192.168.6.132:8005 192.168.6.132:8006

代表为每个创建的主服务器节点创建一个从服务器节点(

--replicas 1 1其实代表的是副本个数)

第七步:验证集群:

(1)连接任意一个客户端即可:./redis-cli -c -h -p (-a访问服务端密码,-c表示集群模式,指定ip地址和端口号)如:/usr/local/redis-5.0.2/src/redis-cli -a 111111 -c -h 192.168.6.132 -p 8001

(2)进行验证: cluster info(查看集群信息)、cluster nodes(查看节点列表)

(3)进行数据操作验证

(4)关闭集群则需要逐个进行关闭,使用命令:

/usr/local/redis/bin/redis-cli -a 111111 -c -h 192.168.6.132 -p 800* shutdown

3、Java操作redis集群

借助redis的java客户端jedis可以操作以上集群,引用jedis版本的maven坐标如下:

<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

<version>2.9.0</version>

</dependency>

Java编写访问redis集群的代码非常简单,如下所示:

import java.io.IOException;

import java.util.HashSet;

import java.util.Set;

import redis.clients.jedis.HostAndPort;

import redis.clients.jedis.JedisCluster;

import redis.clients.jedis.JedisPoolConfig;

/**

* 访问redis集群

* @author 图灵-郭嘉老师 (QQ 2790284115)

*

*/

public class RedisCluster

{

public static void main(String[] args) throws IOException

{

Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();

jedisClusterNode.add(new HostAndPort("192.168.0.61", 8001));

jedisClusterNode.add(new HostAndPort("192.168.0.62", 8002));

jedisClusterNode.add(new HostAndPort("192.168.0.63", 8003));

jedisClusterNode.add(new HostAndPort("192.168.0.61", 8004));

jedisClusterNode.add(new HostAndPort("192.168.0.62", 8005));

jedisClusterNode.add(new HostAndPort("192.168.0.63", 8006));

JedisPoolConfig config = new JedisPoolConfig();

config.setMaxTotal(100);

config.setMaxIdle(10);

config.setTestOnBorrow(true);

//connectionTimeout:指的是连接一个url的连接等待时间

//soTimeout:指的是连接上一个url,获取response的返回等待时间

JedisCluster jedisCluster = new JedisCluster(jedisClusterNode, 6000, 5000, 10, "zhuge", config);

System.out.println(jedisCluster.set("student", "zhuge"));

System.out.println(jedisCluster.set("age", "18"));

System.out.println(jedisCluster.get("student"));

System.out.println(jedisCluster.get("age"));

jedisCluster.close();

}

}

运行效果如下:

OK

OK

zhuge

18

3、Redis集群原理分析

Redis Cluster 将所有数据划分为 16384 的 slots(槽位),每个节点负责其中一部分槽位。槽位的信息存储于每个节点中。

当 Redis Cluster 的客户端来连接集群时,它也会得到一份集群的槽位配置信息并将其缓存在客户端本地。这样当客户端要查找某个 key 时,可以直接定位到目标节点。同时因为槽位的信息可能会存在客户端与服务器不一致的情况,还需要纠正机制来实现槽位信息的校验调整。

槽位定位算法

Cluster 默认会对 key 值使用 crc16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。

HASH_SLOT = CRC16(key) mod 16384

Cluster 还允许用户强制某个 key 挂在特定槽位上,通过在 key 字符串里面嵌入 tag 标 记,这就可以强制 key 所挂在的槽位等于 tag 所在的槽位。

如; set {aaa}b s1

将只对 aaa 进行 crc16 的运算。这一点可以在源代码中得到证实。

跳转重定位

当客户端向一个错误的节点发出了指令,该节点会发现指令的 key 所在的槽位并不归自己管理,这时它会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据。客户端收到指令后除了跳转到正确的节点上去操作,还会同步更新纠正本地的槽位映射表缓存,后续所有 key 将使用新的槽位映射表。

网络抖动

真实世界的机房网络往往并不是风平浪静的,它们经常会发生各种各样的小问题。比如网络抖动就是非常常见的一种现象,突然之间部分连接变得不可访问,然后很快又恢复正常。

为解决这种问题,Redis Cluster 提供了一种选项cluster-node-timeout,表示当某个节点持续 timeout 的时间失联时,才可以认定该节点出现故障,需要进行主从切换。如果没有这个选项,网络抖动会导致主从频繁切换 (数据的重新复制)。

相关推荐

了解Linux目录,那你就了解了一半的Linux系统

大到公司或者社群再小到个人要利用Linux来开发产品的人实在是多如牛毛,每个人都用自己的标准来配置文件或者设置目录,那么未来的Linux则就是一团乱麻,也对管理造成许多麻烦。后来,就有所谓的FHS(F...

Linux命令,这些操作要注意!(linux命令?)

刚玩Linux的人总觉得自己在演黑客电影,直到手滑输错命令把公司服务器删库,这才发现命令行根本不是随便乱用的,而是“生死簿”。今天直接上干货,告诉你哪些命令用好了封神!喜欢的一键三连,谢谢观众老爷!!...

Linux 命令速查手册:这 30 个高频指令,拯救 90% 的运维小白!

在Linux系统的世界里,命令行是强大的武器。对于运维小白而言,掌握一些高频使用的Linux命令,能极大提升工作效率,轻松应对各种系统管理任务。今天,就为大家奉上精心整理的30个Linu...

linux必学的60个命令(linux必学的20个命令)

以下是Linux必学的20个基础命令:1.cd:切换目录2.ls:列出文件和目录3.mkdir:创建目录4.rm:删除文件或目录5.cp:复制文件或目录6.mv:移动/重命名文件或目录7....

提高工作效率的--Linux常用命令,能够决解95%以上的问题

点击上方关注,第一时间接受干货转发,点赞,收藏,不如一次关注评论区第一条注意查看回复:Linux命令获取linux常用命令大全pdf+Linux命令行大全pdf为什么要学习Linux命令?1、因为Li...

15 个实用 Linux 命令(linux命令用法及举例)

Linux命令行是系统管理员、开发者和技术爱好者的强大工具。掌握实用命令不仅能提高效率,还能解锁Linux系统的无限潜力,本文将深入介绍15个实用Linux命令。ls-列出目录内容l...

Linux 常用命令集合(linux常用命令全集)

系统信息arch显示机器的处理器架构(1)uname-m显示机器的处理器架构(2)uname-r显示正在使用的内核版本dmidecode-q显示硬件系统部件-(SMBIOS/DM...

Linux的常用命令就是记不住,怎么办?

1.帮助命令1.1help命令#语法格式:命令--help#作用:查看某个命令的帮助信息#示例:#ls--help查看ls命令的帮助信息#netst...

Linux常用文件操作命令(linux常用文件操作命令有哪些)

ls命令在Linux维护工作中,经常使用ls这个命令,这是最基本的命令,来写几条常用的ls命令。先来查看一下使用的ls版本#ls--versionls(GNUcoreutils)8.4...

Linux 常用命令(linux常用命令)

日志排查类操作命令查看日志cat/var/log/messages、tail-fxxx.log搜索关键词grep"error"xxx.log多条件过滤`grep-E&#...

简单粗暴收藏版:Linux常用命令大汇总

号主:老杨丨11年资深网络工程师,更多网工提升干货,请关注公众号:网络工程师俱乐部下午好,我的网工朋友在Linux系统中,命令行界面(CLI)是管理员和开发人员最常用的工具之一。通过命令行,用户可...

「Linux」linux常用基本命令(linux常用基本命令和用法)

Linux中许多常用命令是必须掌握的,这里将我学linux入门时学的一些常用的基本命令分享给大家一下,希望可以帮助你们。总结送免费学习资料(包含视频、技术学习路线图谱、文档等)1、显示日期的指令:d...

Linux的常用命令就是记不住,怎么办?于是推出了这套教程

1.帮助命令1.1help命令#语法格式:命令--help#作用:查看某个命令的帮助信息#示例:#ls--help查看ls命令的帮助信息#netst...

Linux的30个常用命令汇总,运维大神必掌握技能!

以下是Linux系统中最常用的30个命令,精简版覆盖日常操作核心需求,适合快速掌握:一、文件/目录操作1.`ls`-列出目录内容`ls-l`(详细信息)|`ls-a`(显示隐藏文件)...

Linux/Unix 系统中非常常用的命令

Linux/Unix系统中非常常用的命令,它们是进行文件操作、文本处理、权限管理等任务的基础。下面是对这些命令的简要说明:**文件操作类:*****`ls`(list):**列出目录内容,显...