HStreamDB Newsletter 2022-03|订阅功能优化、两个客户端更新、开源 3 个 bench tool…

2022-4-2

本月,HStreamDB 团队对 HStream Server 进行了进一步优化,包括 read path 协议简化和代码重构、增加 mutual TLS 支持等。同时也对客户端进行了更新,Java 客户端通过改进 BufferedProducer 提升了多 key 场景下的写入性能,并发布了 Golang Client 的第一个版本。此外还开源了一些基本的 bench tool,并修复了在各种测试中发现的问题。

HStream Server

read path 协议简化和代码重构

read path 是指 HStream Server 中负责实现 Subscription 功能的模块,这部分代码的逻辑相对比较复杂,总的来说主要包括以下两大部分:

  • Subscription 的状态管理:主要涉及消费进度追踪、ACK 窗口信息的维护、Record 超时重传的处理、Snapshot 的提交和持久化等,这部分是保证 at least once 和后续要支持的 exactly once 的 Record 消费的关键。
  • Consumer Group 维护和动态数据派发:多个 Consumer 可以共同消费一个 Subscription 上的数据,Consumer 的数量和加入退出等都是动态变化的,同时 Subscription 关联的 Stream 下的分区也是动态创建的。这种双端的动态性给快速将各个分区里的数据派发给合适的 Consumer,并在发生失败时及时调整分配带来了很大的挑战。

在 HStream v0.7 的实现中,一个 Subscription 的相关状态可能分布在集群内的多个 HServer 的节点上,虽然这种设计带来了很大的灵活性和细粒度的扩展性,但也造成了实现的复杂性。不仅在 read path 上 Client 和 Server 需要多轮 RPC 通信,而且在高并发情况下跨节点进行状态维护是非常困难的,目前也已经发现相关实现引入了若干复杂的 Bug 并引起一般情况下 Consumer 性能的下降。

为此,在新的实现中我们限制让一个 Subscription 的状态不跨节点,这带来了协议的简化,而且在新的实现中我们大量使用 STM 进行并发状态的处理,得益于 STM 提供的易用性和可组合性,在保证正确性的同时改进了高并发情况下的性能。

mutual TLS 支持

基于 TLS 可以实现连接加密,身份认证等安全特性,本月支持 mTLS 的相关代码已经 merge 进主分支。虽然这一功能将在 v0.8 正式发布,但目前已经可以通过 HStreamDB 的 latest 镜像体验这一功能,通过在 HServer 的配置中启用以下配置即可开启 TLS 支持,具体可参考文档:https://hstream.io/docs/en/latest/security/overview.html

# TLS options

# enable tls, which requires tls-key-path and tls-cert-path options
enable-tls: true

# key file path for tls, can be generated by openssl
tls-key-path: /path/to/the/server.key.pem

# the signed certificate by CA for the key(tls-key-path)
tls-cert-path: /path/to/the/signed.server.cert.pem

# optional for tls, if tls-ca-path is not empty, then enable mTLS(mutual tls),
# in handshake phase, server will request and verify client's certificate.
tls-ca-path: /path/to/the/ca.cert.pem

支持配置 Stream 的 Backlog duration

现在在创建 Stream 的时候,可以指定 Backlog duration 属性,这个属性决定了当前 Stream 的数据可以在 HStreamDB 中驻留多久,超过这个期限的数据将被清理。

Java Client

BufferedProducer 改进和性能优化

为方便理解和使用,我们对 BufferedProducer 的相关配置做了调整,主要分为 BatchSetting 和 FlowControlSetting。其中 BatchSetting 主要控制 BufferedProducer 如何做 batch,batch 的大小和发送时机等,可以通过 recordCountLimit, bytesLimit, ageLimit 三个选项来共同控制,可以灵活配置实现根据不同场景满足不同的吞吐和时延需求。FlowControlSetting 主要控制整个 BufferedProducer 占用的内存空间大小,以及达到限制之后的行为,目前到限之后的默认行为是阻塞。同时,BufferedProducer 对多个不同 orderingKey 的数据改用并行发送的策略,提高了多 key 场景下的写入性能。

Consumer Batch ACK

之前 Consumer 对于每条 Record 的 ACK 是立即发送的,这在大量数据的场景下存在性能问题,现在为 ACK 也启用了 batch 机制,提升了 Consumer 的性能。

TLS 支持

Java Client 目前也已经加入了对 TLS 的支持,可通过以下方式使用:

HStreamClient.builder()
  .serviceUrl(serviceUrl)
  // enable tls
  .enableTLS()
  .tlsCaPath("/path/to/ca.pem")

  // for authentication
  .enableTlsAuthentication()
  .tlsKeyPath("path/to/role01.key-pk8.pem")
  .tlsCertPath("path/to/signed.role01.cert.pem")
  .build()

Golang Client

hstreamdb-go v0.1.0 发布

hstreamdb-go 是 HStreamDB 的 Golang 客户端,本月已发布 v0.1.0,目前支持和 HStreamDB 的基本交互能力,仓库请见 https://github.com/hstreamdb/hstreamdb-go

测试

Chaos Testing

遵循 Chaos Engineering 的多样化真实事件和自动化连续运行的原则,我们对先前基于 Jepsen 的故障注入测试进行了丰富, 除了基本的节点失败故障,还引入了外部服务失败故障、数据丢包和网络延迟等故障类型。这部分测试也会自动持续高频率的运行,以便及时发现和解决问题。

bench tools

本月我们开源了基本的 HStreamDB bench tool ,可以用来快速评估 HStreamDB 的性能,仓库见 https://github.com/hstreamdb/bench。这些 bench tool 基于 hstreamdb-java 开发,目前主要包含:

  • writeBench:测试 HStreamDB 的写入性能
  • readBench:测试 HStreamDB 的读性能
  • writeReadBench:测试 HStreamDB 读写混合负载下的性能

问题修复

本月我们还修复了若干在各种测试中发现的问题,其中影响较大的包括:

  • 修复了由 Zookeeper 集群失败后引起 HServer 意外退出的问题
  • 修复了负载均衡算法在某些情况下的分配均匀性的问题
  • 修复了某些情况下 Consumer 引起 HServer 意外退出的问题

推荐阅读