正如无数开发人员在使用 Redis 的过程中发现的那样,在某个时候我们会超过我们的第一个 Redis 服务器。 也许我们需要记录更多信息,也许我们需要更多空间用于缓存,或者也许我们已经跳过了并正在使用后面章节中描述的更高级的服务。 无论出于何种原因,我们都需要更多服务器。
为了便于过渡到更多服务器,我建议为应用程序的每个单独部分运行一个 Redis 服务器 - 一个用于日志记录,一个用于统计,一个用于缓存,一个用于 cookie,等等。 请注意,您可以在一台机器上运行多个 Redis 服务器; 它们只需要在不同的端口上运行。 或者,如果您想减少系统管理负载,您也可以在 Redis 中使用不同的“数据库”。 无论哪种方式,通过将不同的数据拆分到不同的键空间中,您向更多或更大服务器的过渡在某种程度上得到了简化。 不幸的是,随着服务器和/或 Redis 数据库数量的增加,管理和分发所有这些服务器的配置信息变得更加繁琐。
在上一节中,我们使用 Redis 作为配置信息的来源,以确定是否应该提供维护页面。 我们可以再次使用 Redis 来告诉我们有关其他 Redis 服务器的信息。 更具体地说,让我们使用一个已知的 Redis 服务器作为配置信息的目录,以发现如何连接到为不同的应用程序或服务组件提供数据的所有其他 Redis 服务器。 在此过程中,我们将以这样一种方式构建它,即当配置更改时,我们将连接到正确的服务器。 我们的实现将比此示例的要求更通用,但我确信,在您开始使用此方法获取配置信息后,您将开始将其用于非 Redis 服务器和服务。
我们将构建一个函数,该函数将从一个键中提取 JSON 编码的配置值,该键以服务类型和该服务所针对的应用程序组件命名。 例如,如果我们想提取保存统计信息的 Redis 服务器的连接信息,我们将提取键 config:redis:statistics。 以下列表显示了用于设置配置的代码。
def set_config(conn, type, component, config): conn.set( 'config:%s:%s'%(type, component), json.dumps(config))
有了这个 set_config() 函数,我们可以设置我们可能想要的任何 JSON 可编码配置。 通过语义上的轻微更改,以及一个结构类似于我们之前的 is_under_maintenance() 函数的 get_config() 函数,我们可以替换 is_under_maintenance()。 请参阅以下列表,了解与 set_config() 匹配的函数,该函数允许我们在本地缓存配置信息 1 秒、10 秒或 0 秒,具体取决于我们的需要。
CONFIGS = {} CHECKED = {} def get_config(conn, type, component, wait=1): key = 'config:%s:%s'%(type, component)
if CHECKED.get(key) < time.time() - wait:
检查我们是否应该更新有关此组件的配置信息。
CHECKED[key] = time.time()
我们可以,所以更新我们上次检查此连接的时间。
config = json.loads(conn.get(key) or '{}')
获取此组件的配置。
config = dict((str(k), config[k]) for k in config)
将潜在的 Unicode 关键字参数转换为字符串关键字参数。
old_config = CONFIGS.get(key)
获取此组件的旧配置。
if config != old_config:
如果配置不同…
CONFIGS[key] = config
…更新配置。
return CONFIGS.get(key)
现在我们有一对用于获取和设置配置的函数,我们可以走得更远。 我们开始采用这种存储和提取配置的方式,是为了设置和创建到各种不同 Redis 服务器的连接。 但是到目前为止,我们编写的几乎每个函数的第一个参数都是连接参数。 与其需要手动获取我们正在使用的各种服务的连接,不如构建一种方法来帮助我们自动连接到这些服务。