我正在尝试将大量数据加载到 10 节点 Cassandra 环中。
执行插入的脚本获得约 4000 次插入 / 秒,大概在网络 I/O 上被阻塞。我在一台机器上启动了其中的 8 个,吞吐量几乎呈线性增长。(单个吞吐量略有下降,但通过额外的流程得到了更多的补偿。)
这工作得很好,但是,我仍然没有获得足够的吞吐量,所以我在另外 3 个虚拟机上启动了相同的设置。(因此,8 个进程 * 4 个 VM)在第一个附加 VM 之后,随着进一步 VM 的添加频率和严重性的增加,会发生以下情况:
- 客户端开始接收超时错误。他们可以重新尝试他们的写入,但因为他们是分批这样做的,他们的前进进度几乎完全被消除了。
- 环变得不稳定,节点开始将自己标记为“关闭”。此外,不同的节点往往对谁宕机有不同的想法。脚本中止时环不会恢复。(我什至无法通过重启单个节点来解决这个问题:我不得不重启整个环。)
“下”不一。在我最后一次运行中:
- 4 个节点完全死亡。(Cassandra 根本没有运行。)检查日志,似乎没有任何关于它为什么死亡的记录。
- 第五天,卡桑德拉正在奔跑。
nodetool status
在那个节点上挂起。两个线程似乎处于某种无限循环中。(他们一直在使用 100% 的 CPU。)java.lang.OutOfMemoryError: Java heap space
日志中有一个。
代码本质上是:
def prepped_batch_insert(session, items, insert_query, silent=False):
# A mapping of number of inserts -> a prepared query for that number of
# inserts.
prepped_statements = {}
def get_prepped_statement(inserts):
if inserts in prepped:
# We already created a prepared query for this many inserts, use
# it:
return prepped_statements[inserts]
else:
# We haven't yet created a prepared query for this many inserts, so
# do so now:
query = ['BEGIN UNLOGGED BATCH']
for idx in xrange(inserts):
query.append(insert_query.query)
query.append('APPLY BATCH;')
query = '\n'.join(query)
ps = session.prepare(query)
prepped_statements[inserts] = ps
return ps
def do_prepped_batch_insert(batch)
ps = get_prepped_statement(len(batch))
# Generate the list of params to the prepared query:
params = []
for idx, item in enumerate(batch):
for k in insert_query.keyorder:
params.append(item[k])
# Do it.
session.execute(ps, params)
return inserter.insert_and_time(
items, # data generator
do_prepped_batch_insert, # The above function
_WHAT_APPEARS_TO_BE_THE_OPTIMAL_CASSANDRA_BATCH_SIZE, # = 200
silent=silent,
)
该函数insert_and_time
分成items
大小为 200 的批次,调用上述函数,并对整个套件和 kaboodle 进行计时。(此代码对戒指有毒。)
我们尝试了更多的读取,因为(有人告诉我)每秒 20k 的插入速度很慢(以这种速度插入我想插入的数据需要一段时间……),而且 Cassandra 具有高容量。
我的问题:
- 我在做什么有什么不寻常的地方吗?哪里不对了?
- 我只是对我的戒指进行 DDoS 攻击吗?
- 我该如何去调试有什么问题?
- 一个错误的客户端,恕我直言,永远不能杀死服务器。(以上内容并没有非常错误。)我能做些什么来防止这种情况发生?
¹客户端似乎也慢慢泄漏文件描述符。我不认为这是相关的。(我.shutdown
同时调用集群和连接。)查看驱动程序源,似乎有很多异常会导致泄漏的路径。