dot 快速的未来即将在您所在的城市举办活动。

加入我们参加 Redis 发布活动

如何将 Redis 集成到您的持续集成和持续交付 (CI/CD) 流程中

本周早些时候,我写了一篇关于 Redis 如何通过帮助他们安全地发布新功能并在需要时以最小的影响回滚这些功能,来帮助分布式开发团队的文章。今天,我将深入探讨有关功能切换、功能上下文和错误日志如何增强您的持续集成和持续交付 (CI/CD) 流程的具体细节。

使用 Redis 进行功能切换

“功能切换”是一组模式,可以帮助您快速安全地向应用程序用户交付新功能。功能切换也称为功能标志、功能位或功能切换。

Redis - Figure 5: Feature toggles stored in redis_ent_1
图 5:存储在 redis_ent_1 中的功能切换

在 Redis Enterprise 中,使用本机 Redis HASH 数据结构非常容易构建切换策略。

使用 Redis-cli 或您选择的语言的任何 Redis 客户端,您可以创建具有设置切换标志、发布号、开发人员姓名、覆盖标志等的值的 HASH 键(例如“useNewAlgorithm”)。

使用这种类型的数据结构,您可以在 Redis 中设置任意数量的功能切换。然后,您的应用程序可以在运行时查找这些切换,以检查实时标志状态和元数据。

使用这种类型的数据结构,您可以在 Redis 中设置任意数量的功能切换。然后,您的应用程序可以在运行时查找这些切换,以检查实时标志状态和元数据。

HSET useNewAlgorithm toggle "True" releaseNum "2.5" fingerprint "John S" override "fb-user"
HGETALL useNewAlgorithm

响应

 1) "name"
 2) "John Smith"
 3) "email"
 4) "john.smith@jsmith.com"
 5) "phone"
 6) "718-111-2222"
 7) "authType"
 8) "fb-user"
 9) "creationTime"
10) "Fri Apr 5 09:51:05 GMT-5"

使用 Redis 进行功能上下文

“功能上下文”是基于特定上下文(例如发出请求的用户)的动态路由决策。它可以直接从会话管理中读取,而会话管理是 Redis 的一个流行用例。

图 6:存储在 redis_ent_1 中的功能上下文(会话存储)

同样,使用本机 Redis HASH 数据结构和 Redis-cli(或任何 Redis 客户端),您可以在键中存储会话数据,并在运行时查找以读取实时值。

例如,在图 6 中,“sessionAuthorized”方法使用存储在会话键中的“authType”值检查用户是否已使用 Facebook 登录。

HSET session:4156e021:1234 name "John Smith" email "john.smith@jsmith.com" phone "718-111-2222" authType "fb-user" creationTime "Fri Apr 5 09:51:05 GMT-5"

HGETALL session:4156e021:1234

响应

 1) "name"
 2) "John Smith"
 3) "email"
 4) "john.smith@jsmith.com"
 5) "phone"
 6) "718-111-2222"
 7) "authType"
 8) "fb-user"
 9) "creationTime"
10) "Fri Apr 5 09:51:05 GMT-5"

随时阅读有关会话存储的更多信息 此处

使用 Redis 创建快速可搜索的错误数据库

“错误数据库”是用于存储运行时报告的错误的集中式数据存储。错误可以存储在 RediSearch 中,RediSearch 是一个功能强大的文本搜索和二级索引引擎,提供快速搜索以查找它们。Redis Enterprise 附带的 RediSearch 版本支持跨多个服务器进行扩展,使其能够轻松扩展到数百台服务器上的数十亿个文档。

您可以将运行时报告的任何错误推送到 RediSearch,以及来自功能切换和功能上下文的其他有用信息,这将有助于分类过程。

使用 Redis-cli 或任何 Redis 客户端 创建搜索索引。

例如,让我们创建一个名为“toggle_errors_db”的新索引,用于存储使用功能切换时报告的所有错误。

FT.CREATE toggle_errors_db SCHEMA toggleName TEXT toggleValue TEXT fingerPrint TEXT exceptionBody TEXT

让我们使用以下格式添加一些数据到该索引,使用一个新的键:useNewAlgorithm:03-12-19-10-32-05

FT.ADD toggle_errors_db useNewAlgorithm:03-12-19-10-32-05 1.0 FIELDS toggleName 'useNewAlgorithm' toggleValue 'True' fingerPrint 'John S,Stephanie B' exceptionBody 'Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5 at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)'

尝试在该索引上搜索任何包含关键字的对象,例如搜索开发人员姓名:John

FT.SEARCH toggle_errors_db John


响应

1) (integer) 1
2) "useNewAlgorithm:03-12-19-10-32-05"
3) 1) "fingerPrint"
   2) "John S,Stephanie B"
   3) "exceptionBody"
   4) "Exception in thread \"main\" java.lang.ArrayIndexOutOfBoundsException: 5 at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)"
   5) "toggleValue"
   6) "True"
   7) "toggleName"
   8) "useNewAlgorithm"

搜索功能切换名称:useNewAlgorithm

FT.SEARCH toggle_errors_db useNewAlgorithm

响应

1) (integer) 1
2) "useNewAlgorithm:03-12-19-10-32-05"
3) 1) "fingerPrint"
   2) "John S,Stephanie B"
   3) "exceptionBody"
   4) "Exception in thread \"main\" java.lang.ArrayIndexOutOfBoundsException: 5 at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)"
   5) "toggleValue"
   6) "True"
   7) "toggleName"
   8) "useNewAlgorithm"

日志数据库

“日志数据库”是一个跟踪日志消息的集中式数据存储。您可以使用 Redis 存储最近的日志消息列表,这将使您能够随时查看日志的快照。

Figure 8: Logs stored in redis_ent_3
图 8:存储在 redis_ent_3 中的日志

要保留最近的日志列表,您可以 LPUSH 日志消息到 LIST,然后将该 LIST 修剪到固定大小。

稍后,如果您想读取这些日志消息,只需执行简单的 LRANGE 即可获取它们。

SEVERITY = {
logging.DEBUG: 'debug',
logging.INFO: 'info',
logging.WARNING: 'warning',
logging.ERROR: 'error',
logging.CRITICAL: 'critical',
}
SEVERITY.update((name, name) for name in SEVERITY.values())

//设置一个映射,该映射应有助于将大多数日志严重性级别转换为一致的内容
def log_recent(conn, name, message, severity=logging.INFO, pipe=None)
severity = str(SEVERITY.get(severity, severity)).lower()
//尝试将日志级别转换为简单的字符串。
destination = 'recent:%s:%s'%(name, severity)
//创建消息将写入的键。
message = time.asctime() + ' ' + message
//添加当前时间,以便我们知道消息何时发送。
pipe = pipe or conn.pipeline()
pipe.lpush(destination, message)
//将消息添加到日志列表的开头。
pipe.ltrim(destination, 0, 99)
//修剪日志列表,只包含最近的 100 条消息。
pipe.execute()

开始使用 Redis Enterprise

这些技术中的每一种都带来了将您的持续更新提升到新的水平的机会,并最大程度地减少了管理具有频繁发布的大规模应用程序的开发固有的时间和麻烦。当然,Redis Enterprise 是为整个 CI/CD 流程带来更多功能和灵活性的绝佳方式。值得庆幸的是,使用 Redis Enterprise Pro(包括 RediSearch 模块和数据持久性功能)创建 Redis 集群非常容易且免费。

立即开始使用 Redis Enterprise