文档章节

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

江左煤郎
 江左煤郎
发布于 11/09 23:50
字数 1871
阅读 10
收藏 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值前面可以保证批量命令只会在同一个节点中执行。该方法耗时最短,但也会引起数据倾斜

© 著作权归作者所有

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

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

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

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

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

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

淡漠悠然
05/31
0
16
Java开发——Redis云管理平台 实现方案CacheCloud 扫盲

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

欧阳愠斐
07/25
0
0
2017 11-15 redis应用

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

楠人帮
2017/11/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java 动态代理的实现

在Java中可以实现动态代理的方式有很多种:JDK方式、ASM字节码操控框架、开源的分析、编辑和创建Java字节码的类库Javassist、基于ASM框架实现的CGLIB JDK方式:通过Java反射的方式生成动态代...

我爱春天的毛毛雨
6分钟前
1
0
css 总结2

1、背景有关 (1)background-origin:border-box、padding-box、content-box //默认是padding-box(2)background-image: url(img_flwr.gif), url(paper.gif);(3)background-posi......

tianyawhl
7分钟前
1
0
java 每秒钟只允许十个线程同时并发

package com.qimh.thread.concurrent;import java.util.Date;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurren......

qimh
22分钟前
3
0
学习Hadoop大数据基础框架

什么是大数据?进入本世纪以来,尤其是2010年之后,随着互联网特别是移动互联网的发展,数据的增长呈爆炸趋势,已经很难估计全世界的电子设备中存储的数据到底有多少,描述数据系统的数据量的...

本宫没空2
24分钟前
2
0
redis

1,安装 sudo apt-get install redis-server 2,登录本地的 redis-cli 3,修改 .bashrc文件,连接其他线下数据库 vi .bashrc在最后增加alias redisa="redis-cli -h 10.15.100.134 -p 666...

鹏灬
29分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部