Redis¶
Envoy 可以作为 Redis 代理,在集群的实例间对命令进行分区。在这种模式下, Envoy 的目标是在一致性前提下维护可用性和分区容错。这是 Envoy 和 Redis 集群 关键差异。 Envoy 被设计为尽力而为的缓存,意味着它不会试图协调不一致的数据或者保持全局集群成员一致视图。它还支持基于不同的访问模式,驱逐或隔离需求,将命令从不同的工作负载路由到不同的上游集群。
Redis 项目中提供了与 Redis 分区相关的全面参考。请查看 “分区: 如何在多个 Redis 实例间分片?”。
Envoy Redis 特性:
Redis 协议 <https://redis.io/topics/protocol>_ 编解码
基于哈希的分区
Ketama 分布式一致性哈希算法
命令统计详情
主动和被动健康检查
哈希标记
路由前缀
下游客户端和上游服务器分别进行身份验证
针对所有请求或写请求监控
管控 读请求路由. 仅适用于 Redis 集群。
计划的未来增强功能:
额外的时间统计
熔断
对分散的命令进行请求折叠
复制
内置重试
追踪
配置¶
过滤器配置细节,请查看 Redis 代理过滤器 配置参考。
一致的集群定义应该配置 环哈希负载均衡。
如果使用:ref:主动健康检查 <arch_overview_health_checking>,集群需要配置 :ref:` 自定义健康检查 <envoy_v3_api_field_config.core.v3。HealthCheck.custom_health_check>` 其配置为 Redis 健康检查。
如果使用被动健康检查,需要配置 :ref: 异常检测 <arch_overview_outlier_detection>。
为了进行被动健康检查,需要将连接超时、命令超时和连接关闭都映射到 5xx 响应,而来自 Redis 的所有其他响应都视为成功。
Redis 集群支持(实验性)¶
Envoy 目前为 Redis 集群 提供实验性支持。
服务可以使用以任意语言实现的非集群 Redis 客户端连接到代理,就像它是一个单节点 Redis 实例一样。Envoy 代理将跟踪集群拓扑,并根据 规范 向集群中正确的 Redis 节点发送命令。还可以将高级功能(例如从副本中读取)添加到 Envoy 代理中,而不用更新每种语言的 Redis 客户端。
Envoy 通过定期向集群中的随机节点发送 cluster slot cluster slots 命令来跟踪群集的拓扑,并维护以下信息:
已知节点列表
每个分片的主节点
集群节点的增加或减少
更多拓扑配置细节,请查看 Redis 集群 v2 API 参考.
每个 Redis 集群都有它自己的额外信息统计树,根路径为 cluster.<name>.redis_cluster. 包含以下统计:
名称 |
类型 |
描述 |
---|---|---|
max_upstream_unknown_connections_reached |
Counter |
重定向达到连接池 max_upstream_unknown_connections 限制后,上游到未知主机连接未创建的总数 |
upstream_cx_drained |
Counter |
连接关闭前已退出的活跃请求的上游连接总数 |
upstream_commands.upstream_rq_time |
Histogram |
所有类型请求的上游请求时间直方图 |
每个集群的命令统计可以通过设置 enable_command_stats 开启:
名称 |
类型 |
描述 |
---|---|---|
upstream_commands.[command].success |
Counter |
特定 Redis 命令的请求成功总数 |
upstream_commands.[command].failure |
Counter |
特定 Redis 命令的请求失败或撤销总数 |
upstream_commands.[command].total |
Counter |
特定 Redis 命令的请求总数(成功和失败数总和) |
upstream_commands.[command].latency |
Histogram |
特定 Redis 命令的延迟 |
支持的命令¶
在协议级别支持管道。MULTI (事务块)不支持。尽可能使用管道以获得最佳性能。
在命令级别,Envoy 仅支持可以被可靠地哈希到一台服务器的命令。只有 AUTH 和 PING 命令例外。如果下游配置了密码,Envoy 将在本地处理 AUTH,并且在配置了密码之后,在身份认证成功之前,Envoy 不会处理任何其他命令。如果上游为整个集群配置了密码,Envoy 将在连接到上游服务器后透明地发送 AUTH 命令。Envoy 会立即为 PING 命令返回 PONG。PING 命令不接受参数。所有其他支持的参数必须包含一个 key。除了执行失败的情况外,所有支持的命令功能与原始 Redis 命令完全一致。
每个命令的使用详情请参考官方文档 Redis 命令参考。
Command |
Group |
---|---|
AUTH |
Authentication |
PING |
Connection |
DEL |
Generic |
DUMP |
Generic |
EXISTS |
Generic |
EXPIRE |
Generic |
EXPIREAT |
Generic |
PERSIST |
Generic |
PEXPIRE |
Generic |
PEXPIREAT |
Generic |
PTTL |
Generic |
RESTORE |
Generic |
TOUCH |
Generic |
TTL |
Generic |
TYPE |
Generic |
UNLINK |
Generic |
GEOADD |
Geo |
GEODIST |
Geo |
GEOHASH |
Geo |
GEOPOS |
Geo |
GEORADIUS_RO |
Geo |
GEORADIUSBYMEMBER_RO |
Geo |
HDEL |
Hash |
HEXISTS |
Hash |
HGET |
Hash |
HGETALL |
Hash |
HINCRBY |
Hash |
HINCRBYFLOAT |
Hash |
HKEYS |
Hash |
HLEN |
Hash |
HMGET |
Hash |
HMSET |
Hash |
HSCAN |
Hash |
HSET |
Hash |
HSETNX |
Hash |
HSTRLEN |
Hash |
HVALS |
Hash |
LINDEX |
List |
LINSERT |
List |
LLEN |
List |
LPOP |
List |
LPUSH |
List |
LPUSHX |
List |
LRANGE |
List |
LREM |
List |
LSET |
List |
LTRIM |
List |
RPOP |
List |
RPUSH |
List |
RPUSHX |
List |
EVAL |
Scripting |
EVALSHA |
Scripting |
SADD |
Set |
SCARD |
Set |
SISMEMBER |
Set |
SMEMBERS |
Set |
SPOP |
Set |
SRANDMEMBER |
Set |
SREM |
Set |
SSCAN |
Set |
ZADD |
Sorted Set |
ZCARD |
Sorted Set |
ZCOUNT |
Sorted Set |
ZINCRBY |
Sorted Set |
ZLEXCOUNT |
Sorted Set |
ZRANGE |
Sorted Set |
ZRANGEBYLEX |
Sorted Set |
ZRANGEBYSCORE |
Sorted Set |
ZRANK |
Sorted Set |
ZREM |
Sorted Set |
ZREMRANGEBYLEX |
Sorted Set |
ZREMRANGEBYRANK |
Sorted Set |
ZREMRANGEBYSCORE |
Sorted Set |
ZREVRANGE |
Sorted Set |
ZREVRANGEBYLEX |
Sorted Set |
ZREVRANGEBYSCORE |
Sorted Set |
ZREVRANK |
Sorted Set |
ZPOPMIN |
Sorted Set |
ZPOPMAX |
Sorted Set |
ZSCAN |
Sorted Set |
ZSCORE |
Sorted Set |
APPEND |
String |
BITCOUNT |
String |
BITFIELD |
String |
BITPOS |
String |
DECR |
String |
DECRBY |
String |
GET |
String |
GETBIT |
String |
GETRANGE |
String |
GETSET |
String |
INCR |
String |
INCRBY |
String |
INCRBYFLOAT |
String |
MGET |
String |
MSET |
String |
PSETEX |
String |
SET |
String |
SETBIT |
String |
SETEX |
String |
SETNX |
String |
SETRANGE |
String |
STRLEN |
String |
失败模式¶
如果 Redis 抛出错误,我们会将这个错误作为响应传递给命令。Envoy 将 Redis 返回的响应与错误数据类型视为正常响应,并将它传递给调用者。
Envoy 也可以在响应中生成它自己的错误返回给客户端。
错误 |
含义 |
---|---|
no upstream host |
没有上游主机,环状哈希负载均衡器在为键选择环形位置上没有可用的健康主机 |
upstream failure |
上游失败,后端未在超时期限内响应或关闭连接 |
invalid request |
无效请求,因为数据类型或长度的原因,命令在命令拆分器的第一阶段被拒绝 |
unsupported command |
不支持的命令,该命令 Envoy 不能识别,所以不能被哈希到一个后端主机,无法响应 |
finished with n errors |
返回多个错误,分段的命令将会组合多个响应(例如 DEL 命令),如果收到任何错误,将返回接收到的错误总数 |
upstream protocol error |
上游协议错误,分段命令收到一个意外的数据类型或后端响应的数据不符合 Redis 协议 |
wrong number of arguments for command |
命令参数数量错误,Envoy 中的命令参数数量检查未通过 |
NOAUTH Authentication required. |
NOAUTH 需要认证,因下游设置了认证密码且客户端没有认证成功,导致命令被拒绝 |
ERR invalid password |
ERR 密码无效,因密码无效导致命令认证失败 |
ERR Client sent AUTH, but no password is set |
ERR 客户端发送了 AUTH,但未设置密码,收到认证命令,但没有配置下游认证密码 |
使用 MGET 时,每个无法获取的 key 将会生成一个错误响应。例如:如果我们获取 5 个 key 的值,其中 2 个出现后端超时,我们将会获得每个值的错误响应信息。
$ redis-cli MGET a b c d e
1) "alpha"
2) "bravo"
3) (error) upstream failure
4) (error) upstream failure
5) "echo"