【卡桑德拉之路】Cassandra响应式编程风格 – 高级主题 ①反压力
首先
东京卡珊德拉日
今年2023 年 6 月 1 日,Cassandra Day 将在日本举行。去年,Cassandra Day 在柏林、伦敦、阿姆斯特丹、河内、雅加达、休斯敦、圣塔克拉拉、西雅图、新加坡也举办过。
我們將發表有關Apache Cassandra的文章,以迎接在東京舉行的本次活動。

有关Apache Cassandra
Apache Cassandra是一个开源的分布式数据库管理系统。
与其他分布式数据库管理系统类似,使用多个通用服务器构建一个数据库(也可以仅使用一个服务器进行构建,例如用于开发目的)。
在这里,我们将省略详细的说明,将介绍感兴趣的人的角色交给官方网站和维基百科。
卡桑德拉 反应式风格 编程
本文的内容是基于以下文件的基础。
请查阅本文作者撰写的以下文章,介绍了Cassandra反应式编程的基本用法。
高级的话题
后压力
响应式编程中的一个重要功能是背压。
很遗憾,Cassandra的原生协议不适当地支持通过网络在客户端和服务器之间进行背压信息的交换。
从3.10版本开始,Cassandra会(默默地)对客户端进行抑制。
与此同时,在响应式编程的情境下,没有背压机制。
然而,可以说在从Cassandra读取数据方面,这对大多数应用程序来说并不是一个问题。
实际上,在读取方案中,Cassandra充当生产者角色,驱动程序则是消费者。在这种设置下,如果下游的订阅者无法应对吞吐量,驱动程序会逐渐调整从服务器请求页面的速率。这样一来,服务器的吞吐量会被调整,与订阅者的吞吐量匹配。
唯一需要注意的是,如果订阅者非常缓慢,可能会触发查询超时(客户端会引发DriverTimeoutException,服务器则会引发ReadTimeoutException)。
如果在Cassandra中进行写入操作,缺乏客户端和服务器之间的背压通信将成为更大的问题。
实际上,在写入场景中,驱动程序扮演生产者的角色,而Cassandra则充当消费者。在这种设置中,如果上游生产者生成的数据太多,驱动程序将盲目地尽快将写入语句发送到服务器,最终可能导致集群超载或崩溃。这通常通过WriteTimeoutException或OverloadedException等错误表现出来。
在写入集中的场景中,强烈建议限制并发执行写入语句的数量。实现这一目标的简单方法是使用flatMap()方法。在大多数响应式库中,flatMap()方法采用控制并发执行数量的参数形式。
在下面的例子中,我们使用Reactor库的flatMap函数,通过concurrency参数(作为第二个参数)来执行最多10个并发的语句流。
Flux<Statement<?>> stmts = ...;
stmts.flatMap(session::executeReactive, 10).blockLast();
在上述示例中,flatMap同步订阅最多10个并行的ReactiveResultSet实例。同时执行的请求数量被限制为10个。
通常,这足以防止数据写入太快。
在更高级的实现中,可以通过速率限制或节流来控制流的执行。例如,Reactor提供了一个方法delayElements来限制上游发布者的吞吐量。有关更多详细信息,请参阅库的文档。
为了作为最后的手段,可以考虑使用内置的驱动程序要求限制机制,以在驱动程序级别上限制并发执行。然而,在一般情况下,这在响应式应用程序中是不需要的。有关一些示例,请参阅开发者指南中的“Managing concurrency in asynchronous query execution(在异步查询执行中管理并发)”部分。