云数据库 Redis 版
.net 客户端测试代码示例:using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using ServiceStack.Redis;namespace Serv
·
.net 客户端
测试代码示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ServiceStack.Redis;
namespace ServiceStack.Redis.Tests
{
class Program
{
public static void RedisClientTest()
{
string host = "127.0.0.1";/*访问host地址*/
string password = "password";/*密码*/
RedisClient redisClient = new RedisClient(host, 6379, password);
string key = "test-aliyun";
string value = "test-aliyun-value";
redisClient.Set(key, value);
string listKey = "test-aliyun-list";
System.Console.WriteLine("set key " + key + " value " + value);
string getValue = System.Text.Encoding.Default.GetString(redisClient.Get(key));
System.Console.WriteLine("get key " + getValue);
System.Console.Read();
}
public static void RedisPoolClientTest()
{
string[] testReadWriteHosts = new[] {
"redis://password@127.0.0.1:6379"/*redis://密码@访问地址:端口*/
};
RedisConfig.VerifyMasterConnections = false;//需要设置
PooledRedisClientManager redisPoolManager = new PooledRedisClientManager(10/*连接池个数*/, 10/*连接池超时时间*/, testReadWriteHosts);
for (int i = 0; i < 100; i++)
{
IRedisClient redisClient = redisPoolManager.GetClient();//获取连接
RedisNativeClient redisNativeClient = (RedisNativeClient)redisClient;
redisNativeClient.Client = null;//ApsaraDB for Redis不支持client setname所以这里需要显示的把client对象置为null
try
{
string key = "test-aliyun1111";
string value = "test-aliyun-value1111";
redisClient.Set(key, value);
string listKey = "test-aliyun-list";
redisClient.AddItemToList(listKey, value);
System.Console.WriteLine("set key " + key + " value " + value);
string getValue = redisClient.GetValue(key);
System.Console.WriteLine("get key " + getValue);
redisClient.Dispose();//
}
catch (Exception e)
{
System.Console.WriteLine(e.Message);
}
}
System.Console.Read();
}
static void Main(string[] args)
{
//单链接模式
RedisClientTest();
//连接池模式
RedisPoolClientTest();
}
}
}
最佳实践
1.游戏玩家排行榜
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;
public class GameRankSample {
static int TOTAL_SIZE = 20;
public static void main(String[] args)
{
//连接信息,从控制台可以获得
String host = "xxxxxxxxxx.m.cnhz1.kvstore.aliyuncs.com";
int port = 6379;
Jedis jedis = new Jedis(host, port);
try {
//实例密码
String authString = jedis.auth("password");//password
if (!authString.equals("OK"))
{
System.err.println("AUTH Failed: " + authString);
return;
}
//Key(键)
String key = "游戏名:奔跑吧,阿里!";
//清除可能的已有数据
jedis.del(key);
//模拟生成若干个游戏玩家
List<String> playerList = new ArrayList<String>();
for (int i = 0; i < TOTAL_SIZE; ++i)
{
//随机生成每个玩家的ID
playerList.add(UUID.randomUUID().toString());
}
System.out.println("输入所有玩家 ");
//记录每个玩家的得分
for (int i = 0; i < playerList.size(); i++)
{
//随机生成数字,模拟玩家的游戏得分
int score = (int)(Math.random()*5000);
String member = playerList.get(i);
System.out.println("玩家ID:" + member + ", 玩家得分: " + score);
//将玩家的ID和得分,都加到对应key的SortedSet中去
jedis.zadd(key, score, member);
}
//输出打印全部玩家排行榜
System.out.println();
System.out.println(" "+key);
System.out.println(" 全部玩家排行榜 ");
//从对应key的SortedSet中获取已经排好序的玩家列表
Set<Tuple> scoreList = jedis.zrevrangeWithScores(key, 0, -1);
for (Tuple item : scoreList) {
System.out.println("玩家ID:"+item.getElement()+", 玩家得分:"+Double.valueOf(item.getScore()).intValue());
}
//输出打印Top5玩家排行榜
System.out.println();
System.out.println(" "+key);
System.out.println(" Top 玩家");
scoreList = jedis.zrevrangeWithScores(key, 0, 4);
for (Tuple item : scoreList) {
System.out.println("玩家ID:"+item.getElement()+", 玩家得分:"+Double.valueOf(item.getScore()).intValue());
}
//输出打印特定玩家列表
System.out.println();
System.out.println(" "+key);
System.out.println(" 积分在1000至2000的玩家");
//从对应key的SortedSet中获取已经积分在1000至2000的玩家列表
scoreList = jedis.zrangeByScoreWithScores(key, 1000, 2000);
for (Tuple item : scoreList) {
System.out.println("玩家ID:"+item.getElement()+", 玩家得分:"+Double.valueOf(item.getScore()).intValue());
}
} catch (Exception e) {
e.printStackTrace();
}finally{
jedis.quit();
jedis.close();
}
}
}
运行结果
输入所有玩家
玩家ID:9193e26f-6a71-4c76-8666-eaf8ee97ac86, 玩家得分: 3860
玩家ID:db03520b-75a3-48e5-850a-071722ff7afb, 玩家得分: 4853
玩家ID:d302d24d-d380-4e15-a4d6-84f71313f27a, 玩家得分: 2931
玩家ID:bee46f9d-4b05-425e-8451-8aa6d48858e6, 玩家得分: 1796
玩家ID:ec24fb9e-366e-4b89-a0d5-0be151a8cad0, 玩家得分: 2263
玩家ID:e11ecc2c-cd51-4339-8412-c711142ca7aa, 玩家得分: 1848
玩家ID:4c396f67-da7c-4b99-a783-25919d52d756, 玩家得分: 958
玩家ID:a6299dd2-4f38-4528-bb5a-aa2d48a9f94a, 玩家得分: 2428
玩家ID:2e4ec631-1e4e-4ef0-914f-7bf1745f7d65, 玩家得分: 4478
玩家ID:24235a85-85b9-476e-8b96-39f294f57aa7, 玩家得分: 1655
玩家ID:e3e8e1fa-6aac-4a0c-af80-4c4a1e126cd1, 玩家得分: 4064
玩家ID:99bc5b4f-e32a-4295-bc3a-0324887bb77e, 玩家得分: 4852
玩家ID:19e2aa6b-a2d8-4e56-bdf7-8b59f64bd8e0, 玩家得分: 3394
玩家ID:cb62bb24-1318-4af2-9d9b-fbff7280dbec, 玩家得分: 3405
玩家ID:ec0f06da-91ee-447b-b935-7ca935dc7968, 玩家得分: 4391
玩家ID:2c814a6f-3706-4280-9085-5fe5fd56b71c, 玩家得分: 2510
玩家ID:9ee2ed6d-08b8-4e7f-b52c-9adfe1e32dda, 玩家得分: 63
玩家ID:0293b43a-1554-4157-a95b-b78de9edf6dd, 玩家得分: 1008
玩家ID:674bbdd1-2023-46ae-bbe6-dfcd8e372430, 玩家得分: 2265
玩家ID:34574e3e-9cc5-43ed-ba15-9f5405312692, 玩家得分: 3734
游戏名:奔跑吧,阿里!
全部玩家排行榜
玩家ID:db03520b-75a3-48e5-850a-071722ff7afb, 玩家得分:4853
玩家ID:99bc5b4f-e32a-4295-bc3a-0324887bb77e, 玩家得分:4852
玩家ID:2e4ec631-1e4e-4ef0-914f-7bf1745f7d65, 玩家得分:4478
玩家ID:ec0f06da-91ee-447b-b935-7ca935dc7968, 玩家得分:4391
玩家ID:e3e8e1fa-6aac-4a0c-af80-4c4a1e126cd1, 玩家得分:4064
玩家ID:9193e26f-6a71-4c76-8666-eaf8ee97ac86, 玩家得分:3860
玩家ID:34574e3e-9cc5-43ed-ba15-9f5405312692, 玩家得分:3734
玩家ID:cb62bb24-1318-4af2-9d9b-fbff7280dbec, 玩家得分:3405
玩家ID:19e2aa6b-a2d8-4e56-bdf7-8b59f64bd8e0, 玩家得分:3394
玩家ID:d302d24d-d380-4e15-a4d6-84f71313f27a, 玩家得分:2931
玩家ID:2c814a6f-3706-4280-9085-5fe5fd56b71c, 玩家得分:2510
玩家ID:a6299dd2-4f38-4528-bb5a-aa2d48a9f94a, 玩家得分:2428
玩家ID:674bbdd1-2023-46ae-bbe6-dfcd8e372430, 玩家得分:2265
玩家ID:ec24fb9e-366e-4b89-a0d5-0be151a8cad0, 玩家得分:2263
玩家ID:e11ecc2c-cd51-4339-8412-c711142ca7aa, 玩家得分:1848
玩家ID:bee46f9d-4b05-425e-8451-8aa6d48858e6, 玩家得分:1796
玩家ID:24235a85-85b9-476e-8b96-39f294f57aa7, 玩家得分:1655
玩家ID:0293b43a-1554-4157-a95b-b78de9edf6dd, 玩家得分:1008
玩家ID:4c396f67-da7c-4b99-a783-25919d52d756, 玩家得分:958
玩家ID:9ee2ed6d-08b8-4e7f-b52c-9adfe1e32dda, 玩家得分:63
游戏名:奔跑吧,阿里!
Top 玩家
玩家ID:db03520b-75a3-48e5-850a-071722ff7afb, 玩家得分:4853
玩家ID:99bc5b4f-e32a-4295-bc3a-0324887bb77e, 玩家得分:4852
玩家ID:2e4ec631-1e4e-4ef0-914f-7bf1745f7d65, 玩家得分:4478
玩家ID:ec0f06da-91ee-447b-b935-7ca935dc7968, 玩家得分:4391
玩家ID:e3e8e1fa-6aac-4a0c-af80-4c4a1e126cd1, 玩家得分:4064
游戏名:奔跑吧,阿里!
积分在1000至2000的玩家
玩家ID:0293b43a-1554-4157-a95b-b78de9edf6dd, 玩家得分:1008
玩家ID:24235a85-85b9-476e-8b96-39f294f57aa7, 玩家得分:1655
玩家ID:bee46f9d-4b05-425e-8451-8aa6d48858e6, 玩家得分:1796
玩家ID:e11ecc2c-cd51-4339-8412-c711142ca7aa, 玩家得分:1848
2.网上商城商品相关性分析
代码示例
package shop.kvstore.aliyun.com;
import java.util.Set;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;
public class AliyunShoppingMall {
public static void main(String[] args)
{
//ApsaraDB for Redis的连接信息,从控制台可以获得
String host = "xxxxxxxx.m.cnhza.kvstore.aliyuncs.com";
int port = 6379;
Jedis jedis = new Jedis(host, port);
try {
//ApsaraDB for Redis的实例密码
String authString = jedis.auth("password");//password
if (!authString.equals("OK"))
{
System.err.println("AUTH Failed: " + authString);
return;
}
//产品列表
String key0="阿里云:产品:啤酒";
String key1="阿里云:产品:巧克力";
String key2="阿里云:产品:可乐";
String key3="阿里云:产品:口香糖";
String key4="阿里云:产品:牛肉干";
String key5="阿里云:产品:鸡翅";
final String[] aliyunProducts=new String[]{key0,key1,key2,key3,key4,key5};
//初始化,清除可能的已有旧数据
for (int i = 0; i < aliyunProducts.length; i++) {
jedis.del(aliyunProducts[i]);
}
//模拟用户购物
for (int i = 0; i < 5; i++) {//模拟多人次的用户购买行为
customersShopping(aliyunProducts,i,jedis);
}
System.out.println();
//利用ApsaraDB for Redis来输出各个商品间的关联关系
for (int i = 0; i < aliyunProducts.length; i++) {
System.out.println(">>>>>>>>>>与"+aliyunProducts[i]+"一起被购买的产品有<<<<<<<<<<<<<<<");
Set<Tuple> relatedList = jedis.zrevrangeWithScores(aliyunProducts[i], 0, -1);
for (Tuple item : relatedList) {
System.out.println("商品名称:"+item.getElement()+", 共同购买次数:"+Double.valueOf(item.getScore()).intValue());
}
System.out.println();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
jedis.quit();
jedis.close();
}
}
private static void customersShopping(String[] products, int i, Jedis jedis) {
//简单模拟3种购买行为,随机选取作为用户的购买选择
int bought=(int)(Math.random()*3);
if(bought==1){
//模拟业务逻辑:用户购买了如下产品
System.out.println("用户"+i+"购买了"+products[0]+","+products[2]+","+products[1]);
//将产品之间的关联情况记录到ApsaraDB for Redis的SortSet之中
jedis.zincrby(products[0], 1, products[1]);
jedis.zincrby(products[0], 1, products[2]);
jedis.zincrby(products[1], 1, products[0]);
jedis.zincrby(products[1], 1, products[2]);
jedis.zincrby(products[2], 1, products[0]);
jedis.zincrby(products[2], 1, products[1]);
}else if(bought==2){
//模拟业务逻辑:用户购买了如下产品
System.out.println("用户"+i+"购买了"+products[4]+","+products[2]+","+products[3]);
//将产品之间的关联情况记录到ApsaraDB for Redis的SortSet之中
jedis.zincrby(products[4], 1, products[2]);
jedis.zincrby(products[4], 1, products[3]);
jedis.zincrby(products[3], 1, products[4]);
jedis.zincrby(products[3], 1, products[2]);
jedis.zincrby(products[2], 1, products[4]);
jedis.zincrby(products[2], 1, products[3]);
}else if(bought==0){
//模拟业务逻辑:用户购买了如下产品
System.out.println("用户"+i+"购买了"+products[1]+","+products[5]);
//将产品之间的关联情况记录到ApsaraDB for Redis的SortSet之中
jedis.zincrby(products[5], 1, products[1]);
jedis.zincrby(products[1], 1, products[5]);
}
}
}
运行结果
在输入了正确的 ApsaraDB for Redis 实例访问地址和密码之后,运行以上 Java 程序,输出结果如下:
用户0购买了阿里云:产品:巧克力,阿里云:产品:鸡翅
用户1购买了阿里云:产品:牛肉干,阿里云:产品:可乐,阿里云:产品:口香糖
用户2购买了阿里云:产品:啤酒,阿里云:产品:可乐,阿里云:产品:巧克力
用户3购买了阿里云:产品:牛肉干,阿里云:产品:可乐,阿里云:产品:口香糖
用户4购买了阿里云:产品:巧克力,阿里云:产品:鸡翅
>>>>>>>>>>与阿里云:产品:啤酒一起被购买的产品有<<<<<<<<<<<<<<<
商品名称:阿里云:产品:巧克力, 共同购买次数:1
商品名称:阿里云:产品:可乐, 共同购买次数:1
>>>>>>>>>>与阿里云:产品:巧克力一起被购买的产品有<<<<<<<<<<<<<<<
商品名称:阿里云:产品:鸡翅, 共同购买次数:2
商品名称:阿里云:产品:啤酒, 共同购买次数:1
商品名称:阿里云:产品:可乐, 共同购买次数:1
>>>>>>>>>>与阿里云:产品:可乐一起被购买的产品有<<<<<<<<<<<<<<<
商品名称:阿里云:产品:牛肉干, 共同购买次数:2
商品名称:阿里云:产品:口香糖, 共同购买次数:2
商品名称:阿里云:产品:巧克力, 共同购买次数:1
商品名称:阿里云:产品:啤酒, 共同购买次数:1
>>>>>>>>>>与阿里云:产品:口香糖一起被购买的产品有<<<<<<<<<<<<<<<
商品名称:阿里云:产品:牛肉干, 共同购买次数:2
商品名称:阿里云:产品:可乐, 共同购买次数:2
>>>>>>>>>>与阿里云:产品:牛肉干一起被购买的产品有<<<<<<<<<<<<<<<
商品名称:阿里云:产品:可乐, 共同购买次数:2
商品名称:阿里云:产品:口香糖, 共同购买次数:2
>>>>>>>>>>与阿里云:产品:鸡翅一起被购买的产品有<<<<<<<<<<<<<<<
商品名称:阿里云:产品:巧克力, 共同购买次数:2
消息的发布与订阅
代码示例
消息发布者 (即 publish client)
package message.kvstore.aliyun.com;
import redis.clients.jedis.Jedis;
public class KVStorePubClient {
private Jedis jedis;//
public KVStorePubClient(String host,int port, String password){
jedis = new Jedis(host,port);
//KVStore的实例密码
String authString = jedis.auth(password);//password
if (!authString.equals("OK"))
{
System.err.println("AUTH Failed: " + authString);
return;
}
}
public void pub(String channel,String message){
System.out.println(" >>> 发布(PUBLISH) > Channel:"+channel+" > 发送出的Message:"+message);
jedis.publish(channel, message);
}
public void close(String channel){
System.out.println(" >>> 发布(PUBLISH)结束 > Channel:"+channel+" > Message:quit");
//消息发布者结束发送,即发送一个“quit”消息;
jedis.publish(channel, "quit");
}
}
消息订阅者 (即 subscribe client)
package message.kvstore.aliyun.com;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
public class KVStoreSubClient extends Thread{
private Jedis jedis;
private String channel;
private JedisPubSub listener;
public KVStoreSubClient(String host,int port, String password){
jedis = new Jedis(host,port);
//ApsaraDB for Redis的实例密码
String authString = jedis.auth(password);//password
if (!authString.equals("OK"))
{
System.err.println("AUTH Failed: " + authString);
return;
}
}
public void setChannelAndListener(JedisPubSub listener,String channel){
this.listener=listener;
this.channel=channel;
}
private void subscribe(){
if(listener==null || channel==null){
System.err.println("Error:SubClient> listener or channel is null");
}
System.out.println(" >>> 订阅(SUBSCRIBE) > Channel:"+channel);
System.out.println();
//接收者在侦听订阅的消息时,将会阻塞进程,直至接收到quit消息(被动方式),或主动取消订阅
jedis.subscribe(listener, channel);
}
public void unsubscribe(String channel){
System.out.println(" >>> 取消订阅(UNSUBSCRIBE) > Channel:"+channel);
System.out.println();
listener.unsubscribe(channel);
}
@Override
public void run() {
try{
System.out.println();
System.out.println("----------订阅消息SUBSCRIBE 开始-------");
subscribe();
System.out.println("----------订阅消息SUBSCRIBE 结束-------");
System.out.println();
}catch(Exception e){
e.printStackTrace();
}
}
}
消息监听者
package message.kvstore.aliyun.com;
import redis.clients.jedis.JedisPubSub;
public class KVStoreMessageListener extends JedisPubSub{
@Override
public void onMessage(String channel, String message) {
System.out.println(" <<< 订阅(SUBSCRIBE)< Channel:" + channel + " >接收到的Message:" + message );
System.out.println();
//当接收到的message为quit时,取消订阅(被动方式)
if(message.equalsIgnoreCase("quit")){
this.unsubscribe(channel);
}
}
@Override
public void onPMessage(String pattern, String channel, String message) {
// TODO Auto-generated method stub
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
// TODO Auto-generated method stub
}
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
// TODO Auto-generated method stub
}
@Override
public void onPUnsubscribe(String pattern, int subscribedChannels) {
// TODO Auto-generated method stub
}
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
// TODO Auto-generated method stub
}
}
示例主程序
package message.kvstore.aliyun.com;
import java.util.UUID;
import redis.clients.jedis.JedisPubSub;
public class KVStorePubSubTest {
//ApsaraDB for Redis的连接信息,从控制台可以获得
static final String host = "xxxxxxxxxx.m.cnhza.kvstore.aliyuncs.com";
static final int port = 6379;
static final String password="password";//password
public static void main(String[] args) throws Exception{
KVStorePubClient pubClient = new KVStorePubClient(host, port,password);
final String channel = "KVStore频道-A";
//消息发送者开始发消息,此时还无人订阅,所以此消息不会被接收
pubClient.pub(channel, "Aliyun消息1:(此时还无人订阅,所以此消息不会被接收)");
//消息接收者
KVStoreSubClient subClient = new KVStoreSubClient(host, port,password);
JedisPubSub listener = new KVStoreMessageListener();
subClient.setChannelAndListener(listener, channel);
//消息接收者开始订阅
subClient.start();
//消息发送者继续发消息
for (int i = 0; i < 5; i++) {
String message=UUID.randomUUID().toString();
pubClient.pub(channel, message);
Thread.sleep(1000);
}
//消息接收者主动取消订阅
subClient.unsubscribe(channel);
Thread.sleep(1000);
pubClient.pub(channel, "Aliyun消息2:(此时订阅取消,所以此消息不会被接收)");
//消息发布者结束发送,即发送一个“quit”消息;
//此时如果有其他的消息接收者,那么在listener.onMessage()中接收到“quit”时,将执行“unsubscribe”操作。
pubClient.close(channel);
}
}
运行结果
在输入了正确的 ApsaraDB for Redis 实例访问地址和密码之后,运行以上 Java 程序,输出结果如下。
>>> 发布(PUBLISH) > Channel:KVStore频道-A > 发送出的Message:Aliyun消息1:(此时还无人订阅,所以此消息不会被接收)
----------订阅消息SUBSCRIBE 开始-------
>>> 订阅(SUBSCRIBE) > Channel:KVStore频道-A
>>> 发布(PUBLISH) > Channel:KVStore频道-A > 发送出的Message:0f9c2cee-77c7-4498-89a0-1dc5a2f65889
<<< 订阅(SUBSCRIBE)< Channel:KVStore频道-A >接收到的Message:0f9c2cee-77c7-4498-89a0-1dc5a2f65889
>>> 发布(PUBLISH) > Channel:KVStore频道-A > 发送出的Message:ed5924a9-016b-469b-8203-7db63d06f812
<<< 订阅(SUBSCRIBE)< Channel:KVStore频道-A >接收到的Message:ed5924a9-016b-469b-8203-7db63d06f812
>>> 发布(PUBLISH) > Channel:KVStore频道-A > 发送出的Message:f1f84e0f-8f35-4362-9567-25716b1531cd
<<< 订阅(SUBSCRIBE)< Channel:KVStore频道-A >接收到的Message:f1f84e0f-8f35-4362-9567-25716b1531cd
>>> 发布(PUBLISH) > Channel:KVStore频道-A > 发送出的Message:746bde54-af8f-44d7-8a49-37d1a245d21b
<<< 订阅(SUBSCRIBE)< Channel:KVStore频道-A >接收到的Message:746bde54-af8f-44d7-8a49-37d1a245d21b
>>> 发布(PUBLISH) > Channel:KVStore频道-A > 发送出的Message:8ac3b2b8-9906-4f61-8cad-84fc1f15a3ef
<<< 订阅(SUBSCRIBE)< Channel:KVStore频道-A >接收到的Message:8ac3b2b8-9906-4f61-8cad-84fc1f15a3ef
>>> 取消订阅(UNSUBSCRIBE) > Channel:KVStore频道-A
----------订阅消息SUBSCRIBE 结束-------
>>> 发布(PUBLISH) > Channel:KVStore频道-A > 发送出的Message:Aliyun消息2:(此时订阅取消,所以此消息不会被接收)
>>> 发布(PUBLISH)结束 > Channel:KVStore频道-A > Message:quit
以上示例中仅演示了一个发布者与一个订阅者的情况,实际上发布者与订阅者都可以为多个,发送消息的频道(channel)也可以是多个,对以上代码稍作修改即可。
管道传输
代码示例1
性能对比
package pipeline.kvstore.aliyun.com;
import java.util.Date;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
public class RedisPipelinePerformanceTest {
static final String host = "xxxxxx.m.cnhza.kvstore.aliyuncs.com";
static final int port = 6379;
static final String password = "password";
public static void main(String[] args) {
Jedis jedis = new Jedis(host, port);
//ApsaraDB for Redis的实例密码
String authString = jedis.auth(password);// password
if (!authString.equals("OK")) {
System.err.println("AUTH Failed: " + authString);
jedis.close();
return;
}
//连续执行多次命令操作
final int COUNT=5000;
String key = "KVStore-Tanghan";
// 1 ---不使用pipeline操作---
jedis.del(key);//初始化key
Date ts1 = new Date();
for (int i = 0; i < COUNT; i++) {
//发送一个请求,并接收一个响应(Send Request and Receive Response)
jedis.incr(key);
}
Date ts2 = new Date();
System.out.println("不用Pipeline > value为:"+jedis.get(key)+" > 操作用时:" + (ts2.getTime() - ts1.getTime())+ "ms");
//2 ----对比使用pipeline操作---
jedis.del(key);//初始化key
Pipeline p1 = jedis.pipelined();
Date ts3 = new Date();
for (int i = 0; i < COUNT; i++) {
//发出请求 Send Request
p1.incr(key);
}
//接收响应 Receive Response
p1.sync();
Date ts4 = new Date();
System.out.println("使用Pipeline > value为:"+jedis.get(key)+" > 操作用时:" + (ts4.getTime() - ts3.getTime())+ "ms");
jedis.close();
}
}
运行结果1
在输入了正确的 ApsaraDB for Redis 实例访问地址和密码之后,运行以上 Java 程序,输出结果如下。从中可以看出使用 pipeline 的性能要快的多。
不用Pipeline > value为:5000 > 操作用时:5844ms
使用Pipeline > value为:5000 > 操作用时:78ms
代码示例2
在 Jedis 中使用管道(pipeline)时,对于响应数据(response)的处理有两种方式,请参考以下代码示例。
package pipeline.kvstore.aliyun.com;
import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
public class PipelineClientTest {
static final String host = "xxxxxxxx.m.cnhza.kvstore.aliyuncs.com";
static final int port = 6379;
static final String password = "password";
public static void main(String[] args) {
Jedis jedis = new Jedis(host, port);
// ApsaraDB for Redis的实例密码
String authString = jedis.auth(password);// password
if (!authString.equals("OK")) {
System.err.println("AUTH Failed: " + authString);
jedis.close();
return;
}
String key = "KVStore-Test1";
jedis.del(key);//初始化
// -------- 方法1
Pipeline p1 = jedis.pipelined();
System.out.println("-----方法1-----");
for (int i = 0; i < 5; i++) {
p1.incr(key);
System.out.println("Pipeline发送请求");
}
// 发送请求完成,开始接收响应
System.out.println("发送请求完成,开始接收响应");
List<Object> responses = p1.syncAndReturnAll();
if (responses == null || responses.isEmpty()) {
jedis.close();
throw new RuntimeException("Pipeline error: 没有接收到响应");
}
for (Object resp : responses) {
System.out.println("Pipeline接收响应Response: " + resp.toString());
}
System.out.println();
//-------- 方法2
System.out.println("-----方法2-----");
jedis.del(key);//初始化
Pipeline p2 = jedis.pipelined();
//需要先声明Response
Response<Long> r1 = p2.incr(key);
System.out.println("Pipeline发送请求");
Response<Long> r2 = p2.incr(key);
System.out.println("Pipeline发送请求");
Response<Long> r3 = p2.incr(key);
System.out.println("Pipeline发送请求");
Response<Long> r4 = p2.incr(key);
System.out.println("Pipeline发送请求");
Response<Long> r5 = p2.incr(key);
System.out.println("Pipeline发送请求");
try{
r1.get(); //此时还未开始接收响应,所以此操作会出错
}catch(Exception e){
System.out.println(" <<< Pipeline error:还未开始接收响应 >>> ");
}
// 发送请求完成,开始接收响应
System.out.println("发送请求完成,开始接收响应");
p2.sync();
System.out.println("Pipeline接收响应Response: " + r1.get());
System.out.println("Pipeline接收响应Response: " + r2.get());
System.out.println("Pipeline接收响应Response: " + r3.get());
System.out.println("Pipeline接收响应Response: " + r4.get());
System.out.println("Pipeline接收响应Response: " + r5.get());
jedis.close();
}
}
运行结果2
-----方法1-----
Pipeline发送请求
Pipeline发送请求
Pipeline发送请求
Pipeline发送请求
Pipeline发送请求
发送请求完成,开始接收响应
Pipeline接收响应Response: 1
Pipeline接收响应Response: 2
Pipeline接收响应Response: 3
Pipeline接收响应Response: 4
Pipeline接收响应Response: 5
-----方法2-----
Pipeline发送请求
Pipeline发送请求
Pipeline发送请求
Pipeline发送请求
Pipeline发送请求
<<< Pipeline error:还未开始接收响应 >>>
发送请求完成,开始接收响应
Pipeline接收响应Response: 1
Pipeline接收响应Response: 2
Pipeline接收响应Response: 3
Pipeline接收响应Response: 4
Pipeline接收响应Response: 5
事务处理
代码示例1:两个 client 操作不同的 key
package transcation.kvstore.aliyun.com;
import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
public class KVStoreTranscationTest {
static final String host = "xxxxxx.m.cnhza.kvstore.aliyuncs.com";
static final int port = 6379;
static final String password = "password";
//**注意这两个key的内容是不同的
static String client1_key = "KVStore-Transcation-1";
static String client2_key = "KVStore-Transcation-2";
public static void main(String[] args) {
Jedis jedis = new Jedis(host, port);
// ApsaraDB for Redis的实例密码
String authString = jedis.auth(password);//password
if (!authString.equals("OK")) {
System.err.println("认证失败: " + authString);
jedis.close();
return;
}
jedis.set(client1_key, "0");
//启动另一个thread,模拟另外的client
new KVStoreTranscationTest().new OtherKVStoreClient().start();
Thread.sleep(500);
Transaction tx = jedis.multi();//开始事务
//以下操作会集中提交服务器端处理,作为“原子操作”
tx.incr(client1_key);
tx.incr(client1_key);
Thread.sleep(400);//此处Thread的暂停对事务中前后连续的操作并无影响,其他Thread的操作也无法执行
tx.incr(client1_key);
Thread.sleep(300);//此处Thread的暂停对事务中前后连续的操作并无影响,其他Thread的操作也无法执行
tx.incr(client1_key);
Thread.sleep(200);//此处Thread的暂停对事务中前后连续的操作并无影响,其他Thread的操作也无法执行
tx.incr(client1_key);
List<Object> result = tx.exec();//提交执行
//解析并打印出结果
for(Object rt : result){
System.out.println("Client 1 > 事务中> "+rt.toString());
}
jedis.close();
}
class OtherKVStoreClient extends Thread{
@Override
public void run() {
Jedis jedis = new Jedis(host, port);
// ApsaraDB for Redis的实例密码
String authString = jedis.auth(password);// password
if (!authString.equals("OK")) {
System.err.println("AUTH Failed: " + authString);
jedis.close();
return;
}
jedis.set(client2_key, "100");
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Client 2 > "+jedis.incr(client2_key));
}
jedis.close();
}
}
}
运行结果1
Client 2 > 101
Client 2 > 102
Client 2 > 103
Client 2 > 104
Client 1 > 事务中> 1
Client 1 > 事务中> 2
Client 1 > 事务中> 3
Client 1 > 事务中> 4
Client 1 > 事务中> 5
Client 2 > 105
Client 2 > 106
Client 2 > 107
Client 2 > 108
Client 2 > 109
Client 2 > 110
代码示例2:两个 client 操作相同的 key
对以上的代码稍作改动,使得两个 client 操作同一个 key,其余部分保持不变。
... ...
//**注意这两个key的内容现在是相同的
static String client1_key = "KVStore-Transcation-1";
static String client2_key = "KVStore-Transcation-1";
... ...
运行结果2
Client 2 > 101
Client 2 > 102
Client 2 > 103
Client 2 > 104
Client 1 > 事务中> 105
Client 1 > 事务中> 106
Client 1 > 事务中> 107
Client 1 > 事务中> 108
Client 1 > 事务中> 109
Client 2 > 110
Client 2 > 111
Client 2 > 112
Client 2 > 113
Client 2 > 114
Client 2 > 115
更多推荐
已为社区贡献32条内容
所有评论(0)