`
tangzhibin
  • 浏览: 20854 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

redis之初探

阅读更多

 

    之前nosql群里的哥们对redis讨论的挺热闹,今天我也着手试了吧,主要测试2个方面(只是简单测试了下,主要针对jedis java客户端,jedis已实现了consistent hash算法)

 

1:在多节点下,数据的分布均匀情况如何
2:在多节点下,删除可增加节点后,对原有数据的映射关系,及命中情况如何

 

本机上启动3个节点(637963806381

第一:测试数据分布测试情况:

3个节点下,插入10000条数据情况,数据分布还是挺理想的

 

节点 数据量 分布率

6379 node

3365

33.65%

6380 node

3243

32.43%

6381 node

3392

33.92%

 

 

第二:测试增删节点后,对原有数据的影响

 

 

a:首先本机的3个节点(6379、6380、6381),插入10条数据(数据少,分布的还是不均匀的),数据的分布情况为:

 

key:0 put in :127.0.0.1:6380
key:1 put in :127.0.0.1:6380
key:2 put in :127.0.0.1:6381
key:3 put in :127.0.0.1:6381
key:4 put in :127.0.0.1:6380
key:5 put in :127.0.0.1:6381
key:6 put in :127.0.0.1:6379
key:7 put in :127.0.0.1:6380
key:8 put in :127.0.0.1:6381
key:9 put in :127.0.0.1:6379

 

 

b:再把6381节点服务停掉,代码里面不修改节点配置,发现该正确hitkey还是能正确hit到自己的节点(此时后台会抛连接redis异常)

 

key:0 from :127.0.0.1:6380->0
key:1 from :127.0.0.1:6380->1
key:2 from :127.0.0.1:6381->null
key:3 from :127.0.0.1:6381->null
key:4 from :127.0.0.1:6380->4
key:5 from :127.0.0.1:6381->null
key:6 from :127.0.0.1:6379->6
key:7 from :127.0.0.1:6380->7
key:8 from :127.0.0.1:6381->null
key:9 from :127.0.0.1:6379->9

 

 

c:再启动6381这个节点服务,代码里面的配置remove6381,然后重新get所有的key,可以看到该正确hitkey也还是能正确hit到自己的节点

 

 

key:0 from :127.0.0.1:6380->0
key:1 from :127.0.0.1:6380->1
key:2 from :127.0.0.1:6380->null
key:3 from :127.0.0.1:6380->null
key:4 from :127.0.0.1:6380->4
key:5 from :127.0.0.1:6380->null
key:6 from :127.0.0.1:6379->6
key:7 from :127.0.0.1:6380->7
key:8 from :127.0.0.1:6380->null
key:9 from :127.0.0.1:6379->9

 

 

 

其实以上测试已经说明了,jedis客服端在移除或者添加一个cache节点,不影响原有数据的映射关系,这也是一致性hash算法的原理。就这么测这么点,自己玩玩而已,至于性能如何,官方说的挺不错的,大家可以自己去看看...整一个新的分布式缓存我觉得这些必要的测试还是需要的,下面把测试代码发出来,写的很简单,就2个类:

 

 

import java.util.ArrayList;
import java.util.List;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.util.Hashing;
import redis.clients.util.Sharded;

/**
 * 
 * @Title: RedisResourcePool.java 
 * @Copyright: Copyright (c) 2005
 * @Description: <br> <br>
 * @Company: hd
 * @Created on May 4, 2012 3:05:44 PM
 * @author <a href="mailTo:tangzhibin@*.com">tangzhibin</a>
 */
public class RedisResourcePool {
	
	/**ShardedJedisPool底层实现了commons.pool中的GenericObjectPool对象池,it's thread-safety*/
	private ShardedJedisPool shareRedisPool;
	
	void initRedisPool(){
		JedisPoolConfig configs=new JedisPoolConfig();
		/**对象池中最大活动的对象个数*/
		configs.setMaxActive(200);
		/**对象的最大空闲时间*/
		configs.setMaxIdle(60*1000);
		/**客户端获取对象时,如果池中没有空闲的对象(已达MaxActive),则会等待MaxWait时间,在此时间内,如果还没有空闲的对象返回,则抛出异常*/
		configs.setMaxWait(5*1000);
		
		/**设置host port等配置*/
		String []hostPorts={"127.0.0.1:6379","127.0.0.1:6380","127.0.0.1:6381"};
		//String []hostPorts={"127.0.0.1:6379","127.0.0.1:6380"};
		List<JedisShardInfo> jdsInfoList =new ArrayList<JedisShardInfo>(hostPorts.length);
		for(int i=0;i<hostPorts.length;i++){
			String hostPort=hostPorts[i];
			String[] host_port=hostPort.split(":");
			String host=host_port[0];
			/**注意port一定要转为int类型(不能为String),否则JedisShardInfod初始化时, 会将该String作为节点name名称,而把默认的6379作为端口号*/
			int port=Integer.parseInt(host_port[1]);
			JedisShardInfo jedisShardInfo=new JedisShardInfo(host,port);
			jdsInfoList.add(jedisShardInfo);
		}
		/**初始化redis池*/
		this.shareRedisPool = new ShardedJedisPool(configs, jdsInfoList,
				Hashing.MURMUR_HASH, Sharded.DEFAULT_KEY_TAG_PATTERN);
	}
	
	private RedisResourcePool(){
		initRedisPool();
	}
	
    static class RedisResourcePoolIniter{
		
		private static final RedisResourcePool redisResourcePool=new RedisResourcePool();
		
		private static RedisResourcePool getRedisResourcePool(){
			return redisResourcePool;
		}
	}
	
	public ShardedJedis getRedisCacheResource(){
		return shareRedisPool.getResource();
	}
	
	public void restoreRedisCacheResource(ShardedJedis resource){
		if(shareRedisPool!=null && resource!=null){
			shareRedisPool.returnResource(resource);
		}
	}
	
	public static RedisResourcePool getRedisResourcePool(){
		return RedisResourcePoolIniter.getRedisResourcePool();
	}
}

 

 

测试的main函数在此类中

import redis.clients.jedis.Client;
import redis.clients.jedis.ShardedJedis;
/**
 * 
 * @Title: RedisManager.java 
 * @Copyright: Copyright (c) 2005
 * @Description: <br> <br>
 * @Company: hd
 * @Created on May 4, 2012 3:05:44 PM
 * @author <a href="mailTo:tangzhibin">tangzhibin</a>
 */
public class RedisManager {
	
	private RedisResourcePool redisResourcePool=RedisResourcePool.getRedisResourcePool();

	private RedisManager(){}
	
	private static class RedisManagerIniter{
		
		private static final RedisManager redisManager=new RedisManager();
		
		private static RedisManager getRedisManager(){
			return redisManager;
		}
	}
	
	public static RedisManager getRedisManager(){
		return RedisManagerIniter.getRedisManager();
	}
	

	public String set(String key,String value){
		ShardedJedis resource=null;
		try{
			resource=redisResourcePool.getRedisCacheResource();
			Client cli=resource.getShard(key).getClient();
			return resource.set(key, value);
		}finally{
			redisResourcePool.restoreRedisCacheResource(resource);
		}
	}
	
	public Object get(String key){
		ShardedJedis resource=null;
		try{
			resource=redisResourcePool.getRedisCacheResource();
			Client cli=resource.getShard(key).getClient();
			System.out.println("key:"+key+" from :"+cli.getHost()+":"+cli.getPort());
			return resource.get(key);
		}catch(Exception ex){
			ex.printStackTrace();
			return null;
		}finally{
			redisResourcePool.restoreRedisCacheResource(resource);
		}
	}
	
   

	public static void main(String[] args){
		
		RedisManager rm=RedisManager.getRedisManager();
		//set
		for(int i=0;i<10000;i++){
			rm.set(String.valueOf(i),String.valueOf(i));
		}
		
//		//get
//		for(int i=0;i<10;i++){
//			System.out.println(rm.get(String.valueOf(i)));
//		}
//		
		
	}
}

 

分享到:
评论

相关推荐

    redis视频下载地址(百度云)

    Redis_初探_1.mp4 Redis_初探_2.mp4 Redis_初探_3.mp4 Redis_安装_字符串键_1.mp4 Redis_安装_字符串键_2.mp4 Redis_安装_字符串键_3.mp4 Redis_字符串键_BitMap操作_1.mp4 Redis_字符串键_BitMap操作_2.mp4 Redis_...

    redis视频教程百度网盘下载地址及密码

    2016122201_Redis_初探_1.mp4 2016122201_Redis_初探_2.mp4 2016122201_Redis_初探_3.mp4 2016122202_Redis_安装_字符串键_1.mp4 2016122202_Redis_安装_字符串键_2.mp4 2016122202_Redis_安装_字符串键_3.mp4 ...

    redis源码日志

    - **第1章:初探redis** - **位置**: Redis在缓存系统中的定位。 - **作用**: 解释Redis如何与其他系统交互以及其核心功能。 - **第2章:redis事件驱动详解** - **概述**: Redis采用事件驱动模型来处理网络请求...

    Redis V3.0 中文文档

    第 2 章数据类型初探. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 字符串 (Strings) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ...

    Redis 3.0 中文版 - v1.1.pdf

    第 2 章数据类型初探. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 字符串 (Strings) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ....

    .NET下第一次接触Redis数据库

    .NET下的Redis数据库初探 Redis,全称Remote Dictionary Server,是一种高性能的键值对NoSQL数据库,被广泛应用于大型网站的数据存储。与传统的关系型数据库相比,Redis以其高速的读写速度、支持数据自动过期处理和...

    SpringCache缓存初探共5页.pdf.zip

    在这个“SpringCache缓存初探共5页.pdf.zip”压缩包中,很可能是对SpringCache的基础知识进行了简要介绍。虽然文件名暗示内容可能只有5页,但我们可以深入探讨SpringCache的一些核心概念和技术细节。 首先,Spring...

    helm部署应用到k8s集群(helm+k8s)-详细文档

    helm 部署应用到 k8s 集群详细文档 本文档详细介绍了使用 Helm 部署应用到 Kubernetes 集群的过程。Helm 是一个 Kubernetes 的包管理工具,能够方便地将之前打包好的 YAML 文件部署到 Kubernetes 上。...

    CMS模块化开发和演讲稿-大型、高负载网站架构和应用初探(ppt)

    【CMS模块化开发与大型、高负载网站架构和应用初探】 在当今互联网时代,大型、高负载的网站已经成为企业及组织在线业务的核心。CMS(Content Management System,内容管理系统)的模块化开发是构建此类网站的关键...

    Go语言实现的一个简单的秒杀系统.zip

    Java版简易秒杀系统GitHub地址初探开发编程秒杀系统个人网站简介博客CSDN一、原始网页1. 开发环境戈兰Golang1.16.3Go 模块杜松子酒sqlxMySQL5.6+Redis 5.0.32. 部署环境1)除MySQL、Redis外,所有的网页、中间件等都...

    springboot项目整合.zip

    第十二篇:初探RabbitMQ消息队列] 第十三篇:RabbitMQ延迟队列] 第十四篇:强大的 actuator 服务监控与管理] 第十五篇:actuator与spring-boot-admin 第十六篇:定时任务详解] 第十七篇:轻松搞定文件...

    EmptySpringBootProject.zip

    《构建基于MySQL与Redis的SpringBoot应用初探》 在当今的Java开发领域,SpringBoot以其简洁、高效和快速启动的特点,已经成为企业级应用开发的首选框架。本项目"EmptySpringBootProject.zip"是一个基础的Maven项目...

    基于5G与大数据技术的物联网智慧工地平台初探.pdf

    通过使用Memcache、Redis等缓存数据库,可以将热点数据和不常改变的数据存储于内存中,直接部署在Web前端与微服务之间。这样,能够快速读取数据,避免了频繁的硬盘读写操作,从而极大提升了系统的响应速度。 其次,...

    Java Springboot学习资料.rar

    初探RabbitMQ消息队列 RabbitMQ延迟队列 actuator 服务监控与管理 actuator与spring-boot-admin 定时任务详解 文件上传 重复提交(分布式锁) 重复提交(本地锁) WebSocket 安全框架(Shiro) 分布式限流 集成...

    Docker新手初探之常用命令实践记录

    在正式使用Docker之前,我们先来熟悉下Docker中常用的命令,因为对Docker的操作就如同操作Linux一样,大部分操作通过命令完成。 一、登录 为什么要使用登录? 因为我们使用Docker,其实主要使用镜像从而运行容器。...

    Python WEB开发全栈 全套视频.txt

    │ └─6、Python课程初探 ├─第三阶段:Python扩展开发 │ ├─3.1、Tkinter桌面编程 │ │ │ ├─3.2、项目-Python开发跨平台的记事本 │ │ │ ├─3.3、Python 数据库编程 │ │ │ ├─3.4、Python...

    SpringBlade 开发手册.pdf

    包括环境要求、环境准备、基础环境安装、Nacos 安装、Sentinel 安装、Seata 安装、插件安装、工程导入、工程运行、工程测试、开发初探、新建微服务工程、第一个 API、鉴权 API、响应结果、Redis 缓存、第一个 ...

    腾讯微博实现一

    同时,为了提高访问速度,可能会利用Redis等内存数据库进行数据缓存。 其次,消息推送是微博系统中的关键功能。腾讯微博可能使用了消息队列(如RabbitMQ或Kafka)来处理用户的实时信息推送,确保用户能在第一时间...

Global site tag (gtag.js) - Google Analytics