VOLTDB规划手册

本手册用于帮助您对VoltDB做出规划。选择合适的技术不仅仅是在一组特性和另一组特性之间做出决定。了解产品如何适应现有的技术环境以及它在系统需求和技术支撑等方面的需要是很重要的。本书提供了评估VoltDB的指南,包括根据应用程序的特定需求和计划使用的VoltDB特性,对硬件、内存和磁盘的大小进行调整。

  1. 本手册主要内容
  • 第一章 规划
  • 第二章 POC
  • 第三章 硬件选择
  • 第四章 内存尺寸
  • 第五章 产品基准测试
展开查看详情

1. 目录 前言 3 第一章 规划 4 第二章 POC 5 2.1有效分区 5 2.2设计存储过程 6 第三章 硬件选择 7 3.1硬件配置调整 7 3.2吞吐量 8 3.3容量分级 9 3.4 .持久化 11 第四章 内存尺寸 13 4.1数据库容量规划 14 4.1.1定制数据表尺寸 14 4.1.2 定制索引尺寸 16 4.1.3 数据库尺寸评估 17 4.2集群中的数据分布 18 4.2.1集群中的内存使用 18 4.2.2 高可用环境中的内存计算 19 4.3 规划Java Heap Size 19 4.3.1影响堆大小的属性 20 4.3.2如何决定java堆大小 20 第五章 基准测试 21 5.1性能基准测试 22 5.1.1设计基准测试应用 22 5.1.2如何量度吞吐量 25 5.1.3 如何量度延时 26 5.2确定分区数 27

2. 前言 本手册用于帮助您对VoltDB做出规划。选择合适的技术不仅仅是在一组特性和另一组 特性之间做出决定。了解产品如何适应现有的技术环境以及它在系统需求和技术支撑等方 面的需要是很重要的。本书提供了评估VoltDB的指南,包括根据应用程序的特定需求和计 划使用的VoltDB特性,对硬件、内存和磁盘的大小进行调整。 1. 本手册主要内容 本手册分为五个部分 第一章 规划 第二章 POC 第三章 硬件选择 第四章 内存尺寸 第五章 产品基准测试 2. 其他资源 本手册假设您已经熟悉了VoltDB特性。特性的选择,特别是那些与可用性和持久性相 关的特性将影响规划。因此,如果您刚接触VoltDB,我们建议您访问VoltDB网站,熟悉产 品选项和特性。 阅读以下书籍有助于更好地理解设计、开发和管理VoltDB: ● VOLTDB入门手册是对产品的快速介绍,建议新用户使用 ● VOLTDB使用手册包括对产品特性和功能的完整介绍。 ● VOLTDB管理手册针对系统管理人员,包括产品运维和集群管理等内容。 您可以在官方网站​http://www.VoltDB.com​上找到以上书籍和更多的产品帮助信息。 第一章 规划 欢迎使用VoltDB,这是专为高容量事务应用程序设计的一流数据库。由于您正在阅读 这本书,我们假设您正在考虑将VoltDB作为现有或计划中的数据库应用程序。本书的目标 是帮助您理解这样的决策对您计算环境的影响,特别是对硬件需求的影响。 技术评价通常涉及几个相关但独立的活动: ● 特性评估 特性评估的目标是确定产品特性与应用程序需求的匹配程度。对于VoltDB,我们强烈 建议您访问我们的网站,查看可用的产品概述和技术白皮书,看看VoltDB是否适合您。如 果您需要更多的信息,请直接与我们联系。 ● POC 概念验证(POC)通常是一个小型应用程序,它使用所提议的技术模拟关键业务需求。 POC的目标是在小范围内验证该技术在目标使用方面的性能是否符合预期。 ● 硬件规划 一旦确定VoltDB是应用程序的可行候选项,下一步就是确定运行它需要什么硬件环 境。硬件规模调整需要理解业务应用程序的需求(容量、吞吐量和可用性需求)。本书的主 要目标是提供关于VoltDB的必要信息,以帮助您根据特定应用程序的需要执行这种分级操 作。 ● 基准测试 确定了技术的可行性之后,最后一项活动是执行基准测试,以根据预期的工作量评估 其性能。基准测试通常是针对POC应用或类似的原型应用程序执行的。基准测试可以帮助 计算、验证和优化硬件大小。

3. 假设您已经进行特性规划。现在,您已经准备好进行下一步。在使用VoltDB构建概念 验证(POC)、调整硬件大小和对解决方案进行基准测试时,以下几章提供了实用的建 议。 注意,本书对详细的应用程序设计本身没有帮助。关于应用程序设计的建议,我们推 荐关于VoltDB的其他书籍。特别是VoltDB使用手册。 第二章 POC 概念证明(POC)是一个小型应用程序,它用于测试解决方案中的关键需求。对于数据 库应用程序,POC通常关注几个关键指标,分别是验证数据库是否能够支持建议的模式、 查询,以及最终的预期容量和吞吐量。(有关这方面的更多信息,请参阅基准测试一章。) POC不是一个完整的原型。它只是用足够的代码来验证技术是否满足需求。根据特定 的业务需求,每个POC强调不同的数据库功能。一些可能主要关注容量,一些关注可伸缩 性,一些关注吞吐量,等等。 无论业务需求是什么,都必须正确设计VoltDB的两个关键方面,以确保概念得到真正 有效的证明。下面几节讨论如何在POC中使用分区和存储过程。 2.1有效分区 VoltDB是一个分布式数据库。它可以根据应用程序开发人员指定的数据列自动对数据 进行分区。您不需要指定每条数据记录的分区位置,VoltDB会自动为您确定。然而,要想 要有效的利用数据分区特性,您需要仔细选择分区列。最好的分区列通常并不总是最明显 的。 需要记住的重要一点是,VoltDB同时对数据和计算进行分区。为了获得最佳性能,需 要对数据库表和相关查询进行分区,以便能够并行运行最常见的事务。用VoltDB的话说, 事务应该是“单分区的”。 一个单分区事务所操作的数据只位于一个分区上。换句话说,如果在Employee表的 EmpID列上进行分区,EmpID就是这个表的分区列。单分区事务要求,访问Employee表的 查询都必须包含where Employee.EmpID = {value}。为了使单分区事务更容易创建,并不 是所有表都必须分区,不经常更新的表可以复制,这意味着可以在任何单分区事务中访问 它们,无论分区键值是什么。 在为数据库规划分区模式时,需要问自己的重要问题是: ● 哪些是关键的、最频繁的查询?(这些事务需要单分区事务) ● 对于每个关键查询,它访问哪些数据库表,使用哪些列? ● 可以复制这些表吗?(将较小的、更新频率较低的表作为复制表,方便进行关联查 询或join操作) 2.2设计存储过程 将模式和事务设计为单分区是一回事。同样重要的是,确保存储过程的操作方式能够 让VoltDB有效地完成其工作。 第一步是将事务定义为存储过程加载到模式中,关键事务不要以ad hoc方式查询数据 库。VoltDB提供了用于执行任意SQL查询的@AdHoc系统过程,这在构建早期原型以测试 查询或偶尔验证数据库内容时非常有用。但是@AdHoc查询通常作为多分区事务运行,因 此不应该用于关键事务或频繁调用的事务。 第二步是确保使用CREATE PROCEDURE语句中的PARTITION ON子句在数据库模

4.式中正确标识单分区存储过程,并指定适当的分区列。 最后,在设计最大吞吐量时,使用异步方式从POC应用程序中调用存储过程。异步调 用允许VoltDB对事务(及其响应)进行排队,避免了事务完成、结果返回给POC应用程序和 调用下一个过程之间的任何延迟。 本书后面的基准测试为有效地设计和测试概念应用程序的证明提供了额外的建议。 第三章 硬件选择 VoltDB的设计目的是在普通硬件上提供世界级的吞吐量。您不需要最新或最昂贵的硬 件来实现出色的性能。事实上,一组中低端服务器可以轻松地胜过单个高端服务器,因为 VoltDB的吞吐量往往与集群中的服务器数量成线性关系。 人们经常问我们“我们应该使用哪种类型的服务器以及使用多少服务器?”好消息是 VoltDB非常灵活。它适用于各种配置。坏消息是,这个问题的真正答案是“视情况而定”。 没有一种配置适合所有情况。 与任何技术问题一样,在为您的应用程序选择“正确”的硬件时也要进行权衡。本章解 释了这些权衡是什么,并提供了一些通用的经验规则,这些规则可以帮助您为VoltDB选择 合适的硬件配置。 3.1硬件配置调整 对单个服务器进行规划有三个关键方面:处理器的数量和速度、内存的总量以及磁盘 的大小和类型,需要考虑的第四个维度是:要使用的服务器数量。 这些维度中的每一个都会影响VoltDB性能的不同方面。处理器的数量影响每个服务器 上可以有多少个分区,从而影响吞吐量。可用内存明显影响容量或可存储的数据量。磁盘 的大小、数量和类型影响可用性特性(如快照和命令日志记录)的性能。 然而,它们也相互作用。每个服务器的内存越多,执行快照或节点在失败后重新连接 所需的时间就越长。因此,增加服务器数量,但减少每个服务器的内存数量可能会降低持 久性对总体数据库性能的影响。这些都是需要考虑和权衡的。 下面几节将从VoltDB的三个关键方面讨论硬件大小: ● 吞吐量 ● 能力 ● 耐用性 3.2吞吐量 运行VoltDB数据库服务器的最低硬件要求是一台64位机器,拥有两个或多个处理器内 核。服务器拥有的内核越多,该服务器上可能运行的数据库分区就越多。分区越多,越多 数据库的吞吐量就越大。然而,处理器的内核数量并不是限制吞吐量的唯一因素。服务器 配置的不同方面影响数据库进程的不同特性。 例如,尽管服务器拥有的物理内核越多,就会增加服务器可能处理的分区数量,但是 在某种程度上,接收的事务数量和返回的数据有可能会超过了该服务器的网络端口容量。 因此,一台机器上超过12-16个内核可能对VoltDB数据库没有什么价值,因为服务器的网 络适配器成为限制因素。 经验法则 VoltDB在4-16核服务器上运行最好。 应该注意的是,前面的讨论涉及物理处理器内核。一些服务器支持超线程。超线程本

5.质上是处理器内核的虚拟化,是物理内核数量的两倍。例如,一个具有4个内核和超线程的 系统就像一台8个内核的机器。这些虚拟化内核可以提高VoltDB性能,特别是对于物理核 心数量很少(2或4)的服务器。然而,服务器的物理内核越多,对VoltDB性能的改善就越 小。因此,对于物理内核超过8个的VoltDB服务器,不建议使用超线程。为提高吞吐量而 向单个服务器添加处理器的替代方法是添加更多的服务器。如果一个4核服务器可以处理3 个分区,那么两个这样的服务器可以处理6个分区,3个可以处理9个分区,等等。这就是 VoltDB在吞吐量上提供线性扩展的方式。 但同样,扩展服务器数据也有限制。对于峰值性能,将集群节点之间的网络延迟和中 断保持在最小是关键。换句话说,集群的所有节点都应该位于同一个网络交换机上。显然 ,网络交换机的容量限制了它所能支持的节点数量。 经验法则 一个2-32个节点的VoltDB集群,通过同一交换机连接,可以提供最好的性能。 跨交换机的VoltDB集群是可能的(例如,在云环境中几乎总是这样)。然而,集群节点 之间的延迟将对性能产生负面影响,并可能最终限制总体吞吐量。在这些情况下,最好对 不同的配置进行基准测试,以确定预期的性能。 最后,应该注意的是,处理器内核的速度可能对总体吞吐量没有显著影响。处理器速 度影响执行单个事务所需的时间,这可能只是总体吞吐量中的一小部分。对于计算密集型 事务的工作负载,更快的处理器可以提高整体性能。但是对于许多小的或简单的事务,改 进的处理器速度几乎没有影响。 3.3容量分级 数据库规模调整的第二个方面是容量。容量描述数据库可以容纳的最大数据量。因为 VoltDB是内存数据库,所以容量受到集群中所有节点的总内存的限制。当然,服务器的内 存大小设置不能太精确。应该考虑到数据随时间的增长以及数据库服务器中使用内存的其 他部分,这一点非常重要。 第四章内存尺寸中详细说明了中VoltDB服务器如何为数据库内容分配内存。当您有一 个已知的模式时,使用该章执行准确的大小调整。然而,作为一个粗略的估计,您可以使 用下表来近似每一列所需的空间。通过将每个列和索引(包括索引指针)相加,然后乘以预 期的行数,可以确定存储数据库内容所需的内存总量。 表3.1 字段和索引大小 对于用字符而不是字节声明的VARCHAR列,长度计算为每个字符4个字节。 换句话说,对于存储计算,声明为VARCHAR(16)的字符串列与声明为VARCHAR(64 BYTES) 的列长度相同。 您还必须考虑服务器进程本身所需的内存。如果您知道数据库将包含多少个表,以及 每个主机将使用多少个分区,则可以使用以下公式计算服务器进程内存需求: 384MB + (10MB X number of tables) + (128MB X sites per host) 这个公式假设您使用K-safety,这是推荐用于所有生产环境的。如果集群也是数据库

6.复制的主数据库,那么应该将每个主机的站点的乘数从128M增加到256M: 384MB + (10MB X number of tables) + (256MB X sites per host) 如果您不知道数据库将包含多少个表,或者您不确定每个主机使用多少个分区,您可 以使用2g作为中等大小的数据库和服务器的服务器进程大小的粗略估计。但是请注意,一 旦定义了实际配置,您可能需要增加这个估计数。 最后,您对服务器总体所需内存的估计是数据所需内存和服务器进程本身所需内存的 组合,再加上30%作为缓冲区。 Server memory = ( content + server process ) + 30% 当集群成员调整时,计算每个服务器上内容所需的内存大小是总内容大小除以服务器 数量,再加上复制表的百分比。例如,如果复制20%的表,则每台服务器所需空间的粗略 估计为: Per server memory = ( ( content / servers) + 20% + server ) + 30% 在为VoltDB服务器分配内存大小时,一定要记住以下几点: ● 内存使用不仅包括数据存储,还包括处理事务、管理队列和服务器本身处理的临 时存储。 ● 即使在最好的数据分区方案,数据分布也永远不会完全平衡。需要考虑跨服务器 的负载变化。 ● 如果内存使用量超过总内存的70%,操作系统就会开始分页和交换,严重影响性 能。 经验法则 将每个服务器的内存使用量控制在总内存的50-70%以内。 内存技术和颗粒密度发展得如此之快(类似于处理器内核的增加),因此可以配置少量 具有非常大内存容量的服务器,这些服务器提供的容量和性能相当于大量较小的服务器。 但是,使用的内存数量可能会影响数据库管理的其他方面的性能,比如快照和故障恢复。 下一节将讨论为这些特性调整大小时需要考虑的一些权衡。 3.4 .持久化 持久性是指数据库承受(或从)意外事件中恢复的能力。VoltDB有几个特性可以提高数 据库的持久性,包括K-Safety、快照、命令日志记录和数据库复制。 K-Safety复制分区来提供冗余,以防止服务器故障。请注意,当您启用K-Safety时, 您正在跨硬件复制惟一的分区。因此,任何一个副本的硬件资源(特别是服务器和内存)都 在减少。为K-Safe集群调整硬件大小的最简单方法是根据预测的吞吐量和容量调整数据库 的初始实例大小,然后将服务器数量乘以所需的副本数量(即K-Safety值加1)。 经验法则 在使用K- safety时,将集群节点的数量配置为数据库副本数量的整数倍(即K+1)。 在正常情况下,K-Safety对性能没有真正的影响。然而,在从故障中恢复时,集群配 置可能会影响性能。在K-Safe集群中,当一个失败的服务器重新加入时,它从集群的其他 成员那里获得所有分区的副本。分区容量越大(内存大小),恢复分区所需的时间就越长。 由于恢复操作可以阻止数据库事务,因此使用大型服务器或小型服务器的权衡是很重要的 ,大型服务器更容易管理,而更多的小型服务器可以用更少的时间恢复。 其他两个持久性特性——快照和命令日志——对内存和处理能力的影响很小。然而, 这些特性确实需要磁盘上的持久存储。 大多数基于VoltDB的磁盘特性,如快照、导出、网络分区等,都可以在标准磁盘技术 (如SATA驱动器)上得到支持。假设磁盘有足够的容量,它们还可以共享单个磁盘上的空 间。 另一方面,命令日志记录与时间有关,必须跟上服务器上的事务。《VoltDB使用手 册》的命令日志一章详细讨论了异步和同步日志记录之间的权衡,以及每种日志记录使用 的恰当硬件。但总的来说: ● 使用快速磁盘(如电池支持的高速缓存驱动器)进行同步日志记录 ● 使用SATA或其他商品驱动器进行异步日志记录。但是,为命令日志使用专用驱 动器仍然是一个好主意,以避免日志和其他磁盘活动之间的并发问题。 经验法则

7. 当使用命令日志记录时,无论是同步的还是异步的,都要为命令日志使用专用驱动 器。其他磁盘活动(包括命令日志快照)可以共享一个单独的驱动器。 最后,数据库复制(DR)不会影响服务器的内存大小或处理能力。但是对于每个额外的 集群,它确实需要初始硬件的副本。例如,当使用被动DR时,您应该将估计的服务器数量 加倍—一个副本用于主集群,一个副本用于从集群。当使用跨数据中心复制(XDCR)时,您 需要为参与XDCR的每个集群提供一个完整的副本。 经验法则 在使用数据库复制时,将所需的服务器数量乘以涉及的集群数量——两个集群用于被 动DR(主服务器和副本);两个或多个集群,用于XDCR环境中。 第四章 内存尺寸 系统规模评估的一个重要方面是规划应用程序所需的内存。因为VoltDB是内存数据库 ,所以分配足够的内存非常重要。 第3.3节“容量分级”提供了一些简单的公式来估计未来应用程序的内存需求。如果您已 经处于定义良好数据库模式的阶段,并且希望更精确地测量潜在内存使用情况,本章将详 细介绍如何分配内存。 对于VoltDB数据库,有三个方面的内存大小必须考虑: ● 了解存储数据本身需要多少内存,即数据库的内容 ● 根据分区表与复制表的比例和K-safety值评估数据在集群中的分布情况 ● 确定服务器进程的内存需求 每个服务器的估计数据需求和服务器进程所需的java堆大小之和是服务器的总内存需 求。 4.1数据库容量规划 要有效地计划数据库容量,您必须预先知道数据的结构和容量。这意味着您必须至少 有一个初步的数据库模式,包括表、列和索引,以及每个表的预期行数。将初始大小信息 写下来通常很有用,例如一下电子表格中的示例。您的计划还应该考虑到增长,因此您需 要评估初始量和长期增长值。下面是一个机票预订系统的数据库简化示例 使用数据库模式,可以计算单个表记录和索引的大小,这些记录和索引乘以容量可以 很好地估计存储数据库内容所需的总内存。下面几节解释如何计算单个表行和索引的大 小。

8. 4.1.1定制数据表尺寸 单个表行大小取决于表中列的数量和数据类型。对于固定大小的数据类型,如 INTEGER和TIMESTAMP,列使用指定的字节数存储表记录。表4.1“各数据类型的长度”指 定了固定大小数据类型的长度(以字节为单位)。 对于可变长度数据类型,如VARCHAR和VARBINARY,数据的存储方式以及所需的 空间取决于数据的实际长度和最大可能长度。如果最大长度小于64字节,则数据内联存储 在元组中,作为固定长度的数据,使用最大字节数加上长度的1。例如,VARCHAR(32 BYTES)列占用33字节,无论实际数据有多长。 注意,VARCHAR列可以用字符(默认值)或字节声明。对于存储计算,以字符声明的变 长字符串被认为每个字符占用4个字节。换句话说,在字符中声明为VARCHAR(8)的可变 长度字符串占用的空间与声明为VARCHAR(32字节)的字符串相同。 如果最大长度为64字节或更多,则数据存储在内存池中,而不是内联的。为此,在元 组中内联存储一个8字节的指针,一个24字节的字符串引用对象,以及在池中存储数据本 身所需的空间。在池中,数据存储为4字节长度、一个指向字符串引用对象的8字节反向指 针,再加上数据本身。 存储在内存池中的数据不是以任意长度存储的。相反,数据被增加到最小的适当的“池 大小”,其中池大小是2的幂及其中间值。换句话说,池大小包括2、4、6(2+4)、8、 12(8+4)、16、24(8+16)、32等等,最大可达1兆字节的数据加上12字节的指针。例如,如 果Customer表中的LastName列定义为VARCHAR(32)(即最大长度128字节),实际内容为 95字节,则实现消耗160字节: 注意,如果变量最大长度大于或等于64字节,那么即使实际内容小于64字节,它也不 会内联存储。只有当最大长度小于64字节时,可变长度列才内联存储。 表4.1 各数据类型的长度

9. 对于长度可变的并且小于64字节的列,使用上表可以非常精确地计算内存使用量。但 是,对于长度可变的列大于64字节的表,最多也只能是近似的估计。除了内存池带来的可 变性之外,任何大小计算都必须基于对变量列中数据的平均长度的估计。 对于最安全、最保守的估计,您可以在计算可变长度列时使用最大长度。另一方面, 如果有许多可变长度的列,或者您知道数据会有很大的差异,您可以使用一个估计的平均 值或乘以90%,以避免过高估计内存消耗。 4.1.2 定制索引尺寸 索引的大小与表的大小类似,其中索引列的大小和数量决定索引的大小。 VoltDB使用树索引。您可以通过将索引中每一列的大小加上40字节(指针长度)来计算 单个索引条目的大小。列的大小如表4.1“各数据类型的长度”所述,除了非内联的二进制数 据外。对于长度等于或大于64字节的变长列,索引只包含一个8字节指针;数据本身没有复 制。 例如,Customer表上的CustomerByName索引包含VARCHAR(32)字段LastName和 FirstName,每个条目的长度为56字节 如下公式计算索引的大小 (sum-of-column-sizes + 8 + 32) * rowcount 4.1.3 数据库尺寸评估 使用前面的公式,可以估算机票预订数据库的大小。我们可以根据列和数据类型估算 Flight表的各个行。下表演示了Flight表的大小。 对于其他表和索引也可以进行相同的计算。结合表的记录行数,您将得到存储大约 500兆字节的数据库内容所需的总内存的估计值,如下表所示。

10. 4.2集群中的数据分布 在最简单的情况下(单个服务器),上一节中计算的总和可以准确估计数据库内容所需 的内存。然而,VoltDB在集群环境中伸缩性最好。在这种情况下,您需要确定每个服务器 将处理多少数据,这将受到服务器数量、分区表复制表的数量和大小以及所需的可用性级 别(即K-safety)的影响。 下面几节解释如何确定集群中分区表和复制表的分布以及K-safety的影响。 4.2.1集群中的内存使用 很容易想到将数据库内容所需的总内存除以服务器的数量得到单节点内存需求,但这 不是一个准确的公式,原因有二: ● 并非所有数据都是分区的。复制的表(及其索引)出现在所有服务器上。 ● 几乎没有分区方案能够提供完美的均匀分布。关注分布中的一些变化是很重要 的。 要准确计算集群中每个服务器的内存使用量,必须考虑所有复制的表和索引,以及分 区表和索引在每个服务器的部分。 Data per server = replicated tables + (partitioned tables/number of servers) 对第4.1.3节中描述的机票预订系统数据库进行评估,复制表和索引(Flight和Airport)所 需的总内存大约只有12兆字节。其余分区表和索引所需的内存大约为490 MB。假设数据库 在两台服务器上运行,每台服务器上的数据所需的总内存约为256兆: 当然,没有一种分区方案是完美的。因此,提供额外的空间(比如20%到30%)以允许 分区中的任何数据倾斜。 4.2.2 高可用环境中的内存计算 您计划与VoltDB数据库一起使用的特性也会影响容量规划,尤其是K-Safety。通过在

11.集群中复制数据,K-Safety提高了可用性,允许数据库在单节点故障中存活下来。 由于K-Safety涉及复制,它还增加了存储复制数据的内存需求。也许确定K-Safe集群 大小的最简单方法是确定非复制集群的大小,然后乘以K-Safety值+ 1。 例如,假设您计划在一个6节点集群上运行一个K-Safety值为2(换句话说,3个副本)的 数据库。确定每个服务器所需内存容量的最简单方法是计算一个2节点(非k安全)集群的内 存需求,然后创建该硬件和内存配置的三个副本。 4.3 规划Java Heap Size 前面几节解释了如何计算存储数据库内容和索引所需的总内存。您还必须考虑数据库 进程本身,它在Java堆中运行。为最佳堆大小定义一个精确的公式是不可能的。但是,以 下基本准则可用于适应不同的硬件配置和数据库设计。 4.3.1影响堆大小的属性 不同的数据库功能对服务进程影响最为直接,因此java堆大小取决于: ● 模式大小,取决于表和存储过程的总数 ● 每个主机的分区数量 ● 正在使用的特性,特别是K-safety和/或数据库复制 模式大小影响数据库进程的基本需求。模式拥有的表越多,包含的存储过程越多,就 会占用越多的堆空间。提供足够的堆空间是非常重要的,这样无论启用了什么其他特性, 都可以更新模式。 一般的经验法则是基本Java堆大小为384MB,然后为模式中的每个表加10MB内存空 间。存储过程对堆大小的影响不像表的数量那么大。但是,如果您有很多存储过程(即成百 上千个),那么最好在基本堆大小中添加额外的空间,以便更好地运行。 除了基本堆大小之外,使用K-safety和数据库复制(对于主数据库)都增加了对Java堆空 间的需求,增加的数量与每个主机的分区数量成正比。一般来说,每台主机上的每个分区 都需要额外的128MB内存消耗。 例如,每个主机有4个分区的K-safe集群需要额外的512MB,而每个主机有8个分区的 K-safe集群需要1GB。如果该集群也是数据库复制的主集群,那么这些额外的堆需求将分 别增加一倍,达到1GB和2GB。 4.3.2如何决定java堆大小 确定VoltDB集群节点java堆大小的推荐方法如下: 步骤1使用以下公式计算基本Java堆需求: 384MB + (10MB X表数)=Java堆大小 如果您希望在将来添加表,请确保内存是可以扩展的。此外,如果您希望有大量的存 储过程(200个或更多),请相应地增加堆大小。注意,超出最小设置的额外Java堆空间可以 提供更好的性能优势,比如模式更新和节点重新加入时。 步骤2根据生产中使用的硬件(特别是每台服务器的核心)和建议模式的性能测试,确定 每台主机的最佳分区数量。默认情况下,每个主机有8个分区。不建议将每个主机的分区设 置为大于24。 步骤3确定将在生产中使用哪些数据库特性。所有生产环境都推荐使用K-safety、网络 分区检测和命令日志记录。数据库复制(DR)是一个可选特性,它提供了额外的持久性。 如果使用了K-safety,但DR没有使用,则将每个主机的站点数量乘以128MB,以确定 特定于功能的Java堆需求。如果启用了K-safety,并且集群是DR的主数据库,那么将每个 主机的站点数乘以256MB。 步骤4将步骤1中定义的基本Java堆需求加上步骤3中特定于功能的需求,就是生产服

12.务器的推荐Java堆大小。 第五章 基准测试 基准测试是根据已知基线评估性能的过程。对于数据库应用程序,您可以根据其他技 术、目标指标(例如每秒处理的事务数量)进行基准测试,或者在不同的硬件配置上使用相 同的应用程序,以确定哪个生成的结果最好。 对于VoltDB应用程序,基准测试有助于建立以下指标: ● 最佳吞吐量 ● 每个主机的最佳分区数量 5.1性能基准测试 在为数据库应用程序建立性能标准时,通常有两个关键指标: ● 吞吐量——一次可以完成多少事务,通常以每秒事务或TPS来度量 ● 延迟——每个事务花费的时间,通常用事务样本数量的平均或百分位延迟来度量 注意,这两个指标都不准确。对于许多数据库,吞吐量可能会随着事务类型的不同而 变化;无论是读操作还是写操作。VoltDB的优点之一是,对于写操作和读操作,吞吐量不会 发生显著变化。然而,当存在许多多分区事务与单分区事务工作负载时,VoltDB吞吐量确 实会发生变化。这就是为什么在对VoltDB数据库进行基准测试时,正确地设计模式和存储 过程很重要。 延迟可以是从客户机发出事务请求到接收响应的时间,或者从数据库服务器接收请求 到处理完请求的时间。 从客户机应用程序的角度来看,前一种度量(延迟)可能是最准确的。但是,这个度量 包括数据库延迟和客户机和服务器之间的任何网络延迟。后一种度量,即从数据库的角度 来看的延迟,是对技术能力更精确的度量。这个度量包括处理事务本身所需的时间(即存储 过程和它包含的数据库查询),以及请求在队列中等待执行的时间。 5.1.1设计基准测试应用 吞吐量、延迟和系统配置之间存在关系。吞吐量综合了执行一个事务的时间(延时) 和并行处理事务的数量(并行处理事务取决于分区数量)。这就是将性能基准测试与服务 器配置基准测试结合起来进行的重要原因,稍后将对此进行讨论。不同的配置将导致不同 的吞吐量和延迟值。另外,应用程序本身的设计也会影响基准测试结果。 5.1.1.1 良好的应用设计 如前所述,吞吐量和延迟不是抽象的数字。它们是模式、存储过程、应用程序和服务 器配置的结果。与任何VoltDB解决方案一样,要有效地测试性能,必须从设计良好的应用 程序开始。具体地说: ● 对所有表进行分区(小型且主要是只读的表除外) ● 将所有频繁的事务设计为单分区 ● 使用异步过程调用 有关编写有效的VoltDB应用程序的更多信息,请参见第2章 POC。 从POC开始基准测试是一种常见的实践,因为POC包含一个初始数据库模式和解决方

13.案所需的关键事务。如果您决定继续开发,那么在整个过程中定期对应用程序进行基准测 试也是一个好主意,以确保您了解附加功能如何影响您的总体性能目标。 然而,在对POC进行基准测试之前,确定如何度量性能非常重要。下面几节提供了有 用的信息,用于确定在VoltDB应用程序中度量什么以及如何度量。 5.1.1.2 速率限制 延迟和吞吐量是相关的。要度量吞吐量,您的测试应用程序可以尽可能快地进行存储 过程调用,然后度量每秒完成多少次(TPS)。但是,如果测试应用程序调用了更多的事务 ,而服务器可以在该时间段内完成这些事务,那么在处理这些额外的调用之前,必须在队 列中等待。这些事务在队列中等待的时间将导致延迟度量突然出现峰值。 对于任何给定的应用程序和系统配置,都有最优的吞吐量。随着来自客户机应用程序 的调用速率的增加,TPS会直接增加,而延迟则保持相对平稳。然而,当调用率接近并超 过最优吞吐量时,延迟会急剧增加,TPS甚至可能下降,如下图 图5.1 “确定最优吞吐量和延迟” 如果您的测试应用程序以最快的速度发送调用-你所能测量的只是上表右侧的错误吞吐 量和延迟。要确定最佳速率,您需要能够控制基准应用程序提交事务请求的速率。这个过 程称为速率限制。 简单地说,速率限制就是限制应用程序发出的调用数量。例如,下面的程序循环将应 用程序限制为每毫秒最多调用存储过程10次,或每秒10,000次。 boolean done = false; long maxtxns = 10; while (!done) { long txns = 0; long millisecs = System.currentTimeMillis(); while (millisecs == System.currentTimeMillis()) { if ( txns++ < maxtxns } { myClient.callProcedure(new SignInCallback(), "SignIn", id, millisecs); } } } 您可以使用命令行参数来参数化速率极限值maxtxns,然后使用应用程序的多次运行 来创建一个类似于图5.1的图,“确定最佳吞吐量和延迟”。更好的方法是使用延迟限制来自 动控制调用速率,并让应用程序接近最佳吞吐量值。 基于延迟的速率限制是如何实现的呢?方法是为目标延迟设置一个变量,同时为最大允 许吞吐量设置一个变量(如上例中的maxtxns)。应用程序同时测量一段时间内的平均吞吐量

14.和延迟(例如,每1到5秒)。如果平均延迟超过目标,减少每秒最大事务数,然后重复。在 相同的时间段之内,如果延迟仍然超过目标,则再次降低最大事务速率。如果延迟确实达 到了目标,则增加最大事务速率。 通过使用基于延迟目标的速率限制和自动调整的组合,测试应用程序最终将确定当前 配置的最佳吞吐率。由VoltDB软件提供的示例应用程序(如volter和VoltKV)即时采用这种方 法。 5.1.2如何量度吞吐量 通常,为了进行基准测试,有必要对应用程序进行测量。也就是说,添加代码来度量 和报告基准数据。虽然可以(而且很容易)测试VoltDB应用程序,但是我们有更好的办法。 测量VoltDB数据库吞吐量的最简单方法是在基准应用程序运行时监视数据库。您可以 使用VoltDB管理控制台监视数据库,该控制台可以通过任何VoltDB服务器访问,并提供数 据库集群总体吞吐量的图形显示。要获得更详细的信息,可以使用变量来跟踪完成的事务 数量(在异步过程回调中增加变量),从而对应用程序进行测试。然后,通过将事务数除以 自上次报告以来的秒数,定期报告平均TPS。 有关仪表化基准测试应用程序的示例,请参阅投票者示例应用程序。投票者应用程序 的自述说明了如何通过使用命令行参数自定义报表。 5.1.3 如何量度延时 还可以在不使用VoltDB管理控制台检测应用程序的情况下了解总体延迟。管理控制台 提供的延迟图显示了服务器的平均延迟,每隔几秒测量一次。有时,这种方法可以生成一 个具有极大起伏的锯齿图。在这种情况下,解释应用程序总体延迟的最佳方法是想象一条 横过图上高点的线。 为了让基准测试更加准确,您可以使用构建在VoltDB系统过程和Java客户机接口中的 延迟指标。要测试客户机应用程序,可以使用存储过程调用返回的ClientResponse对象来 测量延迟。ClientResponse类包含getClientRoundTrip()和getClusterRoundTrip()方法。这 两种方法都返回一个整数值,表示处理事务所需的毫秒数。getClientRoundTrip()方法报告 总延迟,包括来自客户机应用程序的网络往返。 使用这些方法收集和报告自定义延迟信息很容易。例如,下面的代码片段捕获关于每 个过程回调期间的最小、最大和组合延迟的信息。 static class PocCallback implements ProcedureCallback { @Override public void clientCallback(ClientResponse response) { txncount++; int latency = response.getClusterRoundTrip(); if (latency < minlatency) minlatency = latency; if (latency > maxlatency) maxlatency = latency; sumlatency += latency; . . 基准测试应用程序可以使用这些信息定期报告特定的延迟值,如下所示: if (System.currentTimeMillis() >= nextreport ) { // report latency printf("Min latency: %d\n" + "Max latency: %d\n" + "Average latency: %d\n", minlatency, maxlatency, sumlatency/txncount); // reset variables txncount=0; minlatency = 5000;

15. maxlatency = 0; sumlatency = 0; // report every 5 secsonds nextreport = System.currentTimeMillis() + 5000; } 5.2确定分区数 基准测试的另一个重要目标是确定每个主机的最佳分区数量。每一个VoltDB服务器可 以托管多个分区,或称作“站点”。每个主机的理想站点数量与服务器上可用的处理器内核 数量有关。然而,这并不是一个精确的一对一关系。通常,站点的数量略低于核心的数 量。 随着超线程的出现,这个等式变得更加复杂,它为每个物理内核“虚拟化”多个处理 器。超线程可以提高VoltDB服务器支持的每台主机的站点数量。但是,这与非超线程服务 器并不成正比。 重点 一般来说,每个主机上有4到16个站点时,VoltDB的性能最好。但是,即使处理器内 核的数量可能更多,每个主机也不应该超过24个站点,因为管理这么多站点所需的进程开 始与数据处理发生冲突。 确定每个主机的最佳站点数量的最简单方法是针对目标应用程序进行测试或基准测 试。确定特定硬件上正确站点数量的过程如下: 1. 创建一个基准应用程序来测量最优吞吐量,如5.1节所述。 2. 多次运行基准测试应用程序,每次增加数据库的每个主机的站点数量。 3.注意每次运行的最优吞吐量,并将最优TPS与每台主机的站点数量作图。 随着每个主机的站点数量的增加,最佳吞吐量也会增加。然而,在某些时候,站点的 数量超过了硬件能够支持的线程的数量,在这种情况下,处理器中会发生争用,吞吐量会 降低。下图显示了一个基准的结果图,在一台四核服务器上随站点增减吞吐量的变化。在 这种情况下,每个主机的最优站点数是3个。 图5.2 确定每台主机的最佳站点 通过使用基准应用程序绘制吞吐量和分区之间的关系,可以为您在特定硬件环境中, 最大化数据库性能。

VOLTDB诞生作为支持云端部署的内存数据库,并在持续增强流计算能力,原生分布式架构提供了可伸缩性,同时完全满足ACID要求,数据安全可靠。VOLTDB采用关系型数据存储,支持严格的事务模型和标准SQL。由2014图灵奖得主Mike Stonebraker博士领导全新设计的架构。