Redis
Envoy 可以充当 Redis 代理,在集群中的实例之间分配命令。在这种模式下,Envoy 的目标是在一致性上保持可用性和分区容错。这是比较 Envoy 和 Redis 集群 时的关键点。Envoy 被设计为尽力而为的缓存,这意味着它不会尝试协调不一致的数据或维护集群成员资格的全局一致视图。它还支持根据其访问模式、驱逐或隔离要求将来自不同工作负载的命令路由到不同的上游集群。
Redis 项目提供了有关与 Redis 相关的分区的详细参考。请参阅“分区:如何在多个 Redis 实例之间拆分数据”。
Envoy Redis 的功能:
Redis 协议 编解码器。
基于哈希的分区。
Redis 事务支持。
Ketama 分布。
详细的命令统计信息。
主动和被动健康检查。
哈希标记。
前缀路由。
分离的下游客户端和上游服务器身份验证。
所有请求或仅写入请求的请求镜像。
控制 读取请求路由。这仅适用于 Redis 集群。
计划中的未来增强:
额外的计时统计信息。
断路器。
针对碎片化命令的请求折叠。
复制。
内置重试。
跟踪。
配置
有关过滤器配置详细信息,请参阅 Redis 代理过滤器 配置参考。
相应的集群定义应配置为使用 环形哈希负载均衡。
如果需要 主动健康检查,则应将集群配置为使用 自定义健康检查,并将其配置为 Redis 健康检查器。
如果需要被动健康检查,还应配置 异常检测。
出于被动健康检查的目的,连接超时、命令超时和连接关闭映射到 5xx。来自 Redis 的所有其他响应都被计为成功。
Redis 集群支持
Envoy 提供对 Redis 集群 的支持。
当使用 Envoy 作为 Redis 集群的 sidecar 代理时,服务可以使用任何语言实现的非集群 Redis 客户端连接到代理,就好像它是单个节点 Redis 实例一样。Envoy 代理将跟踪集群拓扑结构,并将命令发送到集群中正确的 Redis 节点,根据 规范。还可以将高级功能(如从副本读取)添加到 Envoy 代理,而不是更新每种语言中的 Redis 客户端。
Envoy 代理通过向集群中的随机节点发送周期性的 集群插槽 命令来跟踪集群的拓扑结构,并维护以下信息
已知节点列表。
每个分片的负责人。
进入或离开集群的节点。
Envoy 代理支持通过 cluster slots
命令响应中的 IP 地址和主机名来识别节点。如果无法解析负责人主机名,Envoy 将定期重试解析所有节点,直到成功。无法解析副本将简单地跳过该副本。另一方面,如果 enable_redirection 选项设置,并且收到包含主机名的 MOVED 或 ASK 响应,Envoy 将不会自动执行 DNS 查找,而是将错误原样传递给客户端。要让 Envoy 执行 DNS 查找并遵循重定向,您需要配置 DNS 缓存选项 dns_cache_config 在连接池设置下。有关如何为重定向启用 DNS 查找的配置示例,请参阅过滤器 配置参考。
有关拓扑结构配置详细信息,请参阅 Redis 集群 v3 API 参考。
每个 Redis 集群都有自己的额外的统计信息树,根节点为 cluster.<name>.redis_cluster.,包含以下统计信息
名称 |
类型 |
描述 |
---|---|---|
max_upstream_unknown_connections_reached |
计数器 |
在重定向后达到连接池的 max_upstream_unknown_connections 限制后,未创建到未知主机的上游连接的总次数 |
upstream_cx_drained |
计数器 |
在关闭之前,已将活动请求排干的上游连接的总数 |
upstream_commands.upstream_rq_time |
直方图 |
所有类型请求的上游请求时间的直方图 |
可以通过设置 enable_command_stats 启用每个集群的命令统计信息。
名称 |
类型 |
描述 |
---|---|---|
upstream_commands.[command].success |
计数器 |
针对特定 Redis 命令的成功请求总数 |
upstream_commands.[command].failure |
计数器 |
针对特定 Redis 命令的失败或取消的请求总数 |
upstream_commands.[command].total |
计数器 |
针对特定 Redis 命令的请求总数(成功和失败的总和) |
upstream_commands.[command].latency |
直方图 |
针对特定 Redis 命令的请求延迟 |
事务
支持事务 (MULTI)。它们的使用与普通的 Redis 没有区别:您使用 MULTI 启动事务,并使用 EXEC 执行事务。在事务中,仅支持 Envoy 支持的命令(见下文),并且是单键命令,即不支持 MGET 和 MSET。支持 DISCARD 命令。
在 Redis 集群模式下工作时,Envoy 将将事务中的所有命令中继到处理事务中第一个基于键的命令的节点。用户有责任确保事务中的所有键都映射到同一个哈希槽,因为命令不会被重定向。
支持的命令
在协议级别,支持管道。尽可能使用管道以获得最佳性能。
在命令级别,Envoy 仅支持可以可靠地哈希到服务器的命令。AUTH、PING 和 ECHO 是唯一的例外。如果已配置下游密码,则 Envoy 将在本地处理 AUTH,并且如果已配置密码,则在身份验证成功之前不会处理其他命令。如果设置了外部身份验证提供程序,Envoy 将改为将身份验证参数发送到外部服务,并根据身份验证响应采取行动。如果与外部身份验证一起设置了下游密码,则验证仍将在外部执行,而下游密码将用于上游身份验证。如果为集群配置了上游身份验证密码,则 Envoy 将在连接到上游服务器时透明地发出 AUTH 命令。Envoy 会立即使用 PONG 响应 PING。不允许对 PING 使用参数。Envoy 会立即使用命令参数响应 ECHO。所有其他支持的命令必须包含一个键。支持的命令在功能上与原始 Redis 命令相同,除了可能在失败场景中。
有关每个命令用法的详细信息,请参阅官方 Redis 命令参考。
命令 |
组 |
---|---|
AUTH |
身份验证 |
ECHO |
连接 |
PING |
连接 |
QUIT |
连接 |
DEL |
通用 |
DISCARD |
事务 |
DUMP |
通用 |
EXEC |
事务 |
EXISTS |
通用 |
EXPIRE |
通用 |
EXPIREAT |
通用 |
PERSIST |
通用 |
PEXPIRE |
通用 |
PEXPIREAT |
通用 |
PTTL |
通用 |
RESTORE |
通用 |
TOUCH |
通用 |
TTL |
通用 |
TYPE |
通用 |
UNLINK |
通用 |
GEOADD |
地理 |
GEODIST |
地理 |
GEOHASH |
地理 |
GEOPOS |
地理 |
GEORADIUS_RO |
地理 |
GEORADIUSBYMEMBER_RO |
地理 |
HDEL |
哈希 |
HEXISTS |
哈希 |
HGET |
哈希 |
HGETALL |
哈希 |
HINCRBY |
哈希 |
HINCRBYFLOAT |
哈希 |
HKEYS |
哈希 |
HLEN |
哈希 |
HMGET |
哈希 |
HMSET |
哈希 |
HSCAN |
哈希 |
HSET |
哈希 |
HSETNX |
哈希 |
HSTRLEN |
哈希 |
HVALS |
哈希 |
PFADD |
HyperLogLog |
PFCOUNT |
HyperLogLog |
LINDEX |
列表 |
LINSERT |
列表 |
LLEN |
列表 |
LPOP |
列表 |
LPUSH |
列表 |
LPUSHX |
列表 |
LRANGE |
列表 |
LREM |
列表 |
LSET |
列表 |
LTRIM |
列表 |
MULTI |
事务 |
RPOP |
列表 |
RPUSH |
列表 |
RPUSHX |
列表 |
PUBLISH |
发布订阅 |
EVAL |
脚本 |
EVALSHA |
脚本 |
SADD |
集合 |
SCARD |
集合 |
SISMEMBER |
集合 |
SMEMBERS |
集合 |
SPOP |
集合 |
SRANDMEMBER |
集合 |
SREM |
集合 |
SSCAN |
集合 |
WATCH |
字符串 |
ZADD |
排序集 |
ZCARD |
排序集 |
ZCOUNT |
排序集 |
ZINCRBY |
排序集 |
ZLEXCOUNT |
排序集 |
ZRANGE |
排序集 |
ZRANGEBYLEX |
排序集 |
ZRANGEBYSCORE |
排序集 |
ZRANK |
排序集 |
ZREM |
排序集 |
ZREMRANGEBYLEX |
排序集 |
ZREMRANGEBYRANK |
排序集 |
ZREMRANGEBYSCORE |
排序集 |
ZREVRANGE |
排序集 |
ZREVRANGEBYLEX |
排序集 |
ZREVRANGEBYSCORE |
排序集 |
ZREVRANK |
排序集 |
ZPOPMIN |
排序集 |
ZPOPMAX |
排序集 |
ZSCAN |
排序集 |
ZSCORE |
排序集 |
APPEND |
字符串 |
BITCOUNT |
字符串 |
BITFIELD |
字符串 |
BITPOS |
字符串 |
DECR |
字符串 |
DECRBY |
字符串 |
GET |
字符串 |
GETBIT |
字符串 |
GETDEL |
字符串 |
GETRANGE |
字符串 |
GETSET |
字符串 |
INCR |
字符串 |
INCRBY |
字符串 |
INCRBYFLOAT |
字符串 |
MGET |
字符串 |
MSET |
字符串 |
PSETEX |
字符串 |
SET |
字符串 |
SETBIT |
字符串 |
SETEX |
字符串 |
SETNX |
字符串 |
SETRANGE |
字符串 |
STRLEN |
字符串 |
XACK |
流 |
XADD |
流 |
XAUTOCLAIM |
流 |
XCLAIM |
流 |
XDEL |
流 |
XLEN |
流 |
XPENDING |
流 |
XRANGE |
流 |
XREVRANGE |
流 |
XTRIM |
流 |
BF.ADD |
布隆过滤器 |
BF.CARD |
布隆过滤器 |
BF.EXISTS |
布隆过滤器 |
BF.INFO |
布隆过滤器 |
BF.INSERT |
布隆过滤器 |
BF.LOADCHUNK |
布隆过滤器 |
BF.MADD |
布隆过滤器 |
BF.MEXISTS |
布隆过滤器 |
BF.RESERVE |
布隆过滤器 |
BF.SCANDUMP |
布隆过滤器 |
失败模式
如果 Redis 抛出错误,我们会将该错误作为命令的响应传递。Envoy 将 Redis 响应中的错误数据类型视为正常响应,并将其传递给调用方。
Envoy 也可以在响应客户端时生成自己的错误。
错误 |
含义 |
---|---|
无上游主机 |
环形哈希负载均衡器在为密钥选择的环形位置没有可用的健康主机。 |
上游故障 |
后端未在超时时间内响应或关闭了连接。 |
无效请求 |
由于数据类型或长度,命令被命令拆分器的第一阶段拒绝。 |
不支持的命令 |
Envoy 无法识别该命令,因此无法提供服务,因为它无法被哈希到后端服务器。 |
以 n 个错误完成 |
对响应进行求和的片段化命令(例如 DEL)将在收到任何错误时返回收到的错误总数。 |
上游协议错误 |
片段化命令收到意外数据类型或后端响应的响应不符合 Redis 协议。 |
命令参数数量错误 |
某些命令在 Envoy 中检查参数数量是否正确。 |
NOAUTH 要求身份验证。 |
由于已设置了下游身份验证密码或外部身份验证,并且客户端未成功进行身份验证,因此拒绝了该命令。 |
ERR 无效密码 |
身份验证命令由于密码无效而失败。 |
ERR <external-message> |
身份验证命令在外部身份验证提供程序上失败。 |
ERR 客户端发送了 AUTH,但未设置密码 |
收到了身份验证命令,但未配置下游身份验证密码或外部身份验证提供程序。 |
在 MGET 的情况下,每个无法获取的单个密钥都会生成一个错误响应。例如,如果我们获取五个密钥并且其中两个密钥的后端超时,我们将在每个密钥的值位置收到一个错误响应。
$ redis-cli MGET a b c d e
1) "alpha"
2) "bravo"
3) (error) upstream failure
4) (error) upstream failure
5) "echo"