您的位置:首页 > 数据库 > Redis

【华为】Redis客户端API使用(java)

2016-09-03 23:09 513 查看

1. 概述

目标读者
本文档专供需要Redis客户端API调用的开发人员,适用于具备Java开发经验的开发人员。

简介
Redis客户端通过API调用,向Redis发起命令调用,向Redis或写入或读出数据。

基本概念
●  Redis服务端
提供服务的一方。
●  Redis单机版服务端
服务端是单个Redis实例提供服务。
●  Redis集群版服务端
服务端由多个Redis主实例和若干从实例组成,共同提供服务。
●  Redis客户端
发起读写命令。
●  Redis 单机版客户端
用来访问Redis单机版服务端的客户端API。
●  Redis 单机版客户端(管道)
Redis单机版客户端通过管道的方式向Redis服务端一次发送多条命令,并一次取得返回结果,在其使用范围内能够较大提高单个客户端的性能。
●  Redis集群版客户端
用来访问Redis集群版服务端的客户端API。
●  Redis集群版客户端(管道)
同单机版客户端的管道模式类似,集群版客户端也可以使用管道模式一次向集群写入多条命令,提高客户端性能。

2. 开发环境准备

操作场景
本开发指南提供了Redis组件的样例代码和常用接口,便于开发者快速熟悉Redis。为了运行Redis组件的样例代码,需要完成下面的操作。

操作步骤
步骤1  确保Redis服务已安装,并正常运行。
步骤2  客户端机器安装Eclipse和JDK程序,安装要求如下:
l   Eclipse使用3.0及以上版本(也可使用NetBeans或者IntelliJ等IDE)。
l   JDK
1.6及以上。
步骤3  如果需要使用Redis集群,需要保证集群状态为“Good”,集群内各Redis实例运行正常。
图  Redis集群状态



步骤4  在FusionInsight Manager界面,点击“Services > Redis > Download Client”,下载Redis客户端。
在弹出的“File Type”信息提示框中的“Save type”勾选“All Client Files”,单击“OK”开始下载客户端软件包,等待下载完成。

图  下载Redis客户端



步骤5  解压下载的客户端,解压目录中“Redis\redis.client.demo”文件夹即为本文档对应的样例工程。“Redis\redis.client.demo\lib”目录内为工程依赖的jar包。
步骤6  导入样例工程到Eclipse开发环境(如果使用其他IDE请注意转化)。
1. 选择“File > Import > General > Existing Projects into Workspace > Next > Browse”。

显示“浏览文件夹”对话框。
2. 选择需要使用的样例工程文件夹,单击“Finish”。

步骤7  设置Eclipse的文本文件编码格式,解决乱码显示问题。
1. 在Eclipse的菜单栏中,选择“Window > Preferences”。

2. 弹出“Preferences”窗口。

3. 在左边导航上选择“General > Workspace”,在“Text file encoding”区域,选中“Other”,并设置参数值为“UTF-8”,单击“Apply”后,单击“OK”。

3. 开发指引

开发流程
1. 确定使用单机版服务端还是集群版服务端。

2. 确定入口IP地址和端口。

3. 导入样例工程,或新建工程并导入样例工程中的jar包文件。

4. 参照代码样例,客户端接口介绍,以及客户端接口文档进行开发。

说明
Redis角色Role_1对应的端口是22400, Role_2对应的端口是22401,以此类推。

通过FusionInsight Manager,用户可以查看单机版服务端或者集群版服务端的运行状态,实时监控Redis实例或者集群的吞吐量。

图  查看Redis实例状态



图  查看Redis集群状态



4. 安全模式

概述
在安装Redis服务时,可以选择是否安装为安全模式。若没有特别的配置,Redis的安全模式与Manager的安全模式一致,且一旦安装后,无法更改。

本节介绍安全模式下的开发。

操作步骤
安全模式下,Redis客户端需要登录认证并授权以后才能访问或操作Redis Server。

步骤1  登录FusionInsight Manager,点击“System > Role Management”,进入角色管理界面。
步骤2  单击“Add Role”,然后“Role name”和“Description”输入角色名字与描述。
步骤3  单击“Rights > Redis Access Manage”,添加集群或单实例的访问权限。



步骤4  在FusionInsight Manager首页,单击“System > User Management > Add User”,添加一个机机(Machine-Machine)用户,并赋予上面步骤中创建的角色权限。
步骤5  用户创建成功后,在用户列表中点击该用户名称后的

,下载相关安全文件。
步骤6  按照样例工程的配置,将下载的安全文件放置到“classes/config”子目录下。
也可以将auth.conf放在classpath路径下,并修改auth.conf中的username(第四步中添加的用户)、realmsName(当前域名)、keyTabFile(keytab文件路径)、krbConfPath(krb5.conf文件路径)。如果keytab文件和krb5.conf是放在当前路径下,keyTabFile和krbConfPath可以只写文件名,否则在auth.conf中配置成绝对路径。





步骤7  Redis Server刷新权限信息需要5-10分钟,按照样例工程配置好安全的信息后,就可以和非安全模式一样,使用客户端了。

5. 代码样例

5.1 单机版客户端使用

功能介绍
使用String类型的IP地址,int类型的PORT端口来初始化一个Jedis,然后就可以调用其方法:set get mset mget 等方法了,每个方法都会返回一个String类型的返回值用来标示操作结果。如果出现网络异常或者Redis服务端异常则会抛出异常。

代码样例
public void testJedis () {  
        Jedis jedis = null; 
        try {  
            //使用IP和端口号初始化  
            jedis = new Jedis ("192.168.0.1", 22400);  
            //方法的最后一个参数为 bool : 是否使用管道模式  
            String result = jedis.set("key111", "value111");  
            System.out.println(result);  
            } catch (Exception e) { 
                e.printStackTrace();  
            } finally {  
                try {  
                    if(jedis!= null){  
                        jedis.close();  
                    } 
                } catch (Exception e) {  
                    e.printStackTrace(); 
                }  
            }  
         }


5.2 集群版客户端使用

功能介绍
集群版使用JedisCluster,初始化参数为HashSet<HostAndPort>为集群中的实例列表,一般只需要填写集群中的某一个实例的IP和PORT即可,也可以填写多个。

代码样例
public void testClusterAdpter() {  
//HostAndPort为集群中任意可以联通的成员。JedisCluster将通过这个成员获取整个集群的信息  
//参数1 : 实例ip地址参数2 :端口  
    HostAndPort host1 = new HostAndPort("192.168.0.1", 22400);  
    HostAndPort host2 = new HostAndPort("192.168.0.1", 22401);  
    //Set中放置一个HostAndPort即可  
    HashSet<HostAndPort> set = new HashSet<HostAndPort>();  
    set.add(host1);  
    set.add(host2);  
    JedisCluster adapter = null;  
    try {  
        adapter = new JedisCluster(set);  
        String result = adapter.set("key111", "value111");  
        System.out.println(result);  
        } catch (Exception e) {  
          e.printStackTrace();  
        } finally {  
    try {  
         if(adapter != null){  
                adapter.close();  
        }  
     } catch (Exception e) {  
         e.printStackTrace();  
     }  
     } 
} 


5.3 集群版客户端管道使用

不需要返回
功能介绍
对于不需要返回值的命令,直接调用JedisCluster 的sync()方法即可。

代码样例
public void testSync() { 
       HostAndPort host1 = new HostAndPort("192.168.0.1", 22400); 
       HostAndPort host2 = new HostAndPort("192.168.0.1", 22401); 
       HashSet<HostAndPort> set = new HashSet<HostAndPort>(); 
       set.add(host1); 
       set.add(host2); 
       JedisCluster cluster = new JedisCluster(set); 
       ClusterBatch pipeline = cluster.getPipeline(); 
       try { 
           pipeline.set("key111", "value111"); 
           pipeline.set("key222", "value333"); 
           pipeline.set("key222", "value444"); 
           pipeline.sync();// 使用不需要返回值情况 
       } catch (Exception e) { 
           e.printStackTrace(); 
       } finally { 
           cluster.close(); 
       if (pipeline != null) { 
           pipeline.close(); 
           } 
       } 
       }


需要全部返回
功能介绍
JedisCluster 的syncAndReturnAll则会返回所有命令的结果,返回类型为:           List<Object>。

代码样例
public void testClusterAdpter() {  
        HostAndPort host1 = new HostAndPort("192.168.0.1", 22400);  
        HostAndPort host2 = new HostAndPort("192.168.0.1", 22401);  
        HashSet<HostAndPort> set = new HashSet<HostAndPort>();  
        set.add(host1);  
        set.add(host2);  
        JedisCluster adapter = new JedisCluster(set);  
        ClusterBatch pipeline = adapter.getPipeline(); 
        try {  
            pipeline.set("key111", "value111");  
            pipeline.set("key222", "value222");  
            pipeline.set("key333", "value333");  
            List<Object> syncAndReturnAll = pipeline.syncAndReturnAll();  
            System.out.println("is equal:"+"OK".equals(syncAndReturnAll.get(0)));  
            System.out.println("is equal:"+"OK".equals(syncAndReturnAll.get(2)));  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            adapter.close();  
        }  
        }


需要部分返回
功能介绍
ClusterAdapter的syncAndReturn(String[])方法则是返回部分需要返回值的接口。其参数为需要返回值的命令的key数组,其返回值为List<Object>。

代码样例
public void testSyncAndReturn() {  
        HostAndPort host1 = new HostAndPort("192.168.0.1", 22400);  
        HostAndPort host2 = new HostAndPort("192.168.0.1", 22401);  
        HashSet<HostAndPort> set = new HashSet<HostAndPort>();  
        set.add(host1);  
        set.add(host2);  
        JedisCluster adapter =new JedisCluster(set);  
        ClusterBatch pipeline = adapter.getPipeline(); 
        try {  
            pipeline.set("key111", "value1");  
            pipeline.set("key222", "value2");  
            pipeline.set("key333", "value3");  
            List<Object> syncAndReturn =  
        pipeline.syncAndReturn(new String[] { "key222", "key333" });  
            System.out.println("is equal:"+"OK".equals(syncAndReturn.get(0)));  
            System.out.println("is equal:"+"OK".equals(syncAndReturn.get(1)));  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
        adapter.close();  
        }  
        }


6. 客户端接口介绍

6.1 简介

Redis接口与社区保持一致,新增的安全模式也不需要修改接口调用,只需要增加相应的配置文件和授权文件即可。

用户可参照社区接口使用:

Redis社区:

http://redis.io/commands

jedis社区:

https://github.com/xetorthio/jedis

6.2 Jedis的使用

可参考样例工程。

import java.util.Arrays;

import java.util.List;

import org.junit.AfterClass;

import org.junit.BeforeClass;

import org.junit.Test;

import redis.clients.jedis.Jedis;

import redis.clients.jedis.JedisPoolConfig;

import redis.clients.jedis.JedisShardInfo;

import redis.clients.jedis.Pipeline;

import redis.clients.jedis.ShardedJedis;

import redis.clients.jedis.ShardedJedisPipeline;

import redis.clients.jedis.ShardedJedisPool;

import redis.clients.jedis.Transaction;

public class JedisDemo { 
private static Jedis jedis; 
private static ShardedJedis sharding; 
private static ShardedJedisPool pool; 
 
@BeforeClass 
public static void setUpBeforeClass() throws Exception { 
List<JedisShardInfo> shards = Arrays.asList(new JedisShardInfo("localhost", 22400), new JedisShardInfo( 
"localhost", 22400)); // 使用相同的ip:port,仅作测试 
 
jedis = new Jedis("localhost"); 
sharding = new ShardedJedis(shards); 
 
pool = new ShardedJedisPool(new JedisPoolConfig(), shards); 
} 
 
@AfterClass 
public static void tearDownAfterClass() throws Exception { 
jedis.disconnect(); 
sharding.disconnect(); 
pool.destroy(); 
} 
 
/** 
* 普通同步方式 
*/ 
@Test 
public void test1Normal() { 
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"); 
} 
 
/** 
* 事务方式 
*/ 
@Test 
public void test2Trans() { 
long start = System.currentTimeMillis(); 
Transaction tx = jedis.multi(); 
for (int i = 0; i < 100000; i++) { 
tx.set("t" + i, "t" + i); 
} 
// System.out.println(tx.get("t1000").get()); 
 
List<Object> results = tx.exec(); 
long end = System.currentTimeMillis(); 
System.out.println("Transaction SET: " + ((end - start) / 1000.0) + " seconds"); 
} 
 
 
/** 
* 管道 
*/ 
@Test 
public void test3Pipelined() { 
Pipeline pipeline = jedis.pipelined(); 
long start = System.currentTimeMillis(); 
for (int i = 0; i < 100000; i++) { 
pipeline.set("p" + i, "p" + i); 
} 
// System.out.println(pipeline.get("p1000").get()); 
List<Object> results = pipeline.syncAndReturnAll(); 
long end = System.currentTimeMillis(); 
System.out.println("Pipelined SET: " + ((end - start) / 1000.0) + " seconds"); 
} 
 
/** 
* 管道中调用事务 
*/ 
@Test 
public void test4combPipelineTrans() { 
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"); 
} 
 
/** 
* 分布式直连同步调用 
*/ 
@Test 
public void test5shardNormal() { 
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"); 
} 
 
/** 
* 分布式直连异步调用 
*/ 
@Test 
public void test6shardpipelined() { 
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"); 
} 
 
/** 
* 分布式连接池同步调用 
*/ 
@Test 
public void test7shardSimplePool() { 
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"); 
} 
 
/** 
* 分布式连接池异步调用 
*/ 
@Test 
public void test8shardPipelinedPool() { 
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"); 
} 
 
}


6.3 JedisCluster的使用

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
public class JedisClusterDemo {
JedisCluster jc = null;
@Before 
public void before() { 
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>(); 
// Jedis Cluster will attempt to discover cluster nodes automatically 
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7000)); 
jc = new JedisCluster(jedisClusterNodes); 
} 
 
@Test 
public void test_incr() { 
 
String key = "page_view"; 
jc.del(key); 
jc.incr(key); 
String result = jc.get(key); 
System.out.println(result); 
Assert.assertEquals("1", result); 
} 
 
@Test 
public void test_setAndGetStringVal() { 
String key = "foo"; 
String value = "bar"; 
jc.set(key, value); 
String result = jc.get(key); 
System.out.println(result); 
Assert.assertEquals(value, result); 
} 
 
@Test 
public void test_setAndGetStringVal_and_set_expire() throws InterruptedException { 
String key = "hello"; 
String value = "world"; 
int seconds = 3; 
jc.setex(key, seconds, value); 
String result = jc.get(key); 
System.out.println(result); 
Assert.assertEquals(value, result); 
Thread.sleep(seconds * 1000); 
result = jc.get(key); 
System.out.println(result); 
Assert.assertEquals(null, result); 
 
} 
 
@Test 
public void test_setAndGetHashVal() { 
 
String key = "website"; 
String field = "google"; 
String value = "google.com"; 
jc.del(key); 
jc.hset(key, field, value); 
String result = jc.hget(key, field); 
System.out.println(result); 
Assert.assertEquals(value, result); 
} 
 
@Test 
public void test_setAndGetListVal() { 
String key = "mylist"; 
jc.del(key); 
String[] vals = { "a", "b", "c" }; 
jc.rpush(key, vals); 
List<String> result = jc.lrange(key, 0, -1); 
System.out.println(result); 
Assert.assertEquals(vals, result); 
} 
 
@Test 
public void test_setAndGetSetVal() { 
 
String key = "language"; 
jc.del(key); 
String[] members = { "java", "ruby", "python" }; 
jc.sadd(key, members); 
Set<String> result = jc.smembers(key); 
System.out.println(result); 
Assert.assertEquals(members, result); 
} 
}


FROM: http://developer.huawei.com/cn/ict/Products/BigData/FusionInsightHD/Redis/SDK
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: