【问题标题】:How do I configure and execute BatchStatement in Cassandra correctly?如何在 Cassandra 中正确配置和执行 BatchStatement?
【发布时间】:2021-03-23 22:48:24
【问题描述】:

在我的 Python (3.8) 应用程序中,我通过 DataStax Python Driver 3.24Cassandra 数据库发出请求。

根据官方文档,我尝试通过BatchStatement 使用单个查询执行多个 CQL 操作。不幸的是,我的代码导致了以下内容的错误:

"errorMessage": "retry_policy should implement cassandra.policies.RetryPolicy"
"errorType": "ValueError"

从我的代码中可以看出,我在BatchStatement 中设置了reply_policy 属性的值。无论如何,我的代码会引发您在上面看到的错误。 reply_policy 属性中必须包含什么样的值?当前冲突的原因是什么?

代码片段

from cassandra.cluster import Cluster, ExecutionProfile, EXEC_PROFILE_DEFAULT
from cassandra.auth import PlainTextAuthProvider
from cassandra.policies import DCAwareRoundRobinPolicy
from cassandra import ConsistencyLevel
from cassandra.query import dict_factory
from cassandra.query import BatchStatement, SimpleStatement
from cassandra.policies import RetryPolicy


auth_provider = PlainTextAuthProvider(username=db_username, password=db_password)
default_profile = ExecutionProfile(
   load_balancing_policy=DCAwareRoundRobinPolicy(local_dc=db_local_dc),
   consistency_level=ConsistencyLevel.LOCAL_QUORUM,
   request_timeout=60,
   row_factory=dict_factory
)
cluster = Cluster(
   db_host,
   auth_provider=auth_provider,
   port=db_port,
   protocol_version=4,
   connect_timeout=60,
   idle_heartbeat_interval=0,
   execution_profiles={EXEC_PROFILE_DEFAULT: default_profile}
)
session = cluster.connect()

name_1, name_2, name_3  = "Bob", "Jack", "Alex"
age_1, age_2, age_3 = 25, 30, 18

cql_statement = "INSERT INTO users (name, age) VALUES (%s, %s)"

batch = BatchStatement(retry_policy=RetryPolicy)
batch.add(SimpleStatement(cql_statement, (name_1, age_1)))
batch.add(SimpleStatement(cql_statement, (name_2, age_2)))
batch.add(SimpleStatement(cql_statement, (name_3, age_3)))
session.execute(batch)

【问题讨论】:

  • 为什么需要那个批次?如果您只想重新插入条目,只需插入 - 它会覆盖现有数据,因为在 Cassandra 中,一切都是 UPSERT ......另外,为什么需要重试策略?留下它,将使用默认的
  • @AlexOtt 你好!正如我在帖子中所说,我有几个 CQL 操作,我试图用一个查询来执行。我了解每个请求都可以单独执行。假设我需要插入一组数据(CQL 查询相同,参数不同)。我已经尝试删除 reply_policy 属性,但错误仍然存​​在。默认情况下,它设置为None,如果您查看BatchStatement 的内部情况。朋友,你有什么想法吗?
  • 在同一个主键上批量删除 + 插入很棘手,并且可能不会像您认为的那样表现...请在帖子中扩展您想要实现的目标,而不是您如何想要达到。为什么首先需要删除+插入组合。此外,添加表的架构会有所帮助
  • 我明白了。这里的帖子只是一个例子。我实际上只需要使用不同的参数执行INSERT 操作。我更新了帖子。可以看看吗?

标签: python python-3.x cassandra nosql datastax-python-driver


【解决方案1】:

嗯,我终于找到了错误。

我从BatchStatement 中删除了retry_policy 属性。然后我的错误是我将 CQL 参数放在 SimpleStatement 中。

这里是工作示例代码 sn-p:

...
batch = BatchStatement(batch_type=BatchType.UNLOGGED)
batch.add(SimpleStatement(cql_statement), (name_1, age_1))
batch.add(SimpleStatement(cql_statement), (name_2, age_2))
batch.add(SimpleStatement(cql_statement), (name_3, age_3))
session.execute(batch)

已编辑:

因此,我在 cmets 离开这篇文章的底部后放弃了BatchStatement。我求你注意他们! CQL 批次与 RBDMS 批次不同。 CQL 批处理不是一种优化,而是用于实现跨多个表的非规范化记录的原子更新。

【讨论】:

  • 请不要这样做 - Cassandra 中的批处理不是针对编写的优化。真的,你会让你的插入变慢。改用准备好的语句 + execute_async - 谷歌在 Cassandra 中对批次的坏和好使用
  • 非常感谢您的回复。显然,您是从个人痛苦的经历中这么说的。但是BatchStatement 不应该比执行单个查询更快吗?假设您需要记录 100,000 条记录。蛮力需要很长时间。不是吗?
  • 没有。它不会更快,因为所有负载都将放在协调节点上,协调节点会将查询发送到保存数据的节点,而不是驱动程序将这些查询直接发送到该节点。放置大量数据的最快方法是使用准备好的查询和 execute_async... 或使用 DSBulk 等外部工具
  • 建议从 DataStax 获取免费的 Cassandra 书...
  • 亚历克斯是正确的。 CQL 批次与 RBDMS 批次不同。 CQL 批处理不是一种优化,而是用于实现跨多个表的非规范化记录的原子更新。如果有帮助,我已经在这篇文章中解释了它们——community.datastax.com/articles/2744。干杯!
猜你喜欢
  • 2014-05-04
  • 1970-01-01
  • 2021-06-26
  • 2015-02-24
  • 2017-01-20
  • 2020-03-31
  • 1970-01-01
  • 2023-04-04
  • 2021-11-23
相关资源
最近更新 更多