`
huangyongxing310
  • 浏览: 490494 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

redis原生应用

阅读更多
redis原生应用


一、普通同步方式
public void test1Normal() {
    Jedis jedis = new Jedis("localhost");	//生成Jedis,连接到redis服务器
    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++) {
        String result = jedis.set("n" + i, "n" + i);//写入一条记录
    }
    long end = System.currentTimeMillis();
    System.out.println("Simple SET: " + ((end - start)/1000.0) + " seconds");
    jedis.disconnect(); //断开连接
}



二、事务方式(Transactions)
redis的事务很简单,他主要目的是保障,一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。
(事务中某个操作失败,并不会回滚其他操作。这一点需要注意。)
public void test2Trans() {
    Jedis jedis = new Jedis("localhost");
    long start = System.currentTimeMillis();
    Transaction tx = jedis.multi();	//开启事务
    for (int i = 0; i < 100000; i++) {
        tx.set("t" + i, "t" + i);
    }
    List<Object> results = tx.exec();   //提交事务
    long end = System.currentTimeMillis();
    System.out.println("Transaction SET: " + ((end - start)/1000.0) + " seconds");
    jedis.disconnect();
}


1.WATCH命令可以监控一个或多个键,一旦其中有一个键里的值被修改(或删除),之后的事务就不会执行。监控一直持续到EXEC命令
(事务中的命令是在EXEC之后才执行的,所以在MULTI命令后可以修改WATCH监控的键值)
2.我们调用jedis.watch(…)方法来监控key,如果调用后key里的值发生变化,则整个事务会执行失败(被放弃),EXEC将放弃当前事务中
的所有命令(返回NULL-multi-bulk回复)。
3.因为redis的命令是一条条执行的(单进程模式),所以用WATCH命令是可以做到数据并发处理的,不存在回滚,因为还没有执行的机
会就被放弃掉了。
4.事务中某个操作失败,并不会回滚其他操作。这一点需要注意。
5.我们可以使用discard()方法来取消事务。就是取消事务队列中的所有指令。

命令说明
1.MULTI
用于标记事务的开始,其后执行的命令都将被存入命令队列,直到执行EXEC时,这些命令才会被原子的执行。

2.EXEC
执行在一个事务内命令队列中的所有命令,同时将当前连接的状态恢复为正常状态,即非事务状态。如果在事务中执行了WATCH命令,
那么只有当WATCH所监控的Keys没有被修改的前提下,EXEC命令才能执行事务队列中的所有命令,否则EXEC将放弃当前事务中的所有命令。
原子性的返回事务中各条命令的返回结果。如果在事务中使用了WATCH,一旦事务被放弃,EXEC将返回NULL-multi-bulk回复。

3.DISCARD
回滚事务队列中的所有命令,同时再将当前连接的状态恢复为正常状态,即非事务状态。如果WATCH命令被使用,该命令将
UNWATCH所有的Keys。

4.WATCH key [key ...]
在MULTI命令执行之前,可以指定待监控的Keys,然而在执行EXEC之前,如果被监控的Keys发生修改,EXEC将放弃执
行该事务队列中的所有命令。

5.UNWATCH
取消当前事务中指定监控的Keys,如果执行了EXEC或DISCARD命令,则无需再手工执行该命令了,因为在此之后,事务中所有被监
控的Keys都将自动取消。


三、管道(Pipelining)
有时,我们需要采用异步方式,一次发送多个指令,不同步等待其返回结果。这样可以取得非常好的执行效率。这就是管道
public void test3Pipelined() {
    Jedis jedis = new Jedis("localhost");
    Pipeline pipeline = jedis.pipelined();
    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++) {
        pipeline.set("p" + i, "p" + i);
    }
    List<Object> results = pipeline.syncAndReturnAll();
    long end = System.currentTimeMillis();
    System.out.println("Pipelined SET: " + ((end - start)/1000.0) + " seconds");
    jedis.disconnect();
}



四、管道中调用事务
就Jedis提供的方法而言,是可以做到在管道中使用事务
public void test4combPipelineTrans() {
    jedis = new Jedis("localhost");
    long start = System.currentTimeMillis();
    Pipeline pipeline = jedis.pipelined();
    pipeline.multi();
    for (int i = 0; i < 100000; i++) {
        pipeline.set("" + i, "" + i);
    }
    pipeline.exec();
    List<Object> results = pipeline.syncAndReturnAll();
    long end = System.currentTimeMillis();
    System.out.println("Pipelined transaction: " + ((end - start)/1000.0) + " seconds");
    jedis.disconnect();
}


发现其效率和单独使用事务差不多,甚至还略微差点。


五、分布式直连同步调用
public void test5shardNormal() {
    List<JedisShardInfo> shards = Arrays.asList(
            new JedisShardInfo("localhost",6379),
            new JedisShardInfo("localhost",6380));

    ShardedJedis sharding = new ShardedJedis(shards);

    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++) {
        String result = sharding.set("sn" + i, "n" + i);
    }
    long end = System.currentTimeMillis();
    System.out.println("Simple@Sharing SET: " + ((end - start)/1000.0) + " seconds");

    sharding.disconnect();
}


这个是分布式直接连接,并且是同步调用,每步执行都返回执行结果。


六、分布式直连异步调用
public void test6shardpipelined() {
    List<JedisShardInfo> shards = Arrays.asList(
            new JedisShardInfo("localhost",6379),
            new JedisShardInfo("localhost",6380));

    ShardedJedis sharding = new ShardedJedis(shards);

    ShardedJedisPipeline pipeline = sharding.pipelined();
    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++) {
        pipeline.set("sp" + i, "p" + i);
    }
    List<Object> results = pipeline.syncAndReturnAll();
    long end = System.currentTimeMillis();
    System.out.println("Pipelined@Sharing SET: " + ((end - start)/1000.0) + " seconds");

    sharding.disconnect();
}



七、分布式连接池同步调用
如果,你的分布式调用代码是运行在线程中,那么上面两个直连调用方式就不合适了,因为直连方式是非线程安全的,
这个时候,你就必须选择连接池调用。
public void test7shardSimplePool() {
    List<JedisShardInfo> shards = Arrays.asList(
            new JedisShardInfo("localhost",6379),
            new JedisShardInfo("localhost",6380));

    ShardedJedisPool pool = new ShardedJedisPool(new JedisPoolConfig(), shards);

    ShardedJedis one = pool.getResource();

    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++) {
        String result = one.set("spn" + i, "n" + i);
    }
    long end = System.currentTimeMillis();
    pool.returnResource(one);
    System.out.println("Simple@Pool SET: " + ((end - start)/1000.0) + " seconds");

    pool.destroy();
}



八、分布式连接池异步调用
public void test8shardPipelinedPool() {
    List<JedisShardInfo> shards = Arrays.asList(
            new JedisShardInfo("localhost",6379),
            new JedisShardInfo("localhost",6380));

    ShardedJedisPool pool = new ShardedJedisPool(new JedisPoolConfig(), shards);

    ShardedJedis one = pool.getResource();

    ShardedJedisPipeline pipeline = one.pipelined();

    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++) {
        pipeline.set("sppn" + i, "n" + i);
    }
    List<Object> results = pipeline.syncAndReturnAll();
    long end = System.currentTimeMillis();
    pool.returnResource(one);
    System.out.println("Pipelined@Pool SET: " + ((end - start)/1000.0) + " seconds");
    pool.destroy();
}




JedisPool应用
1.Jedis使用commons-pool完成池化实现。

先做个配置文件(properties文件):
#最大分配的对象数
redis.pool.maxActive=1024
#最大能够保持idel状态的对象数
redis.pool.maxIdle=200
#当池内没有返回对象时,最大等待时间
redis.pool.maxWait=1000
#当调用borrow Object方法时,是否进行有效性检查
redis.pool.testOnBorrow=true
#当调用return Object方法时,是否进行有效性检查
redis.pool.testOnReturn=true
#IP
redis.ip=172.0.0.1
#Port
redis.port=6379


jedisPool的相关详细配置可参考:http://www.2cto.com/database/201311/254449.html

在静态代码段中完成初始化:
private static JedisPool pool;
static {
	ResourceBundle bundle = ResourceBundle.getBundle("redis");
	if (bundle == null) {
		throw new IllegalArgumentException("[redis.properties] is not found!");
	}
	JedisPoolConfig config = new JedisPoolConfig();
	config.setMaxActive(Integer.valueOf(bundle.getString("redis.pool.maxActive")));
	config.setMaxIdle(Integer.valueOf(bundle.getString("redis.pool.maxIdle")));
	config.setMaxWait(Long.valueOf(bundle.getString("redis.pool.maxWait")));
	config.setTestOnBorrow(Boolean.valueOf(bundle.getString("redis.pool.testOnBorrow")));
	config.setTestOnReturn(Boolean.valueOf(bundle.getString("redis.pool.testOnReturn")));
	pool = new JedisPool(config, bundle.getString("redis.ip"), Integer.valueOf(bundle.getString("redis.port")));
}


修改为Jedis从pool中获得:
// 从池中获取一个Jedis对象
Jedis jedis = pool.getResource();
String keys = "name";
// 删数据
jedis.del(keys);
// 存数据
jedis.set(keys, "snowolf");
// 取数据
String value = jedis.get(keys);
System.out.println(value);
// 释放对象池
pool.returnResource(jedis);



Jedis分布式
Jedis分布式(就是数据按key算出hash后按hash分片方式(就是对数据进行分类,方便后面查找)存到不同的redis服务器)

保留前面的 JedisPoolConfig ,新增两个Redis的IP(redis1.ip,redis2.ip),完成两个
JedisShardInfo 实例 ,并将其丢进List中:
JedisShardInfo jedisShardInfo1 = new JedisShardInfo(
            bundle.getString("redis1.ip"), Integer.valueOf(bundle.getString("redis.port")));
JedisShardInfo jedisShardInfo2 = new JedisShardInfo(
            bundle.getString("redis2.ip"), Integer.valueOf(bundle.getString("redis.port")));
List<JedisShardInfo> list = new LinkedList<JedisShardInfo>();
list.add(jedisShardInfo1);
list.add(jedisShardInfo2);


初始化 ShardedJedisPool 代替 JedisPool:
ShardedJedisPool pool = new ShardedJedisPool(config, list);


改由ShardedJedis,获取Jedis对象:
// 从池中获取一个Jedis对象
ShardedJedis jedis = pool.getResource();
String keys = "name";
String value = "snowolf";
// 删数据
jedis.del(keys);
// 存数据
jedis.set(keys, value);
// 取数据
String v = jedis.get(keys);
System.out.println(v);
// 释放对象池
pool.returnResource(jedis);


通过以上方式,向redis进行set操作的key-value,会通过hash而均匀的分配到pool里的redis机器中。



参考原文:http://www.tuicool.com/articles/jM7RF3Y
参考原文:http://www.open-open.com/lib/view/open1410485827242.html
参考原文:http://www.cnblogs.com/stephen-liu74/archive/2012/03/28/2357783.html
分享到:
评论

相关推荐

    64位windows和原生的redis,windows版本号3.0.503,原生的4.0.8

    Redis是一种高性能的键值对数据存储系统,常用于构建数据缓存、消息队列和数据库。...无论选择哪个版本,了解Redis的基本操作和数据结构,以及如何利用其消息队列功能,都将对提升开发效率和应用性能大有裨益。

    jedis中的redis命令

    Redis是一种开源的高性能键值存储数据库,广泛应用于缓存、会话管理、消息队列等场景。本文将详细介绍Jedis中实现的与Redis命令对应的Java方法,帮助开发者理解如何在Java项目中调用这些方法以实现不同的Redis操作。...

    redis6.2.6的Windows版本

    Redis原生支持Linux操作系统,但在Windows上运行需要借助第三方工具。可以下载Redis的Windows预编译版本,这是最便捷的安装方式。文件名为“redis-6.2.6-win”,包含了所有需要的二进制文件。解压后,找到`redis-...

    ssm+shiro+redis+ecache整合认证权限.zip

    SSM(Spring、SpringMVC、MyBatis)与Shiro、Redis、Ecache整合是构建大型企业级Java应用的常见技术栈。这个压缩包文件的内容可能是为了演示或教学如何在项目中集成这些组件,实现用户认证和权限管理,并利用缓存...

    Redis-6.2.7 Windows 版

    3. **Windows兼容性**:Redis原生支持Linux环境,但通过社区的努力,也有了适用于Windows的版本。这个6.2.7版本是为了确保在Windows上运行的兼容性和稳定性。 4. **安装与运行**:在Windows上,用户只需解压提供的...

    redis 自身实例应用,雪崩,分布式锁

    Redis 自身实例应用、雪崩、分布式锁 Redis 作为一个轻量级的内存 Nosql 数据库,它具有高性能、低延迟、支持事务、支持 pub/sub 消息队列等特点,广泛应用于缓存、消息队列、分布式锁等场景中。今天,我们将深入...

    windows-redis-7.0.0下载

    在Windows环境下,虽然Redis原生是为Linux设计的,但通过社区的努力,已经实现了在Windows上的编译和运行。 标题“windows-redis-7.0.0下载”指的是针对Windows平台的Redis 7.0.0版本。这个版本可能包含了针对...

    redis for windows 6.0.9.zip

    虽然Redis原生为Unix/Linux系统设计,但在Windows上的表现依然良好。需要注意的是,某些Unix特定的功能或优化可能在Windows上不可用。 总结,Redis 6.0.9在Windows环境下的使用涉及安装、配置、数据操作、持久化、...

    Redis-x64-7.0.5-windows11

    1. **编译环境**:由于Redis原生为Linux系统设计,所以在Windows上需要安装交叉编译工具,如msys2和mingw-w64,才能进行编译。 2. **下载源码**:从Redis官网获取最新版本的源代码,或者直接使用提供的Redis-x64-...

    windows版Redis1

    Redis是世界上最受欢迎的开源键值存储系统之一,它在Linux操作系统上原生运行,但为了满足Windows用户的需求,也提供了Windows版本。标题“windows版Redis1”表明我们讨论的是一个适用于Windows操作系统的Redis...

    redis Windows管理工具

    在Windows平台上,虽然Redis原生支持Linux操作系统,但通过社区的努力,我们也有了适用于Windows的版本和管理工具。本文将深入探讨如何在Windows上安装、配置和管理Redis。 首先,Redis在Windows上的实现通常是通过...

    windows版redis

    由于Redis原生是为Linux设计的,因此Windows版本的Redis是由社区成员维护和提供的。在这个特定的版本3.2.100中,开发者已经将其适配到Windows环境,保留了基本功能和性能。 **二、下载与安装** 1. **下载**: 你...

    redis-6.2.6_win10.zip

    由于Redis原生是为Unix环境设计的,Windows上的使用可能遇到一些兼容性问题,如文件路径、信号处理等,需要根据Cygwin64的特点进行适配。同时,注意Windows的防火墙设置,确保Redis的默认端口(6379)能正常通信。 ...

    redis64位下载

    在Windows环境下,虽然Redis原生支持Linux,但通过社区的努力,Windows版本同样能够提供稳定的性能,使得开发者在Windows平台上也能充分利用Redis的强大功能。 总之,Redis64位版本2.8是一个功能丰富、性能强大的...

    Redis-x64-3.0.504.zip

    Redis 原生是为 Linux 设计的,但在 Windows 上也可以通过编译或预编译的二进制包进行安装。Redis-x64-3.0.504.zip 提供了预编译的 Windows 64 位版本,用户可以直接解压并运行。 4. **一键启动和关闭脚本**: ...

    windows redis-2.0.2 附带redis.conf和安装教程

    2. **Windows版本**:虽然Redis原生是为Linux设计的,但通过社区的努力,也有适用于Windows的版本。这里的"redis-2.0.2"是针对Windows 32位系统的版本,适合在32位Windows操作系统上运行。 3. **redis.conf配置文件...

    redis windos客户端

    在Windows环境下,尽管Redis原生是为Unix-like系统设计,但依然可以通过一些客户端工具进行操作。这些客户端工具通常具备图形化界面,使得在Windows操作系统上使用Redis变得更为直观和便捷。它们能够帮助开发者更...

    RedisPlus3.2免安装下载

    RedisPlus作为其增强版,不仅保留了原生Redis的所有特性,还添加了一些实用功能,如图形化界面管理、监控、报警等功能,使得运维人员无需通过命令行就能便捷地进行数据操作和系统监控。 1. **图形化界面**:Redis...

    redis-x86-2.6.12

    由于Redis原生支持Unix/Linux环境,因此在Windows上运行需要特别编译的版本,如"redis-x86-2.6.12"。解压后,用户通常需要执行`redis-server.exe`启动Redis服务,并可以使用`redis-cli.exe`进行客户端操作。 3. ...

    redis windows安装包 3.0.503

    注意,虽然Redis在Windows上可以运行,但其原生环境是Linux。因此,在生产环境中,建议使用Linux作为Redis服务器的操作系统,以获得更好的性能和稳定性。 此外,了解Redis的基本概念和操作命令对于使用和管理Redis...

Global site tag (gtag.js) - Google Analytics