云数据库Redis版与原生Redis完全兼容,支持所有原生Redis支持的客户端,连接数据库的方式也基本相同,您可以根据自身应用特点选用任何兼容Redis协议的客户端程序。
前提条件
根据客户端程序的部署位置,完成下述操作:
客户端程序部署位置 | 需完成的操作 |
ECS实例(推荐) |
|
本地 |
注意事项
如何获取连接信息
在使用客户端程序连接Redis实例时,通常您需要获取以下信息并设置在代码中:
需获取的信息 | 获取方式 |
实例的连接地址 | Redis实例支持多种连接地址,推荐使用专有网络连接,可获得更高的安全性和更低的网络延迟。更多信息,请参见查看连接地址。 |
端口号 | 端口号默认为6379,您也可以自定义端口号。具体操作,请参见修改连接地址或端口。 |
实例的账号(部分客户端程序无需设置) | Redis实例默认会创建一个以实例ID命名的账号(例如r-bp10noxlhcoim2****),您也可以创建一个新的账号并赋予权限。更多信息,请参见创建与管理账号。 |
账号的密码 | 根据选取账号的不同,密码的填写格式有一定区别:
说明
|
常见客户端示例
关于Redis支持的客户端列表请参见Redis Clients。
本文仅列举常见客户端程序连接Redis的代码示例,帮助您快速连接,如需查看通过客户端程序连接Tair(Redis企业版)的代码示例,请参见通过客户端程序连接Tair。
Jedis
下载并安装Jedis客户端。
根据业务需求选择连接方式。
打开Eclipse客户端,创建一个Project并配置pom文件,具体内容如下.
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>Latest version</version> <type>jar</type> <scope>compile</scope> </dependency>
根据Jedis客户端版本,在Project中输入下述代码,然后根据注释提示修改代码。
Jedis 4.3.0
JedisPoolConfig config = new JedisPoolConfig(); // 最大空闲连接数,需自行评估,不超过Redis实例的最大连接数。 config.setMaxIdle(200); // 最大连接数,需自行评估,不超过Redis实例的最大连接数。 config.setMaxTotal(300); config.setTestOnBorrow(false); config.setTestOnReturn(false); // 分别将host和password的值替换为实例的连接地址、密码。 String host = "r-bp10noxlhcoim2****.redis.rds.aliyuncs.com"; String password = "testaccount:Rp829dlwa"; JedisPool pool = new JedisPool(config, host, 6379, 3000, password); Jedis jedis = null; try { jedis = pool.getResource(); // 执行相关操作,示例如下。 jedis.set("foo", "bar"); System.out.println(jedis.get("foo")); jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike"); System.out.println(jedis.zrange("sose", 0, -1)); } catch (Exception e) { // 超时或其他异常处理。 e.printStackTrace(); } finally { if (jedis != null) { jedis.close(); } } pool.destroy(); // 当应用退出,需销毁资源时,调用此方法。此方法会断开连接、释放资源。
Jedis 2.4.0及以下
JedisPoolConfig config = new JedisPoolConfig(); // 最大空闲连接数,需自行评估,不超过Redis实例的最大连接数。 config.setMaxIdle(200); // 最大连接数,需自行评估,不超过Redis实例的最大连接数。 config.setMaxTotal(300); config.setTestOnBorrow(false); config.setTestOnReturn(false); // 分别将host和password的值替换为实例的连接地址、密码。 String host = "r-bp10noxlhcoim2****.redis.rds.aliyuncs.com"; String password = "testaccount:Rp829dlwa"; JedisPool pool = new JedisPool(config, host, 6379, 3000, password); Jedis jedis = null; boolean broken = false; try { jedis = pool.getResource(); // 执行相关操作,示例如下。 jedis.set("foo", "bar"); String foobar = jedis.get("foo"); jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike"); Set < String > sose = jedis.zrange("sose", 0, -1); } catch(Exception e) { broken = true; } finally { if(broken) { pool.returnBrokenResource(jedis); } else if(jedis != null) { pool.returnResource(jedis); } } pool.destroy(); // 当应用退出,需销毁资源时,调用此方法。此方法会断开连接、释放资源。
Jedis单连接(不推荐,单次超时后无法自动恢复)
import redis.clients.jedis.Jedis; public class Jedistest { public static void main(String[] args) { try { String host = "r-bp10noxlhcoim2****.redis.rds.aliyuncs.com";//实例的连接地址。 int port = 6379; Jedis jedis = new Jedis(host, port); // 鉴权信息。 jedis.auth("password");//password String key = "redis"; String value = "aliyun-redis"; // select db默认为0。 jedis.select(1); // Set一个key。 jedis.set(key, value); System.out.println("Set Key " + key + " Value: " + value); // Get 设置进去的key。 String getvalue = jedis.get(key); System.out.println("Get Key " + key + " ReturnValue: " + getvalue); jedis.quit(); jedis.close(); } catch (Exception e) { e.printStackTrace(); } } }
运行上述Project,在Eclipse的控制台输出如下运行结果则表示您已成功连接至云原生内存数据库Tair。
bar [bike, car]
在使用Jedis的过程中,如果设置了一些不合理的参数或错误使用某些功能可能会引起报错,关于如何排查,请参见常见报错。
PhpRedis
下载并安装PhpRedis客户端。
在PHP编辑器中输入下述代码,然后根据注释提示修改代码。
本示例的PHP版本为8.2.1、PhpRedis版本为5.3.7。
<?php /* 分别将host和port的值替换为实例的连接地址、端口号。 */ $host = "r-bp10noxlhcoim2****.redis.rds.aliyuncs.com"; $port = 6379; /* 分别将user和pwd的值替换为实例的账号和密码 */ $user = "testaccount"; $pwd = "Rp829dlwa"; $redis = new Redis(); if ($redis->connect($host, $port) == false) { die($redis->getLastError()); } if ($redis->auth([$user, $pwd]) == false) { die($redis->getLastError()); } /* 完成认证后可执行数据库操作,下述代码为您提供SET与GET的使用示例。 */ if ($redis->set("foo", "bar") == false) { die($redis->getLastError()); } $value = $redis->get("foo"); echo $value; ?>
执行上述代码。
说明常见报错与解决方法:
Cannot assign requested address
,原因分析及排查方法,请参见使用短连接访问Redis出现“Cannot assign requested address”错误。redis protocol error, got ' ' as reply type byte
,请升级您的PhpRedis客户端版本,参见GitHub issue。
redis-py
下载并安装redis-py客户端。
在Python编辑器中输入下述代码,然后根据注释提示修改代码。
本示例的Python版本为3.9、redis-py版本为4.4.1。
#!/usr/bin/env python #-*- coding: utf-8 -*- import redis # 分别将host和port的值替换为实例的连接地址、端口号。 host = 'r-bp10noxlhcoim2****.redis.rds.aliyuncs.com' port = 6379 # 将pwd的值替换为实例的密码。 pwd = 'testaccount:Rp829dlwa' r = redis.Redis(host=host, port=port, password=pwd) # 连接建立后即可执行数据库操作,下述代码为您提供SET与GET的使用示例。 r.set('foo', 'bar') print(r.get('foo'))
执行上述代码。
Spring Data Redis
下载并安装Spring Data Redis客户端。
在Spring Data Redis编辑器中输入下述代码,然后根据注释提示修改代码。
本示例的Spring Data Redis版本为2.7.6。
Spring Data Redis With Jedis(推荐)
@Bean JedisConnectionFactory redisConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("host", port); JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); // 最大连接数, 根据业务需要设置,不能超过实例规格规定的最大连接数。 jedisPoolConfig.setMaxTotal(30); // 最大空闲连接数, 根据业务需要设置,不能超过实例规格规定的最大连接数。 jedisPoolConfig.setMaxIdle(20); // 关闭 testOn[Borrow|Return],防止产生额外的PING。 jedisPoolConfig.setTestOnBorrow(false); jedisPoolConfig.setTestOnReturn(false); JedisClientConfiguration jedisClientConfiguration = JedisClientConfiguration.builder().usePooling().poolConfig( jedisPoolConfig).build(); return new JedisConnectionFactory(config, jedisClientConfiguration); }
Spring Data Redis With Lettuce (不推荐)
@Bean LettuceConnectionFactory redisConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("host", 6379); return new LettuceConnectionFactory(config); }
说明Spring Data Redis 2.0版本后默认使用Lettuce作为驱动,如您希望切换至Jedis,需要排除Lettuce并主动引入Jedis依赖,示例如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <artifactId>lettuce-core</artifactId> <groupId>io.lettuce</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>Latest version</version> </dependency>
执行上述代码。
C或C++
下载并安装C客户端。
在C或C++编辑器中输入下述代码,然后根据注释提示修改代码。
本示例的HiRedis版本为1.1.0。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <hiredis.h> int main(int argc, char **argv) { unsigned int j; redisContext *c; redisReply *reply; if (argc < 4) { printf("Usage: example r-bp10noxlhcoim2****.redis.rds.aliyuncs.com 6379 instance_id password\n"); exit(0); } const char *hostname = argv[1]; const int port = atoi(argv[2]); const char *instance_id = argv[3]; const char *password = argv[4]; struct timeval timeout = { 1, 500000 }; // 1.5 seconds c = redisConnectWithTimeout(hostname, port, timeout); if (c == NULL || c->err) { if (c) { printf("Connection error: %s\n", c->errstr); redisFree(c); } else { printf("Connection error: can't allocate redis context\n"); } exit(1); } /* AUTH */ reply = redisCommand(c, "AUTH %s", password); printf("AUTH: %s\n", reply->str); freeReplyObject(reply); /* PING server */ reply = redisCommand(c,"PING"); printf("PING: %s\n", reply->str); freeReplyObject(reply); /* Set a key */ reply = redisCommand(c,"SET %s %s", "foo", "hello world"); printf("SET: %s\n", reply->str); freeReplyObject(reply); /* Set a key using binary safe API */ reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); printf("SET (binary API): %s\n", reply->str); freeReplyObject(reply); /* Try a GET and two INCR */ reply = redisCommand(c,"GET foo"); printf("GET foo: %s\n", reply->str); freeReplyObject(reply); reply = redisCommand(c,"INCR counter"); printf("INCR counter: %lld\n", reply->integer); freeReplyObject(reply); /* again ... */ reply = redisCommand(c,"INCR counter"); printf("INCR counter: %lld\n", reply->integer); freeReplyObject(reply); /* Create a list of numbers, from 0 to 9 */ reply = redisCommand(c,"DEL mylist"); freeReplyObject(reply); for (j = 0; j < 10; j++) { char buf[64]; snprintf(buf,64,"%d",j); reply = redisCommand(c,"LPUSH mylist element-%s", buf); freeReplyObject(reply); } /* Let's check what we have inside the list */ reply = redisCommand(c,"LRANGE mylist 0 -1"); if (reply->type == REDIS_REPLY_ARRAY) { for (j = 0; j < reply->elements; j++) { printf("%u) %s\n", j, reply->element[j]->str); } } freeReplyObject(reply); /* Disconnects and frees the context */ redisFree(c); return 0; }
编译上述代码。
gcc -o example -g example.c -I /usr/local/include/hiredis -lhiredis
测试运行,完成连接。
example r-bp10noxlhcoim2****.redis.rds.aliyuncs.com 6379 instance_id password
.NET
如果您的Redis实例为集群架构或读写分离架构,且需要执行切换或选择多数据库的操作(SELECT命令),您必须先将cluster_compat_enable
参数设置为0(即关闭原生Redis Cluster语法兼容),然后重启客户端应用,否则将提示报错: Multiple databases are not supported on this server; cannot switch to database
。具体操作,请参见设置实例参数。
下载并安装StackExchange.Redis客户端。
重要不推荐使用ServiceStack.Redis或CSRedis客户端:
若使用ServiceStack.Redis客户端时遇到客户端的相关问题,您需要向该公司购买相关技术支持服务。
CSRedis客户端的原开发者已停止维护。
在StackExchange.Redis编辑器中输入下述代码,然后根据注释提示修改下述示例代码。
本示例的StackExchange.Redis版本为2.5.61。
using StackExchange.Redis; // 分别设置实例的连接地址、端口号和密码。 private static ConfigurationOptions configurationOptions = ConfigurationOptions.Parse("r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379,password=testaccount:Rp829dlwa,connectTimeout=2000"); //the lock for singleton private static readonly object Locker = new object(); //singleton private static ConnectionMultiplexer redisConn; //singleton public static ConnectionMultiplexer getRedisConn() { if (redisConn == null) { lock (Locker) { if (redisConn == null || !redisConn.IsConnected) { redisConn = ConnectionMultiplexer.Connect(configurationOptions); } } } return redisConn; }
说明ConfigurationOptions是StackExchange.Redis的核心,它被整个应用程序共享和重用,应该设置为单例,相关参数设置说明,请参见ConfigurationOptions。
由于
GetDatabase()
返回的对象是轻量级的,每次用的时候从ConnectionMultiplexer对象中获取即可。redisConn = getRedisConn(); var db = redisConn.GetDatabase();
通过客户端程序操作常见的数据结构,示例如下:
String
//set get string strKey = "hello"; string strValue = "world"; bool setResult = db.StringSet(strKey, strValue); Console.WriteLine("set " + strKey + " " + strValue + ", result is " + setResult); //incr string counterKey = "counter"; long counterValue = db.StringIncrement(counterKey); Console.WriteLine("incr " + counterKey + ", result is " + counterValue); //expire db.KeyExpire(strKey, new TimeSpan(0, 0, 5)); Thread.Sleep(5 * 1000); Console.WriteLine("expire " + strKey + ", after 5 seconds, value is " + db.StringGet(strKey)); //mset mget KeyValuePair<RedisKey, RedisValue> kv1 = new KeyValuePair<RedisKey, RedisValue>("key1", "value1"); KeyValuePair<RedisKey, RedisValue> kv2 = new KeyValuePair<RedisKey, RedisValue>("key2", "value2"); db.StringSet(new KeyValuePair<RedisKey, RedisValue>[] {kv1,kv2}); RedisValue[] values = db.StringGet(new RedisKey[] {kv1.Key, kv2.Key}); Console.WriteLine("mget " + kv1.Key.ToString() + " " + kv2.Key.ToString() + ", result is " + values[0] + "&&" + values[1]);
Hash
string hashKey = "myhash"; //hset db.HashSet(hashKey,"f1","v1"); db.HashSet(hashKey,"f2", "v2"); HashEntry[] values = db.HashGetAll(hashKey); //hgetall Console.Write("hgetall " + hashKey + ", result is"); for (int i = 0; i < values.Length;i++) { HashEntry hashEntry = values[i]; Console.Write(" " + hashEntry.Name.ToString() + " " + hashEntry.Value.ToString()); } Console.WriteLine();
List
//list key string listKey = "myList"; //rpush db.ListRightPush(listKey, "a"); db.ListRightPush(listKey, "b"); db.ListRightPush(listKey, "c"); //lrange RedisValue[] values = db.ListRange(listKey, 0, -1); Console.Write("lrange " + listKey + " 0 -1, result is "); for (int i = 0; i < values.Length; i++) { Console.Write(values[i] + " "); } Console.WriteLine();
Set
//set key string setKey = "mySet"; //sadd db.SetAdd(setKey, "a"); db.SetAdd(setKey, "b"); db.SetAdd(setKey, "c"); //sismember bool isContains = db.SetContains(setKey, "a"); Console.WriteLine("set " + setKey + " contains a is " + isContains );
Sorted Set
string sortedSetKey = "myZset"; //sadd db.SortedSetAdd(sortedSetKey, "xiaoming", 85); db.SortedSetAdd(sortedSetKey, "xiaohong", 100); db.SortedSetAdd(sortedSetKey, "xiaofei", 62); db.SortedSetAdd(sortedSetKey, "xiaotang", 73); //zrevrangebyscore RedisValue[] names = db.SortedSetRangeByRank(sortedSetKey, 0, 2, Order.Ascending); Console.Write("zrevrangebyscore " + sortedSetKey + " 0 2, result is "); for (int i = 0; i < names.Length; i++) { Console.Write(names[i] + " "); } Console.WriteLine();
node-redis
下载并安装node-redis客户端。
在node-redis客户端中输入下述代码,然后根据注释提示修改代码。
本示例的Node.js版本为19.4.0、node-redis版本为4.5.1。
import { createClient } from 'redis'; // 分别设置实例的端口号、连接地址、账号、密码 const client = createClient({ // redis[s]://[[username][:password]@][host][:port][/db-number] url: 'redis://testaccount:Rp829dlwa@r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379' }); client.on('error', (err) => console.log('Redis Client Error', err)); await client.connect(); await client.set('foo', 'bar'); const value = await client.get('foo'); console.log("get foo: %s", value); await client.disconnect();
说明若提示
SyntaxError: Cannot use import statement outside a module
,请将.js
文件的后缀改为.mjs
,并在调用时增加--experimental-modules
选项,例如node --experimental-modules redis.mjs
。执行上述代码。
Go-redis
下载并安装Go-Redis客户端。
在Go-redis编辑器中输入下述代码,然后根据注释提示修改代码。
本示例的Go版本为1.18.5、Go-redis版本为8.11.5。
package main import ( "github.com/go-redis/redis" "fmt" ) func ExampleClient() { client := redis.NewClient(&redis.Options{ // 替换为实例的连接地址和端口 Addr: "r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379", // 替换为实例的密码 Password: "testaccount:Rp829dlwa", DB: 0, // use default DB }) // 下述代码为您提供SET与GET的使用示例。 err := client.Set("foo", "bar", 0).Err() if err != nil { panic(err) } val, err := client.Get("foo").Result() if err != nil { panic(err) } fmt.Println("set : foo -> ", val) } func main() { ExampleClient() }
执行上述代码。
Lettuce
Lettuce支持完整Redis API的同步和异步通信使用。由于Lettuce客户端在请求多次请求超时后,不再自动重连,当云数据库Redis因故障等因素导致代理或者数据库节点发生切换时,可能出现连接超时导致无法重连。为避免此类风险,推荐您使用Jedis客户端。
更多信息,请参见Lettuce #2082。