文档章节

Redis应用学习——Redis Cluster客户端

江左煤郎
 江左煤郎
发布于 2018/11/09 23:50
字数 1871
阅读 33
收藏 1

1. moved重定向

    1. 客户端读写(get/set)操作执行过程:如果是一个普通的客户端连接到redis cluster中的任意一个节点,然后向该节点发送一条get/set命令,接收的节点首先会依据该key计算对应槽位,然后再找到槽位所在的节点,判断找到的节点是否是自身,如果是则在当前节点执行该命令,否则回复客户端moved异常,异常中包含真正执行命令的节点的信息,客户端需要使用获取到节点信息,重新连接获取到的节点并发送命令,但是该行为不是自动的,需要主动操作(如下图中第4步,该步骤需要在客户端通过专门编写逻辑代码执行);客户端依据返回的moved异常中的节点信息,进行的转移连接操作就是moved重定向

    2. moved异常演示:首先启动集群,然后以普通模式的客户端连接到任意一个节点上,进行set/get操作,linux中普通模式的客户端对应Java中的Jedis客户端

    2. 可自动进行moved重定向的客户端:

redis-cli  -h host  -p port  -c:linux系统中redis自带的客户端,该客户端可以自动进行moved重定向操作,主要在于-c命令参数,该参数表示以集群模式启动客户端并连接到到集群中的某个节点上,如下图所示,客户端会自动进行连接转移并执行命令

    3. ask重定向:类似于moved重定向,但该转移通常与集群伸缩有关,ask重定向发生在两个节点间进行槽位迁移时,当两个节点正在进行槽位转移时(转移未结束),如果此时客户端向源节点发送一条get/set命令,如果key对应的槽位还在源节点,但槽位中的key已经转移到新节点中,此时就会返回ask转向,然后客户端需要依据返回的ask中的信息执行一个asking命令,然后发送要执行的get/set命令,新节点会返回执行结果。

    4. moved和ask重定向带来的问题:以集群模式客户端(redis-cli  -h host  -p port  -c)连接任意一个节点后,进行大量的get/set命令,如果执行这些命令时发生了很多的moved和ask重定向,那么就会极大影响系统性能

2. smart客户端——JedisCluster

    1. smart客户端:该客户端就是为了改善集群模式客户端(redis-cli  -h host  -p port  -c)可能会因为频繁的moved和ask重定向而导致的性能浪费

    2. smart客户端JedisCluster简单原理介绍:

  • 从集群中选取一个可执行的节点,使用cluster slots命令获取到每个节点和其负责的槽位的关系映射,比如下图,JedisCluster也会通过类似方式,在JedisCluster创建并初始化时,会自动进行该步骤,并且将每个节点和其负责的槽位的关系映射保存在缓存中
  • 每个节点和其负责的槽位的关系映射后,为每一个节点创建一个对应的JedisPool,每当有命令传来时就从该连接池中获取一个Jedis对象,执行完命令后在将该Jedis对象还给JedisPool
  • 准备执行命令,JedisCluster中保存着节点和其负责的槽位的关系映射map,在执行命令时,通过key可以获取到其所在的槽位slot,然后依据map就可以获取到对应的节点,然后找到该节点的JedisPool获取一个Jedis对象,发送并执行命令

    2. 命令执行时的问题:如果说服务端手动进行了一些改动,比如节点迁移,而JedisCluster却未刷新缓存中的每个节点和其负责的槽位的关系映射,那么当再次执行命令时,就有可能出现连接错误,就会发生并返回ask或moved(一般都是moved)异常,此时JedisCluster客户端就会自动的刷新缓存中的节点和其负责的槽位的关系映射,然后重新发送命令执行,但命令发送次数有限制,多次失败之后就会抛出错误

3. JedisCluster的使用

    1. 基本使用:建议使用单例模式管理使用JedisCluster对象

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
public class TestJedisCluster {
	public static void main(String[] args) {
		//保存集群中每个节点中的IP地址和端口
		HashSet<HostAndPort> set=new HashSet<HostAndPort>();
		set.add(new HostAndPort("192.168.10.128", 6380));
		set.add(new HostAndPort("192.168.10.128", 6381));
		set.add(new HostAndPort("192.168.10.128", 6382));
		set.add(new HostAndPort("192.168.10.128", 6383));
		set.add(new HostAndPort("192.168.10.128", 6384));
		set.add(new HostAndPort("192.168.10.128", 6385));
		//创建JedisCluster对象,该对象的构造方法有多个重载版本
		JedisCluster cluster=new JedisCluster(set);
		//执行命令
		cluster.set("hello","world");
		//使用完后,如果确定不在使用该对象,则关闭JedisCluster
		try {
			cluster.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

    2. 多节点执行命令:有一个命令需要集群中的每一个节点都执行一遍,比如生成AOF文件,伪代码过程如下

		//获取到集群中的每一个节点的连接池对象
		Map<String, JedisPool> nodes=cluster.getClusterNodes();
		//遍历每一个节点的连接池对象,获取jedis客户端对象,执行命令
		for(Entry<String, JedisPool> set:nodes.entrySet()){
			JedisPool pool=set.getValue();
			Jedis j=pool.getResource();
			j.bgrewriteaof();//生成AOF文件
			j.close();
		}

    3. 批量执行命令:以类似mget或mset这类批量命令,mget或mset中所有的key值都必须在一个槽位中,执行这类命令有以下几种优化

(1)串行化执行:也就是遍历批量命令中操作的每一个key值,遍历执行这些命令即可,问题就是耗时长,因为每一个命令都要在网络中传输

(2)依据key值聚簇分类在串行执行:遍历批量命令中操作的key值,计算出每一个key值所在的槽位,然后依据槽位找到所在的节点,找到每个命令执行所在的节点后就可以对这些命令进行分组,同一个节点的命令分为一组,然后使用每个节点客户端的Pipeline对象一次性执行每个组中的所有命令(使用Jedis客户端中的流水线执行功能),串行执行执行每一个Pipeline对象,耗时比上面更少,取决于多个Pipeline对象执行时间之和

(3)并行化执行方法2:使用多线程,并行执行每个节点客户端的Pipeline对象,性能更好,耗时取决于执行时间最长的那个Pipeline对象

(4)hash_tag:可以在key值前添加一个{tag},tag即为一个标记值,用大括号括起来并写在key值前面可以保证批量命令只会在同一个节点中执行。该方法耗时最短,但也会引起数据倾斜

© 著作权归作者所有

共有 人打赏支持
江左煤郎
粉丝 26
博文 86
码字总数 220642
作品 0
西安
后端工程师
私信 提问
Redis应用学习——Redis Cluster部署

认识Redis Cluster 1. 集群所解决的问题: 提供极高的并发量,即使单个Redis的并发处理量已经很多,但是在大型应用系统中,仍然远远不足,集群提高了并发处理量 能存储更多的数据,单台Redis...

江左煤郎
2018/11/04
0
0
美团在Redis上踩过的一些坑-5.redis cluster遇到的一些问题

转载请注明出处哈:http://carlosfu.iteye.com/blog/2254154 由于演讲时间有限,有关Redis-Cluster,演讲者没做太多介绍,简单的介绍了一些Redis-Cluster概念作用和遇到的两个问题,我们在Red...

lirulei90
2018/01/05
0
0
Redis 5.0 RC1 发布,专注于提供新的重要特性

Redis 5.0 rc1 已发布,Redis 5 是一个专注于几个重要特性的发行版。不同于 Redis 4 非常专注于操作,Redis 5 的变化大多是面向用户的,在现有的基础上增加新的数据类型和操作类型。 以下是此...

淡漠悠然
2018/05/31
7.1K
18
2017 11-15 redis应用

一.redis介绍 (1)概念:属于非关系型存储数据库——基于kv(键值存储)的开源的内存存储,数据库结构存储。经常被用作数据库,消息队列和缓存。 下载可去官网www.redis.io 或是epel源进行下载 ...

楠人帮
2017/11/17
0
0
Java开发——Redis云管理平台 实现方案CacheCloud 扫盲

本文简述一个redis云平台解决方案,该方案是搜狐TV云平台管理的解决方案CacheCloud ,感兴趣的可以持续关注我的发布。 一、CacheCloud是做什么的 CacheCloud提供一个Redis云管理平台:实现多...

欧阳愠斐
2018/07/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

操作数据库表

/* DML:数据库操作语言 主要对表中的数据库进行 增删改 ****增:插入一条记录 insert into 表名 (列名1,列名2..) values (值1,值2..) 注意: 1.列名可以在表中选择一列或者几列 2.后面的值 必须...

stars永恒
11分钟前
0
0
你真的了解 volatile 关键字吗?

volatile关键字经常在并发编程中使用,其特性是保证可见性以及有序性,但是关于volatile的使用仍然要小心,这需要明白volatile关键字的特性及实现的原理,这也是本篇文章的主要内容。 一、J...

Henrykin
11分钟前
0
0
条码插件TBarCode Office系列教程二(Word Add-In篇)

TBarCode Office是一款适用于Microsoft Word 2007、2010和2013的条码插件,通过此插件可以轻松的在您的文档中嵌入代码。此系列教程旨在介绍TBarCode Office的常见问题及解答,帮助大家学习使...

ymy_666666
11分钟前
0
0
折腾Java设计模式之命令模式

博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the parameterization of clients with different requests, ......

大萌小路
12分钟前
1
0
微服务架构:基于微服务和Docker容器技术的PaaS云平台架构设计

基于微服务架构和Docker容器技术的PaaS云平台建设目标是给我们的开发人员提供一套服务快速开发、部署、运维管理、持续开发持续集成的流程。平台提供基础设施、中间件、数据服务、云服务器等资...

编程SHA
13分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部