阿里云云数据库Tair(兼容Redis)深度对接使用指南
1. Tair是什么:重新定义云原生内存数据库
阿里云云数据库Tair(兼容Redis)是一款兼容开源Redis协议标准、提供内存加硬盘混合存储的数据库服务。它基于高可靠双机热备架构及可平滑扩展的集群架构,充分满足高吞吐、低延迟及弹性变配的业务需求。Tair并非简单的Redis托管服务,而是阿里云在深度理解Redis内核与云原生架构基础上打造的企业级内存数据库产品。
Tair与原生Redis的关系可以用一句话概括:完全兼容,全面超越。云数据库Tair(兼容Redis)实例与原生Redis完全兼容,支持所有原生Redis支持的客户端,连接数据库的方式也基本相同。这意味着开发者现有的Redis代码、客户端工具和运维脚本几乎可以无缝迁移到Tair上。但Tair的价值远不止于兼容——它在性能、扩展能力、数据结构和企业级功能上都实现了对开源Redis的超越。
需要先登录阿里云控制台,点击:阿里云控制台
1.1 Tair的核心优势
Tair(企业版)内存型实例采用多线程模型,读写性能达到同规格Redis开源版实例的3倍。这意味着在相同的实例规格下,Tair能够承载3倍于开源Redis的操作吞吐量。对于高并发、低延迟的业务场景,这一性能优势具有决定性的意义。
Tair提供了多种实例类型以满足不同业务需求:内存型(TairDRAM)适合并发量大、读写热点多、对性能要求极高的场景;持久内存型(TairSCM)提供命令级持久化能力;混合存储型(TairPersistent)整合内存与磁盘优势,在提供高速读写的同时满足数据持久化需求。此外,Tair Serverless KV Redis兼容版实例具备自动扩缩容以及按实际访问量计费的能力,高峰时自动扩容保障业务平稳,使用期间仅按实际访问量计费,有效降低使用成本。
Tair(企业版)集成了多个自研的扩展数据结构,包括TairString、TairHash、TairZset、GIS、Bloom、Doc、TS、Cpc、Roaring、Search和Vector等,从多方面扩展Redis的适用性。这些数据结构能够帮助开发者精简大量代码并提高业务整体性能。
2. 对接前的准备工作:创建实例与网络配置
在开始对接Tair之前,需要完成实例创建、网络打通和白名单设置三个关键步骤。
2.1 创建Tair实例
登录阿里云控制台,进入云数据库Tair产品页面,点击创建实例。在创建过程中需要选择:地域(建议与业务服务器在同一地域)、实例规格(根据预期QPS和数据量选择)、版本(推荐选择Tair企业版以使用扩展数据结构)、架构类型(标准版、集群版或读写分离版)。集群架构下分片数量为2至256分片,分片规格为1GB至64GB,整体容量可达2GB至16TB。
2.2 打通网络连接
客户端与Tair实例的网络互通是连接成功的关键前提。最推荐的方式是将业务部署在同一个专有网络VPC下的ECS实例中。Tair具备极强的性能,如果部署位置过远(例如通过公网连接),网络延迟将极大影响读写性能。判断是否在同一专有网络的方法很简单:进入ECS控制台查看实例详情中的专有网络信息,再进入Tair控制台查看实例详情中的专有网络信息,对比两者是否一致。
如果客户端位于本地数据中心,可以通过高速通道物理专线将本地IDC与云端的Tair实例连接起来。如果必须从公网连接,需要先设置IP白名单,然后申请公网连接地址。但需要特别注意:由于网络延迟和带宽限制等因素,连接公网地址时可能会出现不稳定的情况。
2.3 设置IP白名单
只有在白名单中的IP才能访问Tair实例。设置方法如下:访问实例列表,选择地域后点击目标实例ID,在左侧导航栏单击白名单设置。根据客户端位置添加对应白名单:对于同一VPC内的ECS,可以选择加载ECS私网IP的方式批量添加;对于ACK集群,可以添加ACK对应的安全组;对于公网客户端,需要获取客户端的公网IP地址(可通过curl ifconfig.me命令获取)并添加到白名单中。
如果客户端的IP是动态变化的,可以设置IP段(CIDR模式),例如10.23.12.0/24表示10.23.12.0至10.23.12.255的IP范围。也可以通过脚本监测IP变动后调用修改IP白名单的API自动更新。
2.4 获取连接信息
完成上述配置后,在实例详情页的连接信息区域可以获取连接地址(Hostname)和端口号(Port)。默认端口为6379。实例的VIP地址在维护、变配时可能发生变化,建议使用实例提供的域名地址进行连接。
3. 客户端选型与连接实践
由于Tair完全兼容Redis协议,所有支持Redis的客户端都可以连接Tair。但为了获得最佳体验和官方技术支持,阿里云针对不同开发语言推荐了特定的客户端版本。
3.1 Java客户端:Jedis与TairJedis
对于Java开发者,Jedis是官方推荐的首选客户端。Jedis 4.x及以上版本推荐使用4.4.0及以上,Jedis 2.x或3.x推荐使用3.10.0及以上。如果使用Tair(企业版)内存型实例,强烈推荐使用TairJedis客户端——这是阿里云基于Jedis开发的Tair增强型客户端,支持新数据结构的封装类。TairJedis不仅兼容所有Jedis的功能,还额外支持Tair扩展数据结构的专用命令。
下面是一个使用Jedis连接池连接Tair的完整示例:
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class TairConnectionExample {
public static void main(String[] args) {
// 创建连接池配置
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(200); // 最大连接数
poolConfig.setMaxIdle(50); // 最大空闲连接数
poolConfig.setMinIdle(10); // 最小空闲连接数
poolConfig.setMaxWaitMillis(3000); // 获取连接的最大等待时间
poolConfig.setTestOnBorrow(true); // 获取连接时测试可用性
poolConfig.setTestOnReturn(true); // 归还连接时测试可用性
// 创建连接池
String host = "r-xxxxxxxxxxxx.redis.rds.aliyuncs.com";
int port = 6379;
String password = "your_password";
JedisPool jedisPool = new JedisPool(poolConfig, host, port, 3000, password);
// 使用连接池获取连接并执行操作
try (Jedis jedis = jedisPool.getResource()) {
// 设置一个键值对
jedis.set("user:1001:name", "张三");
// 获取键值
String name = jedis.get("user:1001:name");
System.out.println("用户名称: " + name);
// 设置带过期时间的键
jedis.setex("session:token:abc123", 3600, "active");
// 使用Hash结构存储用户信息
jedis.hset("user:1001", "age", "25");
jedis.hset("user:1001", "city", "杭州");
String age = jedis.hget("user:1001", "age");
System.out.println("用户年龄: " + age);
} catch (Exception e) {
e.printStackTrace();
} finally {
jedisPool.close();
}
}
}如果使用TairJedis,依赖配置如下:
<dependency>
<groupId>com.aliyun.tair</groupId>
<artifactId>tairjedis-sdk</artifactId>
<version>最新版本</version>
</dependency>3.2 Python客户端:redis-py与tair-py
Python开发者可以使用标准的redis-py库连接Tair。如果需要使用Tair的扩展数据结构,可以安装tair-py依赖。安装命令:pip3 install redis 或 pip3 install tair。
下面是一个使用redis-py连接Tair的完整示例:
import redis
# 创建Tair连接
def get_tair_connection():
client = redis.StrictRedis(
host='r-xxxxxxxxxxxx.redis.rds.aliyuncs.com',
port=6379,
password='your_password',
decode_responses=True, # 自动解码返回的字节为字符串
socket_connect_timeout=5,
socket_timeout=5,
retry_on_timeout=True
)
return client
def main():
client = get_tair_connection()
# 测试连接
try:
client.ping()
print("Tair连接成功!")
except Exception as e:
print(f"连接失败: {e}")
return
# 基本操作
client.set('user:1002:name', '李四')
name = client.get('user:1002:name')
print(f'用户名称: {name}')
# 设置带过期时间的键
client.setex('session:token:def456', 1800, 'valid')
# Hash操作
client.hset('user:1002', mapping={'age': '30', 'city': '上海', 'position': '工程师'})
user_info = client.hgetall('user:1002')
print(f'用户信息: {user_info}')
# List操作 - 模拟消息队列
client.rpush('task:queue', 'task1', 'task2', 'task3')
task = client.lpop('task:queue')
print(f'消费任务: {task}')
# 使用pipeline批量操作
pipe = client.pipeline()
pipe.incr('counter:visits')
pipe.expire('counter:visits', 86400)
pipe.get('counter:visits')
results = pipe.execute()
print(f'访问次数: {results[2]}')
if __name__ == '__main__':
main()使用tair-py连接并操作扩展数据结构的示例:
from tair import Tair
from tair import ResponseError
# 创建Tair客户端(支持扩展数据结构)
client = Tair(
host='r-xxxxxxxxxxxx.redis.rds.aliyuncs.com',
port=6379,
password='your_password',
decode_responses=True
)
# 使用TairString - 带版本号的String
try:
# CAS命令:只有版本号匹配时才更新
client.cas('counter:order', '100', '200') # 如果当前值为100则更新为200
# CAD命令:删除指定版本的值
client.cad('counter:order', '200')
except ResponseError as e:
print(f'操作失败: {e}')
# 使用TairHash - 支持Field级别过期
client.exhset('user:devices', mapping={'phone': 'iPhone15', 'pad': 'iPadPro'})
client.expexpire('user:devices', 'phone', 3600) # phone字段1小时后过期3.3 其他语言客户端推荐
对于C/C++开发者,推荐使用Hiredis 1.2.0及以上版本。对于C#开发者,推荐使用StackExchange.Redis 2.7.20及以上版本。对于Go、Node.js、PHP等语言,选择社区活跃的Redis客户端即可。
4. Tair扩展数据结构深度解析
Tair企业版的最大亮点之一是提供了丰富的扩展数据结构,这些数据结构能够显著简化复杂场景下的业务开发。
4.1 TairString:带版本号的字符串
TairString是一种带版本号的string类型数据结构,在Redis String的基础上增加了版本控制能力。它支持CAS(Compare-And-Swap)和CAD(Compare-And-Delete)命令,可实现简洁高效的高性能分布式锁。此外,TairString还在Redis String加减功能的基础上支持了边界设置,可以将INCRBY、INCRBYFLOAT的结果限制在指定范围内。
4.2 TairHash:支持Field级过期的Hash
TairHash支持为Hash中的每个field单独设置过期时间和版本。这一特性在多设备登录管理场景中尤为有用——可以将用户ID设置为Key、设备类型设置为Field、用户Token设置为Value,同时可对每个Field设置不同的过期时间。相比之下,原生Redis的Hash只能对整个Key设置过期时间,无法精细化控制单个字段。
4.3 TairZset:多维排行榜
TairZset可实现256个维度的double类型分值排序,提供普通排行榜和多维排行榜的能力。在游戏排行榜、商品热销榜等场景中,TairZset可以同时按多个维度(如销量、评分、时间)进行排序,大幅简化业务代码。
4.4 其他扩展数据结构
TairGIS支持地理信息系统相关接口,支持点、线、面的查询以及包含、被包含、相交等多种关系判断。TairDoc是一种文档类型的数据结构,支持JSON标准。TairBloom提供布隆过滤器功能,TairTS提供时序数据处理能力,TairSearch支持全文检索,TairVector支持向量检索。合理利用这些modules能够显著提升业务功能的开发速度并简化代码逻辑。
5. 开发运维规范与性能优化
阿里云结合多年的运维经验,从业务部署、Key设计、SDK、命令、运维管理等维度总结了Tair的开发运维规范。
5.1 Key设计规范
避免使用大Key和大Value。Tair的高并发能力不等同于高吞吐能力,将大Value存储在Tair里不仅不会显著提升访问性能,反而会影响Tair整体的服务能力。在集群架构下,大Key还会引发数据倾斜,导致部分分片节点负载过高而其他分片闲置。
合理设置Key的过期时间。Tair数据过期后并不会立即被删除,而是依赖主动删除和被动删除两种机制。主动删除是后台进程定期扫描并删除部分过期Key,被动删除是在访问时发现Key已过期再删除。这意味着过期数据可能在一段时间内仍然占据内存空间。建议在业务低峰期通过系统运维管理(OOS)配置定期任务,扫描所有Key并立即删除已过期的Key,释放内存占用。
避免使用KEYS命令进行全库扫描。KEYS命令会消耗大量网络资源且极易引发线程阻塞。应使用SCAN命令进行分批遍历。
5.2 连接管理规范
使用连接池管理连接。Jedis本身是线程不安全的,频繁创建和销毁连接会有性能损耗,应使用连接池代替直连。连接池的核心参数需要根据业务特点合理配置:最大连接数(maxTotal)应根据业务并发量设置,最大空闲连接数(maxIdle)和最小空闲连接数(minIdle)应平衡资源占用与连接创建开销,最大等待时间(maxWaitMillis)应根据业务容忍的延迟设置。
关注客户端版本。非必要尽量不使用小众SDK或小众SDK版本,应选择社区活跃、已知缺陷数相对较少的稳定版本。及时关注对应SDK的版本更新动态。
5.3 命令使用规范
避免在线上环境使用危险命令如FLUSHALL、FLUSHDB、KEYS等。使用通配符、Lua并发、1对多的PUBSUB、热点Key等会大量消耗计算资源。Streaming慢消费和大Key会占用大量存储资源。
如果使用集群架构,需要开启cluster语法兼容以支持JedisCluster等客户端访问Cluster节点。开启后可以将自建的Redis Cluster无缝迁移到阿里云上,无需修改业务代码。
5.4 性能优化实践
启用数据压缩可以显著降低内存占用。实测显示,启用Snappy压缩可使内存占用降低40%,对数值型数据效果尤其显著。利用Tair的冷热分离能力,通过配置L2缓存将长期未访问的数据自动降级,可进一步优化内存使用。
针对集群架构,需要关注数据倾斜问题。如果发现个别数据分片节点的性能指标远高于其他分片,应检查是否存在热点Key或大Key,并通过拆分大Key、调整Key分布等方式解决。
6. 数据迁移:从自建Redis到Tair
阿里云数据传输服务DTS支持将自建Redis或第三方云Redis的数据迁移到Tair,可以在不停服的情况下平滑完成数据库迁移。
DTS支持从自建Redis集群同步至云数据库Tair(兼容Redis)实例,目标实例支持的版本为4.0或5.0版本。对于从AWS Elasticache或MemoryDB迁移至Tair的场景,推荐通过DTS实现平滑迁移。DTS支持全量数据迁移和增量数据迁移,增量迁移会根据使用时长产生费用。
迁移过程中,DTS会在源库中插入一个前缀为DTS_REDIS_TIMESTAMP_HEARTBEAT的Key用于记录更新时间点。如果源库为集群架构,DTS会在各个shard上均插入该Key,迁移过程中会自动过滤该Key。
7. 监控报警与运维管理
Tair提供了丰富的监控指标,包括CPU使用率、内存使用率、平均时延、QPS等。通过云监控服务,可以对这些指标设置报警规则。
在Tair控制台的报警设置页面可以查看当前实例的监控项。也可以进入云监控控制台创建报警规则:当监控项超过设定阈值时(例如实例的CPU使用率大于90%),系统将自动发送报警通知。报警方式支持短信、邮件、钉钉等多种渠道。
针对Tair全球多活实例,可以设置子实例间同步延迟的监控报警。当监控指标达到报警条件时,云监控自动发送报警通知,帮助及时定位和处理故障。
8. Serverless KV:免运维的弹性选择
Tair Serverless KV Redis兼容版实例是面向不想关心规格配置的用户的理想选择。实例会自动适应应用程序的RCU(读操作)和WCU(写操作)以及存储用量需求,根据工作负载自动进行扩缩容。
存储空间范围为0至25TB,能够根据用量自动扩缩容。每个RCU表示单个客户端访问4KB的数据。每个WCU表示单个客户端写入512B的数据。实例初始性能峰值为30000 RCU/s和20000 WCU/s,当流量超过性能峰值的60%时开始自动扩容。最大容量为25TB,最大连接数为400000个。
需要注意的是,扩容期间超过原峰值部分的请求会进行排队(与开源Redis行为一致)。如果希望被限流的请求直接返回错误而非排队等待,可以通过客户端配置进行调整。
9. 常见问题解答
问题1:Tair和阿里云Redis社区版有什么区别?
Tair是阿里云自研的企业级内存数据库产品,完全兼容Redis协议,但在性能、扩展数据结构和企业级功能上全面超越了开源Redis。Tair(企业版)内存型实例采用多线程模型,性能可达同规格Redis开源版的3倍。同时Tair提供了TairString、TairHash、TairZset等10余种自研扩展数据结构。
问题2:我应该选择Jedis还是TairJedis?
如果使用Tair(企业版)内存型实例并需要使用扩展数据结构,强烈推荐使用TairJedis。TairJedis基于Jedis开发,兼容所有Jedis功能的同时额外支持Tair扩展数据结构的专用命令。如果只使用标准Redis命令,Jedis完全够用。
问题3:如何排查Tair连接超时或无法连接的问题?
首先检查IP白名单是否正确配置。其次确认客户端与Tair实例的网络是否互通——最可靠的方式是将业务部署在同一个VPC下。如果使用公网连接,需要确认已申请公网连接地址。最后检查密码是否正确。
问题4:Tair的内存用满了怎么办?
Tair内存占满时会触发数据逐出策略,默认策略为volatile-lru,即从已设置过期时间的Key中清除最少使用的Key。建议通过拆分大Key、合理设置过期策略、升级实例规格等方法解决问题。也可以在业务低峰期通过OOS定期清理过期Key释放内存。
问题5:如何从自建Redis迁移到Tair且不停服?
使用阿里云数据传输服务DTS可以实现不停服迁移。DTS支持全量数据迁移和增量数据迁移。在全量迁移的基础上,DTS将源库的增量更新实时同步到目标库中。配置时需确保源库可正常执行PSYNC或SYNC命令。
问题6:Tair支持哪些编程语言的客户端?
Tair兼容Redis协议,支持所有Redis客户端。Java推荐Jedis或TairJedis;Python推荐redis-py或tair-py;C/C++推荐Hiredis;C#推荐StackExchange.Redis。其他语言选择社区活跃的Redis客户端即可。



