带有cassandra和python的快速时间序列批量插入

时间:2016-11-07 11:32:34

标签: python cassandra time-series bulkinsert influxdb

我正在尝试使用cassandra python客户端找到在Cassandra中插入时间序列数据的最快方法。我在localhost上运行。

准备代码如下:

session.execute("CREATE KEYSPACE testt WITH replication = {'class' : 'SimpleStrategy', 'replication_factor': '1'}")
session.set_keyspace('testt')
session.execute('CREATE TABLE t (id text, time timestamp, t float, PRIMARY KEY (id, time))')

prepared = session.prepare("""
    INSERT INTO t (id, time, t)
    VALUES (?, ?, ?)
    """)

index = pd.date_range("2003-01-01", "2004-01-01", freq="1min")
t = np.random.rand(len(index))*2-1
df = pd.DataFrame({'time': index, 't': t}).set_index('time')

print(len(df))
# 525601

然后我尝试了两种策略。第一种是使用BatchStatements:

before = datetime.datetime.now()
x = 0
delta = 65535
while x < len(df):
    batch = BatchStatement(cassandra.query.BatchType.UNLOGGED)
    for i, r in df.iloc[x : x + delta].iterrows():
        batch.add(prepared, ("ID1", i, r['t']))
    session.execute(batch)    
    x += delta  
print("Elapsed: {}".format(datetime.datetime.now() - before)) 
# Elapsed: 0:01:01.341848

请注意,65535跳转是由BatchStatement大小的上限引起的。

..第二个是使用execute_async:

before = datetime.datetime.now()
for i, r in df.iterrows():
    session.execute_async(prepared.bind(("ID1", i, r['t'])))
print("Elapsed: {}".format(datetime.datetime.now() - before)) 
# Elapsed: 0:03:51.169409

我也尝试过使用InfluxDB(使用其DataFrame客户端)的相同场景,其中相同的插入大约需要5秒。所以我的问题是,如果成为某种反模式的受害者(我阅读了一些博客文章,但似乎做得不错),或者如果使用Cassandra这种类型的插入只是x12慢。

有扩展到更多服务器节点的空间 - 或客户端的python多处理等 - 但我想先了解单节点性能。

任何指针都会非常感激!

1 个答案:

答案 0 :(得分:1)

批处理(特殊用例除外)总是比插入它们慢。为了提高性能而进行 unlogged 批处理的主要情况是,它们都属于同一个分区,而不是你的分区。

cqlsh的GetIdToken可能与使用python驱动程序时看到的速度一样快。您可以看到经过大量优化的代码https://github.com/apache/cassandra/blob/trunk/pylib/cqlshlib/copyutil.py