实现 Cassandra 集群配置

实现 Cassandra 集群配置。

Launchpad 蓝图:https://blueprints.launchpad.net/trove/+spec/cassandra-cluster

问题描述

Cassandra 本质上是一个分布式数据库,由“平等”的节点组成。“平等”意味着集群中的任何节点都可以接收和处理请求。它不像某些其他数据库(MongoDB)那样有查询路由器或配置服务器。它对单个节点的硬件配置没有限制(即,节点可以具有不同的规格)。

当一个节点接收到请求(它成为该请求的协调者)时,它使用分区键(主键的一部分)来计算哪些节点(副本)包含请求的数据(数据是根据分区键的哈希值分布的)。然后,它将请求传递给副本并收集结果。它的工作是组合响应并发送给客户端。数据库中存储的每个字段(值)都伴随着时间戳(或已删除数据的情况下的墓碑标记)。协调者使用这些时间戳将数据的最新视图编译成结果集。因此,节点的时钟同步至关重要。

Cassandra 的设计使其能够在任何给定节点发生故障时仍然可用。这是通过放宽一致性要求来实现的。Cassandra 提供所谓的最终一致性。容错性和一致性都可以进行调整。容错性可以在键空间级别配置(复制因子)。一致性可以在全局级别或每个请求级别控制(一致性级别)。

复制因子确定将持有给定键空间数据的副本数量。Cassandra 可以将副本分组到“机架”中。 “机架”是一组共享共同故障点的节点(副本)。Cassandra 始终尝试跨多个机架分发数据,以便一个机架的故障不会使数据无法访问。

示例

假设我们有一个三节点系统(节点 #1、#2 和 #3)和一个复制因子 (RC) 为 2 的键空间。现在假设用户发出一个插入语句,该语句落在节点 #3(协调者)上。协调者使用分区键来确定数据属于哪些节点,假设是 #1。因此,它将数据存储在节点 #1 上,并且因为 RC=2,也在下一个节点 #2 上。现在假设节点 #1 和 #2 共享一个共同的故障点,并被放置在同一个机架中。协调者因此将第二个副本存储在下一个可用不在该机架中的节点上 - 即 #3(自身)。

Cassandra 还具有数据中心的概念。数据中心通常是地理上远离的节点组,它们拥有自己的一组机架。它们的行为非常类似于独立的集群。

示例

假设上面的示例发生在数据中心 DC1 中,但所涉及的键空间也配置为复制到 DC2(DC1 的复制因子不必与 DC2 相同)。协调者然后向 DC2 中的一个节点发送异步请求,然后该节点以相同的方式处理它。

请注意,对于特定的数据中心,键空间具有复制因子 RC=0 并不罕见 - 一个原因是法律法规要求某些数据存储在特定的地理区域内。

每个节点都配置了一个集群名称。单个集群中的所有节点必须共享相同的集群名称。集群中的各个节点交换所谓的消息 - 关于集群拓扑的基本信息。新添加的节点以相同的方式了解所有其他节点。只需要提供一组初始消息种子(来自集群内的已激活节点)。建议种子节点来自所有 DC 的多个机架(以防其中一个宕机)。

所有这些配置都存储在标准的 ‘cassandra.yaml’ 文件中,该文件已经由客户代理管理2

节点成员资格(机架/dc)存储在与主配置文件相同的目录中的 ‘cassandra-rackdc.properties’ 文件中。

提议的变更

本规范提出了以下与集群相关的操作

  • 创建

  • 扩展

  • 缩减

  • 删除

只有机架支持将作为此补丁的一部分实现。所有节点都将被放置在单个 DC(‘dc1’)中。机架将映射到客户端传递的可用区 (AZ)。如果没有指定 AZ,则节点将被放置在单个默认机架(‘rack1’)中。

创建集群

  • 配置请求数量的实例。

  • 等待实例变为活动状态。

  • 选择种子节点。它们应包括每个数据中心和机架中的至少一个节点。

  • 使用种子列表配置每个集群节点。请注意,在新的空集群的初始启动期间,种子节点必须禁用自动引导。配置完所有节点后,一次启动一个种子节点(此时禁用自动引导),然后启动其余节点(自动引导可以启用,因为种子节点已经在运行)。

  • 通过第一个节点创建数据库中的 (‘os_admin’) 用户。其余节点将自动复制数据库中的更改。只需更新其他节点上的本地身份验证文件。

扩展集群

  • 配置请求数量的实例。

  • 等待实例变为活动状态。

  • 根据更新的集群几何形状重新计算种子节点,并使用更新的种子列表配置每个集群节点。

  • 从先前存在的节点检索超级用户凭据,并将其保存到新添加的节点上。

  • 首先一次启动一个添加的节点中的任何种子,然后启动其余节点。

  • 在先前存在的每个节点上运行 nodetool cleanup,以删除不再属于这些节点的键(它们现在属于一些添加的节点)。

    首先将节点置于 BLOCKED 状态,然后启动清理。清理完成后恢复节点的状态。任务管理器可以轮询节点状态更改,并在准备好时继续到下一个节点。

    该操作必须在所有先前存在的节点上按顺序运行,并且可能需要花费大量时间。清理通常可以安全地推迟到低使用率时段。

缩减集群

  • 如果删除了任何现有的种子节点,则根据更新的集群几何形状重新计算种子节点。

  • 如果需要,更新剩余节点上的种子列表。

  • 在删除的节点上运行 nodetool decommission。Cassandra 将从停用节点流式传输数据到剩余节点。完成数据传输后关闭数据库。

  • 等待删除的节点进入 SHUTDOWN 状态。

  • 删除停用实例。

配置

将在 Cassandra 配置组中实现以下配置值

cfg.BoolOpt('cluster_support', default=True,
            help='Enable clusters to be created and managed.'),
cfg.StrOpt('api_strategy',
           default='trove.common.strategies.cluster.experimental.'
           'cassandra.api.CassandraAPIStrategy',
           help='Class that implements datastore-specific API logic.'),
cfg.StrOpt('taskmanager_strategy',
           default='trove.common.strategies.cluster.experimental'
           '.cassandra.taskmanager.CassandraTaskManagerStrategy',
           help='Class that implements datastore-specific task manager '
                'logic.'),
cfg.StrOpt('guestagent_strategy',
           default='trove.common.strategies.cluster.experimental'
           '.cassandra.guestagent.CassandraGuestAgentStrategy',
           help='Class that implements datastore-specific Guest Agent API '
                'logic.'),

数据库

公共 API

公共 API 安全

Python API

CLI (python-troveclient)

内部 API

将在 CassandraGuestAgentAPI 中实现以下方法

def get_data_center(self):
    LOG.debug("Retrieving the data center for node: %s" % self.id)
    return self._call("get_data_center", guest_api.AGENT_LOW_TIMEOUT,
                      self.version_cap)

def get_rack(self):
    LOG.debug("Retrieving the rack for node: %s" % self.id)
    return self._call("get_rack", guest_api.AGENT_LOW_TIMEOUT,
                      self.version_cap)

def set_seeds(self, seeds):
    LOG.debug("Configuring the gossip seeds for node: %s" % self.id)
    return self._call("set_seeds", guest_api.AGENT_LOW_TIMEOUT,
                      self.version_cap, seeds=seeds)

def get_seeds(self):
    LOG.debug("Retrieving the gossip seeds for node: %s" % self.id)
    return self._call("get_seeds", guest_api.AGENT_LOW_TIMEOUT,
                      self.version_cap)

def set_auto_bootstrap(self, enabled):
    LOG.debug("Setting the auto-bootstrap to '%s' for node: %s"
              % (enabled, self.id))
    return self._call("set_auto_bootstrap", guest_api.AGENT_LOW_TIMEOUT,
                      self.version_cap, enabled=enabled)

def cluster_complete(self):
    LOG.debug("Sending a setup completion notification for node: %s"
              % self.id)
    return self._call("cluster_complete", guest_api.AGENT_LOW_TIMEOUT,
                      self.version_cap)

def node_cleanup_begin(self):
    LOG.debug("Signaling the node to prepare for cleanup: %s" % self.id)
    return self._call("node_cleanup_begin", guest_api.AGENT_LOW_TIMEOUT,
                      self.version_cap)

def node_cleanup(self):
    LOG.debug("Running cleanup on node: %s" % self.id)
    return self._cast('node_cleanup', self.version_cap)

def node_decommission(self):
    LOG.debug("Decommission node: %s" % self.id)
    return self._cast("node_decommission", self.version_cap)

def cluster_secure(self, password):
    LOG.debug("Securing the cluster via node: %s" % self.id)
    return self._call(
        "cluster_secure", guest_api.AGENT_HIGH_TIMEOUT,
        self.version_cap, password=password)

def get_admin_credentials(self):
    LOG.debug("Retrieving the admin credentials from node: %s" % self.id)
    return self._call("get_admin_credentials", guest_api.AGENT_LOW_TIMEOUT,
                      self.version_cap)

def store_admin_credentials(self, admin_credentials):
    LOG.debug("Storing the admin credentials on node: %s" % self.id)
    return self._call("store_admin_credentials",
                      guest_api.AGENT_LOW_TIMEOUT, self.version_cap,
                      admin_credentials=admin_credentials)

Guest Agent

除了上述方法之外,还将实现写入 ‘cassandra-rackdc.properties’ 文件的功能。

节点成员资格(机架/dc)将包含在传递到 prepare 方法的 cluster_info 字典中。

备选方案

Dashboard 影响 (UX)

需要将 Cassandra 启用为集群数据存储。

实现

负责人

主要负责人

Petr Malik <pmalik@tesora.com>

里程碑

Mitaka

工作项

工作将作为单个提交交付。

升级影响

依赖项

此实现严重依赖于以下工作

  • 蓝图 cassandra-database-user-functions 1

  • 蓝图 cassandra-configuration-groups 2

  • 蓝图 cassandra-backup-restore 3

测试

  • 将根据需要添加管理器单元测试。

  • 场景测试已经涵盖了已实现的功能。

文档影响

需要更新 Cassandra 数据存储文档以反映集群支持。

参考资料

1

Cassandra 用户/数据库实现审查:https://review.openstack.org/#/c/206739/

2(1,2)

Cassandra 配置审查:https://review.openstack.org/#/c/206740/

3

Cassandra 备份/恢复审查:https://review.openstack.org/#/c/206751/

附录