Cassandra性能低下?
我需要在Cassandra和MongoDB(或者其他NoSQL数据库,欢迎推荐)之间做选择,因为我的项目需要处理大量的数据插入(每天大约100万条)。所以我写了一个小测试来测量写入性能。以下是插入Cassandra的代码:
import time
import os
import random
import string
import pycassa
def get_random_string(string_length):
return ''.join(random.choice(string.letters) for i in xrange(string_length))
def connect():
"""Connect to a test database"""
connection = pycassa.connect('test_keyspace', ['localhost:9160'])
db = pycassa.ColumnFamily(connection,'foo')
return db
def random_insert(db):
"""Insert a record into the database. The record has the following format
ID timestamp
4 random strings
3 random integers"""
record = {}
record['id'] = str(time.time())
record['str1'] = get_random_string(64)
record['str2'] = get_random_string(64)
record['str3'] = get_random_string(64)
record['str4'] = get_random_string(64)
record['num1'] = str(random.randint(0, 100))
record['num2'] = str(random.randint(0, 1000))
record['num3'] = str(random.randint(0, 10000))
db.insert(str(time.time()), record)
if __name__ == "__main__":
db = connect()
start_time = time.time()
for i in range(1000000):
random_insert(db)
end_time = time.time()
print "Insert time: %lf " %(end_time - start_time)
而插入MongoDB的代码基本相同,只是连接函数不同:
def connect():
"""Connect to a test database"""
connection = pymongo.Connection('localhost', 27017)
db = connection.test_insert
return db.foo2
测试结果显示,插入Cassandra大约需要1046秒,而插入MongoDB只需要437秒。按理说,Cassandra在插入数据方面应该比MongoDB快很多。那么,我哪里做错了呢?
5 个回答
当你有多个节点同时运行时,你才能真正发挥Cassandra的强大功能。任何一个节点都可以处理写入请求。如果你只是让客户端同时发送很多请求到同一个节点,这样做并不会有太大帮助,反而可能会造成拥堵。
- 在测试期间,查看Cassandra的日志,看看发生了什么。Cassandra会在内存表(Memtable)满了之后开始写入磁盘(这个设置是可以调整的,设置得大一些,你就会在内存和磁盘的提交日志之间进行处理)。如果在你的测试过程中,内存表需要写入磁盘,那么性能就会受到影响。我不太清楚MongoDB是什么时候写入磁盘的。
如果我没记错的话,Cassandra 允许你选择是否进行类似于 MongoDB 的“安全模式”插入。(我不太记得 Cassandra 里这个功能的名字了)
换句话说,Cassandra 可以设置为先把数据写入磁盘,然后再返回结果,而不是像 MongoDB 默认那样,插入后立刻返回,但并不知道插入是否成功。也就是说,你的应用程序不会等待服务器确认插入是否成功。
你可以通过在 MongoDB 中使用安全模式来改变这种行为,但这样做会对性能产生很大的影响。开启安全模式后,你可能会看到不同的结果。
Cassandra没有MongoDB那种不安全模式的功能。(我们以前有过,但后来把它去掉了,因为这真的是个坏主意。)
另一个主要问题是你在进行单线程插入。Cassandra是为了处理高并发而设计的;你需要使用多线程测试。可以看看http://spyced.blogspot.com/2010/01/cassandra-05.html底部的图表(虽然实际数据已经过时一年多,但原理依然成立)。
Cassandra的源代码分发包里包含了这样的测试,放在contrib/stress文件夹里。