Skip to content

Commit

Permalink
Redis demo
Browse files Browse the repository at this point in the history
Signed-off-by: huabing zhao <zhaohuabing@gmail.com>
  • Loading branch information
zhaohuabing committed May 8, 2023
1 parent b1d6dd9 commit 0df6697
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 6 deletions.
4 changes: 1 addition & 3 deletions content/zh/docs/v1.x/tutorials/redis/_index.md
Expand Up @@ -3,6 +3,4 @@ title: Redis 流量管理
weight: 2000
---

Redis 是一种高性能的键值数据库,通常被用作缓存、会话存储和消息代理等用途。Redis 可以部署为单机模式或者 Cluster 模式,但不同模式的客户端访问方式不同,这增加了应用使用 Redis 的开发成本。通过采用 Aeraki Mesh 的 Redis 流量管理功能,我们可以在不修改客户端代码的前提下切换后端的 Redis 部署模式,实现客户端无感知的 Redis Cluster 数据分片,并提供读写分离、流量镜像等高级流量管理功能。

比如您在测试集群使用一个小型的单实例的 Redis ,而在生产环境使用一个复杂而稳定的多副本实例的集群模式的Redis,通过 Aeraki Mesh,您将无需修改您应用的代码/配置,从而尽可能的保证了开发,预发布,线上环境相同([Dev/prod parity](https://12factor.net/dev-prod-parity))。
Redis 是一种高性能的键值数据库,通常被用作缓存、会话存储和消息代理等用途。Aeraki Mesh 提供了对 Redis 的流量管理能力,可以实现客户端无感知的 Redis Cluster 数据分片,按 key 将客户端请求路由到不同的 Redis 服务,读写分离,流量镜像,故障注入等高级流量管理功能。
15 changes: 13 additions & 2 deletions content/zh/docs/v1.x/tutorials/redis/cluster.md
Expand Up @@ -4,8 +4,18 @@ description:
weight: 03
---

Redis 可以部署为单机模式或者 [Cluster 模式](https://redis.io/docs/reference/cluster-spec/)。Cluster 模式相对于单机模式有以下优点:

例如,当我们通过 Redis 客户端访问 demo 中部署的 Redis cluster,会出现下面的访问错误:
* 支持水平扩展,可以通过增加节点数量可提高集群的性能和容量。
* 支持自动分区,可以将数据分散到不同的节点上,提高负载均衡和可用性。
* 具备一定的容错能力,即使某个节点宕机或网络出现问题,也可以自动进行故障转移和恢复。

Redis 要求采用不同的 client API 访问单机模式和 Cluster 模式。通过采用 Aeraki Mesh 的 Redis 流量管理功能,我们可以在不修改客户端代码的前提下切换后端的 Redis 部署模式,从而降低了应用开发成本。

比如在测试集群使用一个小型的单实例的 Redis ,而在生产环境使用一个复杂而稳定的多副本实例的集群模式的Redis,通过 Aeraki Mesh,我们无需修改应用的代码/配置,从而尽可能的保证了开发,预发布,线上环境相同([Dev/prod parity](https://12factor.net/dev-prod-parity))。


当我们通过 Redis 客户端访问 demo 中部署的 Redis cluster,会出现下面的访问错误:

```bash
kubectl exec -it `kubectl get pod -l app=redis-client -n redis -o jsonpath="{.items[0].metadata.name}"` -c redis-client -n redis -- redis-cli -h redis-cluster
Expand All @@ -14,7 +24,7 @@ redis-cluster:6379> set foo bar
(error) MOVED 15495 10.244.0.23:6379
```

这是因为 Redis 客户端采用了普通模式的 API,而 redis-cluster 服务则是一个 Redis Cluster,该 Cluster 由6台 Redis 服务器组成。通过配置 [RdisDestination](https://aeraki.net/zh/docs/v1.x/reference/redis/#RedisDestination)Aeraki Mesh 可以屏蔽掉这种差异
这是因为 Redis 客户端采用了普通模式的 API,而 redis-cluster 服务则是一个 Redis Cluster,该 Cluster 由 6 台 Redis 服务器组成。通过配置 [RdisDestination](https://aeraki.net/zh/docs/v1.x/reference/redis/#RedisDestination)我们可以屏蔽掉这种差异

```yaml
kubectl apply -f- <<EOF
Expand All @@ -41,3 +51,4 @@ redis-cluster:6379> set foo bar
OK
```

采用该方法,我们可以在应用业务规模逐渐扩张,单一 Redis 节点压力过大时,将系统中的 Redis 从单节点无缝迁移到集群模式。在集群模式下,不同 key 的数据被缓存在不同的数据分片中,我们可以增加分片中 Replica 节点的数量来对一个分片进行扩容,也可以增加分片个数来对整个集群进行扩展,以应对由于业务不断扩展而增加的数据压力。Aeraki Mesh 通过配置 Envoy 代理了 Redis 的流量,整个迁移和扩容过程对客户端完全透明,不会影响到线上业务的正常运行。
39 changes: 39 additions & 0 deletions content/zh/docs/v1.x/tutorials/redis/external-redis.md
@@ -0,0 +1,39 @@
---
title: 连接集群外 Redis 服务
description:
weight: 11
---

如果需要连接到一个集群外的 Redis 服务,我们可以采用一个[无选择器服务](https://kubernetes.io/docs/concepts/services-networking/service/#services-without-selectors)来定义该服务,然后创建一个 EndpointSlice 来指定该服务的外部地址。然后就可以像集群内服务一样使用 RedisService 和 Redis Destination 来对该服务进行流量管理了。

```yaml
kubectl apply -f- <<EOF
apiVersion: v1
kind: Service
metadata:
name: external-redis
namespace: redis
spec:
ports:
- name: tcp-redis
protocol: TCP
port: 6379
targetPort: 6379
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: external-redis
namespace: redis
labels:
kubernetes.io/service-name: external-redis
addressType: IPv4
ports:
- name: tcp-redis
port: 6379
protocol: TCP
endpoints:
- addresses:
- 10.244.0.26 # 集群外 Redis 实例的地址,比如云厂商提供的 Redis 服务。
EOF
```
2 changes: 1 addition & 1 deletion content/zh/docs/v1.x/tutorials/redis/fault-injection.md
@@ -1,7 +1,7 @@
---
title: Redis 故障注入
description:
weight: 05
weight: 10
---

采用 [RedisService](https://aeraki.net/zh/docs/v1.x/reference/redis/#RedisService) ,我们可以为 Redis 服务注入故障,该功能可以用于混沌测试等场景,以检验系统是否对于 Redis 故障进行了恰当的容错处理。
Expand Down
36 changes: 36 additions & 0 deletions content/zh/docs/v1.x/tutorials/redis/read-policy.md
@@ -0,0 +1,36 @@
---
title: Redis 读写分离
description:
weight: 05
---

在 Redis Cluster 中有多个分片(Slot),每个 Redis 分片中,通常有一个 Master 节点,一到多个 Slave(Replica)节点。Master 节点负责写操作,并将数据变化同步到 Slave 节点。Slave 节点作为备份节点,当 Master 不可用时,Slave 可以被选举成为新的 Master。由于 Slave 中保存了和 Master 中相同的数据,因此也可以响应客户端的读操作。

Aeraki Mesh 支持通过 [RedisService](https://aeraki.net/zh/docs/v1.x/reference/redis/#RedisService) 来为 Redis 设置不同的读策略:

* MASTER: 缺省的读模式。只从 Master 节点读取数据,当客户端要求数据强一致性时需要采用该模式。该模式对 Master 压力较大,在同一个分片内无法采用多个节点对读操作进行负载分担。
* PREFER_MASTER: 优先从 Master 节点读取数据,当 Master 节点不可用时,从 Replica 节点读取。
* REPLICA: 只从 Replica 节点读取数据,由于 Master 到 Replica 的数据复制过程是异步执行的,采用该方式有可能读取到过期的数据,因此适用于客户端对数据一致性要求不高的场景。该模式下可以采用多个 Replica 节点来分担来自客户端的读负载。
* PREFER_REPLICA: 优先从 Replica 节点读取数据,当 Replica 节点不可用时,从 Master 节点读取。
* ANY: 从任意节点读取数据。

如果客户端对缓存数据不要求强一致性,我们可以把读模式设置为 REPLICA。在该模式下,Master 节点只处理写操作,Slave 节点处理读操作,减少了 Master 节点的工作压力。随着业务的扩展,我们还可以在分片中增加更多的 Replica,以对读操作进行负载分担。

```yaml
kubectl apply -f- <<EOF
apiVersion: redis.aeraki.io/v1alpha1
kind: RedisService
metadata:
name: redis-cluster
namespace: redis
spec:
host:
- redis-cluster.redis.svc.cluster.local
settings:
readPolicy: REPLICA
redis:
- route:
host: redis-cluster.redis.svc.cluster.local
EOF
```

0 comments on commit 0df6697

Please sign in to comment.