ChaosBlade 项目指南:我是如何为社区贡献 Redis 故障场景

本文涉及的产品
性能测试 PTS,5000VUM额度
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: ChaosBlade 项目指南:我是如何为社区贡献 Redis 故障场景

作者:中国移动磐基 CMChaos 混沌工程团队,晁元宁(@Yuaninga),Reviewer of ChaosBlade


01 Redis 新特性介绍


1.1 背景

Redis 实际使用过程中会存在一些故障演练需求。例如:模拟触发所有 key 过期的极端故障场景、模拟主动触发 Redis 内存淘汰策略释放内存场景等等。


所以,根据以上故障演练需求,决定对 ChaosBlade 新增模拟 Redis 缓存过期实验和模拟 Redis 缓存内存限制实验,丰富 ChaosBlade 的混沌实验场景。


1.2 模拟Redis缓存过期实验

1.2.1 实验用途

模拟 Redis 缓存单个 key 缓存过期,触发缓存指定 key 过期的实验场景。

模拟 Redis 缓存所有 key 缓存过期,触发缓存所有 key 过期的极端异常场景。


1.2.2 实现原理

通过使用 go-redis 包中的 Golang 接口修改 Redis 缓存 Key 的过期时间,来实现模拟 Redis 缓存过期实验。


1.2.3 使用示例

# 设置key 1分钟后过期
# blade create redis cache-expire --addr 192.168.56.101:6379 --password 123456 --key test1 --expiry 1m
{"code":200,"success":true,"result":"b6a0f477b7fb1f4c"}
# 当要设置的过期时间大于key当前过期时间时,设置新过期时间。不存在则直接设置。
# blade create redis cache-expire --addr 192.168.56.101:6379 --password 123456 --key test1 --option GT --expiry 1m
{"code":200,"success":true,"result":"b6a0f477b7fb1f4c"}


1.2.4 官方文档

https://chaosblade.io/docs/experiment-types/host/redis/blade_create_redis_cache_expire


1.3 模拟 Redis 缓存内存限制实验

1.3.1 实验用途

通过修改 Redis 配置 maxmemory 的大小,模拟超出 Redis 缓存内存限制,从而触发 Redis 内存淘汰策略释放内存场景。


1.3.2 实现原理

通过使用 go-redis 包中的 Golang 接口修改 Redis maxmemory 配置,来实现模拟 Redis 缓存内存限制实验。


1.3.3 使用示例

# 设置Redis maxmemory为256M
# blade create redis cache-limit --addr 192.168.56.101:6379 --password 123456  --size 256M
{"code":200,"success":true,"result":"b6a0f477b7fb1f4c"}
# 设置Redis maxmemory为原值的50%
# blade create redis cache-limit --addr 192.168.56.101:6379 --password 123456  --percent 50
{"code":200,"success":true,"result":"b6a0f477b7fb1f4c"}


1.3.4 官方文档

https://chaosblade.io/docs/experiment-types/host/redis/blade_create_redis_cache_limit


02 开源贡献新人入门


2.1 概述

本部分以两个新增 Redis 故障场景为例,帮助刚接触 ChaosBlade 的社区同学快速入门开源贡献。开源贡献新人入门前置条件为:了解混沌工程相关知识和掌握 Golang 开发。


2.2 贡献流程图




2.3 第一步:分析故障演练需求,确认新增原子事件

确认新增原子事件之前,首先要分析故障演练的需求价值。根据上述第一部分的背景介绍,我们了解到 Redis 实际使用过程中会存在模拟触发所有 key 过期的极端故障场景、模拟主动触发 Redis 内存淘汰策略释放内存场景等等故障演练需求。


所以,基于存在的故障演练需求价值,确认新增模拟 Redis 缓存过期实验和模拟 Redis 缓存内存限制实验。


2.4 第二步:Fork 项目&本地拉取代码并创建 dev 分支



2.5 第三步:正式开始新原子事件开发

2.5.1 拉取 chaosblade-exec-middleware 项目代码

  • middleware 项目:
  • 包含 Nginx、Redis 等中间件相关实验核心代码。
  • 项目地址:


2.5.2 新建 redis 目录

该目录放置 Redis 原子事件核心代码

mkdir chaosblade-exec-middleware/exec/redis


2.5.3 新建 redis.go 文件

package redis
import (
  "github.com/chaosblade-io/chaosblade-spec-go/spec"
)
type RedisCommandSpec struct {
  spec.BaseExpModelCommandSpec
}
func (*RedisCommandSpec) Name() string {
  return "redis"
}
func (*RedisCommandSpec) ShortDesc() string {
  return "Redis experiment"
}
func (*RedisCommandSpec) LongDesc() string {
  return "Redis experiment"
}
func NewRedisCommandSpec() spec.ExpModelCommandSpec {
  return &RedisCommandSpec{
    spec.BaseExpModelCommandSpec{
      ExpActions: []spec.ExpActionCommandSpec{
        NewCacheExpireActionSpec(),
        NewCacheLimitActionSpec(),
      },
      ExpFlags: []spec.ExpFlagSpec{},
    },
  }
}


2.5.4 Redis 原子事件包含到 Model

  • model 目录位置:
  • chaosblade-exec-middleware/exec/model/ 目录
  • model 目录不同文件对应不同系统支持:
  • model_darwin.go 支持 Mac 系统
  • model_linux.go 支持 linux 系统
  • model_windows.go 支持 windows 系统
  • model 具体代码:

https://github.com/chaosblade-io/chaosblade-exec-middleware/tree/main/exec/model


package model
import (
  "github.com/chaosblade-io/chaosblade-exec-middleware/exec/nginx";
  "github.com/chaosblade-io/chaosblade-exec-middleware/exec/redis";
  "github.com/chaosblade-io/chaosblade-spec-go/spec";
)
// GetAllExpModels returns the experiment model specs in the project.
// Support for other project about chaosblade
func GetAllExpModels() []spec.ExpModelCommandSpec {
  return []spec.ExpModelCommandSpec{
    nginx.NewNginxCommandSpec(),
    redis.NewRedisCommandSpec(),
  }


2.5.5 Redis 原子事件包含到编译文件

  • 具体文件:
  • 添加 Redis 到 chaosblade-exec-middleware/build/spec.go
  • 具体代码:

https://github.com/chaosblade-io/chaosblade-exec-middleware/blob/main/build/spec.go


...
// getModels returns experiment models in the project
func getModels() *spec.Models {
  modelCommandSpecs := []spec.ExpModelCommandSpec{
    nginx.NewNginxCommandSpec(),
    redis.NewRedisCommandSpec(), // <== Redis相关 
  }
  specModels := make([]*spec.Models, 0)
  for _, modeSpec := range modelCommandSpecs {
    flagSpecs := append(modeSpec.Flags(), model.GetSSHExpFlags()...)
    modeSpec.SetFlags(flagSpecs)
    specModel := util.ConvertSpecToModels(modeSpec, spec.ExpPrepareModel{}, "host")
    specModels = append(specModels, specModel)
  }
  return util.MergeModels(specModels...)
}
...


2.5.6 开发具体原子事件

  • 缓存过期实验:

https://github.com/chaosblade-io/chaosblade-exec-middleware/blob/main/exec/redis/redis_cache_expire.go


  • 缓存内存限制实验:

https://github.com/chaosblade-io/chaosblade-exec-middleware/blob/main/exec/redis/redis_cache_limit.go


2.6 第四步:使用 Goland 本地调试,有 bug 或优化再次开发调试

2.6.1 搭建准备 Redis 服务

  • 参考相关文档:


2.6.2 使用 Goland Debug

  • 官方文档:    


1) 打开 main.go 点击三角按钮,选择 Modify Run  Configuration...



2) 修改 debug 配置:详细使用可以查看 Goland 官方文档



3) 执行 Debug 操作:详细使用可以查看 Goland 官方文档



2.7 第五步:本地编译并替换测试环境旧编译文件

2.7.1 参考官方文档执行编译

1) 如果在 mac 系统上,编译当前系统的版本,请执行:

make build_darwin


2) 如果想在 mac 系统上,编译 linux 系统 x86 架构版本,请执行:

make build_linux


3) 如果想在 mac 系统上,编译 linux 系统 arm 架构版本,请执行:

make build_linux_arm


说明:其他系统编译说明参考官方文档

https://github.com/chaosblade-io/chaosblade/blob/master/README_CN.md


2.7.2 编译后文件存放在 target 目录中



2.7.3 测试环境替换为新编译文件

将测试服务器 chaosblade 目录以下文件替换为新版本:


  • chaosblade-1.7.2/bin/chaos_middleware
  • chaosblade-1.7.2/yaml/chaosblade-middleware-spec-1.7.2.yaml


2.8 第六步:测试环境测试直至通过

2.8.1 测试模拟缓存过期实验

1) 执行实验:

#示例1:expire a key
blade create redis cache-expire --addr 192.168.56.101:6379 --password 123456 --key test1 --expiry 1m
#示例2:expire all keys only when the new expiry is greater than current one
blade create redis cache-expire --addr 192.168.56.101:6379 --password 123456 --option GT --expiry 1m


2) 验证实验结果:

# 实验前
192.168.56.101:6379> set  test1 test2
OK
192.168.56.101:6379> get test1
"test2"
192.168.56.101:6379> expire test1 3000
(integer) 1
192.168.56.101:6379> ttl test1
(integer) 2924
# 实验后
# blade create redis cache-expire --addr 192.168.56.101:6379 --password 123456 --option GT --expiry 1m
192.168.56.101:6379> ttl test1
(integer) 58


2.8.2 测试模拟缓存内存限制实验

1) 执行实验:

# 示例:set maxmemory to 256M
blade create redis cache-limit --addr 192.168.56.101:6379 --password 123456  --size 256M


2) 验证实验结果:

# 实验前
192.168.56.101:6379> config get maxmemory
1) "maxmemory"
2) "0"
# 实验后
# blade create redis cache-limit --addr 192.168.56.101:6379 --password 123456  --size 256M
192.168.56.101:6379> config get maxmemory
1) "maxmemory"
2) "256000000"


说明:测试有 bug 或待优化,重复开发、调试和编译步骤


2.9 第七步:使用 dev 分支创建和提交 PR

2.9.1 推送本地 dev 分支 GitHub 远程

# commit
git commit -s  -m "add 2 redis experiments"
# push
git push origin dev


2.9.2  登录 GitHub 使用 dev 分支创建和提交 PR



2.9.3  提交 PR 后准备官网 chaosblade 文档贡献

https://chaosblade.io/docs/1.7.0/community/docs/


2.10 第八步:PR 审查直至审查通过



2.11 第九步:PR 合并至 main,新增原子事件贡献成功



联系我们:

ChaosBlade 官方网址:

https://chaosblade.io/


ChaosBlade Github:

https://github.com/chaosblade-io/chaosblade


ChaosBlade 钉钉社区交流群:23177705

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
监控 NoSQL Java
场景题:百万数据插入Redis有哪些实现方案?
场景题:百万数据插入Redis有哪些实现方案?
40 1
场景题:百万数据插入Redis有哪些实现方案?
|
1月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
77 6
|
10天前
|
NoSQL Java API
springboot项目Redis统计在线用户
通过本文的介绍,您可以在Spring Boot项目中使用Redis实现在线用户统计。通过合理配置Redis和实现用户登录、注销及统计逻辑,您可以高效地管理在线用户。希望本文的详细解释和代码示例能帮助您在实际项目中成功应用这一技术。
21 3
|
8天前
|
缓存 NoSQL 网络协议
【Azure Redis】因为Redis升级引发了故障转移后的问题讨论
3:对于Redis的Server Load指标,每秒创建连接数的并发值,是否有建议呢? 【答】:为了避免将缓存推到 100% 服务器负载,建议将连接创建速率保持在每秒 30 个以下。
|
1月前
|
存储 缓存 NoSQL
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
62 4
|
1月前
|
存储 消息中间件 NoSQL
【redis】redis的特性和主要应用场景
【redis】redis的特性和主要应用场景
107 1
|
1月前
|
存储 NoSQL Java
Spring Boot项目中使用Redis实现接口幂等性的方案
通过上述方法,可以有效地在Spring Boot项目中利用Redis实现接口幂等性,既保证了接口操作的安全性,又提高了系统的可靠性。
39 0
|
4月前
|
NoSQL Redis 索引
Redis 中ZSET数据类型命令使用及对应场景总结
Redis 中ZSET数据类型命令使用及对应场景总结
89 2
|
4月前
|
NoSQL Redis
Redis set数据类型命令使用及应用场景使用总结
Redis set数据类型命令使用及应用场景使用总结
47 1
|
4月前
|
NoSQL Linux Redis
Redis性能优化问题之想确认Redis延迟变大是否因为fork耗时导致的,如何解决
Redis性能优化问题之想确认Redis延迟变大是否因为fork耗时导致的,如何解决